Update bundled coverage.py to version 4.2.0

This commit is contained in:
Dmitry Trofimov
2016-10-18 21:09:33 +02:00
parent 59bbcccc61
commit e784e6fed1
42 changed files with 6223 additions and 3804 deletions

View File

@@ -1,9 +1,16 @@
"""Reporter foundation for Coverage."""
# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
# For details: https://bitbucket.org/ned/coveragepy/src/default/NOTICE.txt
"""Reporter foundation for coverage.py."""
import os
import warnings
from coverage.files import prep_patterns, FnmatchMatcher
from coverage.misc import CoverageException, NoSource, NotPython, isolate_module
os = isolate_module(os)
import fnmatch, os
from coverage.codeunit import code_unit_factory
from coverage.files import prep_patterns
from coverage.misc import CoverageException, NoSource, NotPython
class Reporter(object):
"""A base class for all reporters."""
@@ -18,45 +25,45 @@ class Reporter(object):
self.coverage = coverage
self.config = config
# The code units to report on. Set by find_code_units.
self.code_units = []
# The directory into which to place the report, used by some derived
# classes.
self.directory = None
def find_code_units(self, morfs):
"""Find the code units we'll report on.
# Our method find_file_reporters used to set an attribute that other
# code could read. That's been refactored away, but some third parties
# were using that attribute. We'll continue to support it in a noisy
# way for now.
self._file_reporters = []
`morfs` is a list of modules or filenames.
@property
def file_reporters(self):
"""Keep .file_reporters working for private-grabbing tools."""
warnings.warn(
"Report.file_reporters will no longer be available in Coverage.py 4.2",
DeprecationWarning,
)
return self._file_reporters
def find_file_reporters(self, morfs):
"""Find the FileReporters we'll report on.
`morfs` is a list of modules or file names.
Returns a list of FileReporters.
"""
morfs = morfs or self.coverage.data.measured_files()
file_locator = self.coverage.file_locator
self.code_units = code_unit_factory(morfs, file_locator)
reporters = self.coverage._get_file_reporters(morfs)
if self.config.include:
patterns = prep_patterns(self.config.include)
filtered = []
for cu in self.code_units:
for pattern in patterns:
if fnmatch.fnmatch(cu.filename, pattern):
filtered.append(cu)
break
self.code_units = filtered
matcher = FnmatchMatcher(prep_patterns(self.config.include))
reporters = [fr for fr in reporters if matcher.match(fr.filename)]
if self.config.omit:
patterns = prep_patterns(self.config.omit)
filtered = []
for cu in self.code_units:
for pattern in patterns:
if fnmatch.fnmatch(cu.filename, pattern):
break
else:
filtered.append(cu)
self.code_units = filtered
matcher = FnmatchMatcher(prep_patterns(self.config.omit))
reporters = [fr for fr in reporters if not matcher.match(fr.filename)]
self.code_units.sort()
self._file_reporters = sorted(reporters)
return self._file_reporters
def report_files(self, report_fn, morfs, directory=None):
"""Run a reporting function on a number of morfs.
@@ -64,29 +71,34 @@ class Reporter(object):
`report_fn` is called for each relative morf in `morfs`. It is called
as::
report_fn(code_unit, analysis)
report_fn(file_reporter, analysis)
where `code_unit` is the `CodeUnit` for the morf, and `analysis` is
the `Analysis` for the morf.
where `file_reporter` is the `FileReporter` for the morf, and
`analysis` is the `Analysis` for the morf.
"""
self.find_code_units(morfs)
file_reporters = self.find_file_reporters(morfs)
if not self.code_units:
if not file_reporters:
raise CoverageException("No data to report.")
self.directory = directory
if self.directory and not os.path.exists(self.directory):
os.makedirs(self.directory)
for cu in self.code_units:
for fr in file_reporters:
try:
report_fn(cu, self.coverage._analyze(cu))
report_fn(fr, self.coverage._analyze(fr))
except NoSource:
if not self.config.ignore_errors:
raise
except NotPython:
# Only report errors for .py files, and only if we didn't
# explicitly suppress those errors.
if cu.should_be_python() and not self.config.ignore_errors:
raise
# NotPython is only raised by PythonFileReporter, which has a
# should_be_python() method.
if fr.should_be_python():
if self.config.ignore_errors:
self.coverage._warn("Could not parse Python file {0}".format(fr.filename))
else:
raise