diff options
Diffstat (limited to 'coverage')
-rw-r--r-- | coverage/cmdline.py | 2 | ||||
-rw-r--r-- | coverage/config.py | 3 | ||||
-rw-r--r-- | coverage/control.py | 27 | ||||
-rw-r--r-- | coverage/data.py | 10 | ||||
-rw-r--r-- | coverage/misc.py | 8 |
5 files changed, 36 insertions, 14 deletions
diff --git a/coverage/cmdline.py b/coverage/cmdline.py index 5f1919d0..e82cf27c 100644 --- a/coverage/cmdline.py +++ b/coverage/cmdline.py @@ -427,7 +427,7 @@ class CoverageScript(object): # Do something. self.coverage = self.covpkg.coverage( - data_suffix = bool(options.parallel_mode), + data_suffix = options.parallel_mode, cover_pylib = options.pylib, timid = options.timid, branch = options.branch, diff --git a/coverage/config.py b/coverage/config.py index 3248177e..b8f114a9 100644 --- a/coverage/config.py +++ b/coverage/config.py @@ -18,6 +18,7 @@ class CoverageConfig(object): self.branch = False self.cover_pylib = False self.data_file = ".coverage" + self.parallel = False self.timid = False # Defaults for [report] @@ -56,6 +57,8 @@ class CoverageConfig(object): self.cover_pylib = cp.getboolean('run', 'cover_pylib') if cp.has_option('run', 'data_file'): self.data_file = cp.get('run', 'data_file') + if cp.has_option('run', 'parallel'): + self.parallel = cp.getboolean('run', 'parallel') if cp.has_option('run', 'timid'): self.timid = cp.getboolean('run', 'timid') diff --git a/coverage/control.py b/coverage/control.py index 18fc2aa6..0e60fc53 100644 --- a/coverage/control.py +++ b/coverage/control.py @@ -10,6 +10,7 @@ from coverage.config import CoverageConfig from coverage.data import CoverageData from coverage.files import FileLocator from coverage.html import HtmlReporter +from coverage.misc import bool_or_none from coverage.results import Analysis from coverage.summary import SummaryReporter from coverage.xmlreport import XmlReporter @@ -29,13 +30,13 @@ class coverage(object): """ - def __init__(self, data_file=None, data_suffix=False, cover_pylib=None, + def __init__(self, data_file=None, data_suffix=None, cover_pylib=None, auto_data=False, timid=None, branch=None, config_file=True): """ `data_file` is the base name of the data file to use, defaulting to - ".coverage". `data_suffix` is appended to `data_file` to create the - final file name. If `data_suffix` is simply True, then a suffix is - created with the machine and process identity included. + ".coverage". `data_suffix` is appended (with a dot) to `data_file` to + create the final file name. If `data_suffix` is simply True, then a + suffix is created with the machine and process identity included. `cover_pylib` is a boolean determining whether Python code installed with the Python interpreter is measured. This includes the Python @@ -79,7 +80,7 @@ class coverage(object): # 4: from constructor arguments: self.config.from_args( data_file=data_file, cover_pylib=cover_pylib, timid=timid, - branch=branch + branch=branch, parallel=bool_or_none(data_suffix) ) self.auto_data = auto_data @@ -96,11 +97,11 @@ class coverage(object): ) # Create the data file. - if data_suffix: + if data_suffix or self.config.parallel: if not isinstance(data_suffix, string_class): # if data_suffix=True, use .machinename.pid.random - data_suffix = ".%s.%s.%06d" % ( - socket.gethostname(), os.getpid(), random.randint(0,999999) + data_suffix = "%s.%s.%06d" % ( + socket.gethostname(), os.getpid(), random.randint(0, 999999) ) else: data_suffix = None @@ -250,6 +251,14 @@ class coverage(object): current measurements. """ + # If the .coveragerc file specifies parallel=True, then self.data + # already points to a suffixed data file. This won't be right for + # combining, so make a new self.data with no suffix. + from coverage import __version__ + self.data = CoverageData( + basename=self.config.data_file, + collector="coverage v%s" % __version__ + ) self.data.combine_parallel_data() def _harvest_data(self): @@ -412,7 +421,7 @@ def process_startup(): """ cps = os.environ.get("COVERAGE_PROCESS_START") if cps: - cov = coverage(config_file=cps, auto_data=True, data_suffix=True) + cov = coverage(config_file=cps, auto_data=True) if os.environ.get("COVERAGE_COVERAGE"): # Measuring coverage within coverage.py takes yet more trickery. cov.cover_prefix = "Please measure coverage.py!" diff --git a/coverage/data.py b/coverage/data.py index f9d0edbd..9359af12 100644 --- a/coverage/data.py +++ b/coverage/data.py @@ -34,7 +34,8 @@ class CoverageData(object): `suffix` is a suffix to append to the base file name. This can be used for multiple or parallel execution, so that many coverage data files - can exist simultaneously. + can exist simultaneously. A dot will be used to join the base name and + the suffix. `collector` is a string describing the coverage measurement software. @@ -47,7 +48,7 @@ class CoverageData(object): # ever do any file storage. self.filename = basename or ".coverage" if suffix: - self.filename += suffix + self.filename += "." + suffix self.filename = os.path.abspath(self.filename) # A map from canonical Python source file name to a dictionary in @@ -168,12 +169,13 @@ class CoverageData(object): """Combine a number of data files together. Treat `self.filename` as a file prefix, and combine the data from all - of the data files starting with that prefix. + of the data files starting with that prefix plus a dot. """ data_dir, local = os.path.split(self.filename) + localdot = local + '.' for f in os.listdir(data_dir or '.'): - if f.startswith(local): + if f.startswith(localdot): full_path = os.path.join(data_dir, f) new_lines, new_arcs = self._read_file(full_path) for filename, file_data in new_lines.items(): diff --git a/coverage/misc.py b/coverage/misc.py index 0e6bcf99..4959efe0 100644 --- a/coverage/misc.py +++ b/coverage/misc.py @@ -60,6 +60,14 @@ def expensive(fn): return _wrapped +def bool_or_none(b): + """Return bool(b), but preserve None.""" + if b is None: + return None + else: + return bool(b) + + class CoverageException(Exception): """An exception specific to Coverage.""" pass |