summaryrefslogtreecommitdiff
path: root/coverage
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2015-10-03 16:59:46 -0400
committerNed Batchelder <ned@nedbatchelder.com>2015-10-03 16:59:46 -0400
commita877aaf13d9f72ee317b392c86313a3003bcb3b8 (patch)
tree22fdb568fd85c4179774fdfb4024486e37d3e1ce /coverage
parentb27f9eab849696b46e9fbb84dcdc0f34078684d1 (diff)
downloadpython-coveragepy-git-a877aaf13d9f72ee317b392c86313a3003bcb3b8.tar.gz
Combine can now ignore errors.
Diffstat (limited to 'coverage')
-rw-r--r--coverage/cmdline.py11
-rw-r--r--coverage/config.py6
-rw-r--r--coverage/control.py13
-rw-r--r--coverage/data.py25
4 files changed, 45 insertions, 10 deletions
diff --git a/coverage/cmdline.py b/coverage/cmdline.py
index 2802948e..6f5719fd 100644
--- a/coverage/cmdline.py
+++ b/coverage/cmdline.py
@@ -58,6 +58,10 @@ class Opts(object):
'-i', '--ignore-errors', action='store_true',
help="Ignore errors while reading source files.",
)
+ ignore_combine_errors = optparse.make_option(
+ '-i', '--ignore-errors', action='store_true',
+ help="Ignore errors while reading data files.",
+ )
include = optparse.make_option(
'', '--include', action='store',
metavar="PAT1,PAT2,...",
@@ -265,7 +269,10 @@ CMDS = {
),
'combine': CmdOptionParser(
- "combine", GLOBAL_ARGS,
+ "combine",
+ [
+ Opts.ignore_combine_errors,
+ ] + GLOBAL_ARGS,
usage="<path1> <path2> ... <pathN>",
description=(
"Combine data from multiple coverage files collected "
@@ -464,7 +471,7 @@ class CoverageScript(object):
elif options.action == "combine":
self.coverage.load()
data_dirs = args or None
- self.coverage.combine(data_dirs)
+ self.coverage.combine(data_dirs, ignore_errors=options.ignore_errors)
self.coverage.save()
return OK
diff --git a/coverage/config.py b/coverage/config.py
index 458d4903..8aff41dc 100644
--- a/coverage/config.py
+++ b/coverage/config.py
@@ -162,6 +162,9 @@ class CoverageConfig(object):
self.source = None
self.timid = False
+ # Defaults for [combine]
+ self.ignore_combine_errors = False
+
# Defaults for [report]
self.exclude_list = DEFAULT_EXCLUDE[:]
self.fail_under = 0
@@ -277,6 +280,9 @@ class CoverageConfig(object):
('source', 'run:source', 'list'),
('timid', 'run:timid', 'boolean'),
+ # [combine]
+ ('ignore_combine_errors', 'combine:ignore_errors', 'boolean'),
+
# [report]
('exclude_list', 'report:exclude_lines', 'regexlist'),
('fail_under', 'report:fail_under', 'int'),
diff --git a/coverage/control.py b/coverage/control.py
index 16b09c84..77737181 100644
--- a/coverage/control.py
+++ b/coverage/control.py
@@ -279,7 +279,7 @@ class Coverage(object):
# data file will be written into the directory where the process
# started rather than wherever the process eventually chdir'd to.
self.data = CoverageData(debug=self.debug)
- self.data_files = CoverageDataFiles(basename=self.config.data_file)
+ self.data_files = CoverageDataFiles(basename=self.config.data_file, warn=self._warn)
# The directories for files considered "installed with the interpreter".
self.pylib_dirs = set()
@@ -757,7 +757,7 @@ class Coverage(object):
self.get_data()
self.data_files.write(self.data, suffix=self.data_suffix)
- def combine(self, data_paths=None):
+ def combine(self, data_paths=None, ignore_errors=None):
"""Combine together a number of similarly-named coverage data files.
All coverage data files whose name starts with `data_file` (from the
@@ -776,6 +776,8 @@ class Coverage(object):
self._init()
self.get_data()
+ self.config.from_args(ignore_combine_errors=ignore_errors)
+
aliases = None
if self.config.paths:
aliases = PathAliases()
@@ -784,7 +786,12 @@ class Coverage(object):
for pattern in paths[1:]:
aliases.add(pattern, result)
- self.data_files.combine_parallel_data(self.data, aliases=aliases, data_paths=data_paths)
+ self.data_files.combine_parallel_data(
+ self.data,
+ aliases=aliases,
+ data_paths=data_paths,
+ ignore_errors=self.config.ignore_combine_errors,
+ )
def get_data(self):
"""Get the collected data and reset the collector.
diff --git a/coverage/data.py b/coverage/data.py
index c608f489..b8d9dadf 100644
--- a/coverage/data.py
+++ b/coverage/data.py
@@ -601,12 +601,15 @@ class CoverageData(object):
class CoverageDataFiles(object):
"""Manage the use of coverage data files."""
- def __init__(self, basename=None):
+ def __init__(self, basename=None, warn=None):
"""Create a CoverageDataFiles to manage data files.
+ `warn` is the warning function to use.
+
`basename` is the name of the file to use for storing data.
"""
+ self.warn = warn
# Construct the file name that will be used for data storage.
self.filename = os.path.abspath(basename or ".coverage")
@@ -659,7 +662,7 @@ class CoverageDataFiles(object):
filename += "." + suffix
data.write_file(filename)
- def combine_parallel_data(self, data, aliases=None, data_paths=None):
+ def combine_parallel_data(self, data, aliases=None, data_paths=None, ignore_errors=False):
"""Combine a number of data files together.
Treat `self.filename` as a file prefix, and combine the data from all
@@ -677,6 +680,9 @@ class CoverageDataFiles(object):
Every data file found and combined is then deleted from disk.
+ If `ignore_errors` is True, then files that cannot be read will cause
+ a warning, and will not be deleted.
+
"""
# Because of the os.path.abspath in the constructor, data_dir will
# never be an empty string.
@@ -696,9 +702,18 @@ class CoverageDataFiles(object):
for f in files_to_combine:
new_data = CoverageData()
- new_data.read_file(f)
- data.update(new_data, aliases=aliases)
- file_be_gone(f)
+ try:
+ new_data.read_file(f)
+ except CoverageException as exc:
+ if not ignore_errors:
+ raise
+ if self.warn:
+ # The CoverageException has the file name in it, so just
+ # use the message as the warning.
+ self.warn(str(exc))
+ else:
+ data.update(new_data, aliases=aliases)
+ file_be_gone(f)
def canonicalize_json_data(data):