Python's type hinting system is there for a static type checker to validate your code and T is just a placeholder for the type system, like a slot in a template language. It can't be used as an indirect reference to a specific type.

You need to subclass your generic type if you want to produce a concrete implementation. And because Gender is a class and not an instance, you'd need to tell the type system how you plan to use a Type[T] somewhere, too.

Because you also want to be able to use T as an Enum() (calling it with EnumSubclass(int(character))), I'd also bind the typevar; that way the type checker will understand that all concrete forms of Type[T] are callable and will produce individual T instances, but also that those T instances will always have a .value attribute:

from typing import ClassVar, List, Union, Type, TypeVar, Generic
from enum import IntEnum

T = TypeVar('T', bound=IntEnum)  # only IntEnum subclasses

class EnumAggregate(Generic[T]):
    # Concrete implementations can reference `enum` *on the class itself*,
    # which will be an IntEnum subclass.
    enum: ClassVar[Type[T]]

    def __init__(self, value: Union[int, str, List[T]]) -> None:
        if not value:
            raise ValueError('Parameter "value" cannot be empty!')

        if isinstance(value, list):
            self._value = ''.join([str(x.value) for x in value])
        else:
            self._value = str(value)

    def __contains__(self, item: T) -> bool:
        return item in self.to_list

    @property
    def to_list(self) -> List[T]:
        # the concrete implementation needs to use self.enum here
        return [self.enum(int(character)) for character in self._value]

    @property
    def value(self) -> str:
        return self._value

    @classmethod
    def all(cls) -> str:
        # the concrete implementation needs to reference cls.enum here
        return ''.join([str(x.value) for x in cls.enum])

With the above generic class you can now create a concrete implementation, using your Gender IntEnum fitted into the T slot and as a class attribute:

class Gender(IntEnum):
    MALE = 1
    FEMALE = 2
    DIVERS = 3


class Genders(EnumAggregate[Gender]):
    enum = Gender

To be able to access the IntEnum subclass as a class attribute, we needed to use typing.ClassVar[]; otherwise the type checker has to assume the attribute is only available on instances.

And because the Gender IntEnum subclass is itself a class, we need to tell the type checker about that too, hence the use of typing.Type[].

Now the Gender concrete subclass works; the use of EnumAggregate[Gender] as a base class tells the type checker to substitute T for Gender everywhere, and because the implementation uses enum = Gender, the type checker sees that this is indeed correctly satisfied and the code passes all checks:

$ bin/mypy so65064844.py
Success: no issues found in 1 source file

and you can call Genders.all() to produce a string:

>>> Genders.all()
'123'

Note that I'd not store the enum values as strings, but rather as integers. There is little value in converting it back and forth here, and you are limiting yourself to enums with values between 0 and 9 (single digits).

Answer from Martijn Pieters on Stack Overflow
🌐
Mypy
mypy.readthedocs.io › en › stable › generics.html
Generics - mypy 1.20.0 documentation
If you really need this, you can define a generic class with a __call__ method. A type variable can also be restricted to having values that are subtypes of a specific type. This type is called the upper bound of the type variable, and it is specified using T: <bound> when using the Python ...
🌐
Python
typing.python.org › en › latest › reference › generics.html
Generics — typing documentation
... To use this feature on Python versions earlier than 3.11, you will need to import Self from typing_extensions (version 4.0 or newer). There are three main kinds of generic types with respect to subtype relations between them: invariant, covariant, and contravariant.
Discussions

