summaryrefslogtreecommitdiff
path: root/coverage/multiproc.py
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2016-07-24 09:39:47 -0400
committerNed Batchelder <ned@nedbatchelder.com>2016-07-24 09:39:47 -0400
commit9ca201f512d16e542f8cd4e8b83f87fe1beac4d5 (patch)
treea4e6d90cfdd32d9d37ae7cfe0f4acbd633df8c00 /coverage/multiproc.py
parentae89878f20e6ef2009d8351668ffa522a02f6c7b (diff)
downloadpython-coveragepy-git-9ca201f512d16e542f8cd4e8b83f87fe1beac4d5.tar.gz
Set the rcfile for multiprocessing subprocesses
Diffstat (limited to 'coverage/multiproc.py')
-rw-r--r--coverage/multiproc.py25
1 files changed, 19 insertions, 6 deletions
diff --git a/coverage/multiproc.py b/coverage/multiproc.py
index f9341ef8..78c680c7 100644
--- a/coverage/multiproc.py
+++ b/coverage/multiproc.py
@@ -5,11 +5,18 @@
import multiprocessing
import multiprocessing.process
+import os
import sys
-# An attribute that will be set on modules to indicate that they have been
+from coverage.misc import contract
+
+# An attribute that will be set on the module to indicate that it has been
# monkey-patched.
-PATCHED_MARKER = "_coverage$rcfile"
+PATCHED_MARKER = "_coverage$patched"
+
+# The environment variable that specifies the rcfile for subprocesses.
+COVERAGE_RCFILE_ENV = "_COVERAGE_RCFILE"
+
if sys.version_info >= (3, 4):
OriginalProcess = multiprocessing.process.BaseProcess
@@ -18,13 +25,13 @@ else:
original_bootstrap = OriginalProcess._bootstrap
-
class ProcessWithCoverage(OriginalProcess):
"""A replacement for multiprocess.Process that starts coverage."""
+
def _bootstrap(self):
"""Wrapper around _bootstrap to start coverage."""
- from coverage import Coverage
- rcfile = getattr(multiprocessing, PATCHED_MARKER)
+ from coverage import Coverage # avoid circular import
+ rcfile = os.environ[COVERAGE_RCFILE_ENV]
cov = Coverage(data_suffix=True, config_file=rcfile)
cov.start()
try:
@@ -46,6 +53,7 @@ class Stowaway(object):
patch_multiprocessing(state['rcfile'])
+@contract(rcfile=str)
def patch_multiprocessing(rcfile):
"""Monkey-patch the multiprocessing module.
@@ -55,6 +63,7 @@ def patch_multiprocessing(rcfile):
`rcfile` is the path to the rcfile being used.
"""
+
if hasattr(multiprocessing, PATCHED_MARKER):
return
@@ -63,6 +72,10 @@ def patch_multiprocessing(rcfile):
else:
multiprocessing.Process = ProcessWithCoverage
+ # Set the value in ProcessWithCoverage that will be pickled into the child
+ # process.
+ os.environ[COVERAGE_RCFILE_ENV] = rcfile
+
# When spawning processes rather than forking them, we have no state in the
# new process. We sneak in there with a Stowaway: we stuff one of our own
# objects into the data that gets pickled and sent to the sub-process. When
@@ -83,4 +96,4 @@ def patch_multiprocessing(rcfile):
spawn.get_preparation_data = get_preparation_data_with_stowaway
- setattr(multiprocessing, PATCHED_MARKER, rcfile)
+ setattr(multiprocessing, PATCHED_MARKER, True)