Skip to content

Commit

Permalink
Fix generic TypedDict/NamedTuple fixup (python#14675)
Browse files Browse the repository at this point in the history
Fixes python#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.
  • Loading branch information
ilevkivskyi authored and ilinum committed Feb 14, 2023
1 parent 83db085 commit 510d717
Show file tree
Hide file tree
Showing 3 changed files with 60 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
44 changes: 44 additions & 0 deletions test-data/unit/check-incremental.test
Original file line number Diff line number Diff line change
Expand Up @@ -6359,3 +6359,47 @@ from m import Foo
[file m.py]
from missing_module import Meta # type: ignore[import]
class Foo(metaclass=Meta): ...

[case testIncrementalNativeInt]
import a
[file a.py]
from mypy_extensions import i64
x: i64 = 0
[file a.py.2]
from mypy_extensions import i64
x: i64 = 0
y: int = x
[builtins fixtures/tuple.pyi]
[out]
[out2]

[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 510d717

Please sign in to comment.