Skip to content

Commit

Permalink
Always reset binder when checking deferred nodes (#17643)
Browse files Browse the repository at this point in the history
Fixes #17595
  • Loading branch information
ilevkivskyi committed Aug 4, 2024
1 parent 6f20721 commit 50d0d04
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 4 deletions.
9 changes: 5 additions & 4 deletions mypy/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -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."""
Expand Down
37 changes: 37 additions & 0 deletions test-data/unit/check-functions.test
Original file line number Diff line number Diff line change
Expand Up @@ -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]

0 comments on commit 50d0d04

Please sign in to comment.