Skip to content

Commit 8eb14fb

Browse files
authored
Comprehensions trigger is_func_scope() (#20540)
Fixes #20530
1 parent 659b8a7 commit 8eb14fb

File tree

2 files changed

+26
-3
lines changed

2 files changed

+26
-3
lines changed

mypy/semanal.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6297,21 +6297,33 @@ def visit_type_application(self, expr: TypeApplication) -> None:
62976297

62986298
def visit_list_comprehension(self, expr: ListComprehension) -> None:
62996299
if any(expr.generator.is_async):
6300-
if not self.is_func_scope() or not self.function_stack[-1].is_coroutine:
6300+
if (
6301+
not self.is_func_scope()
6302+
or not self.function_stack
6303+
or not self.function_stack[-1].is_coroutine
6304+
):
63016305
self.fail(message_registry.ASYNC_FOR_OUTSIDE_COROUTINE, expr, code=codes.SYNTAX)
63026306

63036307
expr.generator.accept(self)
63046308

63056309
def visit_set_comprehension(self, expr: SetComprehension) -> None:
63066310
if any(expr.generator.is_async):
6307-
if not self.is_func_scope() or not self.function_stack[-1].is_coroutine:
6311+
if (
6312+
not self.is_func_scope()
6313+
or not self.function_stack
6314+
or not self.function_stack[-1].is_coroutine
6315+
):
63086316
self.fail(message_registry.ASYNC_FOR_OUTSIDE_COROUTINE, expr, code=codes.SYNTAX)
63096317

63106318
expr.generator.accept(self)
63116319

63126320
def visit_dictionary_comprehension(self, expr: DictionaryComprehension) -> None:
63136321
if any(expr.is_async):
6314-
if not self.is_func_scope() or not self.function_stack[-1].is_coroutine:
6322+
if (
6323+
not self.is_func_scope()
6324+
or not self.function_stack
6325+
or not self.function_stack[-1].is_coroutine
6326+
):
63156327
self.fail(message_registry.ASYNC_FOR_OUTSIDE_COROUTINE, expr, code=codes.SYNTAX)
63166328

63176329
with self.enter(expr):

test-data/unit/check-async-await.test

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1080,3 +1080,14 @@ class Launcher(P):
10801080

10811081
[builtins fixtures/async_await.pyi]
10821082
[typing fixtures/typing-async.pyi]
1083+
1084+
[case testInvalidAsyncForInComprehensionNoCrash]
1085+
# a # is at the end to mark these not as section headers
1086+
[[5 async for _ in [5]] for _ in []]# # E: "async for" outside async function \
1087+
# E: "list[int]" has no attribute "__aiter__" (not async iterable)
1088+
[{5 async for _ in [5]} for _ in []]# # E: "async for" outside async function \
1089+
# E: "list[int]" has no attribute "__aiter__" (not async iterable)
1090+
[{5: 5 async for _ in [5]} for _ in []]# # E: "async for" outside async function \
1091+
# E: "list[int]" has no attribute "__aiter__" (not async iterable)
1092+
[builtins fixtures/async_await.pyi]
1093+
[typing fixtures/typing-async.pyi]

0 commit comments

Comments
 (0)