diff --git a/mypy/semanal.py b/mypy/semanal.py index 176a9e4053a81..ec3c1d45e5110 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -5163,10 +5163,11 @@ def visit_yield_expr(self, e: YieldExpr) -> None: e.expr.accept(self) def visit_await_expr(self, expr: AwaitExpr) -> None: - if not self.is_func_scope(): - self.fail('"await" outside function', expr) + if not self.is_func_scope() or not self.function_stack: + # We check both because is_function_scope() returns True inside comprehensions. + self.fail('"await" outside function', expr, serious=True, blocker=True) elif not self.function_stack[-1].is_coroutine: - self.fail('"await" outside coroutine ("async def")', expr) + self.fail('"await" outside coroutine ("async def")', expr, serious=True, blocker=True) expr.expr.accept(self) # diff --git a/test-data/unit/check-async-await.test b/test-data/unit/check-async-await.test index d53cba2fc642b..40efe2d2cece4 100644 --- a/test-data/unit/check-async-await.test +++ b/test-data/unit/check-async-await.test @@ -943,3 +943,15 @@ async def bar(x: Union[A, B]) -> None: [builtins fixtures/async_await.pyi] [typing fixtures/typing-async.pyi] + +[case testInvalidComprehensionNoCrash] +async def foo(x: int) -> int: ... + +crasher = [await foo(x) for x in [1, 2, 3]] # E: "await" outside function + +def bad() -> None: + y = [await foo(x) for x in [1, 2, 3]] # E: "await" outside coroutine ("async def") +async def good() -> None: + y = [await foo(x) for x in [1, 2, 3]] # OK +[builtins fixtures/async_await.pyi] +[typing fixtures/typing-async.pyi]