python - Classmethods on generic classes - Stack Overflow
I try to call a classmethod on a generic class: from typing import List, Union, TypeVar, Generic from enum import IntEnum class Gender(IntEnum): MALE = 1 FEMALE = 2 DIVERS = 3 T = Type... More on stackoverflow.com
🌐 stackoverflow.com
When to make classes & functions generic in python?
I don't understand the, idunno, premise of the question, I guess? Firstly, narrowing the type of a function parameter (or more generally, anything that's contravariant) is not allowed. This is a violation of Liskov: class Parent: def func(self, x: int): ... class Child(Parent): def func(self, x: bool): ... And secondly, your 2nd example doesn't typecheck. The way you're using the TypeVar makes no sense - it's neither bound to a generic class, nor does it appear in the function signature more than once. It's really unclear to me what problem you're trying to solve. More on reddit.com
🌐 r/learnpython
7
1
August 29, 2023
how to define python generic classes - Stack Overflow
Note that if you have T used in __init__ of non-generic class, it is not very cool, although currently not disallowed. Now, if you use T in some methods of generic class, it refers to that replaced value and results in typecheck errors, if passed types are not compatible with expected. More on stackoverflow.com
🌐 stackoverflow.com
Inside a generic class - how to get the class of type variable? - Python Help - Discussions on Python.org
I have a generic class inside which I need to use the type variable to check parameter types. Inside the validate() method I assign it to the ItemClass variable: """Test generic class and usage of the generic type inside.""" from __future__ import annotations from typing import List, TypeVar, ... More on discuss.python.org
🌐 discuss.python.org
0
November 6, 2022
🌐
Medium
medium.com › @steveYeah › using-generics-in-python-99010e5056eb
Using Generics in Python. If you are using type hints in Python… | by SteveYeah | Medium
July 21, 2021 - Here we have created the generic class Registry. This is done by extending the Generic base class, and by defining the generic types we want to be valid within this class. In this case we define T(line 5) which is then used within methods of the Registry class.
Top answer
1 of 2
6

Python's type hinting system is there for a static type checker to validate your code and T is just a placeholder for the type system, like a slot in a template language. It can't be used as an indirect reference to a specific type.

You need to subclass your generic type if you want to produce a concrete implementation. And because Gender is a class and not an instance, you'd need to tell the type system how you plan to use a Type[T] somewhere, too.

Because you also want to be able to use T as an Enum() (calling it with EnumSubclass(int(character))), I'd also bind the typevar; that way the type checker will understand that all concrete forms of Type[T] are callable and will produce individual T instances, but also that those T instances will always have a .value attribute:

from typing import ClassVar, List, Union, Type, TypeVar, Generic
from enum import IntEnum

T = TypeVar('T', bound=IntEnum)  # only IntEnum subclasses

class EnumAggregate(Generic[T]):
    # Concrete implementations can reference `enum` *on the class itself*,
    # which will be an IntEnum subclass.
    enum: ClassVar[Type[T]]

    def __init__(self, value: Union[int, str, List[T]]) -> None:
        if not value:
            raise ValueError('Parameter "value" cannot be empty!')

        if isinstance(value, list):
            self._value = ''.join([str(x.value) for x in value])
        else:
            self._value = str(value)

    def __contains__(self, item: T) -> bool:
        return item in self.to_list

    @property
    def to_list(self) -> List[T]:
        # the concrete implementation needs to use self.enum here
        return [self.enum(int(character)) for character in self._value]

    @property
    def value(self) -> str:
        return self._value

    @classmethod
    def all(cls) -> str:
        # the concrete implementation needs to reference cls.enum here
        return ''.join([str(x.value) for x in cls.enum])

With the above generic class you can now create a concrete implementation, using your Gender IntEnum fitted into the T slot and as a class attribute:

class Gender(IntEnum):
    MALE = 1
    FEMALE = 2
    DIVERS = 3


class Genders(EnumAggregate[Gender]):
    enum = Gender

To be able to access the IntEnum subclass as a class attribute, we needed to use typing.ClassVar[]; otherwise the type checker has to assume the attribute is only available on instances.

And because the Gender IntEnum subclass is itself a class, we need to tell the type checker about that too, hence the use of typing.Type[].

Now the Gender concrete subclass works; the use of EnumAggregate[Gender] as a base class tells the type checker to substitute T for Gender everywhere, and because the implementation uses enum = Gender, the type checker sees that this is indeed correctly satisfied and the code passes all checks:

