diff options
author | Marc Mueller <30130371+cdce8p@users.noreply.github.com> | 2021-07-11 11:36:06 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-11 11:36:06 +0200 |
commit | bbd969803d2fc6e6e1473ebbed115d0e40c2cb8c (patch) | |
tree | 627faafccb06797fd9c020e910970c04c7e3c594 | |
parent | c9c498348174b38ce35bfe001353c8ebea262802 (diff) | |
download | astroid-git-bbd969803d2fc6e6e1473ebbed115d0e40c2cb8c.tar.gz |
Don't infer MatchAs in assigned_stmts if pattern is not None (#1096)
* Move protocol match tests to separate class
* Don't infer MatchAs in assigned_stmts if pattern is not None
-rw-r--r-- | astroid/protocols.py | 6 | ||||
-rw-r--r-- | tests/unittest_protocols.py | 125 |
2 files changed, 70 insertions, 61 deletions
diff --git a/astroid/protocols.py b/astroid/protocols.py index 228000ab..f97fb948 100644 --- a/astroid/protocols.py +++ b/astroid/protocols.py @@ -839,8 +839,10 @@ def match_as_assigned_stmts( """Infer MatchAs as the Match subject if it's the only MatchCase pattern else raise StopIteration to yield Uninferable. """ - if isinstance(self.parent, nodes.MatchCase) and isinstance( - self.parent.parent, nodes.Match + if ( + isinstance(self.parent, nodes.MatchCase) + and isinstance(self.parent.parent, nodes.Match) + and self.pattern is None ): yield self.parent.parent.subject diff --git a/tests/unittest_protocols.py b/tests/unittest_protocols.py index e130b570..3059e55b 100644 --- a/tests/unittest_protocols.py +++ b/tests/unittest_protocols.py @@ -267,71 +267,78 @@ def test_named_expr_inference(): @pytest.mark.skipif(not PY310_PLUS, reason="Match requires python 3.10") -def test_assigned_stmts_match_mapping(): - """Assigned_stmts for MatchMapping not yet implemented. +class TestPatternMatching: + @staticmethod + def test_assigned_stmts_match_mapping(): + """Assigned_stmts for MatchMapping not yet implemented. - Test the result is 'Uninferable' and no exception is raised. - """ - assign_stmts = extract_node( + Test the result is 'Uninferable' and no exception is raised. """ - var = {1: "Hello", 2: "World"} - match var: - case {**rest}: #@ - pass - """ - ) - match_mapping: nodes.MatchMapping = assign_stmts.pattern # type: ignore - assert match_mapping.rest - assigned = next(match_mapping.rest.assigned_stmts()) - assert assigned == util.Uninferable - - -@pytest.mark.skipif(not PY310_PLUS, reason="Match requires python 3.10") -def test_assigned_stmts_match_star(): - """Assigned_stmts for MatchStar not yet implemented. - - Test the result is 'Uninferable' and no exception is raised. - """ - assign_stmts = extract_node( + assign_stmts = extract_node( + """ + var = {1: "Hello", 2: "World"} + match var: + case {**rest}: #@ + pass """ - var = (0, 1, 2) - match var: - case (0, 1, *rest): #@ - pass - """ - ) - match_sequence: nodes.MatchSequence = assign_stmts.pattern # type: ignore - match_star = match_sequence.patterns[2] - assert isinstance(match_star, nodes.MatchStar) and match_star.name - assigned = next(match_star.name.assigned_stmts()) - assert assigned == util.Uninferable + ) + match_mapping: nodes.MatchMapping = assign_stmts.pattern # type: ignore + assert match_mapping.rest + assigned = next(match_mapping.rest.assigned_stmts()) + assert assigned == util.Uninferable + @staticmethod + def test_assigned_stmts_match_star(): + """Assigned_stmts for MatchStar not yet implemented. -@pytest.mark.skipif(not PY310_PLUS, reason="Match requires python 3.10") -def test_assigned_stmts_match_as(): - """Assigned_stmts for MatchAs only implemented for the most basic case (y).""" - assign_stmts = extract_node( + Test the result is 'Uninferable' and no exception is raised. """ - var = 42 - match var: #@ - case 2 | x: #@ - pass - case y: #@ - pass - """ - ) - subject: nodes.Const = assign_stmts[0].subject # type: ignore - match_or: nodes.MatchOr = assign_stmts[1].pattern # type: ignore - match_as: nodes.MatchAs = assign_stmts[2].pattern # type: ignore - - assert match_as.name - assigned_match_as = next(match_as.name.assigned_stmts()) - assert assigned_match_as == subject - - match_or_1 = match_or.patterns[1] - assert isinstance(match_or_1, nodes.MatchAs) and match_or_1.name - assigned_match_or_1 = next(match_or_1.name.assigned_stmts()) - assert assigned_match_or_1 == util.Uninferable + assign_stmts = extract_node( + """ + var = (0, 1, 2) + match var: + case (0, 1, *rest): #@ + pass + """ + ) + match_sequence: nodes.MatchSequence = assign_stmts.pattern # type: ignore + match_star = match_sequence.patterns[2] + assert isinstance(match_star, nodes.MatchStar) and match_star.name + assigned = next(match_star.name.assigned_stmts()) + assert assigned == util.Uninferable + + @staticmethod + def test_assigned_stmts_match_as(): + """Assigned_stmts for MatchAs only implemented for the most basic case (y).""" + assign_stmts = extract_node( + """ + var = 42 + match var: #@ + case 2 | x: #@ + pass + case (1, 2) as y: #@ + pass + case z: #@ + pass + """ + ) + subject: nodes.Const = assign_stmts[0].subject # type: ignore + match_or: nodes.MatchOr = assign_stmts[1].pattern # type: ignore + match_as_with_pattern: nodes.MatchAs = assign_stmts[2].pattern # type: ignore + match_as: nodes.MatchAs = assign_stmts[3].pattern # type: ignore + + match_or_1 = match_or.patterns[1] + assert isinstance(match_or_1, nodes.MatchAs) and match_or_1.name + assigned_match_or_1 = next(match_or_1.name.assigned_stmts()) + assert assigned_match_or_1 == util.Uninferable + + assert match_as_with_pattern.name and match_as_with_pattern.pattern + assigned_match_as_pattern = next(match_as_with_pattern.name.assigned_stmts()) + assert assigned_match_as_pattern == util.Uninferable + + assert match_as.name + assigned_match_as = next(match_as.name.assigned_stmts()) + assert assigned_match_as == subject if __name__ == "__main__": |