Repository navigation
Enable generic NamedTuples #13396
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enable generic NamedTuples #13396
Changes from 1 commit
550423e
83f7808
417fc57
12c4f02
41fab83
98a637d
7905afb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1186,23 +1186,79 @@ NT[str](key=0, value=0) # E: Argument "value" to "NT" has incompatible type "in | |
| [case testGenericNamedTupleMethods] | ||
| from typing import Generic, NamedTuple, TypeVar | ||
|
|
||
| T = TypeVar("T") | ||
| class NT(NamedTuple, Generic[T]): | ||
| key: int | ||
| value: T | ||
| x: int | ||
|
|
||
| nti: NT[int] | ||
| reveal_type(nti * x) # N: Revealed type is "builtins.tuple[builtins.int, ...]" | ||
|
|
||
| nts: NT[str] | ||
| reveal_type(nts * x) # N: Revealed type is "builtins.tuple[builtins.object, ...]" | ||
| [builtins fixtures/tuple.pyi] | ||
| [typing fixtures/typing-namedtuple.pyi] | ||
|
|
||
| [case testGenericNamedTupleCustomMethods] | ||
| from typing import Generic, NamedTuple, TypeVar | ||
|
|
||
| T = TypeVar("T") | ||
| class NT(NamedTuple, Generic[T]): | ||
| key: int | ||
| value: T | ||
| def foo(self) -> T: ... | ||
| @classmethod | ||
| def from_value(cls, value: T) -> NT[T]: ... | ||
|
|
||
| nts: NT[str] | ||
| reveal_type(nts.foo()) # N: Revealed type is "builtins.str" | ||
|
|
||
| nti = NT.from_value(1) | ||
| reveal_type(nti) # N: Revealed type is "Tuple[builtins.int, builtins.int, fallback=__main__.NT[builtins.int]]" | ||
| NT[str].from_value(1) # E: Argument 1 to "from_value" of "NT" has incompatible type "int"; expected "str" | ||
| [builtins fixtures/tuple.pyi] | ||
| [typing fixtures/typing-namedtuple.pyi] | ||
|
|
||
| [case testGenericNamedTupleSubtyping] | ||
| from typing import Generic, NamedTuple, TypeVar | ||
| from typing import Generic, NamedTuple, TypeVar, Tuple | ||
|
|
||
| T = TypeVar("T") | ||
| class NT(NamedTuple, Generic[T]): | ||
| key: int | ||
| value: T | ||
|
|
||
| nts: NT[str] | ||
| nti: NT[int] | ||
|
|
||
| def foo(x: Tuple[int, ...]) -> None: ... | ||
| foo(nti) | ||
| foo(nts) # E: Argument 1 to "foo" has incompatible type "NT[str]"; expected "Tuple[int, ...]" | ||
| [builtins fixtures/tuple.pyi] | ||
| [typing fixtures/typing-namedtuple.pyi] | ||
|
|
||
| [case testGenericNamedTupleJoin] | ||
| from typing import Generic, NamedTuple, TypeVar | ||
| from typing import Generic, NamedTuple, TypeVar, Tuple | ||
|
|
||
| T = TypeVar("T") | ||
| class NT(NamedTuple, Generic[T]): | ||
| key: int | ||
| value: T | ||
|
|
||
| nts: NT[str] | ||
| nti: NT[int] | ||
| x: Tuple[int, ...] | ||
|
|
||
| def foo(x: T, y: T) -> T: ... | ||
| reveal_type(foo(nti, nti)) # N: Revealed type is "Tuple[builtins.int, builtins.int, fallback=__main__.NT[builtins.int]]" | ||
|
|
||
| # Here fallbacks are object because named tuples are invariant. | ||
| reveal_type(foo(nti, nts)) # N: Revealed type is "Tuple[builtins.int, builtins.object, fallback=builtins.object]" | ||
| reveal_type(foo(nts, nti)) # N: Revealed type is "Tuple[builtins.int, builtins.object, fallback=builtins.object]" | ||
|
|
||
| reveal_type(foo(nti, x)) # N: Revealed type is "builtins.tuple[builtins.int, ...]" | ||
|
Comment on lines
+1273
to
+1275
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The difference here (Tuple for fixed-length and builtins.tuple for variable-length) is unfortunate but that seems like a problem for a different PR.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IIRC in error messages we format them nicely, it is only |
||
| reveal_type(foo(nts, x)) # N: Revealed type is "builtins.tuple[builtins.object, ...]" | ||
| reveal_type(foo(x, nti)) # N: Revealed type is "builtins.tuple[builtins.int, ...]" | ||
| reveal_type(foo(x, nts)) # N: Revealed type is "builtins.tuple[builtins.object, ...]" | ||
| [builtins fixtures/tuple.pyi] | ||
| [typing fixtures/typing-namedtuple.pyi] | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This causes a circular import:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for reporting! Do you have a (preferably simple) repro for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Simply importing
mypy.reportwithout mypyc enabled should trigger this issue.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See #13809 Btw just curious, why do you need to
import mypy.reportdirectly?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's one of sanity checks in nixpkgs, to make sure mypy module is not broken.