From a9eb14c27eed0de48339fb14bb0e36ed5d498693 Mon Sep 17 00:00:00 2001 From: Ivan Levkivskyi Date: Sun, 4 Aug 2024 21:45:53 +0100 Subject: [PATCH] Always reset binder when checking deferred nodes --- mypy/checker.py | 9 +++---- test-data/unit/check-functions.test | 37 +++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/mypy/checker.py b/mypy/checker.py index 59de599006a8b..82633a5b6c0e6 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -540,10 +540,11 @@ def check_partial(self, node: DeferredNodeType | FineGrainedDeferredNodeType) -> self.check_top_level(node) else: self.recurse_into_functions = True - if isinstance(node, LambdaExpr): - self.expr_checker.accept(node) - else: - self.accept(node) + with self.binder.top_frame_context(): + if isinstance(node, LambdaExpr): + self.expr_checker.accept(node) + else: + self.accept(node) def check_top_level(self, node: MypyFile) -> None: """Check only the top-level of a module, skipping function definitions.""" diff --git a/test-data/unit/check-functions.test b/test-data/unit/check-functions.test index ef5a66b6ecde2..b681c544a6bda 100644 --- a/test-data/unit/check-functions.test +++ b/test-data/unit/check-functions.test @@ -3409,3 +3409,40 @@ for factory in ( reveal_type(factory) # N: Revealed type is "def () -> Union[builtins.str, None]" var = factory() [builtins fixtures/tuple.pyi] + +[case testLambdaInDeferredDecoratorNoCrash] +def foo(x): + pass + +class Bar: + def baz(self, x): + pass + +class Qux(Bar): + @foo(lambda x: None) + def baz(self, x) -> None: + pass +[builtins fixtures/tuple.pyi] + +[case testGeneratorInDeferredDecoratorNoCrash] +from typing import Protocol, TypeVar + +T = TypeVar("T", covariant=True) + +class SupportsNext(Protocol[T]): + def __next__(self) -> T: ... + +def next(i: SupportsNext[T]) -> T: ... + +def foo(x): + pass + +class Bar: + def baz(self, x): + pass + +class Qux(Bar): + @next(f for f in [foo]) + def baz(self, x) -> None: + pass +[builtins fixtures/tuple.pyi]