Skip to content

Commit 3a0cbdb

Browse files
committed
add match support to 103/104
1 parent 265b3a7 commit 3a0cbdb

File tree

3 files changed

+78
-1
lines changed

3 files changed

+78
-1
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ repos:
4242
hooks:
4343
- id: mypy
4444
# uses py311 syntax, mypy configured for py39
45-
exclude: tests/(eval|autofix)_files/.*_py311.py
45+
exclude: tests/(eval|autofix)_files/.*_py(310|311).py
4646

4747
- repo: https://github.com/RobertCraigie/pyright-python
4848
rev: v1.1.396

flake8_async/visitors/visitor103_104.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,25 @@ def visit_If(self, node: ast.If):
199199
# if body didn't raise, or it's unraised after else, set unraise
200200
self.unraised = not body_raised or self.unraised
201201

202+
def visit_Match(self, node: ast.Match): # type: ignore[name-defined]
203+
if not self.unraised:
204+
return
205+
self.visit(node.subject) # this doesn't matter for 103/104, idr if it matters
206+
all_cases_raise = True
207+
has_fallback = False
208+
for case in node.cases:
209+
# check for "bare pattern", i.e `case varname:`
210+
has_fallback |= (
211+
case.guard is None
212+
and isinstance(case.pattern, ast.MatchAs) # type: ignore[attr-defined]
213+
and case.pattern.pattern is None
214+
)
215+
self.visit_nodes(case.body)
216+
all_cases_raise &= not self.unraised
217+
self.unraised = True
218+
219+
self.unraised = not (all_cases_raise and has_fallback)
220+
202221
# A loop is guaranteed to raise if:
203222
# condition always raises, or
204223
# else always raises, and
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
"""Test for ASYNC103/ASYNC104 with structural pattern matching
2+
3+
ASYNC103: no-reraise-cancelled
4+
ASYNC104: cancelled-not-raised
5+
"""
6+
7+
# ARG --enable=ASYNC103,ASYNC104
8+
9+
10+
def foo() -> Any: ...
11+
12+
13+
try:
14+
...
15+
except BaseException as e: # ASYNC103_trio: 7, "BaseException"
16+
match foo():
17+
case True:
18+
raise e
19+
case False:
20+
...
21+
case _:
22+
raise e
23+
24+
try:
25+
...
26+
except BaseException: # ASYNC103_trio: 7, "BaseException"
27+
match foo():
28+
case True:
29+
raise
30+
31+
try:
32+
...
33+
except BaseException: # safe
34+
match foo():
35+
case True:
36+
raise
37+
case False:
38+
raise
39+
case _:
40+
raise
41+
try:
42+
...
43+
except BaseException: # ASYNC103_trio: 7, "BaseException"
44+
match foo():
45+
case _ if foo():
46+
raise
47+
try:
48+
...
49+
except BaseException: # ASYNC103_trio: 7, "BaseException"
50+
match foo():
51+
case 1:
52+
return # ASYNC104: 12
53+
case 2:
54+
raise
55+
case 3:
56+
return # ASYNC104: 12
57+
case blah:
58+
raise

0 commit comments

Comments
 (0)