Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 25 additions & 11 deletions docs/reference/generics.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ code. These types are interesting in that they are parametrised by other types!
A ``list[str]`` isn't just a list, it's a list of strings. Types with type
parameters like this are called *generic types*.

.. note::

Python 3.12 introduced :pep:`695`, which allows defining generics using
type parameter syntax (e.g., ``class Foo[T]:`` and ``def func[T](x: T) -> T:``).
The older ``TypeVar`` and ``Generic``-based syntax remains supported
for compatibility with earlier Python versions.

You can define your own generic classes that take type parameters, similar to
built-in types such as ``list[X]``. Note that such user-defined generics are a
moderately advanced feature and you can get far without ever using them.
Expand All @@ -19,11 +26,7 @@ Here is a very simple generic class that represents a stack:

.. code-block:: python

from typing import TypeVar, Generic

T = TypeVar('T')

class Stack(Generic[T]):
class Stack[T]:
def __init__(self) -> None:
# Create an empty list with items of type T
self.items: list[T] = []
Expand All @@ -37,6 +40,17 @@ Here is a very simple generic class that represents a stack:
def empty(self) -> bool:
return not self.items

For compatibility with older Python versions, the same class may be written as:

.. code-block:: python

from typing import TypeVar, Generic

T = TypeVar('T')

class Stack(Generic[T]):
...

The ``Stack`` class can be used to represent a stack of any type:
``Stack[int]``, ``Stack[tuple[int, str]]``, etc.

Expand All @@ -56,7 +70,7 @@ construction of the instance will be type checked correspondingly.

.. code-block:: python

class Box(Generic[T]):
class Box[T]:
def __init__(self, content: T) -> None:
self.content = content

Expand Down Expand Up @@ -96,12 +110,12 @@ can be used as a base class for another class (generic or non-generic). For exam
data: StrDict[int, int] # error: "StrDict" expects no type arguments, but 2 given
data2: StrDict # OK

# This is a user-defined generic class
class Receiver(Generic[T]):
def accept(self, value: T) -> None: ...
# This is a user-defined generic class
class Receiver(Generic[T]):
def accept(self, value: T) -> None: ...

# This is a generic subclass of Receiver
class AdvancedReceiver(Receiver[T]): ...
# This is a generic subclass of Receiver
class AdvancedReceiver(Receiver[T]): ...

.. note::

Expand Down