python / mypy

Optional static typing for Python
https://www.mypy-lang.org/
Other
18.46k stars 2.83k forks source link

Mypy cannot guess callable return type (`Tuple[Type[T], ...] -> T`) #17700

Open jeongukjae opened 2 months ago

jeongukjae commented 2 months ago

Bug Report

It looks like mypy cannot detect some types like following type.

To Reproduce

Playground: https://mypy-play.net/?mypy=latest&python=3.12&gist=f83671bbbc02711ac90962ae786b418b

from typing import Union, Type, Tuple, TypeVar

T = TypeVar("T")

def some_types(type_: Union[Type[T], Tuple[Type[T], ...]]) -> T:
    ...

def int_str_float_fn(a: int | str | float) -> None:
    ...

a = some_types((int, str, float))

int_str_float_fn(a)  # should't be an error

I got an error like

main.py:14: error: Argument 1 to "int_str_float_fn" has incompatible type "object"; expected "int | str | float"  [arg-type]

Expected Behavior

No error here.

Screenshot 2024-08-21 at 18 13 42

I think VSCode has a quite good guess here. Mypy seems guessing a is object.

Actual Behavior

Your Environment

jeongukjae commented 2 months ago

Tried to figure out, but couldn't.

Test case:

[case testVariadicGenericFunction]
# flags: --python-version 3.10
from typing import Union, Type, Tuple, TypeVar

T = TypeVar("T")

def some_types(types_: Tuple[Type[T], ...]) -> T: ...
def int_str_float_fn(a: int | str | float) -> None: ...

a = some_types((int, str, float))  # This should be int | str | float

int_str_float_fn(a)  # should't be an error
[builtins fixtures/tuple.pyi]
jeongukjae commented 2 months ago

Looks like mypy joins int, str, float to object rather than using union in here: https://github.com/python/mypy/blob/fe15ee69b9225f808f8ed735671b73c31ae1bed8/mypy/solve.py#L277-L282