Skip to main content

Python-Generics

Unittests status badge Coverage status badge Linting status badge Black status badge

Ever wondered how to do something like this?

from typing import Generic, TypeVar

T = TypeVar("T")

class MySuperClass(Generic[T]):
    def get_my_type(self) -> type[T]:
        return T  # This does not work

class MySubType(MySuperClass[str]):
    def use_my_type(self):
        my_type = self.get_my_type()  # This should return str
        assert isinstance("Hello", my_type)

This package provides functionalities to resolve this issue i.e. to determine the values of generic type variables in Python. As of now, it only supports two functions: get_type_vars and get_filled_type. These functions work also with pydantic generic models (only tested with pydantic > v2.3.0). They also work with PEP 695 generic types.

The package has no dependencies itself.

Installation

The package is available on PyPI:

pip install python-generics

How to use (in your own application)

The get_type_vars function returns a tuple of all type variables for a given generic type. The TypeVars are determined by Generic if the type is a subclass of Generic. Otherwise, they are determined by the indexed supertypes (the order of the returned tuple is the lexicographical in the list of the supertypes).

from typing import Generic, TypeVar
from generics import get_type_vars

T = TypeVar("T")
U = TypeVar("U")
V = TypeVar("V")

class A(Generic[T, U]):
    pass

class B(A[T, U], Generic[U, T]):
    pass

class C(B[T, U], A[T, V]):
    pass

assert get_type_vars(A) == (T, U)
assert get_type_vars(B) == (U, T)
assert get_type_vars(C) == (T, U, V)

The get_filled_type function determines for a single TypeVar the value if defined somewhere. To determine the value, you have to pass a type or an instance of a type that is a subclass of a generic type of which you want to determine the value of the TypeVar.

Instead of supplying the TypeVar itself, you can define the integer position of the TypeVar in the tuple of TypeVars of the generic type.

from typing import Generic, TypeVar
from generics import get_filled_type

T = TypeVar("T")
U = TypeVar("U")
V = TypeVar("V")

class A(Generic[T, U]):
    pass

class B(A[str, U]):
    pass

assert get_filled_type(A[str, U], A, T) == str
assert get_filled_type(B[int](), A, 0) == str

The get_filled_type function is especially useful if you have generic super types in which you want to determine the value of a TypeVar inside methods.

from typing import Generic, TypeVar, Any
from generics import get_filled_type

T = TypeVar("T")

class MySuperType(Generic[T]):
    def get_type(self) -> Any:
        return get_filled_type(self, MySuperType, 0)

class MySubType(MySuperType[str]):
    pass

assert MySubType().get_type() == str

Limitations

Due to how generics are implemented in Python, it is not possible to determine the value of a TypeVar inside the constructor. This would require some stack trace analysis and is currently not implemented in this project. However, for most scenarios there is an easy workaround for this.

What does not work:

from generics import get_filled_type

class MySuperType[T]:
    def __init__(self):
        self.my_type = get_filled_type(self, MySuperType, 0)
        # This will raise a TypeError with something like
        # "The value of the TypeVar is undefined"
_ = MySuperType[str]()

But instead, you can do this:

from generics import get_filled_type

class MySuperType[T]:
    def __init__(self):
        self._my_type: type[T] | None = None

    @property
    def my_type(self) -> type[T]:
        if self._my_type is None:
            self._my_type = get_filled_type(self, MySuperType, 0)
        return self._my_type

instance = MySuperType[str]()
assert instance.my_type is str

Note that the property will only resolve after the constructor has been called i.e. the object has been created. You cannot use it inside the constructor.

How to use this Repository on Your Machine (as a developer)

Follow the instructions in our Python template repository.

Contribute

You are very welcome to contribute to this template repository by opening a pull request against the main branch.

Metadata

Release files for python-generics 0.2.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for python-generics 0.2.5
File Size Uploaded
python_generics-0.2.5.tar.gz 72.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for python-generics 0.2.5
File Interpreter ABI Platform
python_generics-0.2.5-py3-none-any.whl Python 3 none any Details

Total release size: 79.7 kB

Release files / python_generics-0.2.5.tar.gz

Download URL python_generics-0.2.5.tar.gz
Size 72.5 kB
Tags Source
SHA-256 checksum
How to use checksums
27c9fdb4a437654051ab1d2dfd3d46431b1bba28d5685e5ccbbd5737e7109bc9
BLAKE2b-256 checksum
How to use checksums
aea37609d7121bb3d4b5e513e74469413bb9b78979600ee5f1d3fea3695806ce
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 27, 2026.

Transparency log

Release files / python_generics-0.2.5-py3-none-any.whl

Download URL python_generics-0.2.5-py3-none-any.whl
Size 7.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
dbf34e31bc18afb369d92632d267b65d9f0bf85403f57c2dd68def673db21cdb
BLAKE2b-256 checksum
How to use checksums
f1a8418c7272ce930641af86af91462009d3744e9a604cd307b7728cd9dc98fb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 27, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.5 This release

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.0

2 release files

0.0.4

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page