Skip to content

Commit 08a0b07

Browse files
authored
Do not cache fast container types inside lambdas (#20166)
Fixes #20163. `fast_container_type` uses another layer of expression cache, it also has to be bypassed from within lambdas.
1 parent 5bdfe7e commit 08a0b07

File tree

2 files changed

+22
-2
lines changed

2 files changed

+22
-2
lines changed

mypy/checkexpr.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5099,7 +5099,10 @@ def fast_container_type(
50995099
self.resolved_type[e] = NoneType()
51005100
return None
51015101
ct = self.chk.named_generic_type(container_fullname, [vt])
5102-
self.resolved_type[e] = ct
5102+
if not self.in_lambda_expr:
5103+
# We cannot cache results in lambdas - their bodies can be accepted in
5104+
# error-suppressing watchers too early
5105+
self.resolved_type[e] = ct
51035106
return ct
51045107

51055108
def _first_or_join_fast_item(self, items: list[Type]) -> Type | None:
@@ -5334,7 +5337,10 @@ def fast_dict_type(self, e: DictExpr) -> Type | None:
53345337
self.resolved_type[e] = NoneType()
53355338
return None
53365339
dt = self.chk.named_generic_type("builtins.dict", [kt, vt])
5337-
self.resolved_type[e] = dt
5340+
if not self.in_lambda_expr:
5341+
# We cannot cache results in lambdas - their bodies can be accepted in
5342+
# error-suppressing watchers too early
5343+
self.resolved_type[e] = dt
53385344
return dt
53395345

53405346
def check_typeddict_literal_in_context(

test-data/unit/check-inference-context.test

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,20 @@ f(
709709
A(), r=B())
710710
[builtins fixtures/isinstance.pyi]
711711

712+
[case testLambdaWithFastContainerType]
713+
from collections.abc import Callable
714+
from typing import Never, TypeVar
715+
716+
T = TypeVar("T")
717+
718+
def f(a: Callable[[], T]) -> None: ...
719+
720+
def foo(x: str) -> Never: ...
721+
722+
f(lambda: [foo(0)]) # E: Argument 1 to "foo" has incompatible type "int"; expected "str"
723+
f(lambda: {"x": foo(0)}) # E: Argument 1 to "foo" has incompatible type "int"; expected "str"
724+
[builtins fixtures/tuple.pyi]
725+
712726

713727
-- Overloads + generic functions
714728
-- -----------------------------

0 commit comments

Comments
 (0)