summaryrefslogtreecommitdiff
path: root/coverage
diff options
context:
space:
mode:
Diffstat (limited to 'coverage')
-rw-r--r--coverage/env.py3
-rw-r--r--coverage/parser.py21
2 files changed, 24 insertions, 0 deletions
diff --git a/coverage/env.py b/coverage/env.py
index 81f61794..89abbb2e 100644
--- a/coverage/env.py
+++ b/coverage/env.py
@@ -102,6 +102,9 @@ class PYBEHAVIOR:
# When leaving a with-block, do we visit the with-line again for the exit?
exit_through_with = (PYVERSION >= (3, 10, 0, 'beta'))
+ # Match-case construct.
+ match_case = (PYVERSION >= (3, 10))
+
# Coverage.py specifics.
# Are we using the C-implemented trace function?
diff --git a/coverage/parser.py b/coverage/parser.py
index ff395dad..abaa2e50 100644
--- a/coverage/parser.py
+++ b/coverage/parser.py
@@ -1018,6 +1018,27 @@ class AstArcAnalyzer:
return exits
@contract(returns='ArcStarts')
+ def _handle__Match(self, node):
+ start = self.line_for_node(node)
+ last_start = start
+ exits = set()
+ had_wildcard = False
+ for case in node.cases:
+ # The wildcard case doesn't execute the pattern.
+ case_start = self.line_for_node(case.pattern)
+ if isinstance(case.pattern, ast.MatchAs):
+ had_wildcard = True
+ if case.pattern.name is None:
+ case_start = self.line_for_node(case.body[0])
+ self.add_arc(last_start, case_start, "the pattern on line {lineno} always matched")
+ from_start = ArcStart(case_start, cause="the pattern on line {lineno} never matched")
+ exits |= self.add_body_arcs(case.body, from_start=from_start)
+ last_start = case_start
+ if not had_wildcard:
+ exits.add(from_start)
+ return exits
+
+ @contract(returns='ArcStarts')
def _handle__NodeList(self, node):
start = self.line_for_node(node)
exits = self.add_body_arcs(node.body, from_start=ArcStart(start))