summaryrefslogtreecommitdiff
path: root/coverage/report.py
diff options
context:
space:
mode:
Diffstat (limited to 'coverage/report.py')
-rw-r--r--coverage/report.py70
1 files changed, 43 insertions, 27 deletions
diff --git a/coverage/report.py b/coverage/report.py
index 33a46070..609dc2de 100644
--- a/coverage/report.py
+++ b/coverage/report.py
@@ -1,9 +1,15 @@
-"""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
+from coverage.misc import CoverageException, NoSource, NotPython, isolate_module
+
+os = isolate_module(os)
class Reporter(object):
@@ -19,40 +25,45 @@ class Reporter(object):
self.coverage = coverage
self.config = config
- # The FileReporters to report on. Set by find_file_reporters.
- self.file_reporters = []
-
# The directory into which to place the report, used by some derived
# classes.
self.directory = None
+ # 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 = []
+
+ @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 filenames.
+ `morfs` is a list of modules or file names.
+
+ Returns a list of FileReporters.
"""
- self.file_reporters = self.coverage._get_file_reporters(morfs)
+ reporters = self.coverage._get_file_reporters(morfs)
if self.config.include:
- patterns = prep_patterns(self.config.include)
- matcher = FnmatchMatcher(patterns)
- filtered = []
- for fr in self.file_reporters:
- if matcher.match(fr.filename):
- filtered.append(fr)
- self.file_reporters = 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)
- matcher = FnmatchMatcher(patterns)
- filtered = []
- for fr in self.file_reporters:
- if not matcher.match(fr.filename):
- filtered.append(fr)
- self.file_reporters = filtered
+ matcher = FnmatchMatcher(prep_patterns(self.config.omit))
+ reporters = [fr for fr in reporters if not matcher.match(fr.filename)]
- self.file_reporters.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.
@@ -66,16 +77,16 @@ class Reporter(object):
`analysis` is the `Analysis` for the morf.
"""
- self.find_file_reporters(morfs)
+ file_reporters = self.find_file_reporters(morfs)
- if not self.file_reporters:
+ 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 fr in self.file_reporters:
+ for fr in file_reporters:
try:
report_fn(fr, self.coverage._analyze(fr))
except NoSource:
@@ -84,5 +95,10 @@ class Reporter(object):
except NotPython:
# Only report errors for .py files, and only if we didn't
# explicitly suppress those errors.
- if fr.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