Argument type `Union[T, List[T]]` fails to infer constaints
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 20.6k
- Forks
- 3.3k
- PR merge metrics
- PR metrics pending
Description
While working on #11128 I got hit by this.
This code does not type check:
from typing import TypeVar, Union, List
T1 = TypeVar("T1")
def promote_list(item: Union[T1, List[T1]]) -> List[T1]:
...
exprs: List[int]
reveal_type(promote_list(exprs)) # error
# ex.py:9: note: Revealed type is "builtins.list[<nothing>]"
# ex.py:9: error: Argument 1 to "promote_list" has incompatible type "List[int]"; expected "List[<nothing>]"
reveal_type(promote_list(1)) # ok
# Revealed type is "builtins.list[builtins.int*]"
Which is not what I expect. For example, TypeScript solves this properly:
function protomoteList<T>(input: T | T[]): T[] {
return []
}
function test(input: number[]) {}
test(protomoteList(1)) # ok
Cause
It happens somewhere here: https://github.com/python/mypy/blob/b3ff2a683bd41a176c597d3c3ba65f6a31f805c5/mypy/constraints.py#L168-L171
I will try to solve this, but I know that this is going to be complicated.
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
Start with the reproduction in the issue and inspect mypy/constraints.py around lines 168-171, where the reported cause occurs. Confirm the current behavior for Union[T1, List[T1]] with the provided reveal_type calls; done means the List[int] argument type-checks and the result is inferred as List[int].
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- compilers, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100