From 5a031b056c6f9613b3fa4ceb1a6b73774b56195c Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Wed, 6 Mar 2024 19:41:31 -0500 Subject: [PATCH] fix: correct the missing branch message for the last case of a match/case --- CHANGES.rst | 4 ++++ coverage/parser.py | 4 +++- tests/test_parser.py | 28 +++++++++++++++------------- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index b87ee7f53..eebfcc38f 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -23,6 +23,10 @@ upgrading your version of coverage.py. Unreleased ---------- +- Fix: the last case of a match/case statement had an incorrect message if the + branch was missed. It said the pattern never matched, when actually the + branch is missed if the last case always matched. + - Fix: clicking a line number in the HTML report now positions more accurately. diff --git a/coverage/parser.py b/coverage/parser.py index 6cf73446e..5ad534701 100644 --- a/coverage/parser.py +++ b/coverage/parser.py @@ -1112,7 +1112,9 @@ def _handle__Match(self, node: ast.Match) -> set[ArcStart]: exits |= self.add_body_arcs(case.body, from_start=from_start) last_start = case_start if not had_wildcard: - exits.add(from_start) + exits.add( + ArcStart(case_start, cause="the pattern on line {lineno} always matched"), + ) return exits def _handle__NodeList(self, node: NodeList) -> set[ArcStart]: diff --git a/tests/test_parser.py b/tests/test_parser.py index f17c8f2be..7f50e55b5 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -902,21 +902,23 @@ def test_missing_arc_descriptions_bug460(self) -> None: assert parser.missing_arc_description(2, -3) == "line 3 didn't finish the lambda on line 3" @pytest.mark.skipif(not env.PYBEHAVIOR.match_case, reason="Match-case is new in 3.10") - def test_match_case_with_default(self) -> None: - parser = self.parse_text("""\ - for command in ["huh", "go home", "go n"]: - match command.split(): - case ["go", direction] if direction in "nesw": - match = f"go: {direction}" - case ["go", _]: - match = "no go" - print(match) + def test_match_case(self) -> None: + parser = self.parse_text("""\ + match command.split(): + case ["go", direction] if direction in "nesw": # 2 + match = f"go: {direction}" + case ["go", _]: # 4 + match = "no go" + print(match) # 6 """) - assert parser.missing_arc_description(3, 4) == ( - "line 3 didn't jump to line 4, because the pattern on line 3 never matched" + assert parser.missing_arc_description(2, 3) == ( + "line 2 didn't jump to line 3, because the pattern on line 2 never matched" ) - assert parser.missing_arc_description(3, 5) == ( - "line 3 didn't jump to line 5, because the pattern on line 3 always matched" + assert parser.missing_arc_description(2, 4) == ( + "line 2 didn't jump to line 4, because the pattern on line 2 always matched" + ) + assert parser.missing_arc_description(4, 6) == ( + "line 4 didn't jump to line 6, because the pattern on line 4 always matched" )