Skip to content

Commit a1f785e

Browse files
authored
Revert "Now lambda is counted as a valid context in handle_cannot_determine_type (#11215)" (#11694)
This reverts commit d37c2be. Lambdas can't be safely deferred. There are various subtle assumptions about lambdas not being deferred in different parts of the codebase, and figuring out how to do this safely is almost certainly not worth the trouble. This would be very difficult to validate, since lambda deferral would probably happen very rarely in practice.
1 parent 1393e3f commit a1f785e

File tree

4 files changed

+4
-35
lines changed

4 files changed

+4
-35
lines changed

mypy/checker.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -404,8 +404,8 @@ def defer_node(self, node: DeferredNodeType, enclosing_class: Optional[TypeInfo]
404404
self.deferred_nodes.append(DeferredNode(node, enclosing_class))
405405

406406
def handle_cannot_determine_type(self, name: str, context: Context) -> None:
407-
node = self.scope.top_function()
408-
if self.pass_num < self.last_pass and isinstance(node, (FuncDef, LambdaExpr)):
407+
node = self.scope.top_non_lambda_function()
408+
if self.pass_num < self.last_pass and isinstance(node, FuncDef):
409409
# Don't report an error yet. Just defer. Note that we don't defer
410410
# lambdas because they are coupled to the surrounding function
411411
# through the binder and the inferred type of the lambda, so it

mypy/checkexpr.py

+1-7
Original file line numberDiff line numberDiff line change
@@ -3928,13 +3928,7 @@ def visit_conditional_expr(self, e: ConditionalExpr, allow_none_return: bool = F
39283928
def analyze_cond_branch(self, map: Optional[Dict[Expression, Type]],
39293929
node: Expression, context: Optional[Type],
39303930
allow_none_return: bool = False) -> Type:
3931-
# We need to be have the correct amount of binder frames.
3932-
# Sometimes it can be missing for unreachable parts.
3933-
with (
3934-
self.chk.binder.frame_context(can_skip=True, fall_through=0)
3935-
if len(self.chk.binder.frames) > 1
3936-
else self.chk.binder.top_frame_context()
3937-
):
3931+
with self.chk.binder.frame_context(can_skip=True, fall_through=0):
39383932
if map is None:
39393933
# We still need to type check node, in case we want to
39403934
# process it for isinstance checks later

test-data/unit/check-callable.test

-22
Original file line numberDiff line numberDiff line change
@@ -351,28 +351,6 @@ def f(t: T) -> A:
351351

352352
[builtins fixtures/callable.pyi]
353353

354-
[case testCallableTypeVarBoundAndLambdaDefer]
355-
# See https://github.com/python/mypy/issues/11212
356-
from typing import Callable, TypeVar
357-
358-
C = TypeVar('C', bound=Callable)
359-
360-
def dec(val: None) -> Callable[[C], C]:
361-
def wrapper(f):
362-
return f
363-
return wrapper
364-
365-
lambda: foo() + 2 # error was here
366-
367-
@dec(None)
368-
def foo() -> int:
369-
return 2
370-
371-
lambda: foo() + 2 # double check
372-
373-
reveal_type(foo() + 2) # N: Revealed type is "builtins.int"
374-
[builtins fixtures/callable.pyi]
375-
376354
[case testCallableTypeUnion]
377355
from abc import ABCMeta, abstractmethod
378356
from typing import Type, Union

test-data/unit/check-optional.test

+1-4
Original file line numberDiff line numberDiff line change
@@ -738,11 +738,8 @@ class A:
738738

739739
def f(self, x: Optional['A']) -> None:
740740
assert x
741-
lambda: (self.y, x.a)
741+
lambda: (self.y, x.a) # E: Cannot determine type of "y"
742742
self.y = int()
743-
[out]
744-
main:8: error: Cannot determine type of "y"
745-
main:8: error: Item "None" of "Optional[A]" has no attribute "a"
746743
[builtins fixtures/isinstancelist.pyi]
747744

748745
[case testDeferredAndOptionalInferenceSpecialCase]

0 commit comments

Comments
 (0)