Consider the ambiguous (yet somewhat useful) type: T | list[T]. It is problematic since given any list, e.g., list[int], it can bind T to int, which is the expected behavior, or to list[int], which is surprising, but yet consistent with the type definition. Mypy does neither.
from typing import assert_type, Never
def f[T](x: T | list[T]) -> list[T] | T:
if isinstance(x, list):
return [y for y in x]
else:
return x
reveal_type(f(1)) # list[int] | int
reveal_type(f([])) # list[Never]
reveal_type(f([1, 2, 3])) # list[Never]
# It also flags an issue: expect that argument for f to be list[Never]
The first revealed type is correct.
The second one (for f([])), is strange. It probably should infer Any | list[Any] (which simplifies to Any). Mypy assigns list[Never] which perhaps is acceptable if we remember that list[Never] | Never also simplifies to list[Never].
However, Mypy infers T = Never regardless of the list being empty or not and the issue persists if we replace list with any generic container type of T. The last example illustrate this and Mypy complaints that [1,2,3] is not of the type list[Never].
I checked with Pyright, and it does (mostly) the expected behavior. It fails,however when trying to infer the type of an empty list, but inference on empty lists is always problematic, so I think it is acceptable.
- Mypy version used: 2.1 (but i tested with many others in Mypy playground)
- Python version used: 3.13
Consider the ambiguous (yet somewhat useful) type:
T | list[T]. It is problematic since given any list, e.g., list[int], it can bind T toint, which is the expected behavior, or tolist[int], which is surprising, but yet consistent with the type definition. Mypy does neither.The first revealed type is correct.
The second one (for
f([])), is strange. It probably should inferAny | list[Any](which simplifies toAny). Mypy assigns list[Never] which perhaps is acceptable if we remember thatlist[Never] | Neveralso simplifies tolist[Never].However, Mypy infers T = Never regardless of the list being empty or not and the issue persists if we replace list with any generic container type of T. The last example illustrate this and Mypy complaints that [1,2,3] is not of the type list[Never].
I checked with Pyright, and it does (mostly) the expected behavior. It fails,however when trying to infer the type of an empty list, but inference on empty lists is always problematic, so I think it is acceptable.