Skip to content

Commit 50d0d04

Browse files
authored
Always reset binder when checking deferred nodes (#17643)
Fixes #17595
1 parent 6f20721 commit 50d0d04

File tree

2 files changed

+42
-4
lines changed

2 files changed

+42
-4
lines changed

mypy/checker.py

+5-4
Original file line numberDiff line numberDiff line change
@@ -540,10 +540,11 @@ def check_partial(self, node: DeferredNodeType | FineGrainedDeferredNodeType) ->
540540
self.check_top_level(node)
541541
else:
542542
self.recurse_into_functions = True
543-
if isinstance(node, LambdaExpr):
544-
self.expr_checker.accept(node)
545-
else:
546-
self.accept(node)
543+
with self.binder.top_frame_context():
544+
if isinstance(node, LambdaExpr):
545+
self.expr_checker.accept(node)
546+
else:
547+
self.accept(node)
547548

548549
def check_top_level(self, node: MypyFile) -> None:
549550
"""Check only the top-level of a module, skipping function definitions."""

test-data/unit/check-functions.test

+37
Original file line numberDiff line numberDiff line change
@@ -3409,3 +3409,40 @@ for factory in (
34093409
reveal_type(factory) # N: Revealed type is "def () -> Union[builtins.str, None]"
34103410
var = factory()
34113411
[builtins fixtures/tuple.pyi]
3412+
3413+
[case testLambdaInDeferredDecoratorNoCrash]
3414+
def foo(x):
3415+
pass
3416+
3417+
class Bar:
3418+
def baz(self, x):
3419+
pass
3420+
3421+
class Qux(Bar):
3422+
@foo(lambda x: None)
3423+
def baz(self, x) -> None:
3424+
pass
3425+
[builtins fixtures/tuple.pyi]
3426+
3427+
[case testGeneratorInDeferredDecoratorNoCrash]
3428+
from typing import Protocol, TypeVar
3429+
3430+
T = TypeVar("T", covariant=True)
3431+
3432+
class SupportsNext(Protocol[T]):
3433+
def __next__(self) -> T: ...
3434+
3435+
def next(i: SupportsNext[T]) -> T: ...
3436+
3437+
def foo(x):
3438+
pass
3439+
3440+
class Bar:
3441+
def baz(self, x):
3442+
pass
3443+
3444+
class Qux(Bar):
3445+
@next(f for f in [foo])
3446+
def baz(self, x) -> None:
3447+
pass
3448+
[builtins fixtures/tuple.pyi]

0 commit comments

Comments
 (0)