With mypy, are there any ways to get the type of `T` in a generic function?

With mypy, reveal_type() can get the type of Tin a generic class as shown below:

class MyCls[T = int]:
# class MyCls(Generic[T]):

    def __init__(self, x: T | None = None) -> None: ...

reveal_type(MyCls()) # builtins.int

reveal_type(MyCls[int]())   # builtins.int
reveal_type(MyCls[bool]())  # builtins.bool
reveal_type(MyCls[float]()) # builtins.float
reveal_type(MyCls[str]())   # builtins.str

reveal_type(MyCls(100))     # builtins.int
reveal_type(MyCls(True))    # builtins.bool
reveal_type(MyCls(3.14))    # builtins.float
reveal_type(MyCls('Hello')) # builtins.str

reveal_type(MyCls[int](100))     # builtins.int
reveal_type(MyCls[bool](True))   # builtins.bool
reveal_type(MyCls[float](3.14))  # builtins.float
reveal_type(MyCls[str]('Hello')) # builtins.str

But reveal_type()cannot get the type of Tin a generic function as shown below:

def func[T = int](x: T | None = None) -> None: ...

reveal_type(func())        # None
reveal_type(func(100))     # None
reveal_type(func(True))    # None
reveal_type(func(3.14))    # None
reveal_type(func('Hello')) # None

So are there any ways to get the type of Tin a generic function?

Generic functions are not yet supported in Python’s typing system.

You can read about the ongoing effort to make it happen at PEP 718: subscriptable functions.

T = int means int is the default of T if you don’t specify anything. What I assume you wanted to do is T: int which means T is bound to int, or simplified T must be an int or a subclass of int.

In what kind of situation would this be relevant? In your example, func()==None, func(100)==None, …

If you had a func typed as def func[T](x:T)->T or def func[T](x:T)->Callable[[],T] the mypy would reveal something

1 Like