From d3b2d9d1557dd46caf1912c6a34ee8746fa35ff5 Mon Sep 17 00:00:00 2001 From: josetapadas Date: Wed, 13 Nov 2024 09:51:36 +0000 Subject: [PATCH 01/12] fix: refactor sem analysis of the await-not-async on generators and list comprehension --- mypy/semanal.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/mypy/semanal.py b/mypy/semanal.py index 59e4594353f0f..7347fbdecf284 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -228,6 +228,7 @@ set_callable_name as set_callable_name, ) from mypy.semanal_typeddict import TypedDictAnalyzer +from mypy.traverser import has_await_expression from mypy.tvar_scope import TypeVarLikeScope from mypy.typeanal import ( SELF_TYPE_NAMES, @@ -6074,9 +6075,9 @@ def visit_type_application(self, expr: TypeApplication) -> None: expr.types[i] = analyzed def visit_list_comprehension(self, expr: ListComprehension) -> None: - if any(expr.generator.is_async): + if any(expr.generator.is_async) or has_await_expression(expr): if not self.is_func_scope() or not self.function_stack[-1].is_coroutine: - self.fail(message_registry.ASYNC_FOR_OUTSIDE_COROUTINE, expr, code=codes.SYNTAX) + self.fail(message_registry.ASYNC_FOR_OUTSIDE_COROUTINE, expr, code=codes.SYNTAX, serious=True) expr.generator.accept(self) @@ -6090,7 +6091,7 @@ def visit_set_comprehension(self, expr: SetComprehension) -> None: def visit_dictionary_comprehension(self, expr: DictionaryComprehension) -> None: if any(expr.is_async): if not self.is_func_scope() or not self.function_stack[-1].is_coroutine: - self.fail(message_registry.ASYNC_FOR_OUTSIDE_COROUTINE, expr, code=codes.SYNTAX) + self.fail(message_registry.ASYNC_FOR_OUTSIDE_COROUTINE, expr, code=codes.SYNTAX, serious=True) with self.enter(expr): self.analyze_comp_for(expr) @@ -6167,7 +6168,7 @@ def visit_await_expr(self, expr: AwaitExpr) -> None: # This is not a blocker, because some enviroments (like ipython) # support top level awaits. self.fail('"await" outside function', expr, serious=True, code=codes.TOP_LEVEL_AWAIT) - elif not self.function_stack[-1].is_coroutine: + elif not self.function_stack[-1].is_coroutine and not self.is_in_generator_expression(expr): self.fail( '"await" outside coroutine ("async def")', expr, @@ -6176,6 +6177,9 @@ def visit_await_expr(self, expr: AwaitExpr) -> None: ) expr.expr.accept(self) + def is_in_generator_expression(self, node: AwaitExpr): + return self.scope_stack[-1] == SCOPE_COMPREHENSION + # # Patterns # From ed2937a611dd6e39192a4c4a841a05cdc9b96c0a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 13 Nov 2024 09:59:34 +0000 Subject: [PATCH 02/12] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- mypy/semanal.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/mypy/semanal.py b/mypy/semanal.py index 7347fbdecf284..f54320bc0c649 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -6077,7 +6077,12 @@ def visit_type_application(self, expr: TypeApplication) -> None: def visit_list_comprehension(self, expr: ListComprehension) -> None: if any(expr.generator.is_async) or has_await_expression(expr): if not self.is_func_scope() or not self.function_stack[-1].is_coroutine: - self.fail(message_registry.ASYNC_FOR_OUTSIDE_COROUTINE, expr, code=codes.SYNTAX, serious=True) + self.fail( + message_registry.ASYNC_FOR_OUTSIDE_COROUTINE, + expr, + code=codes.SYNTAX, + serious=True, + ) expr.generator.accept(self) @@ -6091,7 +6096,12 @@ def visit_set_comprehension(self, expr: SetComprehension) -> None: def visit_dictionary_comprehension(self, expr: DictionaryComprehension) -> None: if any(expr.is_async): if not self.is_func_scope() or not self.function_stack[-1].is_coroutine: - self.fail(message_registry.ASYNC_FOR_OUTSIDE_COROUTINE, expr, code=codes.SYNTAX, serious=True) + self.fail( + message_registry.ASYNC_FOR_OUTSIDE_COROUTINE, + expr, + code=codes.SYNTAX, + serious=True, + ) with self.enter(expr): self.analyze_comp_for(expr) @@ -6168,7 +6178,9 @@ def visit_await_expr(self, expr: AwaitExpr) -> None: # This is not a blocker, because some enviroments (like ipython) # support top level awaits. self.fail('"await" outside function', expr, serious=True, code=codes.TOP_LEVEL_AWAIT) - elif not self.function_stack[-1].is_coroutine and not self.is_in_generator_expression(expr): + elif not self.function_stack[-1].is_coroutine and not self.is_in_generator_expression( + expr + ): self.fail( '"await" outside coroutine ("async def")', expr, From c97bce79ad46e39a5b189e0ce5bb4af5931027cd Mon Sep 17 00:00:00 2001 From: josetapadas Date: Wed, 13 Nov 2024 10:12:16 +0000 Subject: [PATCH 03/12] chore: added unit test --- test-data/unit/check-async-await.test | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/test-data/unit/check-async-await.test b/test-data/unit/check-async-await.test index 0ef08e5a07751..8cee6c4a8e220 100644 --- a/test-data/unit/check-async-await.test +++ b/test-data/unit/check-async-await.test @@ -1013,13 +1013,15 @@ async def foo(x: int) -> int: ... # These are allowed in some cases: top_level = await foo(1) # E: "await" outside function [top-level-await] -crasher = [await foo(x) for x in [1, 2, 3]] # E: "await" outside function [top-level-await] +crasher = [await foo(x) for x in [1, 2, 3]] # E: "async for" outside async function [syntax] \ + # E: "await" outside function [top-level-await] def bad() -> None: # These are always critical / syntax issues: - y = [await foo(x) for x in [1, 2, 3]] # E: "await" outside coroutine ("async def") [await-not-async] + y = [await foo(x) for x in [1, 2, 3]] # E: "async for" outside async function [syntax] 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] @@ -1080,3 +1082,13 @@ class Launcher(P): [builtins fixtures/async_await.pyi] [typing fixtures/typing-async.pyi] + +[case testAwaitInsideGeneratorExpr] +def foo(): + yield 0 + +def bar(): + (await x for x in foo()) + +[builtins fixtures/async_await.pyi] +[typing fixtures/typing-async.pyi] From ada4720a08670ae2123a16f78c81d6932a681439 Mon Sep 17 00:00:00 2001 From: josetapadas Date: Wed, 13 Nov 2024 10:17:50 +0000 Subject: [PATCH 04/12] chore: refactor to remove function for simple check --- mypy/semanal.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/mypy/semanal.py b/mypy/semanal.py index f54320bc0c649..de1a36f2c5df2 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -6178,9 +6178,7 @@ def visit_await_expr(self, expr: AwaitExpr) -> None: # This is not a blocker, because some enviroments (like ipython) # support top level awaits. self.fail('"await" outside function', expr, serious=True, code=codes.TOP_LEVEL_AWAIT) - elif not self.function_stack[-1].is_coroutine and not self.is_in_generator_expression( - expr - ): + elif not self.function_stack[-1].is_coroutine and self.scope_stack[-1] != SCOPE_COMPREHENSION: self.fail( '"await" outside coroutine ("async def")', expr, @@ -6189,9 +6187,6 @@ def visit_await_expr(self, expr: AwaitExpr) -> None: ) expr.expr.accept(self) - def is_in_generator_expression(self, node: AwaitExpr): - return self.scope_stack[-1] == SCOPE_COMPREHENSION - # # Patterns # From 43fc65af4a092651c0d1d00ca865917501ad206b Mon Sep 17 00:00:00 2001 From: josetapadas Date: Wed, 13 Nov 2024 11:17:47 +0000 Subject: [PATCH 05/12] fix: fixed the await outside coroutine within list comprehensions error --- mypy/message_registry.py | 2 ++ mypy/semanal.py | 12 ++++++++++-- test-data/unit/check-async-await.test | 5 +++-- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/mypy/message_registry.py b/mypy/message_registry.py index c0b422d4a35da..b32e169a61ed4 100644 --- a/mypy/message_registry.py +++ b/mypy/message_registry.py @@ -80,6 +80,8 @@ def with_additional_msg(self, info: str) -> ErrorMessage: ASYNC_FOR_OUTSIDE_COROUTINE: Final = '"async for" outside async function' ASYNC_WITH_OUTSIDE_COROUTINE: Final = '"async with" outside async function' +AWAIT_WITH_OUTSIDE_COROUTINE: Final = '"await" outside coroutine ("async def")' + INCOMPATIBLE_TYPES_IN_YIELD: Final = ErrorMessage('Incompatible types in "yield"') INCOMPATIBLE_TYPES_IN_YIELD_FROM: Final = ErrorMessage('Incompatible types in "yield from"') INCOMPATIBLE_TYPES_IN_STR_INTERPOLATION: Final = "Incompatible types in string interpolation" diff --git a/mypy/semanal.py b/mypy/semanal.py index de1a36f2c5df2..5517a62ae53ef 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -6075,7 +6075,7 @@ def visit_type_application(self, expr: TypeApplication) -> None: expr.types[i] = analyzed def visit_list_comprehension(self, expr: ListComprehension) -> None: - if any(expr.generator.is_async) or has_await_expression(expr): + if any(expr.generator.is_async): if not self.is_func_scope() or not self.function_stack[-1].is_coroutine: self.fail( message_registry.ASYNC_FOR_OUTSIDE_COROUTINE, @@ -6083,6 +6083,14 @@ def visit_list_comprehension(self, expr: ListComprehension) -> None: code=codes.SYNTAX, serious=True, ) + elif has_await_expression(expr): + if not self.is_func_scope() or not self.function_stack[-1].is_coroutine: + self.fail( + message_registry.AWAIT_WITH_OUTSIDE_COROUTINE, + expr, + code=codes.SYNTAX, + serious=True, + ) expr.generator.accept(self) @@ -6180,7 +6188,7 @@ def visit_await_expr(self, expr: AwaitExpr) -> None: self.fail('"await" outside function', expr, serious=True, code=codes.TOP_LEVEL_AWAIT) elif not self.function_stack[-1].is_coroutine and self.scope_stack[-1] != SCOPE_COMPREHENSION: self.fail( - '"await" outside coroutine ("async def")', + message_registry.AWAIT_WITH_OUTSIDE_COROUTINE, expr, serious=True, code=codes.AWAIT_NOT_ASYNC, diff --git a/test-data/unit/check-async-await.test b/test-data/unit/check-async-await.test index 8cee6c4a8e220..15e9cc6c289e3 100644 --- a/test-data/unit/check-async-await.test +++ b/test-data/unit/check-async-await.test @@ -1013,15 +1013,16 @@ async def foo(x: int) -> int: ... # These are allowed in some cases: top_level = await foo(1) # E: "await" outside function [top-level-await] -crasher = [await foo(x) for x in [1, 2, 3]] # E: "async for" outside async function [syntax] \ +crasher = [await foo(x) for x in [1, 2, 3]] # E: "await" outside coroutine ("async def") [syntax] \ # E: "await" outside function [top-level-await] def bad() -> None: # These are always critical / syntax issues: - y = [await foo(x) for x in [1, 2, 3]] # E: "async for" outside async function [syntax] + y = [await foo(x) for x in [1, 2, 3]] # E: "await" outside coroutine ("async def") [syntax] 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] From e3004a1c08bf1975de6a8694d5c4bb247a063bf4 Mon Sep 17 00:00:00 2001 From: josetapadas Date: Wed, 13 Nov 2024 11:21:50 +0000 Subject: [PATCH 06/12] chore: error type is not syntax but await-not-async --- mypy/semanal.py | 2 +- test-data/unit/check-async-await.test | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/mypy/semanal.py b/mypy/semanal.py index 5517a62ae53ef..63057a41aa226 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -6088,7 +6088,7 @@ def visit_list_comprehension(self, expr: ListComprehension) -> None: self.fail( message_registry.AWAIT_WITH_OUTSIDE_COROUTINE, expr, - code=codes.SYNTAX, + code=codes.AWAIT_NOT_ASYNC, serious=True, ) diff --git a/test-data/unit/check-async-await.test b/test-data/unit/check-async-await.test index 15e9cc6c289e3..bac74f2654cdd 100644 --- a/test-data/unit/check-async-await.test +++ b/test-data/unit/check-async-await.test @@ -1013,16 +1013,17 @@ async def foo(x: int) -> int: ... # These are allowed in some cases: top_level = await foo(1) # E: "await" outside function [top-level-await] -crasher = [await foo(x) for x in [1, 2, 3]] # E: "await" outside coroutine ("async def") [syntax] \ +crasher = [await foo(x) for x in [1, 2, 3]] # E: "await" outside coroutine ("async def") [await-not-async] \ # E: "await" outside function [top-level-await] def bad() -> None: # These are always critical / syntax issues: - y = [await foo(x) for x in [1, 2, 3]] # E: "await" outside coroutine ("async def") [syntax] + y = [await foo(x) for x in [1, 2, 3]] # E: "await" outside coroutine ("async def") [await-not-async] 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] From e7ef1f686db61b176705e69ceffcf34101f59d1d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 13 Nov 2024 11:25:36 +0000 Subject: [PATCH 07/12] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- mypy/semanal.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mypy/semanal.py b/mypy/semanal.py index 63057a41aa226..e724693fb272e 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -6186,7 +6186,10 @@ def visit_await_expr(self, expr: AwaitExpr) -> None: # This is not a blocker, because some enviroments (like ipython) # support top level awaits. self.fail('"await" outside function', expr, serious=True, code=codes.TOP_LEVEL_AWAIT) - elif not self.function_stack[-1].is_coroutine and self.scope_stack[-1] != SCOPE_COMPREHENSION: + elif ( + not self.function_stack[-1].is_coroutine + and self.scope_stack[-1] != SCOPE_COMPREHENSION + ): self.fail( message_registry.AWAIT_WITH_OUTSIDE_COROUTINE, expr, From 0c82fb99ba8fd39c603da6c9e1abb7af17809bb1 Mon Sep 17 00:00:00 2001 From: josetapadas Date: Thu, 14 Nov 2024 12:02:07 +0000 Subject: [PATCH 08/12] fix: added await-outside-coroutine checks also to list and dict comprehensions --- mypy/message_registry.py | 4 +-- mypy/semanal.py | 35 ++++++++++++++++----------- test-data/unit/check-async-await.test | 13 +++++++++- 3 files changed, 35 insertions(+), 17 deletions(-) diff --git a/mypy/message_registry.py b/mypy/message_registry.py index b32e169a61ed4..f48e1d22d506c 100644 --- a/mypy/message_registry.py +++ b/mypy/message_registry.py @@ -79,8 +79,8 @@ def with_additional_msg(self, info: str) -> ErrorMessage: ASYNC_FOR_OUTSIDE_COROUTINE: Final = '"async for" outside async function' ASYNC_WITH_OUTSIDE_COROUTINE: Final = '"async with" outside async function' - -AWAIT_WITH_OUTSIDE_COROUTINE: Final = '"await" outside coroutine ("async def")' +AWAIT_OUTSIDE_FUNCTION: Final = '"await" outside function' +AWAIT_OUTSIDE_COROUTINE: Final = '"await" outside coroutine ("async def")' INCOMPATIBLE_TYPES_IN_YIELD: Final = ErrorMessage('Incompatible types in "yield"') INCOMPATIBLE_TYPES_IN_YIELD_FROM: Final = ErrorMessage('Incompatible types in "yield from"') diff --git a/mypy/semanal.py b/mypy/semanal.py index e724693fb272e..39c3ee0c7245c 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -6074,6 +6074,18 @@ def visit_type_application(self, expr: TypeApplication) -> None: if analyzed is not None: expr.types[i] = analyzed + def _check_await_outside_coroutine(self, expr: ListComprehension | SetComprehension | DictionaryComprehension) -> None: + if not has_await_expression(expr): + return + + if not self.is_func_scope() or not self.function_stack[-1].is_coroutine: + self.fail( + message_registry.AWAIT_OUTSIDE_COROUTINE, + expr, + code=codes.AWAIT_NOT_ASYNC, + serious=True, + ) + def visit_list_comprehension(self, expr: ListComprehension) -> None: if any(expr.generator.is_async): if not self.is_func_scope() or not self.function_stack[-1].is_coroutine: @@ -6083,14 +6095,8 @@ def visit_list_comprehension(self, expr: ListComprehension) -> None: code=codes.SYNTAX, serious=True, ) - elif has_await_expression(expr): - if not self.is_func_scope() or not self.function_stack[-1].is_coroutine: - self.fail( - message_registry.AWAIT_WITH_OUTSIDE_COROUTINE, - expr, - code=codes.AWAIT_NOT_ASYNC, - serious=True, - ) + + self._check_await_outside_coroutine(expr) expr.generator.accept(self) @@ -6099,6 +6105,8 @@ def visit_set_comprehension(self, expr: SetComprehension) -> None: if not self.is_func_scope() or not self.function_stack[-1].is_coroutine: self.fail(message_registry.ASYNC_FOR_OUTSIDE_COROUTINE, expr, code=codes.SYNTAX) + self._check_await_outside_coroutine(expr) + expr.generator.accept(self) def visit_dictionary_comprehension(self, expr: DictionaryComprehension) -> None: @@ -6111,6 +6119,8 @@ def visit_dictionary_comprehension(self, expr: DictionaryComprehension) -> None: serious=True, ) + self._check_await_outside_coroutine(expr) + with self.enter(expr): self.analyze_comp_for(expr) expr.key.accept(self) @@ -6185,13 +6195,10 @@ def visit_await_expr(self, expr: AwaitExpr) -> None: # We check both because is_function_scope() returns True inside comprehensions. # This is not a blocker, because some enviroments (like ipython) # support top level awaits. - self.fail('"await" outside function', expr, serious=True, code=codes.TOP_LEVEL_AWAIT) - elif ( - not self.function_stack[-1].is_coroutine - and self.scope_stack[-1] != SCOPE_COMPREHENSION - ): + self.fail(message_registry.AWAIT_OUTSIDE_FUNCTION, expr, serious=True, code=codes.TOP_LEVEL_AWAIT) + elif not self.function_stack[-1].is_coroutine and self.scope_stack[-1] != SCOPE_COMPREHENSION: self.fail( - message_registry.AWAIT_WITH_OUTSIDE_COROUTINE, + message_registry.AWAIT_OUTSIDE_COROUTINE, expr, serious=True, code=codes.AWAIT_NOT_ASYNC, diff --git a/test-data/unit/check-async-await.test b/test-data/unit/check-async-await.test index bac74f2654cdd..5fbdfdcb9f16d 100644 --- a/test-data/unit/check-async-await.test +++ b/test-data/unit/check-async-await.test @@ -1085,12 +1085,23 @@ class Launcher(P): [builtins fixtures/async_await.pyi] [typing fixtures/typing-async.pyi] -[case testAwaitInsideGeneratorExpr] +[case testAwaitOutsideCoroutine] def foo(): yield 0 def bar(): (await x for x in foo()) + (await x for x in xs) # OK + [await x for x in xs] # E: "await" outside coroutine ("async def") + {await x for x in xs} # E: "await" outside coroutine ("async def") + {0: await x for x in xs} # E: "await" outside coroutine ("async def") + {await x: 0 for x in xs} # E: "await" outside coroutine ("async def") + + (x for x in await xs) # E: "await" outside coroutine ("async def") + [x for x in await xs] # E: "await" outside coroutine ("async def") + {x for x in await xs} # E: "await" outside coroutine ("async def") + {x: 0 for x in await xs} # E: "await" outside coroutine ("async def") + [builtins fixtures/async_await.pyi] [typing fixtures/typing-async.pyi] From 8e8298ee5d16df2b6efcef5bd20751e067351df1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 12:08:19 +0000 Subject: [PATCH 09/12] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- mypy/semanal.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/mypy/semanal.py b/mypy/semanal.py index 39c3ee0c7245c..7c5824733138a 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -6074,7 +6074,9 @@ def visit_type_application(self, expr: TypeApplication) -> None: if analyzed is not None: expr.types[i] = analyzed - def _check_await_outside_coroutine(self, expr: ListComprehension | SetComprehension | DictionaryComprehension) -> None: + def _check_await_outside_coroutine( + self, expr: ListComprehension | SetComprehension | DictionaryComprehension + ) -> None: if not has_await_expression(expr): return @@ -6195,8 +6197,16 @@ def visit_await_expr(self, expr: AwaitExpr) -> None: # We check both because is_function_scope() returns True inside comprehensions. # This is not a blocker, because some enviroments (like ipython) # support top level awaits. - self.fail(message_registry.AWAIT_OUTSIDE_FUNCTION, expr, serious=True, code=codes.TOP_LEVEL_AWAIT) - elif not self.function_stack[-1].is_coroutine and self.scope_stack[-1] != SCOPE_COMPREHENSION: + self.fail( + message_registry.AWAIT_OUTSIDE_FUNCTION, + expr, + serious=True, + code=codes.TOP_LEVEL_AWAIT, + ) + elif ( + not self.function_stack[-1].is_coroutine + and self.scope_stack[-1] != SCOPE_COMPREHENSION + ): self.fail( message_registry.AWAIT_OUTSIDE_COROUTINE, expr, From 0fee8d6046edcb213327158afa18ec550327b9e7 Mon Sep 17 00:00:00 2001 From: josetapadas Date: Mon, 18 Nov 2024 17:43:35 +0000 Subject: [PATCH 10/12] chore: remove artefact from update data --- test-data/unit/check-async-await.test | 2 -- 1 file changed, 2 deletions(-) diff --git a/test-data/unit/check-async-await.test b/test-data/unit/check-async-await.test index 5fbdfdcb9f16d..381f68bfb97e1 100644 --- a/test-data/unit/check-async-await.test +++ b/test-data/unit/check-async-await.test @@ -1022,8 +1022,6 @@ def bad() -> None: 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] From 95c573075524803ecb0b5af2b766a0e551ff3d2b Mon Sep 17 00:00:00 2001 From: josetapadas Date: Mon, 18 Nov 2024 17:47:09 +0000 Subject: [PATCH 11/12] chore: fail consistently for the new case also on the set comprehension --- mypy/semanal.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mypy/semanal.py b/mypy/semanal.py index 7c5824733138a..79c3258dc9430 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -6105,7 +6105,7 @@ def visit_list_comprehension(self, expr: ListComprehension) -> None: def visit_set_comprehension(self, expr: SetComprehension) -> None: if any(expr.generator.is_async): if not self.is_func_scope() or not self.function_stack[-1].is_coroutine: - self.fail(message_registry.ASYNC_FOR_OUTSIDE_COROUTINE, expr, code=codes.SYNTAX) + self.fail(message_registry.ASYNC_FOR_OUTSIDE_COROUTINE, expr, code=codes.SYNTAX, serious=True) self._check_await_outside_coroutine(expr) From 48148ac612e1153211389b782b813fce581fa1cb Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 17:48:06 +0000 Subject: [PATCH 12/12] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- mypy/semanal.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/mypy/semanal.py b/mypy/semanal.py index 79c3258dc9430..808b32f786f65 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -6105,7 +6105,12 @@ def visit_list_comprehension(self, expr: ListComprehension) -> None: def visit_set_comprehension(self, expr: SetComprehension) -> None: if any(expr.generator.is_async): if not self.is_func_scope() or not self.function_stack[-1].is_coroutine: - self.fail(message_registry.ASYNC_FOR_OUTSIDE_COROUTINE, expr, code=codes.SYNTAX, serious=True) + self.fail( + message_registry.ASYNC_FOR_OUTSIDE_COROUTINE, + expr, + code=codes.SYNTAX, + serious=True, + ) self._check_await_outside_coroutine(expr)