$ bin/mypy so65064844.py
Success: no issues found in 1 source file

and you can call Genders.all() to produce a string:

>>> Genders.all()
'123'

Note that I'd not store the enum values as strings, but rather as integers. There is little value in converting it back and forth here, and you are limiting yourself to enums with values between 0 and 9 (single digits).

2 of 2
3

The other answer does not work anymore, at least in Python 3.10. The type annotation ClassVar[Type[T]] results in a mypy error: ClassVar cannot contain type variables is thrown. This is because ClassVar should only be used in a Protocol and structural subtyping, which is not the best answer for the problem at hand.

The following modification of the other answer works:

class EnumAggregate(Generic[T]):
    enum: type[T]

[...]

class Genders(EnumAggregate[Gender]):
    enum = Gender

Abstract class variables

I would also recommend making enum abstract in some way, so instantiating EnumAggregate[Gender] instead of Genders will raise an error at the time of instantiation, not only at calls of to_list() or all().

This can be done in two ways: Either check the implementation in __init__:

class EnumAggregate(Generic[T]):
    enum: type[T]
    def __init__ 
    [...]
    if not hasattr(type(self), 'enum'):
        raise NotImplementedError("Implementations must define the class variable 'enum'")

Or use an abstract class property, see this discussion. This makes mypy happy in several situations, but not Pylance (see here):

class EnumAggregate(Generic[T]):
    @property
    @classmethod
    @abstractmethod
    def enum(cls) -> type[T]: ...

[...]

class Genders(EnumAggregate[Gender]):
    enum = Gender

However, there are unresolved problems with mypy and decorators, so right now there are spurious errors which might disappear in the future. For reference:

mypy issue 1

mypy issue 2

Discussion whether to deprecate chaining classmethod decorators

🌐
Reddit
reddit.com › r/learnpython › when to make classes & functions generic in python?
r/learnpython on Reddit: When to make classes & functions generic in python?
August 29, 2023 -

I have been generally making my methods generic mostly for the following reasons:

  • I am subclassing an abstract class and want to override a method and narrow the type hinting in the arguments, which would otherwise violate the Liskov substitution principle

  • I am not subclassing/overriding, but would like return values, attributes, etc. of a class to be more narrow than the type hints it is currently bound to, since I may be using that class in many different places with different types.

In particular for the second case, I have realized that there are actually two approaches to tackle this:

  1. make the class generic and provide the type arguments for the instance type hints.

  2. do not make the class generic, but subclass simply for the purpose of updating the type hints

With projects I am working on, with "context" and "manager" classes, there can be many different attributes and methods with many different types (5+), hence, making the class generic on all of them is too verbose. If I do make a class generic, if any other attributes (containing instances of other classes) return those same generic types, I have to propagate the generic type down the entire chain when I am using composition instead of inheritance. This is something I would like to avoid. If I choose option 2, there would be an explosion of subclasses just to override the type hints.

When should I choose 1 or 2? Is there a better way to do this?

Option 1 example:

from typing import Self, TypeVar, Generic

BazT = TypeVar('BazT')

class Bar(Generic[BazT]):
    def method1(self: Self) -> BazT:
        ...

class Foo(Generic[BazT]):
    bar: Bar[BazT]
    
    def method1(self: Self, baz: BazT) -> None:
        ...
    
    def method2(self: Self) -> Bar[BazT]:
        ...

Option 2 example:

from typing import Self, Any, TypeVar

Baz = Any

class Bar:
    def method1(self: Self) -> Baz:
        ...

class Foo:
    bar: Bar
    
    def method1(self: Self, baz: Baz) -> None:
        ...
    
    def method2(self: Self) -> Bar:
        ...
        
BazNarrowed = TypeVar('BazNarrowed', bound=Baz) # (doesn't matter what this is just some more narrow type)

