diff --git a/docs/reference/generics.rst b/docs/reference/generics.rst index c39d2bc11..a50d6eda2 100644 --- a/docs/reference/generics.rst +++ b/docs/reference/generics.rst @@ -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. @@ -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] = [] @@ -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. @@ -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 @@ -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::