mypy icon indicating copy to clipboard operation
mypy copied to clipboard

Tuple types don't work with higher level typing

Open fjarri opened this issue 1 year ago • 2 comments

mypy 1.8.0, python 3.10.10

So tuple types get matched and checked normally in simple situations like this:

a: tuple[int, int] = (2, "a")
# Incompatible types in assignment ...

But imagine I want to define a function that takes a type and returns a value of that type (e.g. by deserializing something as the given type):

from typing import Tuple, TypeVar, Type, List

_T = TypeVar("_T")

def structure(structure_into: Type[_T], obj: str) -> _T:
    raise NotImplementedError

This works with builtin types, or with generics like List:

reveal_type(structure(int, "a"))
# Revealed type is "builtins.int"
reveal_type(structure(List[int], "a"))
# Revealed type is "builtins.list[builtins.int]"

... but not with tuples:

reveal_type(structure(Tuple[int, int], "a"))
# note: Revealed type is "Never"
# error: Argument 1 to "structure" has incompatible type "object"; expected "type[Never]"  [arg-type]

Trying to reveal the type of Tuple itself leads to strange results too (compared to List[...]):

reveal_type(Tuple[int, int])
# Revealed type is "builtins.object"
reveal_type(tuple[int, int])
# Revealed type is "def [_T_co] (typing.Iterable[_T_co`1] =) -> builtins.tuple[_T_co`1, ...]"

So the question is, why does Tuple get a special treatment, and is there a way to make it behave like other generics?

fjarri avatar Feb 21 '24 21:02 fjarri

Same issue with UnionType types (T1 | T2 | ...).

fjarri avatar Mar 15 '24 22:03 fjarri

am having a go at this in https://github.com/urnest/mypy/tree/issue-16935

urnest avatar Apr 25 '24 06:04 urnest