Skip to content

TypeVar with union bound changes return type of type(t)() #18478

Open
@christianbundy

Description

@christianbundy

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)()

https://mypy-play.net/?mypy=latest&python=3.12&flags=show-traceback&gist=ede4bf83e226751762cd82d516093170

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugmypy got something wrong

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions