'How does python typing (or mypy) handle TypeVars that are bound to a Union in isinstance checks?

I have the following code:

from typing import TypeVar, Union

T = TypeVar("T", bound=Union[str, int])

def a(x: T) -> T:
    if isinstance(x, str):
        return x
    return x

but mypy (with --strict) raises error: Incompatible return value type (got "str", expected "T").

In my opinion this should be valid, since

  1. str -> str
  2. subclass(str) -> subclass(str)
  3. int -> int
  4. subclass(int) -> subclass(int)
  5. str | int -> str | int

So either mypy has a bug, or (more likely) my knowledge of TypeVars is not good enough.

Worth noticing:

  • I want to have the str -> str, int -> int mapping, so simply using Union[str, int] won't work.
  • This function is called sometimes with variables of type Union[str, int], so using TypeVar["T", str, int] won't work either.


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source