diff options
-rw-r--r-- | CHANGES.rst | 4 | ||||
-rw-r--r-- | coverage/report.py | 23 | ||||
-rw-r--r-- | tests/test_report.py | 13 |
3 files changed, 22 insertions, 18 deletions
diff --git a/CHANGES.rst b/CHANGES.rst index b4883728..f336cff5 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -23,6 +23,10 @@ Unreleased - Added a :meth:`.CoverageData.purge_files` method to remove recorded data for a particular file. Contributed by `Stephan Deibel <pull 1547_>`_. +- Fix: when reporting commands fail, they will no longer congratulate + themselves with messages like "Wrote XML report to file.xml" before spewing a + traceback about their failure. + - Fix: In some embedded environments, an IndexError could occur on stop() when the originating thread exits before completion. This is now fixed, thanks to `Russell Keith-Magee <pull 1543_>`_, closing `issue 1542`_. diff --git a/coverage/report.py b/coverage/report.py index 74ae1817..09eed0a8 100644 --- a/coverage/report.py +++ b/coverage/report.py @@ -9,7 +9,7 @@ import sys from typing import Callable, Iterable, Iterator, IO, Optional, Tuple, TYPE_CHECKING -from coverage.exceptions import CoverageException, NoDataError, NotPython +from coverage.exceptions import NoDataError, NotPython from coverage.files import prep_patterns, GlobMatcher from coverage.misc import ensure_dir_for_file, file_be_gone from coverage.plugin import FileReporter @@ -47,26 +47,25 @@ def render_report( if output_path == "-": outfile = sys.stdout else: - # Ensure that the output directory is created; done here - # because this report pre-opens the output file. - # HTMLReport does this using the Report plumbing because - # its task is more complex, being multiple files. + # Ensure that the output directory is created; done here because this + # report pre-opens the output file. HtmlReporter does this on its own + # because its task is more complex, being multiple files. ensure_dir_for_file(output_path) outfile = open(output_path, "w", encoding="utf-8") file_to_close = outfile + delete_file = True try: - return reporter.report(morfs, outfile=outfile) - except CoverageException: - delete_file = True - raise + ret = reporter.report(morfs, outfile=outfile) + if file_to_close is not None: + msgfn(f"Wrote {reporter.report_type} to {output_path}") + delete_file = False + return ret finally: - if file_to_close: + if file_to_close is not None: file_to_close.close() if delete_file: file_be_gone(output_path) # pragma: part covered (doesn't return) - else: - msgfn(f"Wrote {reporter.report_type} to {output_path}") def get_analysis_to_report( diff --git a/tests/test_report.py b/tests/test_report.py index 3d87b514..c85c6b47 100644 --- a/tests/test_report.py +++ b/tests/test_report.py @@ -5,7 +5,7 @@ from __future__ import annotations -from typing import IO, Iterable, List, Optional +from typing import IO, Iterable, List, Optional, Type import pytest @@ -21,7 +21,7 @@ class FakeReporter: report_type = "fake report file" - def __init__(self, output: str = "", error: bool = False) -> None: + def __init__(self, output: str = "", error: Optional[Type[Exception]] = None) -> None: self.output = output self.error = error self.morfs: Optional[Iterable[TMorf]] = None @@ -31,7 +31,7 @@ class FakeReporter: self.morfs = morfs outfile.write(self.output) if self.error: - raise CoverageException("You asked for it!") + raise self.error("You asked for it!") return 17.25 @@ -57,10 +57,11 @@ class RenderReportTest(CoverageTest): assert f.read().rstrip() == b"Gr\xc3\xa9\xc3\xa8tings!" assert msgs == ["Wrote fake report file to output.txt"] - def test_exception(self) -> None: - fake = FakeReporter(error=True) + @pytest.mark.parametrize("error", [CoverageException, ZeroDivisionError]) + def test_exception(self, error: Type[Exception]) -> None: + fake = FakeReporter(error=error) msgs: List[str] = [] - with pytest.raises(CoverageException, match="You asked for it!"): + with pytest.raises(error, match="You asked for it!"): render_report("output.txt", fake, [], msgs.append) assert self.stdout() == "" self.assert_doesnt_exist("output.txt") |