--- a/DebugClients/Python3/coverage/data.py Sat Jul 23 13:33:54 2016 +0200 +++ b/DebugClients/Python3/coverage/data.py Sun Jul 24 12:01:01 2016 +0200 @@ -4,6 +4,7 @@ """Coverage data for coverage.py.""" import glob +import itertools import json import optparse import os @@ -16,7 +17,9 @@ from coverage.backward import iitems, string_class from coverage.debug import _TEST_NAME_FILE from coverage.files import PathAliases -from coverage.misc import CoverageException, file_be_gone +from coverage.misc import CoverageException, file_be_gone, isolate_module + +os = isolate_module(os) class CoverageData(object): @@ -176,11 +179,12 @@ """ if self._arcs is not None: - if filename in self._arcs: - return [s for s, __ in self._arcs[filename] if s > 0] + arcs = self._arcs.get(filename) + if arcs is not None: + all_lines = itertools.chain.from_iterable(arcs) + return list(set(l for l in all_lines if l > 0)) elif self._lines is not None: - if filename in self._lines: - return self._lines[filename] + return self._lines.get(filename) return None def arcs(self, filename): @@ -574,7 +578,7 @@ def add_to_hash(self, filename, hasher): """Contribute `filename`'s data to the `hasher`. - `hasher` is a :class:`coverage.misc.Hasher` instance to be updated with + `hasher` is a `coverage.misc.Hasher` instance to be updated with the file's data. It should only get the results data, not the run data. @@ -601,12 +605,15 @@ 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") @@ -675,7 +682,9 @@ If `data_paths` is not provided, then the directory portion of `self.filename` is used as the directory to search for data files. - Every data file found and combined is then deleted from disk. + Every data file found and combined is then deleted from disk. If a file + cannot be read, a warning will be issued, and the file will not be + deleted. """ # Because of the os.path.abspath in the constructor, data_dir will @@ -696,9 +705,16 @@ 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 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):