Skip to content

Commit

Permalink
[Backport] Fix generic TypedDict/NamedTuple fixup (#14701)
Browse files Browse the repository at this point in the history
Backport of  #14675.

---------

Co-authored-by: Ivan Levkivskyi <levkivskyi@gmail.com>
  • Loading branch information
ilinum and ilevkivskyi committed Feb 15, 2023
1 parent a9051d2 commit 18c4693
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 2 deletions.
4 changes: 4 additions & 0 deletions mypy/fixup.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,13 @@ def visit_type_info(self, info: TypeInfo) -> None:
if info.tuple_type:
info.tuple_type.accept(self.type_fixer)
info.update_tuple_type(info.tuple_type)
if info.special_alias:
info.special_alias.alias_tvars = list(info.defn.type_vars)
if info.typeddict_type:
info.typeddict_type.accept(self.type_fixer)
info.update_typeddict_type(info.typeddict_type)
if info.special_alias:
info.special_alias.alias_tvars = list(info.defn.type_vars)
if info.declared_metaclass:
info.declared_metaclass.accept(self.type_fixer)
if info.metaclass_type:
Expand Down
14 changes: 12 additions & 2 deletions mypy/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -3473,8 +3473,13 @@ def __init__(

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

@classmethod
def from_typeddict_type(cls, info: TypeInfo) -> TypeAlias:
"""Generate an alias to the TypedDict type described by a given TypeInfo."""
"""Generate an alias to the TypedDict type described by a given TypeInfo.
NOTE: this doesn't set type alias type variables (for generic TypedDicts),
they must be set by the caller (when fully analyzed).
"""
assert info.typeddict_type
# TODO: is it possible to refactor this to set the correct type vars here?
return TypeAlias(
info.typeddict_type.copy_modified(
fallback=mypy.types.Instance(info, info.defn.type_vars)
Expand Down
31 changes: 31 additions & 0 deletions test-data/unit/check-incremental.test
Original file line number Diff line number Diff line change
Expand Up @@ -6359,3 +6359,34 @@ from m import Foo
[file m.py]
from missing_module import Meta # type: ignore[import]
class Foo(metaclass=Meta): ...

[case testGenericTypedDictWithError]
import b
[file a.py]
from typing import Generic, TypeVar
from typing_extensions import TypedDict

TValue = TypeVar("TValue")
class Dict(TypedDict, Generic[TValue]):
value: TValue

[file b.py]
from a import Dict, TValue

def f(d: Dict[TValue]) -> TValue:
return d["value"]
def g(d: Dict[TValue]) -> TValue:
return d["x"]

[file b.py.2]
from a import Dict, TValue

def f(d: Dict[TValue]) -> TValue:
return d["value"]
def g(d: Dict[TValue]) -> TValue:
return d["y"]
[builtins fixtures/dict.pyi]
[out]
tmp/b.py:6: error: TypedDict "a.Dict[TValue]" has no key "x"
[out2]
tmp/b.py:6: error: TypedDict "a.Dict[TValue]" has no key "y"

0 comments on commit 18c4693

Please sign in to comment.