Skip to content

Commit 18c4693

Browse files
ilinumilevkivskyi
andauthored
[Backport] Fix generic TypedDict/NamedTuple fixup (#14701)
Backport of #14675. --------- Co-authored-by: Ivan Levkivskyi <[email protected]>
1 parent a9051d2 commit 18c4693

File tree

3 files changed

+47
-2
lines changed

3 files changed

+47
-2
lines changed

mypy/fixup.py

+4
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,13 @@ def visit_type_info(self, info: TypeInfo) -> None:
8080
if info.tuple_type:
8181
info.tuple_type.accept(self.type_fixer)
8282
info.update_tuple_type(info.tuple_type)
83+
if info.special_alias:
84+
info.special_alias.alias_tvars = list(info.defn.type_vars)
8385
if info.typeddict_type:
8486
info.typeddict_type.accept(self.type_fixer)
8587
info.update_typeddict_type(info.typeddict_type)
88+
if info.special_alias:
89+
info.special_alias.alias_tvars = list(info.defn.type_vars)
8690
if info.declared_metaclass:
8791
info.declared_metaclass.accept(self.type_fixer)
8892
if info.metaclass_type:

mypy/nodes.py

+12-2
Original file line numberDiff line numberDiff line change
@@ -3473,8 +3473,13 @@ def __init__(
34733473

34743474
@classmethod
34753475
def from_tuple_type(cls, info: TypeInfo) -> TypeAlias:
3476-
"""Generate an alias to the tuple type described by a given TypeInfo."""
3476+
"""Generate an alias to the tuple type described by a given TypeInfo.
3477+
3478+
NOTE: this doesn't set type alias type variables (for generic tuple types),
3479+
they must be set by the caller (when fully analyzed).
3480+
"""
34773481
assert info.tuple_type
3482+
# TODO: is it possible to refactor this to set the correct type vars here?
34783483
return TypeAlias(
34793484
info.tuple_type.copy_modified(fallback=mypy.types.Instance(info, info.defn.type_vars)),
34803485
info.fullname,
@@ -3484,8 +3489,13 @@ def from_tuple_type(cls, info: TypeInfo) -> TypeAlias:
34843489

34853490
@classmethod
34863491
def from_typeddict_type(cls, info: TypeInfo) -> TypeAlias:
3487-
"""Generate an alias to the TypedDict type described by a given TypeInfo."""
3492+
"""Generate an alias to the TypedDict type described by a given TypeInfo.
3493+
3494+
NOTE: this doesn't set type alias type variables (for generic TypedDicts),
3495+
they must be set by the caller (when fully analyzed).
3496+
"""
34883497
assert info.typeddict_type
3498+
# TODO: is it possible to refactor this to set the correct type vars here?
34893499
return TypeAlias(
34903500
info.typeddict_type.copy_modified(
34913501
fallback=mypy.types.Instance(info, info.defn.type_vars)

test-data/unit/check-incremental.test

+31
Original file line numberDiff line numberDiff line change
@@ -6359,3 +6359,34 @@ from m import Foo
63596359
[file m.py]
63606360
from missing_module import Meta # type: ignore[import]
63616361
class Foo(metaclass=Meta): ...
6362+
6363+
[case testGenericTypedDictWithError]
6364+
import b
6365+
[file a.py]
6366+
from typing import Generic, TypeVar
6367+
from typing_extensions import TypedDict
6368+
6369+
TValue = TypeVar("TValue")
6370+
class Dict(TypedDict, Generic[TValue]):
6371+
value: TValue
6372+
6373+
[file b.py]
6374+
from a import Dict, TValue
6375+
6376+
def f(d: Dict[TValue]) -> TValue:
6377+
return d["value"]
6378+
def g(d: Dict[TValue]) -> TValue:
6379+
return d["x"]
6380+
6381+
[file b.py.2]
6382+
from a import Dict, TValue
6383+
6384+
def f(d: Dict[TValue]) -> TValue:
6385+
return d["value"]
6386+
def g(d: Dict[TValue]) -> TValue:
6387+
return d["y"]
6388+
[builtins fixtures/dict.pyi]
6389+
[out]
6390+
tmp/b.py:6: error: TypedDict "a.Dict[TValue]" has no key "x"
6391+
[out2]
6392+
tmp/b.py:6: error: TypedDict "a.Dict[TValue]" has no key "y"

0 commit comments

Comments
 (0)