Skip to content

Commit cf75971

Browse files
authored
add support for match statement (#630)
1 parent 4cf2189 commit cf75971

File tree

2 files changed

+96
-1
lines changed

2 files changed

+96
-1
lines changed

pyflakes/checker.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,8 @@ def iter_child_nodes(node, omit=None, _fields_order=_FieldsOrder()):
275275
yield field
276276
elif isinstance(field, list):
277277
for item in field:
278-
yield item
278+
if isinstance(item, ast.AST):
279+
yield item
279280

280281

281282
def convert_to_value(item):
@@ -691,6 +692,8 @@ def getNodeName(node):
691692
return node.id
692693
if hasattr(node, 'name'): # an ExceptHandler node
693694
return node.name
695+
if hasattr(node, 'rest'): # a MatchMapping node
696+
return node.rest
694697

695698

696699
TYPING_MODULES = frozenset(('typing', 'typing_extensions'))
@@ -2378,3 +2381,12 @@ def COMPARE(self, node):
23782381
left = right
23792382

23802383
self.handleChildren(node)
2384+
2385+
MATCH = MATCH_CASE = MATCHCLASS = MATCHOR = MATCHSEQUENCE = handleChildren
2386+
MATCHSINGLETON = MATCHVALUE = handleChildren
2387+
2388+
def _match_target(self, node):
2389+
self.handleNodeStore(node)
2390+
self.handleChildren(node)
2391+
2392+
MATCHAS = MATCHMAPPING = MATCHSTAR = _match_target

pyflakes/test/test_match.py

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
from sys import version_info
2+
3+
from pyflakes.test.harness import TestCase, skipIf
4+
5+
6+
@skipIf(version_info < (3, 10), "Python >= 3.10 only")
7+
class TestMatch(TestCase):
8+
def test_match_bindings(self):
9+
self.flakes('''
10+
def f():
11+
x = 1
12+
match x:
13+
case 1 as y:
14+
print(f'matched as {y}')
15+
''')
16+
self.flakes('''
17+
def f():
18+
x = [1, 2, 3]
19+
match x:
20+
case [1, y, 3]:
21+
print(f'matched {y}')
22+
''')
23+
self.flakes('''
24+
def f():
25+
x = {'foo': 1}
26+
match x:
27+
case {'foo': y}:
28+
print(f'matched {y}')
29+
''')
30+
31+
def test_match_pattern_matched_class(self):
32+
self.flakes('''
33+
from a import B
34+
35+
match 1:
36+
case B(x=1) as y:
37+
print(f'matched {y}')
38+
''')
39+
self.flakes('''
40+
from a import B
41+
42+
match 1:
43+
case B(a, x=z) as y:
44+
print(f'matched {y} {a} {z}')
45+
''')
46+
47+
def test_match_placeholder(self):
48+
self.flakes('''
49+
def f():
50+
match 1:
51+
case _:
52+
print('catchall!')
53+
''')
54+
55+
def test_match_singleton(self):
56+
self.flakes('''
57+
match 1:
58+
case True:
59+
print('true')
60+
''')
61+
62+
def test_match_or_pattern(self):
63+
self.flakes('''
64+
match 1:
65+
case 1 | 2:
66+
print('one or two')
67+
''')
68+
69+
def test_match_star(self):
70+
self.flakes('''
71+
x = [1, 2, 3]
72+
match x:
73+
case [1, *y]:
74+
print(f'captured: {y}')
75+
''')
76+
77+
def test_match_double_star(self):
78+
self.flakes('''
79+
x = {'foo': 'bar', 'baz': 'womp'}
80+
match x:
81+
case {'foo': k1, **rest}:
82+
print(f'{k1=} {rest=}')
83+
''')

0 commit comments

Comments
 (0)