summaryrefslogtreecommitdiff
path: root/coverage
diff options
context:
space:
mode:
Diffstat (limited to 'coverage')
-rw-r--r--coverage/cmdline.py2
-rw-r--r--coverage/config.py3
-rw-r--r--coverage/control.py27
-rw-r--r--coverage/data.py10
-rw-r--r--coverage/misc.py8
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