Skip to content

Commit

Permalink
Fix type narrowing in lambda expressions (#16407)
Browse files Browse the repository at this point in the history
Fixes #4297

Fix is straightforward: without properly pushing lambda expression on
the stack, the previous fix @JukkaL added for nested functions doesn't
work for lambdas (it thinks that we are at global scope).
  • Loading branch information
ilevkivskyi authored Nov 4, 2023
1 parent 8c57df0 commit 544e6ce
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 1 deletion.
3 changes: 2 additions & 1 deletion mypy/checkexpr.py
Original file line number Diff line number Diff line change
Expand Up @@ -5195,7 +5195,8 @@ def visit_lambda_expr(self, e: LambdaExpr) -> Type:
else:
# Type context available.
self.chk.return_types.append(inferred_type.ret_type)
self.chk.check_func_item(e, type_override=type_override)
with self.chk.tscope.function_scope(e):
self.chk.check_func_item(e, type_override=type_override)
if not self.chk.has_type(e.expr()):
# TODO: return expression must be accepted before exiting function scope.
self.accept(e.expr(), allow_none_return=True)
Expand Down
13 changes: 13 additions & 0 deletions test-data/unit/check-inference-context.test
Original file line number Diff line number Diff line change
Expand Up @@ -1482,3 +1482,16 @@ b: Any
i = i if isinstance(i, int) else b
reveal_type(i) # N: Revealed type is "Union[Any, builtins.int]"
[builtins fixtures/isinstance.pyi]

[case testLambdaInferenceUsesNarrowedTypes]
from typing import Optional, Callable

def f1(key: Callable[[], str]) -> None: ...
def f2(key: object) -> None: ...

def g(b: Optional[str]) -> None:
if b:
f1(lambda: reveal_type(b)) # N: Revealed type is "builtins.str"
z: Callable[[], str] = lambda: reveal_type(b) # N: Revealed type is "builtins.str"
f2(lambda: reveal_type(b)) # N: Revealed type is "builtins.str"
lambda: reveal_type(b) # N: Revealed type is "builtins.str"

0 comments on commit 544e6ce

Please sign in to comment.