summaryrefslogtreecommitdiff
path: root/coverage
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2021-06-06 12:10:38 -0400
committerNed Batchelder <ned@nedbatchelder.com>2021-06-06 12:42:07 -0400
commit95c582fd8038a7158ff96baff4186f5fb601afd4 (patch)
treeb870edb23108bdd473df3781d65c74d547bc7a78 /coverage
parent734ee8760df75427753e54b4d8078cfa06484da3 (diff)
downloadpython-coveragepy-git-95c582fd8038a7158ff96baff4186f5fb601afd4.tar.gz
feat: add support for Python 3.10 match-case statements
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))