class BarSubclass(Bar):
    def method1(self: Self) -> BazNarrowed:
        ...

class FooSubclass(Foo):
    bar: BarSubclass
    
    def method1(self: Self, baz: BazNarrowed) -> None:
        ...
    
    def method2(self: Self) -> BarSubclass:
        ...
Top answer
1 of 3
2
I don't understand the, idunno, premise of the question, I guess? Firstly, narrowing the type of a function parameter (or more generally, anything that's contravariant) is not allowed. This is a violation of Liskov: class Parent: def func(self, x: int): ... class Child(Parent): def func(self, x: bool): ... And secondly, your 2nd example doesn't typecheck. The way you're using the TypeVar makes no sense - it's neither bound to a generic class, nor does it appear in the function signature more than once. It's really unclear to me what problem you're trying to solve.
2 of 3
1
Please roast me if I'm wrong on this, but this appears to be the exact situation for which TypeGuard in typing module was developed, as of Python 3.10. PEP-647 ~~~TypeGuard = typing.TypeGuard~~~ Special typing form used to annotate the return type of a user-defined type guard function. ``TypeGuard`` only accepts a single type argument. At runtime, functions marked this way should return a boolean. ``TypeGuard`` aims to benefit *type narrowing* -- a technique used by static type checkers to determine a more precise type of an expression within a program's code flow. Usually type narrowing is done by analyzing conditional code flow and applying the narrowing to a block of code. The conditional expression here is sometimes referred to as a "type guard". Sometimes it would be convenient to use a user-defined boolean function as a type guard. Such a function should use ``TypeGuard[...]`` as its return type to alert static type checkers to this intention. Using ``-> TypeGuard`` tells the static type checker that for a given function: 1. The return value is a boolean. 2. If the return value is ``True``, the type of its argument is the type inside ``TypeGuard``. For example:: def is_str(val: Union[str, float]): # "isinstance" type guard if isinstance(val, str): # Type of ``val`` is narrowed to ``str`` ... else: # Else, type of ``val`` is narrowed to ``float``. ... Strict type narrowing is not enforced -- ``TypeB`` need not be a narrower form of ``TypeA`` (it can even be a wider form) and this may lead to type-unsafe results. The main reason is to allow for things like narrowing ``List[object]`` to ``List[str]`` even though the latter is not a subtype of the former, since ``List`` is invariant. The responsibility of writing type-safe type guards is left to the user. ``TypeGuard`` also works with type variables. For more information, see PEP 647 (User-Defined Type Guards).
Top answer
1 of 1
5

Type checking vs runtime

