TypeVar with union bound changes return type of type(t)()
#18478
Description
Bug Report
I'd expect that for any t: T
, you should be able to call type(t)()
and it should either returnT
or raise an exception. This seems to be true in most cases, but when using a TypeVar with a union bound it seems to be falling back to the union value.
To Reproduce
I've put together three functions that I believe to be practically equivalent:
def generic[T](t: T) -> T:
type_t: type[T] = type(t)
return type(t)()
def generic_constraint[T: (int, str)](t: T) -> T:
type_t: type[T] = type(t)
return type(t)()
def generic_bound[T: int | str](t: T) -> T:
type_t: type[T] = type(t)
return type(t)()
Expected Behavior
I'd expect for all three functions to type-check successfully, like it does in the Pyright playground.
Actual Behavior
While Mypy was happy with generic
and generic_constraint
, it errors on generic_bound
:
main.py:11: error: Incompatible return value type (got "int | str", expected "T") [return-value]
I originally bumped into this while working on a function set up slightly differently, which I think has the same problem:
def generic_bount[T: int | str](t: type[T]) -> T:
return t()
I don't think this is the same problem solved by PEP 747, but it's possible that I've misunderstood.
Your Environment
- Mypy version used: 1.14.1
- Mypy command-line flags: N/A
- Mypy configuration options from
mypy.ini
(and other config files): N/A - Python version used: 3.12
Potentially related