diff options
author | Ned Batchelder <ned@nedbatchelder.com> | 2019-06-16 17:00:16 -0400 |
---|---|---|
committer | Ned Batchelder <ned@nedbatchelder.com> | 2019-06-16 17:00:16 -0400 |
commit | 237ac7a9518d6764a4af5a203d7e07caa7f5891a (patch) | |
tree | b8b7eddd93241fcd11c6f72ae17838da61cdb6bd | |
parent | 3a04a88e88a92882ef92cf6778e42eaf3d4001f4 (diff) | |
download | python-coveragepy-git-237ac7a9518d6764a4af5a203d7e07caa7f5891a.tar.gz |
Get rid of Reporter base class
-rw-r--r-- | coverage/annotate.py | 10 | ||||
-rw-r--r-- | coverage/html.py | 12 | ||||
-rw-r--r-- | coverage/report.py | 122 | ||||
-rw-r--r-- | coverage/summary.py | 10 | ||||
-rw-r--r-- | coverage/xmlreport.py | 10 |
5 files changed, 67 insertions, 97 deletions
diff --git a/coverage/annotate.py b/coverage/annotate.py index 3380dccc..35b21360 100644 --- a/coverage/annotate.py +++ b/coverage/annotate.py @@ -9,12 +9,12 @@ import re from coverage.files import flat_rootname from coverage.misc import ensure_dir, isolate_module -from coverage.report import Reporter +from coverage.report import get_analysis_to_report os = isolate_module(os) -class AnnotateReporter(Reporter): +class AnnotateReporter(object): """Generate annotated source files showing line coverage. This reporter creates annotated copies of the measured source files. Each @@ -37,7 +37,8 @@ class AnnotateReporter(Reporter): """ def __init__(self, coverage, config): - super(AnnotateReporter, self).__init__(coverage, config) + self.coverage = coverage + self.config = config self.directory = None blank_re = re.compile(r"\s*(#|$)") @@ -51,7 +52,8 @@ class AnnotateReporter(Reporter): """ self.directory = directory self.coverage.get_data() - self.report_files(self.annotate_file, morfs) + for fr, analysis in get_analysis_to_report(self.coverage, self.config, morfs): + self.annotate_file(fr, analysis) def annotate_file(self, fr, analysis): """Annotate a single file. diff --git a/coverage/html.py b/coverage/html.py index 629f7d6a..627a19a0 100644 --- a/coverage/html.py +++ b/coverage/html.py @@ -16,7 +16,7 @@ from coverage.backward import iitems from coverage.data import add_data_to_hash from coverage.files import flat_rootname from coverage.misc import CoverageException, ensure_dir, file_be_gone, Hasher, isolate_module -from coverage.report import Reporter +from coverage.report import get_analysis_to_report from coverage.results import Numbers from coverage.templite import Templite @@ -74,7 +74,7 @@ def write_html(fname, html): fout.write(html.encode('ascii', 'xmlcharrefreplace')) -class HtmlReporter(Reporter): +class HtmlReporter(object): """HTML reporting.""" # These files will be copied from the htmlfiles directory to the output @@ -92,7 +92,8 @@ class HtmlReporter(Reporter): ] def __init__(self, cov, config): - super(HtmlReporter, self).__init__(cov, config) + self.coverage = cov + self.config = config self.directory = None title = self.config.html_title if env.PY2: @@ -108,7 +109,7 @@ class HtmlReporter(Reporter): self.pyfile_html_source = read_data("pyfile.html") self.source_tmpl = Templite(self.pyfile_html_source, self.template_globals) - self.data = cov.get_data() + self.data = self.coverage.get_data() self.files = [] self.all_files_nums = [] @@ -146,7 +147,8 @@ class HtmlReporter(Reporter): # Process all the files. self.coverage.get_data().set_query_contexts(self.config.query_contexts) - self.report_files(self.html_file, morfs) + for fr, analysis in get_analysis_to_report(self.coverage, self.config, morfs): + self.html_file(fr, analysis) if not self.all_files_nums: raise CoverageException("No data to report.") diff --git a/coverage/report.py b/coverage/report.py index 2675cf0f..2c2e0198 100644 --- a/coverage/report.py +++ b/coverage/report.py @@ -3,85 +3,47 @@ """Reporter foundation for coverage.py.""" -import os - from coverage.files import prep_patterns, FnmatchMatcher -from coverage.misc import CoverageException, NoSource, NotPython, isolate_module - -os = isolate_module(os) - - -class Reporter(object): - """A base class for all reporters.""" - - def __init__(self, coverage, config): - """Create a reporter. - - `coverage` is the coverage instance. `config` is an instance of - CoverageConfig, for controlling all sorts of behavior. - - """ - self.coverage = coverage - self.config = config - - # 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 = [] - - 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. - - """ - reporters = self.coverage._get_file_reporters(morfs) - - if self.config.report_include: - matcher = FnmatchMatcher(prep_patterns(self.config.report_include)) - reporters = [fr for fr in reporters if matcher.match(fr.filename)] - - if self.config.report_omit: - matcher = FnmatchMatcher(prep_patterns(self.config.report_omit)) - reporters = [fr for fr in reporters if not matcher.match(fr.filename)] - - self._file_reporters = sorted(reporters) - return self._file_reporters - - def report_files(self, report_fn, morfs): - """Run a reporting function on a number of morfs. - - `report_fn` is called for each relative morf in `morfs`. It is called - as:: - - report_fn(file_reporter, analysis) - - where `file_reporter` is the `FileReporter` for the morf, and - `analysis` is the `Analysis` for the morf. - - """ - file_reporters = self.find_file_reporters(morfs) - - if not file_reporters: - raise CoverageException("No data to report.") - - for fr in file_reporters: - try: - report_fn(fr, self.coverage._analyze(fr)) - except NoSource: - if not self.config.ignore_errors: +from coverage.misc import CoverageException, NoSource, NotPython + + +def get_analysis_to_report(coverage, config, morfs): + """Get the files to report on. + + For each morf in `morfs`, if it should be reported on (based on the omit + and include configuration options), yield a pair, the `FileReporter` and + `Analysis` for the morf. + + """ + file_reporters = coverage._get_file_reporters(morfs) + + if config.report_include: + matcher = FnmatchMatcher(prep_patterns(config.report_include)) + file_reporters = [fr for fr in file_reporters if matcher.match(fr.filename)] + + if config.report_omit: + matcher = FnmatchMatcher(prep_patterns(config.report_omit)) + file_reporters = [fr for fr in file_reporters if not matcher.match(fr.filename)] + + if not file_reporters: + raise CoverageException("No data to report.") + + for fr in sorted(file_reporters): + try: + analysis = coverage._analyze(fr) + except NoSource: + if not config.ignore_errors: + raise + except NotPython: + # Only report errors for .py files, and only if we didn't + # explicitly suppress those errors. + # NotPython is only raised by PythonFileReporter, which has a + # should_be_python() method. + if fr.should_be_python(): + if config.ignore_errors: + msg = "Could not parse Python file {0}".format(fr.filename) + coverage._warn(msg, slug="couldnt-parse") + else: raise - except NotPython: - # Only report errors for .py files, and only if we didn't - # explicitly suppress those errors. - # NotPython is only raised by PythonFileReporter, which has a - # should_be_python() method. - if fr.should_be_python(): - if self.config.ignore_errors: - msg = "Could not parse Python file {0}".format(fr.filename) - self.coverage._warn(msg, slug="couldnt-parse") - else: - raise + else: + yield (fr, analysis) diff --git a/coverage/summary.py b/coverage/summary.py index 5b197f60..6e711089 100644 --- a/coverage/summary.py +++ b/coverage/summary.py @@ -6,16 +6,17 @@ import sys from coverage import env -from coverage.report import Reporter +from coverage.report import get_analysis_to_report from coverage.results import Numbers from coverage.misc import NotPython, CoverageException, output_encoding -class SummaryReporter(Reporter): +class SummaryReporter(object): """A reporter for writing the summary report.""" def __init__(self, coverage, config): - super(SummaryReporter, self).__init__(coverage, config) + self.coverage = coverage + self.config = config self.branches = coverage.get_data().has_arcs() self.outfile = None self.fr_analysis = [] @@ -40,7 +41,8 @@ class SummaryReporter(Reporter): self.outfile = outfile or sys.stdout self.coverage.get_data().set_query_contexts(self.config.query_contexts) - self.report_files(self.report_one_file, morfs) + for fr, analysis in get_analysis_to_report(self.coverage, self.config, morfs): + self.report_one_file(fr, analysis) # Prepare the formatting strings, header, and column sorting. max_name = max([len(fr.relative_filename()) for (fr, analysis) in self.fr_analysis] + [5]) diff --git a/coverage/xmlreport.py b/coverage/xmlreport.py index 8ecdc24a..a414ed40 100644 --- a/coverage/xmlreport.py +++ b/coverage/xmlreport.py @@ -14,7 +14,7 @@ from coverage import env from coverage import __url__, __version__, files from coverage.backward import iitems from coverage.misc import isolate_module -from coverage.report import Reporter +from coverage.report import get_analysis_to_report os = isolate_module(os) @@ -30,11 +30,12 @@ def rate(hit, num): return "%.4g" % (float(hit) / num) -class XmlReporter(Reporter): +class XmlReporter(object): """A reporter for writing Cobertura-style XML coverage results.""" def __init__(self, coverage, config): - super(XmlReporter, self).__init__(coverage, config) + self.coverage = coverage + self.config = config self.source_paths = set() if config.source: @@ -71,7 +72,8 @@ class XmlReporter(Reporter): xcoverage.appendChild(self.xml_out.createComment(" Based on %s " % DTD_URL)) # Call xml_file for each file in the data. - self.report_files(self.xml_file, morfs) + for fr, analysis in get_analysis_to_report(self.coverage, self.config, morfs): + self.xml_file(fr, analysis) xsources = self.xml_out.createElement("sources") xcoverage.appendChild(xsources) |