After writing this, I finally understood @Alexander point in first comment: whatever you write in annotations, it does not affect runtime, and your code is executed in the same way (sorry, I missed that you're looking just not from type checking perspective). This is core principle of python typing, as opposed to strongly typed languages (which makes it wonderful IMO): you can always say "I don't need types here - save my time and mental health". Type annotations are used to help some third-party tools, like mypy (type checker maintained by python core team) and IDEs. IDEs can suggest you something based on this information, and mypy checks whether your code can work if your types match the reality.

Generic version

T = TypeVar('T')

class Stack(Generic[T]):
    def __init__(self) -> None:
        self.items: list[T] = []

    def push(self, item: T) -> None:
        self.items.append(item)

    def pop(self) -> T:
        return self.items.pop()

    def empty(self) -> bool:
        return not self.items

You can treat type variables like regular variables, but intended for "meta" usage and ignored (well, there are some runtime traces, but they exist primary for introspection purpose) on runtime. They are substituted once for every binding context (more about it - below), and can be defined only once per module scope.

The code above declares normal generic class with one type argument. Now you can say Stack[int] to refer to a stack of integers, which is great. Current definition allows either explicit typing or using implicit Any parametrization:

# Explicit type
int_stack: Stack[int] = Stack()
reveal_type(int_stack)  # N: revealed type is "__main__.Stack[builtins.int]
int_stack.push(1)  # ok
int_stack.push('foo')  # E: Argument 1 to "push" of "Stack" has incompatible type "str"; expected "int"  [arg-type]
reveal_type(int_stack.pop())  # N: revealed type is "builtins.int"
# No type results in mypy error, similar to `x = []`
any_stack = Stack()  # E: need type annotation for any_stack
# But if you ignore it, the type becomes `Stack[Any]`
reveal_type(any_stack)  # N: revealed type is "__main__.Stack[Any]
any_stack.push(1)  # ok
any_stack.push('foo')  # ok too
reveal_type(any_stack.pop())  # N: revealed type is "Any"

To make the intended usage easier, you can allow initialization from iterable (I'm not covering the fact that you should be using collections.deque instead of list and maybe instead of this Stack class, assuming it is just a toy collection):

from collections.abc import Iterable

class Stack(Generic[T]):
    def __init__(self, items: Iterable[T] | None) -> None:
        # Create an empty list with items of type T
        self.items: list[T] = list(items or [])
    ...

deduced_int_stack = Stack([1])
reveal_type(deduced_int_stack)  # N: revealed type is "__main__.Stack[builtins.int]"

To sum up, generic classes have some type variable bound to the class body. When you create an instance of such class, it can be parametrized with some type - it may be another type variable or some fixed type, like int or tuple[str, Callable[[], MyClass[bool]]]. Then all occurrences of T in its body (except for nested classes, which are perhaps out of "quick glance" explanation context) are replaced with this type (or Any, if it is not given and cannot be deduced). This type can be deduced iff at least one of __init__ or __new__ arguments has type referring to T (just T or, say, list[T]), and otherwise you have to specify it. Note that if you have T used in __init__ of non-generic class, it is not very cool, although currently not disallowed.

Now, if you use T in some methods of generic class, it refers to that replaced value and results in typecheck errors, if passed types are not compatible with expected.

You can play with this example here.

Working outside of generic context

However, not all usages of type variables are related to generic classes. Fortunately, you cannot declare generic function with possibility to declare generic arg on calling side (like function<T> fun(x: number): T and fun<string>(0)), but there is enough more stuff. Let's begin with simpler examples - pure functions:

T = TypeVar('T')

def func1() -> T:
    return 1
def func2(x: T) -> int:
    return 1
def func3(x: T) -> T:
    return x
def func4(x: T, y: T) -> int:
    return 1

First function is declared to return some value of unbound type T. It obviously makes no sense, and recent mypy versions even learned to mark it as error. Your function return depends only on arguments and external state - and type variable must be present there, right? You cannot also declare global variable of type T in module scope, because T is still unbound - and thus neither func1 args nor module-scoped variables can depend on T.

Second function is more interesting. It does not cause mypy error, although still makes not very much sense: we can bind some type to T, but what is the difference between this and func2_1(x: Any) -> int: ...? We can speculate that now T can be used as annotation in function body, which can help in some corner case with type variable having upper bound parameterizing an invariant class used covariantly (imagine needing a list[Parent] with .count() method and __getitem__, but still allowing list[Child] to be passed in and ignoring both Sequence existence and custom protocol option). Similar example is even explicitly referenced in PEP as valid.

The third and fourth functions are typical examples of type variables in functions. The third declares function returning the same type as it's argument.

The fourth function takes two arguments of the same type (arbitrary one). It is more useful if you have T = TypeVar('T', bound=Something) or T = TypeVar('T', str, bytes): you can concatenate two arguments of type T, but cannot - of type str | bytes, like in the below example:

T = TypeVar('T', str, bytes)

def total_length(x: T, y: T) -> int:
    return len(x + y)

The most important fact about all examples above in this section: T doesnot have to be the same for different functions. You can call func3(1), then func3(['bar']) and then func4('foo', 'bar'). T is int, list[str] and str in these calls - no need to match.

With this in mind your second solution is clear:

T = TypeVar('T')

class Stack:
    def __init__(self) -> None:
        # Create an empty list with items of type T
        self.items: list[T] = []  # E: Type variable "__main__.T" is unbound  [valid-type]

    def push(self, item: T) -> None:
        self.items.append(item)

    def pop(self) -> T:  # E: A function returning TypeVar should receive at least one argument containing the same TypeVar  [type-var]
        return self.items.pop()

Here is mypy issue, discussing similar case.

__init__ says that we set attribute x to value of type T, but this T is lost later (T is scoped only within __init__) - so mypy rejects the assignment.

push is ill-formed and T has no meaning here, but it does not result in invalid typing situation, so is not rejected (type of argument is erased to Any, so you still can call push with some argument).

pop is invalid, because typechecker needs to know what my_stack.pop() will return. It could say "I give up - just have your Any", and will be perfectly valid (PEP does not enforce this). but mypy is more smart and denies invalid-by-design usage.

Edge case: you can return SomeGeneric[T] with unbound T, for example, in factory functions:

def make_list() -> list[T]: ...

mylist: list[str] = make_list()

because otherwise type argument couldn't have been specified on calling site

For better understanding of type variables and generics in python, I suggest you to read PEP483 and PEP484 - usually PEPs are more like a boring standard, but these are really good as a starting point.

There are many edge cases omitted there, which still cause hot discussions in mypy team (and probably other typecheckers too) - say, type variables in staticmethods of generic classes, or binding in classmethods used as constructors - mind that they can be used on instances too. However, basically you can:

  • have a TypeVar bound to class (Generic or Protocol, or some Generic subclass - if you subclass Iterable[T], your class is already generic in T) - then all methods use the same T and can contain it in one or both sides
  • or have a method-scoped/function-scoped type variable - then it's useful if repeated in the signature more than once (not necessary "clean" - it may be parametrizing another generic)
  • or use type variables in generic aliases (like LongTuple = tuple[T, T, T, T] - then you can do x: LongTuple[int] = (1, 2, 3, 4)
  • or do something more exotic with type variables, which is probably out of scope
🌐
GeeksforGeeks
geeksforgeeks.org › python › python-generics
Python Generics - GeeksforGeeks
October 29, 2025 - Instances container_int and container_str are created, holding an integer and a string respectively, and their content is retrieved using the retrieve_content method. ... from typing import TypeVar, Generic T = TypeVar('T') class Container(Generic[T]): def __init__(self, content: T): self.content = content def retrieve_content(self) -> T: return self.content container_int = Container(10) container_str = Container('GeeksforGeeks') print(container_int.retrieve_content()) print(container_str.retrieve_content()) ... Duck typing and Python generics are two different concepts, but they can be related in how they allow for flexible and dynamic programming in Python.
Find elsewhere
🌐
Python.org
discuss.python.org › python help
Inside a generic class - how to get the class of type variable? - Python Help - Discussions on Python.org
November 6, 2022 - I have a generic class inside which I need to use the type variable to check parameter types. Inside the validate() method I assign it to the ItemClass variable: """Test generic class and usage of the generic type inside.""" from __future__ import annotations from typing import List, TypeVar, Sequence, Iterator, Callable T = TypeVar("T") class ListFromItem(List[T]): """Generic class for Pydantic lists which can be created from a single item.""" @classmethod def __get_validators_...
🌐
GitHub
github.com › python › mypy › issues › 1337
`@classmethod` of `Generic` class · Issue #1337 · python/mypy
April 6, 2016 - from typing import TypeVar, Generic T = TypeVar('T') class A(Generic[T]): @classmethod def func(cls) -> T: pass class B(A['B']): pass def except_b(b: B): pass except_b(B.func()) is a valid python3 code, but mypy warns that file:20: error...
Author   tharvik
🌐
Gui Commits
guicommits.com › python-generic-type-function-class
Python Generic function and class types - Gui Commits
March 1, 2024 - Typescript relies consistently on <> e.g. <int> and <str>. I do believe Python should follow the same logic for []. To make this happen we must define a class and override its __new__ magic method to behave like a function: import typing as t T = t.TypeVar("T") # 👇 Keep class name lowercase so it feels like a function, name it as you want your '''function''' to be named: class get_something(t.Generic[T]): # 👇 This is the secret def __new__( cls, v: str, # Add here as many args you think your function should take ): generated_instance = super().__new__(cls) return generated_instance.execute(v) # 👇 Pretend this is your actual function implementation, name it anything you wish def execute(self, v: str) -> T: # 👈 Define T as the return type ...
🌐
Tutorialspoint
tutorialspoint.com › python › python_generics.htm
Python - Generics
In Python, generics is a mechanism with which you to define functions, classes, or methods that can operate on multiple types while maintaining type safety. With the implementation of Generics enable it is possible to write reusable code that can be
🌐
CodeSignal
codesignal.com › learn › courses › advanced-functional-programming-techniques-2 › lessons › python-generics
Python Generics | CodeSignal Learn
Python's typing module provides tools for generics, like TypeVar, which lets us define a variable type. Let's explore how to use it in code. ... We define a generic class using TypeVar from the typing module. This acts as a placeholder for any data type.
🌐
Stack Overflow
stackoverflow.com › questions › 76618112 › calling-class-method-on-generic-type-for-class-in-python
Calling class method on generic type for class in Python - Stack Overflow
Python can only know the correct class for T once the class has been instantiated. When it is instantiated you can assign a field to the correct class and use that to call the class_method: from typing import Generic, Type, TypeVar class Foo: @classmethod def class_method(cls): print('class method') class Bar(Foo): pass T = TypeVar('T', bound=Foo) class Base(Generic[T]): def __init__(self, cls: Type[T]): self.cls = cls def do_thing(self): print(f'{self.cls=}') # This works result = self.cls.class_method() class Derived(Base[Bar]): def do_other_thing(self): result = self.do_thing() with_isntance = Derived(Bar()) with_isntance.do_other_thing() with_class = Derived(Bar) with_class.do_other_thing()
🌐
ArjanCodes
arjancodes.com › blog › python-generics-tutorial
How to Use Python Generics Effectively | ArjanCodes
May 30, 2024 - Much of the code we write is reusable, ... in Python come into play. Generics allow you to write functions and classes that can operate on any data type while maintaining clear type expectations....
🌐
GitHub
github.com › python › typing › issues › 629
Runtime Access to Generic Types on Class Method · Issue #629 · python/typing
May 4, 2019 - import typing import typing_inspect T = typing.TypeVar("T") class Inst(typing.Generic[T]): @classmethod def hi(cls): return cls ... topic: featureDiscussions about new features for Python's type annotationsDiscussions about new features for Python's type annotations
Author   saulshanabrook
🌐
Real Python
realpython.com › ref › glossary › generic-type
generic type | Python Glossary – Real Python
The type parameter T in the class header makes Stack a generic class, and you use list[T] to store items of that type. The Stack supports pushing items of type T onto the stack and popping them off, enforcing type safety. For example, Stack[int]() creates a stack for integers, while Stack[str]() creates a stack for strings, and both enforce consistent typing for their operations. ... In this guide, you'll look at Python type checking.
🌐
pytz
pythonhosted.org › generic
generic v0.2 documentation
class generic.multidispatch.MethodDispatcher(argspec, params_arity)¶
🌐
mypy
mypy.readthedocs.io › en › latest › generics.html
Generics - mypy 2.0.0+dev.a399e1caf5a531e93debf1b8071033ed4f2946f8 documentation
If you really need this, you can define a generic class with a __call__ method. A type variable can also be restricted to having values that are subtypes of a specific type. This type is called the upper bound of the type variable, and it is specified using T: <bound> when using the Python ...