Unpacking a NamedTuple leads to unusual results
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 15.6k
- Forks
- 1.8k
- Avg merge
- 12h 13m
- Merged PRs (30d)
- 52
Description
Pyright doesn't allow unpacking a namedtuple when it's provided directly after *:
type Foo = tuple[*F] # Unpack is not allowed in this context
However, pyright seems to support unpacking type parameters with a tuple bound. If a NamedTuple is filled in for the parameter, strange things happen. Code example (pyright 1.1.405):
from typing import reveal_type, NamedTuple
class F(NamedTuple):
x: int
y: str
type UnpackThing[Xs: tuple[object, ...]] = tuple[*Xs]
type Foo = UnpackThing[F]
def fn(foo: Foo) -> None:
reveal_type(foo) # tuple[*F]
# ^technically not wrong, but probably should be tuple[int, str]
reveal_type(foo[0]) # Type of "foo[0]" is "*F"
# (expected: 'Type of "foo[0]" is "int"')
reveal_type(foo[1]) # info: Type of "foo[1]" is "F"
# AND error: Index 1 is out of range for type Foo
# (expected: 'Type of "foo[1]" is "str"')
reveal_type(foo[0].__replace__) # "(*, x: int = ..., y: str = ...) -> *F"
# ^maybe pyright thinks that foo is just tuple[F]?
It seems like pyright is assigning an invalid "*F" type as the first and only element in the tuple for the inferred type of foo, similarly to #10637
Here's a different way of producing such a type:
def duplicate[T: tuple[object, ...]](tup: T) -> tuple[*T, *T]:
...
foo = duplicate(F(1, "a"))
reveal_type(foo) # Type of "foo" is "tuple[*F, *F]"
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the issue with the two provided snippets using pyright 1.1.405, focusing on the NamedTuple and tuple type-parameter cases. Trace how the inferred tuple[*F] and tuple[*F, *F] types are represented and indexed; done means the revealed types and index behavior match tuple[int, str] and the expected duplicate expansion.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100