Open olahesoo opened 5 months ago
I believe this is because T
in the first is str | None
, which mypy can probably capture as a single type, but for the second it's str | int
which mypy is coercing to object
since that's the only type that captures both of them.
Does it work with:
def gen_fun(fun: Callable[[], T]) -> T:
return fun()
It does work, furthermore adding float
to the union makes the second one no longer work.
import typing
T = typing.TypeVar("T")
def gen_fun_one(fun: typing.Callable[[], T | int]) -> T | int:
return fun()
def gen_fun_two(fun: typing.Callable[[], T | None]) -> T | None:
return fun()
def gen_fun_three(fun: typing.Callable[[], T]) -> T:
return fun()
def foo() -> int | str | None:
pass
def bar() -> int | str | float | None:
pass
typing.reveal_type(gen_fun_one(foo)) # Union[builtins.str, None, builtins.int]
typing.reveal_type(gen_fun_one(bar)) # builtins.object
typing.reveal_type(gen_fun_two(foo)) # builtins.object
typing.reveal_type(gen_fun_two(bar)) # builtins.object
typing.reveal_type(gen_fun_three(foo)) # Union[builtins.int, builtins.str, None]
typing.reveal_type(gen_fun_three(bar)) # Union[builtins.int, builtins.str, builtins.float, None]
Gist URL: https://gist.github.com/mypy-play/5d4c79853b831518d2f870b3d9d9ca93 Playground URL: https://mypy-play.net/?mypy=latest&python=3.12&gist=5d4c79853b831518d2f870b3d9d9ca93
It looks to me like a join-v-union issue
Bug Report
Generic function with signature
(fun: Callable[[], T | None]) -> T | None
has its type incorrectly widened tobuiltins.object
whenT
is a union typeTo Reproduce
Gist URL: https://gist.github.com/mypy-play/f2401bd493520f4c72cad4a416195e19 Playground URL: https://mypy-play.net/?mypy=latest&python=3.12&gist=f2401bd493520f4c72cad4a416195e19
Expected Behavior
Both
gen_fun_one(foo)
andgen_fun_two(foo)
are of typestr | int | None
Actual Behavior
Function
gen_fun_two(foo)
is of typebuiltins.object
Your Environment