Skip to content

Commit ec511c6

Browse files
authored
Fix generic TypedDict/NamedTuple fixup (#14675)
Fixes #14638 TBH I don't remember why do we need to create the "incomplete" type alias (with empty type variables), and set up type variables later. But I didn't want to risk a larger refactoring and just fixed the missing calls surfaced by the issue instead.
1 parent 0b4ccae commit ec511c6

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
@@ -3495,8 +3495,13 @@ def __init__(
34953495

34963496
@classmethod
34973497
def from_tuple_type(cls, info: TypeInfo) -> TypeAlias:
3498-
"""Generate an alias to the tuple type described by a given TypeInfo."""
3498+
"""Generate an alias to the tuple type described by a given TypeInfo.
3499+
3500+
NOTE: this doesn't set type alias type variables (for generic tuple types),
3501+
they must be set by the caller (when fully analyzed).
3502+
"""
34993503
assert info.tuple_type
3504+
# TODO: is it possible to refactor this to set the correct type vars here?
35003505
return TypeAlias(
35013506
info.tuple_type.copy_modified(fallback=mypy.types.Instance(info, info.defn.type_vars)),
35023507
info.fullname,
@@ -3506,8 +3511,13 @@ def from_tuple_type(cls, info: TypeInfo) -> TypeAlias:
35063511

35073512
@classmethod
35083513
def from_typeddict_type(cls, info: TypeInfo) -> TypeAlias:
3509-
"""Generate an alias to the TypedDict type described by a given TypeInfo."""
3514+
"""Generate an alias to the TypedDict type described by a given TypeInfo.
3515+
3516+
NOTE: this doesn't set type alias type variables (for generic TypedDicts),
3517+
they must be set by the caller (when fully analyzed).
3518+
"""
35103519
assert info.typeddict_type
3520+
# TODO: is it possible to refactor this to set the correct type vars here?
35113521
return TypeAlias(
35123522
info.typeddict_type.copy_modified(
35133523
fallback=mypy.types.Instance(info, info.defn.type_vars)

test-data/unit/check-incremental.test

+31
Original file line numberDiff line numberDiff line change
@@ -6372,3 +6372,34 @@ y: int = x
63726372
[builtins fixtures/tuple.pyi]
63736373
[out]
63746374
[out2]
6375+
6376+
[case testGenericTypedDictWithError]
6377+
import b
6378+
[file a.py]
6379+
from typing import Generic, TypeVar
6380+
from typing_extensions import TypedDict
6381+
6382+
TValue = TypeVar("TValue")
6383+
class Dict(TypedDict, Generic[TValue]):
6384+
value: TValue
6385+
6386+
[file b.py]
6387+
from a import Dict, TValue
6388+
6389+
def f(d: Dict[TValue]) -> TValue:
6390+
return d["value"]
6391+
def g(d: Dict[TValue]) -> TValue:
6392+
return d["x"]
6393+
6394+
[file b.py.2]
6395+
from a import Dict, TValue
6396+
6397+
def f(d: Dict[TValue]) -> TValue:
6398+
return d["value"]
6399+
def g(d: Dict[TValue]) -> TValue:
6400+
return d["y"]
6401+
[builtins fixtures/dict.pyi]
6402+
[out]
6403+
tmp/b.py:6: error: TypedDict "a.Dict[TValue]" has no key "x"
6404+
[out2]
6405+
tmp/b.py:6: error: TypedDict "a.Dict[TValue]" has no key "y"

0 commit comments

Comments
 (0)