Skip to content

Now lambda is counted as a valid context in handle_cannot_determine_type #11215

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions mypy/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -389,8 +389,8 @@ def defer_node(self, node: DeferredNodeType, enclosing_class: Optional[TypeInfo]
self.deferred_nodes.append(DeferredNode(node, enclosing_class))

def handle_cannot_determine_type(self, name: str, context: Context) -> None:
node = self.scope.top_non_lambda_function()
if self.pass_num < self.last_pass and isinstance(node, FuncDef):
node = self.scope.top_function()
if self.pass_num < self.last_pass and isinstance(node, (FuncDef, LambdaExpr)):
# Don't report an error yet. Just defer. Note that we don't defer
# lambdas because they are coupled to the surrounding function
# through the binder and the inferred type of the lambda, so it
Expand Down
8 changes: 7 additions & 1 deletion mypy/checkexpr.py
Original file line number Diff line number Diff line change
Expand Up @@ -3876,7 +3876,13 @@ def visit_conditional_expr(self, e: ConditionalExpr, allow_none_return: bool = F
def analyze_cond_branch(self, map: Optional[Dict[Expression, Type]],
node: Expression, context: Optional[Type],
allow_none_return: bool = False) -> Type:
with self.chk.binder.frame_context(can_skip=True, fall_through=0):
# We need to be have the correct amount of binder frames.
# Sometimes it can be missing for unreachable parts.
with (
self.chk.binder.frame_context(can_skip=True, fall_through=0)
if len(self.chk.binder.frames) > 1
else self.chk.binder.top_frame_context()
):
if map is None:
# We still need to type check node, in case we want to
# process it for isinstance checks later
Expand Down
22 changes: 22 additions & 0 deletions test-data/unit/check-callable.test
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,28 @@ def f(t: T) -> A:

[builtins fixtures/callable.pyi]

[case testCallableTypeVarBoundAndLambdaDefer]
# See https://github.com/python/mypy/issues/11212
from typing import Callable, TypeVar

C = TypeVar('C', bound=Callable)

def dec(val: None) -> Callable[[C], C]:
def wrapper(f):
return f
return wrapper

lambda: foo() + 2 # error was here

@dec(None)
def foo() -> int:
return 2

lambda: foo() + 2 # double check

reveal_type(foo() + 2) # N: Revealed type is "builtins.int"
[builtins fixtures/callable.pyi]

[case testCallableTypeUnion]
from abc import ABCMeta, abstractmethod
from typing import Type, Union
Expand Down
5 changes: 4 additions & 1 deletion test-data/unit/check-optional.test
Original file line number Diff line number Diff line change
Expand Up @@ -738,8 +738,11 @@ class A:

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

[case testDeferredAndOptionalInferenceSpecialCase]
Expand Down