diff --git a/CHANGELOG.md b/CHANGELOG.md index 37b517051..e23bf1a32 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - #852 Implement patchedast handlers for TypeAlias - #853 Implement patchedast handlers TypeVar - #847 Avoid printing autoimport syntax errors (@yangfan-yf-yf) +- #819 supports MatchOr, MatchSequence, MatchStar (@jheld) # Release 1.14.0 diff --git a/rope/refactor/patchedast.py b/rope/refactor/patchedast.py index d3a14102c..8ebfda398 100644 --- a/rope/refactor/patchedast.py +++ b/rope/refactor/patchedast.py @@ -788,6 +788,13 @@ def _Match(self, node): children.extend(node.cases) self._handle(node, children) + def _MatchOr(self, node): + children = [*self._child_nodes(node.patterns, "|")] + self._handle(node, children) + + def _MatchSingleton(self, node): + self._handle(node, [str(node.value)]) + def _match_case(self, node): children = ["case", node.pattern] if node.guard: @@ -796,6 +803,13 @@ def _match_case(self, node): children.extend(node.body) self._handle(node, children) + def _MatchSequence(self, node): + children = ["[", *self._child_nodes(node.patterns, ","), "]"] + self._handle(node, children) + + def _MatchStar(self, node): + self._handle(node, ["*", node.name or "_"]) + def _MatchAs(self, node): if node.pattern: children = [node.pattern, "as", node.name] diff --git a/ropetest/refactor/patchedasttest.py b/ropetest/refactor/patchedasttest.py index 57fdc0e08..da6c993a1 100644 --- a/ropetest/refactor/patchedasttest.py +++ b/ropetest/refactor/patchedasttest.py @@ -1424,6 +1424,94 @@ def test_match_node_with_wildcard(self): "_" ]) + @testutils.only_for_versions_higher("3.10") + def test_match_node_with_match_or(self): + source = dedent( + """\ + match x: + case 'v'|'z': + print(x) + """ + ) + ast_frag = patchedast.get_patched_ast(source, True) + checker = _ResultChecker(self, ast_frag) + self.assert_single_case_match_block(checker, "MatchOr") + checker.check_children("MatchOr", ["MatchValue", "", "|", "", "MatchValue"]) + + @testutils.only_for_versions_higher("3.10") + def test_match_node_with_match_singleton_true(self): + source = dedent( + """\ + match x: + case True: + print(x) + """ + ) + ast_frag = patchedast.get_patched_ast(source, True) + checker = _ResultChecker(self, ast_frag) + self.assert_single_case_match_block(checker, "MatchSingleton") + checker.check_children("MatchSingleton", ["True"]) + + @testutils.only_for_versions_higher("3.10") + def test_match_node_with_match_singleton_none(self): + source = dedent( + """\ + match x: + case None: + print(x) + """ + ) + ast_frag = patchedast.get_patched_ast(source, True) + checker = _ResultChecker(self, ast_frag) + self.assert_single_case_match_block(checker, "MatchSingleton") + checker.check_children("MatchSingleton", ["None"]) + + @testutils.only_for_versions_higher("3.10") + def test_match_node_with_match_sequence_with_star_wildcard(self): + source = dedent( + """\ + match x: + case [*_]: + print(x) + """ + ) + ast_frag = patchedast.get_patched_ast(source, True) + checker = _ResultChecker(self, ast_frag) + self.assert_single_case_match_block(checker, "MatchSequence") + checker.check_children("MatchSequence", ["[", "", "MatchStar", "", "]"]) + + @testutils.only_for_versions_higher("3.10") + def test_match_node_with_match_sequence_with_tail_capture(self): + source = dedent( + """\ + match x: + case [1, 2, *rest]: + print(rest) + """ + ) + ast_frag = patchedast.get_patched_ast(source, True) + checker = _ResultChecker(self, ast_frag) + self.assert_single_case_match_block(checker, "MatchSequence") + checker.check_children("MatchSequence", [ + "[", "", "MatchValue", "", ",", " ", "MatchValue", "", ",", " ", "MatchStar", "", "]", + ]) + + @testutils.only_for_versions_higher("3.10") + def test_match_node_with_match_sequence_with_star_and_value(self): + source = dedent( + """\ + match x: + case [*_, "something"]: + print(x) + """ + ) + ast_frag = patchedast.get_patched_ast(source, True) + checker = _ResultChecker(self, ast_frag) + self.assert_single_case_match_block(checker, "MatchSequence") + checker.check_children( + "MatchSequence", ["[", "", "MatchStar", "", ",", " ", "MatchValue", "", "]"] + ) + @testutils.only_for_versions_higher("3.10") def test_match_node_with_match_as_capture_pattern(self): source = dedent("""\