summaryrefslogtreecommitdiff
path: root/coverage
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2019-06-16 15:38:26 -0400
committerNed Batchelder <ned@nedbatchelder.com>2019-06-16 15:38:26 -0400
commit3a04a88e88a92882ef92cf6778e42eaf3d4001f4 (patch)
treed3cad2010fc7726cd0185b710d3792a183962f1a /coverage
parent591ac5b27974e10386559f54b7c5a81e69e5210d (diff)
downloadpython-coveragepy-git-3a04a88e88a92882ef92cf6778e42eaf3d4001f4.tar.gz
Refactor text reporting to use the same code paths as other reports
Diffstat (limited to 'coverage')
-rw-r--r--coverage/cmdline.py7
-rw-r--r--coverage/report.py3
-rw-r--r--coverage/summary.py110
3 files changed, 55 insertions, 65 deletions
diff --git a/coverage/cmdline.py b/coverage/cmdline.py
index a6a72c32..c3d011d9 100644
--- a/coverage/cmdline.py
+++ b/coverage/cmdline.py
@@ -20,7 +20,7 @@ from coverage.collector import CTracer
from coverage.data import line_counts
from coverage.debug import info_formatter, info_header
from coverage.execfile import PyRunner
-from coverage.misc import BaseCoverageException, ExceptionDuringRun, NoSource
+from coverage.misc import BaseCoverageException, ExceptionDuringRun, NoSource, output_encoding
from coverage.results import should_fail_under
@@ -788,7 +788,10 @@ def main(argv=None):
status = ERR
except BaseCoverageException as err:
# A controlled error inside coverage.py: print the message to the user.
- print(err)
+ msg = err.args[0]
+ if env.PY2:
+ msg = msg.encode(output_encoding())
+ print(msg)
status = ERR
except SystemExit as err:
# The user called `sys.exit()`. Exit with their argument, if any.
diff --git a/coverage/report.py b/coverage/report.py
index 4f81d99c..2675cf0f 100644
--- a/coverage/report.py
+++ b/coverage/report.py
@@ -81,6 +81,7 @@ class Reporter(object):
# 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))
+ msg = "Could not parse Python file {0}".format(fr.filename)
+ self.coverage._warn(msg, slug="couldnt-parse")
else:
raise
diff --git a/coverage/summary.py b/coverage/summary.py
index 9e0ccbfd..5b197f60 100644
--- a/coverage/summary.py
+++ b/coverage/summary.py
@@ -8,7 +8,7 @@ import sys
from coverage import env
from coverage.report import Reporter
from coverage.results import Numbers
-from coverage.misc import NotPython, CoverageException, output_encoding, StopEverything
+from coverage.misc import NotPython, CoverageException, output_encoding
class SummaryReporter(Reporter):
@@ -16,8 +16,19 @@ class SummaryReporter(Reporter):
def __init__(self, coverage, config):
super(SummaryReporter, self).__init__(coverage, config)
- data = coverage.get_data()
- self.branches = data.has_arcs()
+ self.branches = coverage.get_data().has_arcs()
+ self.outfile = None
+ self.fr_analysis = []
+ self.skipped_count = 0
+ self.total = Numbers()
+ self.fmt_err = u"%s %s: %s"
+
+ def writeout(self, line):
+ """Write a line to the output, adding a newline."""
+ if env.PY2:
+ line = line.encode(output_encoding())
+ self.outfile.write(line.rstrip())
+ self.outfile.write("\n")
def report(self, morfs, outfile=None):
"""Writes a report summarizing coverage statistics per module.
@@ -26,53 +37,13 @@ class SummaryReporter(Reporter):
for native strings (bytes on Python 2, Unicode on Python 3).
"""
- if outfile is None:
- outfile = sys.stdout
-
- def writeout(line):
- """Write a line to the output, adding a newline."""
- if env.PY2:
- line = line.encode(output_encoding())
- outfile.write(line.rstrip())
- outfile.write("\n")
-
- fr_analysis = []
- skipped_count = 0
- total = Numbers()
-
- fmt_err = u"%s %s: %s"
+ self.outfile = outfile or sys.stdout
self.coverage.get_data().set_query_contexts(self.config.query_contexts)
- for fr in self.find_file_reporters(morfs):
- try:
- analysis = self.coverage._analyze(fr)
- nums = analysis.numbers
- total += nums
-
- if self.config.skip_covered:
- # Don't report on 100% files.
- no_missing_lines = (nums.n_missing == 0)
- no_missing_branches = (nums.n_partial_branches == 0)
- if no_missing_lines and no_missing_branches:
- skipped_count += 1
- continue
- fr_analysis.append((fr, analysis))
- except StopEverything:
- # Don't report this on single files, it's a systemic problem.
- raise
- except Exception:
- report_it = not self.config.ignore_errors
- if report_it:
- typ, msg = sys.exc_info()[:2]
- # NotPython is only raised by PythonFileReporter, which has a
- # should_be_python() method.
- if issubclass(typ, NotPython) and not fr.should_be_python():
- report_it = False
- if report_it:
- writeout(fmt_err % (fr.relative_filename(), typ.__name__, msg))
+ self.report_files(self.report_one_file, morfs)
# Prepare the formatting strings, header, and column sorting.
- max_name = max([len(fr.relative_filename()) for (fr, analysis) in fr_analysis] + [5])
+ max_name = max([len(fr.relative_filename()) for (fr, analysis) in self.fr_analysis] + [5])
fmt_name = u"%%- %ds " % max_name
fmt_skip_covered = u"\n%s file%s skipped due to complete coverage."
@@ -94,15 +65,15 @@ class SummaryReporter(Reporter):
column_order.update(dict(branch=3, brpart=4))
# Write the header
- writeout(header)
- writeout(rule)
+ self.writeout(header)
+ self.writeout(rule)
# `lines` is a list of pairs, (line text, line values). The line text
# is a string that will be printed, and line values is a tuple of
# sortable values.
lines = []
- for (fr, analysis) in fr_analysis:
+ for (fr, analysis) in self.fr_analysis:
try:
nums = analysis.numbers
@@ -125,7 +96,7 @@ class SummaryReporter(Reporter):
if typ is NotPython and not fr.should_be_python():
report_it = False
if report_it:
- writeout(fmt_err % (fr.relative_filename(), typ.__name__, msg))
+ self.writeout(self.fmt_err % (fr.relative_filename(), typ.__name__, msg))
# Sort the lines and write them out.
if getattr(self.config, 'sort', None):
@@ -135,24 +106,39 @@ class SummaryReporter(Reporter):
lines.sort(key=lambda l: (l[1][position], l[0]))
for line in lines:
- writeout(line[0])
+ self.writeout(line[0])
# Write a TOTAl line if we had more than one file.
- if total.n_files > 1:
- writeout(rule)
- args = ("TOTAL", total.n_statements, total.n_missing)
+ if self.total.n_files > 1:
+ self.writeout(rule)
+ args = ("TOTAL", self.total.n_statements, self.total.n_missing)
if self.branches:
- args += (total.n_branches, total.n_partial_branches)
- args += (total.pc_covered_str,)
+ args += (self.total.n_branches, self.total.n_partial_branches)
+ args += (self.total.pc_covered_str,)
if self.config.show_missing:
args += ("",)
- writeout(fmt_coverage % args)
+ self.writeout(fmt_coverage % args)
# Write other final lines.
- if not total.n_files and not skipped_count:
+ if not self.total.n_files and not self.skipped_count:
raise CoverageException("No data to report.")
- if self.config.skip_covered and skipped_count:
- writeout(fmt_skip_covered % (skipped_count, 's' if skipped_count > 1 else ''))
-
- return total.n_statements and total.pc_covered
+ if self.config.skip_covered and self.skipped_count:
+ self.writeout(
+ fmt_skip_covered % (self.skipped_count, 's' if self.skipped_count > 1 else '')
+ )
+
+ return self.total.n_statements and self.total.pc_covered
+
+ def report_one_file(self, fr, analysis):
+ """Report on just one file, the callback from report()."""
+ nums = analysis.numbers
+ self.total += nums
+
+ no_missing_lines = (nums.n_missing == 0)
+ no_missing_branches = (nums.n_partial_branches == 0)
+ if self.config.skip_covered and no_missing_lines and no_missing_branches:
+ # Don't report on 100% files.
+ self.skipped_count += 1
+ else:
+ self.fr_analysis.append((fr, analysis))