Search code examples
pythongenericspython-typing

Getting the generic arguments of a subclass


I have a generic base class and I want to be able to inspect the provided type for it. My approach was using typing.get_args which works like so:

from typing import Generic, Tuple, TypeVarTuple, get_args

T = TypeVarTuple("T")


class Base(Generic[*T]):
    values: Tuple[*T]


Example = Base[int, str]
print(get_args(Example)) # (<class 'int'>, <class 'str'>)

But when I'm inheriting the class, I'm getting an empty list of parameters like so:

class Example2(Base[int, str]):
    pass


print(get_args(Example2)) # ()

What I actually need is to know what types are expected for the values property. I might have the wrong approach but I've also tried to use typing.get_type_hints which seems to just return Tuple[*T] as the type.

So how can I get the typed parameters?

Edit: I need to know the types of the class, not the object.


Solution

  • Use get_args with __orig_bases__:

    print(get_args(Example2.__orig_bases__[0]))  # prints "(<class 'int'>, <class 'str'>)"
    

    For convenience, you can store the generic type parameters in the __init_subclass__ hook:

    from typing import Generic, TypeVarTuple, get_args
    
    T = TypeVarTuple("T")
    
    
    class Base(Generic[*T]):
        values: tuple[*T]
        type_T: tuple[type, ...]
    
        def __init_subclass__(cls) -> None:
            cls.type_T = get_args(cls.__orig_bases__[0])  # type: ignore
    
    
    class Example2(Base[int, str]):
        pass
    
    
    print(Example2.type_T)  # prints "(<class 'int'>, <class 'str'>)"