diff options
-rw-r--r-- | AUTHORS.txt | 1 | ||||
-rw-r--r-- | CHANGES.rst | 3 | ||||
-rw-r--r-- | coverage/monkey.py | 42 | ||||
-rw-r--r-- | igor.py | 7 | ||||
-rw-r--r-- | tests/test_concurrency.py | 7 | ||||
-rw-r--r-- | tests/test_phystokens.py | 11 |
6 files changed, 41 insertions, 30 deletions
diff --git a/AUTHORS.txt b/AUTHORS.txt index de3d6502..0033ec71 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -55,6 +55,7 @@ Noel O'Boyle Pablo Carballo Patrick Mezard Peter Portante +Rodrigue Cloutier Roger Hu Ross Lawley Sandra Martocchia diff --git a/CHANGES.rst b/CHANGES.rst index 76b71a5f..f578f291 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -13,6 +13,9 @@ Unreleased and they will apply to the entire function or class being decorated. This implements the feature requested in `issue 131`_. +- Multiprocessing support is now available on Windows. Thanks, Rodrigue + Cloutier. + .. _issue 131: https://bitbucket.org/ned/coveragepy/issues/131/pragma-on-a-decorator-line-should-affect diff --git a/coverage/monkey.py b/coverage/monkey.py index c4ec68c6..b896dbf5 100644 --- a/coverage/monkey.py +++ b/coverage/monkey.py @@ -11,6 +11,28 @@ import sys # monkey-patched. PATCHED_MARKER = "_coverage$patched" +if sys.version_info >= (3, 4): + + klass = multiprocessing.process.BaseProcess +else: + klass = multiprocessing.Process + +original_bootstrap = klass._bootstrap + + +class ProcessWithCoverage(klass): + """A replacement for multiprocess.Process that starts coverage.""" + def _bootstrap(self): + """Wrapper around _bootstrap to start coverage.""" + from coverage import Coverage + cov = Coverage(data_suffix=True) + cov.start() + try: + return original_bootstrap(self) + finally: + cov.stop() + cov.save() + def patch_multiprocessing(): """Monkey-patch the multiprocessing module. @@ -23,26 +45,6 @@ def patch_multiprocessing(): return if sys.version_info >= (3, 4): - klass = multiprocessing.process.BaseProcess - else: - klass = multiprocessing.Process - - original_bootstrap = klass._bootstrap - - class ProcessWithCoverage(klass): - """A replacement for multiprocess.Process that starts coverage.""" - def _bootstrap(self): - """Wrapper around _bootstrap to start coverage.""" - from coverage import Coverage - cov = Coverage(data_suffix=True) - cov.start() - try: - return original_bootstrap(self) - finally: - cov.stop() - cov.save() - - if sys.version_info >= (3, 4): klass._bootstrap = ProcessWithCoverage._bootstrap else: multiprocessing.Process = ProcessWithCoverage @@ -328,7 +328,12 @@ def print_banner(label): if '__pypy__' in sys.builtin_module_names: version += " (pypy %s)" % ".".join(str(v) for v in sys.pypy_version_info) - which_python = os.path.relpath(sys.executable) + try: + which_python = os.path.relpath(sys.executable) + except ValueError: + # On Windows having a python executable on a different drives + # than the sources cannot be relative + which_python = sys.executable print('=== %s %s %s (%s) ===' % (impl, version, label, which_python)) sys.stdout.flush() diff --git a/tests/test_concurrency.py b/tests/test_concurrency.py index c6d750d0..0f5ffe95 100644 --- a/tests/test_concurrency.py +++ b/tests/test_concurrency.py @@ -222,13 +222,6 @@ class ConcurrencyTest(CoverageTest): class MultiprocessingTest(CoverageTest): """Test support of the multiprocessing module.""" - def setUp(self): - super(MultiprocessingTest, self).setUp() - # Currently, this doesn't work on Windows, something about pickling - # the monkey-patched Process class? - if env.WINDOWS: - self.skip("Multiprocessing support doesn't work on Windows") - def test_multiprocessing(self): self.make_file("multi.py", """\ import multiprocessing diff --git a/tests/test_phystokens.py b/tests/test_phystokens.py index e28fb176..7acc3225 100644 --- a/tests/test_phystokens.py +++ b/tests/test_phystokens.py @@ -103,6 +103,7 @@ ENCODING_DECLARATION_SOURCES = [ b"# This Python file uses this encoding: cp850\n", b"# This file uses a different encoding:\n# coding: cp850\n", b"\n# coding=cp850\n\n", + b"# -*- coding:cp850 -*-\n# vim: fileencoding=cp850\n", ] class SourceEncodingTest(CoverageTest): @@ -168,6 +169,8 @@ class NeuterEncodingDeclarationTest(CoverageTest): ) self.assertEqual(lines_different, 1) + # The neutered source will be detected as having no encoding + # declaration. self.assertEqual( source_encoding(neutered), DEF_ENCODING, @@ -181,5 +184,9 @@ class CompileUnicodeTest(CoverageTest): run_in_temp_dir = False def test_cp1252(self): - uni = u"""# coding: cp1252\n# \u201C curly \u201D\n""" - compile_unicode(uni, "<string>", "exec") + uni = u"""# coding: cp1252\n# \u201C curly \u201D\na = 42""" + # This doesn't raise an exception: + code = compile_unicode(uni, "<string>", "exec") + globs = {} + exec(code, globs) + self.assertEqual(globs['a'], 42) |