Generics
========

This section explains how you can define your own generic classes that take
one or more type arguments, similar to built-in types such as ``list[T]``.
User-defined generics are a moderately advanced feature and you can get far
without ever using them -- feel free to skip this section and come back later.

.. _generic-classes:

Defining generic classes
************************

The built-in collection classes are generic classes. Generic types
accept one or more type arguments within ``[...]``, which can be
arbitrary types. For example, the type ``dict[int, str]`` has the
type arguments ``int`` and ``str``, and ``list[int]`` has the type
argument ``int``.

Programs can also define new generic classes. Here is a very simple
generic class that represents a stack (using the syntax introduced in
Python 3.12):

.. code-block:: python

   class Stack[T]:
       def __init__(self) -> None:
           # Create an empty list with items of type T
           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

There are two syntax variants for defining generic classes in Python.
Python 3.12 introduced a
`new dedicated syntax <https://docs.python.org/3/whatsnew/3.12.html#pep-695-type-parameter-syntax>`_
for defining generic classes (and also functions and type aliases, which
we will discuss later). The above example used the new syntax. Most examples are
given using both the new and the old (or legacy) syntax variants.
Unless mentioned otherwise, they work the same -- but the new syntax
is more readable and more convenient.

Here is the same example using the old syntax (required for Python 3.11
and earlier, but also supported on newer Python versions):

.. code-block:: python

   from typing import TypeVar, Generic

   T = TypeVar('T')  # Define type variable "T"

   class Stack(Generic[T]):
       def __init__(self) -> None:
           # Create an empty list with items of type T
           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

.. note::

    There are currently no plans to deprecate the legacy syntax.
    You can freely mix code using the new and old syntax variants,
    even within a single file (but *not* within a single class).

The ``Stack`` class can be used to represent a stack of any type:
``Stack[int]``, ``Stack[tuple[int, str]]``, etc. You can think of
``Stack[int]`` as referring to the definition of ``Stack`` above,
but with all instances of ``T`` replaced with ``int``.

Using ``Stack`` is similar to built-in container types:

.. code-block:: python

   # Construct an empty Stack[int] instance
   stack = Stack[int]()
   stack.push(2)
   stack.pop()

   # error: Argument 1 to "push" of "Stack" has incompatible type "str"; expected "int"
   stack.push('x')

   stack2: Stack[str] = Stack()
   stack2.push('x')

Construction of instances of generic types is type checked (Python 3.12 syntax):

.. code-block:: python

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

   Box(1)       # OK, inferred type is Box[int]
   Box[int](1)  # Also OK

   # error: Argument 1 to "Box" has incompatible type "str"; expected "int"
   Box[int]('some string')

Here is the definition of ``Box`` using the legacy syntax (Python 3.11 and earlier):

.. code-block:: python

   from typing import TypeVar, Generic

   T = TypeVar('T')

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

.. note::

    Before moving on, let's clarify some terminology.
    The name ``T`` in ``class Stack[T]`` or ``class Stack(Generic[T])``
    declares a *type parameter* ``T`` (of class ``Stack``).
    ``T`` is also called a *type variable*, especially in a type annotation,
    such as in the signature of ``push`` above.
    When the type ``Stack[...]`` is used in a type annotation, the type
    within square brackets is called a *type argument*.
    This is similar to the distinction between function parameters and arguments.

.. _generic-subclasses:

Defining subclasses of generic classes
**************************************

User-defined generic classes and generic classes defined in :py:mod:`typing`
can be used as a base class for another class (generic or non-generic). For
example (Python 3.12 syntax):

.. code-block:: python

   from typing import Mapping, Iterator

   # This is a generic subclass of Mapping
   class MyMap[KT, VT](Mapping[KT, VT]):
       def __getitem__(self, k: KT) -> VT: ...
       def __iter__(self) -> Iterator[KT]: ...
       def __len__(self) -> int: ...

   items: MyMap[str, int]  # OK

   # This is a non-generic subclass of dict
   class StrDict(dict[str, str]):
       def __str__(self) -> str:
           return f'StrDict({super().__str__()})'

   data: StrDict[int, int]  # Error! StrDict is not generic
   data2: StrDict  # OK

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

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

Here is the above example using the legacy syntax (Python 3.11 and earlier):

.. code-block:: python

   from typing import Generic, TypeVar, Mapping, Iterator

   KT = TypeVar('KT')
   VT = TypeVar('VT')

   # This is a generic subclass of Mapping
   class MyMap(Mapping[KT, VT]):
       def __getitem__(self, k: KT) -> VT: ...
       def __iter__(self) -> Iterator[KT]: ...
       def __len__(self) -> int: ...

   items: MyMap[str, int]  # OK

   # This is a non-generic subclass of dict
   class StrDict(dict[str, str]):
       def __str__(self) -> str:
           return f'StrDict({super().__str__()})'

   data: StrDict[int, int]  # Error! StrDict is not generic
   data2: StrDict  # OK

   # 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]): ...

.. note::

    You have to add an explicit :py:class:`~collections.abc.Mapping` base class
    if you want mypy to consider a user-defined class as a mapping (and
    :py:class:`~collections.abc.Sequence` for sequences, etc.). This is because
    mypy doesn't use *structural subtyping* for these ABCs, unlike simpler protocols
    like :py:class:`~collections.abc.Iterable`, which use
    :ref:`structural subtyping <protocol-types>`.

When using the legacy syntax, :py:class:`Generic <typing.Generic>` can be omitted
from bases if there are
other base classes that include type variables, such as ``Mapping[KT, VT]``
in the above example. If you include ``Generic[...]`` in bases, then
it should list all type variables present in other bases (or more,
if needed). The order of type parameters is defined by the following
rules:

* If ``Generic[...]`` is present, then the order of parameters is
  always determined by their order in ``Generic[...]``.
* If there are no ``Generic[...]`` in bases, then all type parameters
  are collected in the lexicographic order (i.e. by first appearance).

Example:

.. code-block:: python

   from typing import Generic, TypeVar, Any

   T = TypeVar('T')
   S = TypeVar('S')
   U = TypeVar('U')

   class One(Generic[T]): ...
   class Another(Generic[T]): ...

   class First(One[T], Another[S]): ...
   class Second(One[T], Another[S], Generic[S, U, T]): ...

   x: First[int, str]        # Here T is bound to int, S is bound to str
   y: Second[int, str, Any]  # Here T is Any, S is int, and U is str

When using the Python 3.12 syntax, all type parameters must always be
explicitly defined immediately after the class name within ``[...]``, and the
``Generic[...]`` base class is never used.

.. _generic-functions:

Generic functions
*****************

Functions can also be generic, i.e. they can have type parameters (Python 3.12 syntax):

.. code-block:: python

   from collections.abc import Sequence

   # A generic function!
   def first[T](seq: Sequence[T]) -> T:
       return seq[0]

Here is the same example using the legacy syntax (Python 3.11 and earlier):

.. code-block:: python

   from typing import TypeVar, Sequence

   T = TypeVar('T')

   # A generic function!
   def first(seq: Sequence[T]) -> T:
       return seq[0]

As with generic classes, the type parameter ``T`` can be replaced with any
type. That means ``first`` can be passed an argument with any sequence type,
and the return type is derived from the sequence item type. Example:

.. code-block:: python

   reveal_type(first([1, 2, 3]))   # Revealed type is "builtins.int"
   reveal_type(first(('a', 'b')))  # Revealed type is "builtins.str"

When using the legacy syntax, a single definition of a type variable
(such as ``T`` above) can be used in multiple generic functions or
classes. In this example we use the same type variable in two generic
functions to declare type parameters:

.. code-block:: python

   from typing import TypeVar, Sequence

   T = TypeVar('T')      # Define type variable

   def first(seq: Sequence[T]) -> T:
       return seq[0]

   def last(seq: Sequence[T]) -> T:
       return seq[-1]

Since the Python 3.12 syntax is more concise, it doesn't need (or have)
an equivalent way of sharing type parameter definitions.

A variable cannot have a type variable in its type unless the type
variable is bound in a containing generic class or function.

When calling a generic function, you can't explicitly pass the values of
type parameters as type arguments. The values of type parameters are always
inferred by mypy. This is not valid:

.. code-block:: python

    first[int]([1, 2])  # Error: can't use [...] with generic function

If you really need this, you can define a generic class with a ``__call__``
method.

.. _type-variable-upper-bound:

Type variables with upper bounds
********************************

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 3.12 syntax. In the definition of a generic function or a generic
class that uses such a type variable ``T``, the type represented by ``T``
is assumed to be a subtype of its upper bound, so you can use methods
of the upper bound on values of type ``T`` (Python 3.12 syntax):

.. code-block:: python

   from typing import SupportsAbs

   def max_by_abs[T: SupportsAbs[float]](*xs: T) -> T:
       # We can use abs(), because T is a subtype of SupportsAbs[float].
       return max(xs, key=abs)

An upper bound can also be specified with the ``bound=...`` keyword
argument to :py:class:`~typing.TypeVar`.
Here is the example using the legacy syntax (Python 3.11 and earlier):

.. code-block:: python

   from typing import TypeVar, SupportsAbs

   T = TypeVar('T', bound=SupportsAbs[float])

   def max_by_abs(*xs: T) -> T:
       return max(xs, key=abs)

In a call to such a function, the type ``T`` must be replaced by a
type that is a subtype of its upper bound. Continuing the example
above:

.. code-block:: python

   max_by_abs(-3.5, 2)   # Okay, has type 'float'
   max_by_abs(5+6j, 7)   # Okay, has type 'complex'
   max_by_abs('a', 'b')  # Error: 'str' is not a subtype of SupportsAbs[float]

Type parameters of generic classes may also have upper bounds, which
restrict the valid values for the type parameter in the same way.

.. _generic-methods-and-generic-self:

Generic methods and generic self
********************************

You can also define generic methods. In
particular, the ``self`` parameter may also be generic, allowing a
method to return the most precise type known at the point of access.
In this way, for example, you can type check a chain of setter
methods (Python 3.12 syntax):

.. code-block:: python

   class Shape:
       def set_scale[T: Shape](self: T, scale: float) -> T:
           self.scale = scale
           return self

   class Circle(Shape):
       def set_radius(self, r: float) -> 'Circle':
           self.radius = r
           return self

   class Square(Shape):
       def set_width(self, w: float) -> 'Square':
           self.width = w
           return self

   circle: Circle = Circle().set_scale(0.5).set_radius(2.7)
   square: Square = Square().set_scale(0.5).set_width(3.2)

Without using generic ``self``, the last two lines could not be type
checked properly, since the return type of ``set_scale`` would be
``Shape``, which doesn't define ``set_radius`` or ``set_width``.

When using the legacy syntax, just use a type variable in the
method signature that is different from class type parameters (if any
are defined). Here is the above example using the legacy
syntax (3.11 and earlier):

.. code-block:: python

   from typing import TypeVar

   T = TypeVar('T', bound='Shape')

   class Shape:
       def set_scale(self: T, scale: float) -> T:
           self.scale = scale
           return self

   class Circle(Shape):
       def set_radius(self, r: float) -> 'Circle':
           self.radius = r
           return self

   class Square(Shape):
       def set_width(self, w: float) -> 'Square':
           self.width = w
           return self

   circle: Circle = Circle().set_scale(0.5).set_radius(2.7)
   square: Square = Square().set_scale(0.5).set_width(3.2)

Other uses include factory methods, such as copy and deserialization methods.
For class methods, you can also define generic ``cls``, using ``type[T]``
or :py:class:`Type[T] <typing.Type>` (Python 3.12 syntax):

.. code-block:: python

   class Friend:
       other: "Friend | None" = None

       @classmethod
       def make_pair[T: Friend](cls: type[T]) -> tuple[T, T]:
           a, b = cls(), cls()
           a.other = b
           b.other = a
           return a, b

   class SuperFriend(Friend):
       pass

   a, b = SuperFriend.make_pair()

Here is the same example using the legacy syntax (3.11 and earlier):

.. code-block:: python

   from typing import TypeVar

   T = TypeVar('T', bound='Friend')

   class Friend:
       other: "Friend | None" = None

       @classmethod
       def make_pair(cls: type[T]) -> tuple[T, T]:
           a, b = cls(), cls()
           a.other = b
           b.other = a
           return a, b

   class SuperFriend(Friend):
       pass

   a, b = SuperFriend.make_pair()

Note that when overriding a method with generic ``self``, you must either
return a generic ``self`` too, or return an instance of the current class.
In the latter case, you must implement this method in all future subclasses.

Note also that mypy cannot always verify that the implementation of a copy
or a deserialization method returns the actual type of self. Therefore
you may need to silence mypy inside these methods (but not at the call site),
possibly by making use of the ``Any`` type or a ``# type: ignore`` comment.

Mypy lets you use generic self types in certain unsafe ways
in order to support common idioms. For example, using a generic
self type in an argument type is accepted even though it's unsafe (Python 3.12
syntax):

.. code-block:: python

   class Base:
       def compare[T: Base](self: T, other: T) -> bool:
           return False

   class Sub(Base):
       def __init__(self, x: int) -> None:
           self.x = x

       # This is unsafe (see below) but allowed because it's
       # a common pattern and rarely causes issues in practice.
       def compare(self, other: 'Sub') -> bool:
           return self.x > other.x

   b: Base = Sub(42)
   b.compare(Base())  # Runtime error here: 'Base' object has no attribute 'x'

For some advanced uses of self types, see :ref:`additional examples <advanced_self>`.

Automatic self types using typing.Self
**************************************

Since the patterns described above are quite common, mypy supports a
simpler syntax, introduced in :pep:`673`, to make them easier to use.
Instead of introducing a type parameter and using an explicit annotation
for ``self``, you can import the special type ``typing.Self`` that is
automatically transformed into a method-level type parameter with the
current class as the upper bound, and you don't need an annotation for
``self`` (or ``cls`` in class methods). The example from the previous
section can be made simpler by using ``Self``:

.. code-block:: python

   from typing import Self

   class Friend:
       other: Self | None = None

       @classmethod
       def make_pair(cls) -> tuple[Self, Self]:
           a, b = cls(), cls()
           a.other = b
           b.other = a
           return a, b

   class SuperFriend(Friend):
       pass

   a, b = SuperFriend.make_pair()

This is more compact than using explicit type parameters. Also, you can
use ``Self`` in attribute annotations in addition to methods.

.. note::

   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).

.. _variance-of-generics:

Variance of generic types
*************************

There are three main kinds of generic types with respect to subtype
relations between them: invariant, covariant, and contravariant.
Assuming that we have a pair of types ``A`` and ``B``, and ``B`` is
a subtype of ``A``, these are defined as follows:

* A generic class ``MyCovGen[T]`` is called covariant in type variable
  ``T`` if ``MyCovGen[B]`` is always a subtype of ``MyCovGen[A]``.
* A generic class ``MyContraGen[T]`` is called contravariant in type
  variable ``T`` if ``MyContraGen[A]`` is always a subtype of
  ``MyContraGen[B]``.
* A generic class ``MyInvGen[T]`` is called invariant in ``T`` if neither
  of the above is true.

Let us illustrate this by few simple examples:

.. code-block:: python

    # We'll use these classes in the examples below
    class Shape: ...
    class Triangle(Shape): ...
    class Square(Shape): ...

* Most immutable container types, such as :py:class:`~collections.abc.Sequence`
  and :py:class:`~frozenset` are covariant. Union types are
  also covariant in all union items: ``Triangle | int`` is
  a subtype of ``Shape | int``.

  .. code-block:: python

    def count_lines(shapes: Sequence[Shape]) -> int:
        return sum(shape.num_sides for shape in shapes)

    triangles: Sequence[Triangle]
    count_lines(triangles)  # OK

    def foo(triangle: Triangle, num: int) -> None:
        shape_or_number: Union[Shape, int]
        # a Triangle is a Shape, and a Shape is a valid Union[Shape, int]
        shape_or_number = triangle

  Covariance should feel relatively intuitive, but contravariance and invariance
  can be harder to reason about.

* :py:class:`~collections.abc.Callable` is an example of type that behaves contravariant
  in types of arguments. That is, ``Callable[[Shape], int]`` is a subtype of
  ``Callable[[Triangle], int]``, despite ``Shape`` being a supertype of
  ``Triangle``. To understand this, consider:

  .. code-block:: python

    def cost_of_paint_required(
        triangle: Triangle,
        area_calculator: Callable[[Triangle], float]
    ) -> float:
        return area_calculator(triangle) * DOLLAR_PER_SQ_FT

    # This straightforwardly works
    def area_of_triangle(triangle: Triangle) -> float: ...
    cost_of_paint_required(triangle, area_of_triangle)  # OK

    # But this works as well!
    def area_of_any_shape(shape: Shape) -> float: ...
    cost_of_paint_required(triangle, area_of_any_shape)  # OK

  ``cost_of_paint_required`` needs a callable that can calculate the area of a
  triangle. If we give it a callable that can calculate the area of an
  arbitrary shape (not just triangles), everything still works.

* ``list`` is an invariant generic type. Naively, one would think
  that it is covariant, like :py:class:`~collections.abc.Sequence` above, but consider this code:

  .. code-block:: python

     class Circle(Shape):
         # The rotate method is only defined on Circle, not on Shape
         def rotate(self): ...

     def add_one(things: list[Shape]) -> None:
         things.append(Shape())

     my_circles: list[Circle] = []
     add_one(my_circles)     # This may appear safe, but...
     my_circles[0].rotate()  # ...this will fail, since my_circles[0] is now a Shape, not a Circle

  Another example of invariant type is ``dict``. Most mutable containers
  are invariant.

When using the Python 3.12 syntax for generics, mypy will automatically
infer the most flexible variance for each class type variable. Here
``Box`` will be inferred as covariant:

.. code-block:: python

   class Box[T]:  # this type is implicitly covariant
       def __init__(self, content: T) -> None:
           self._content = content

       def get_content(self) -> T:
           return self._content

   def look_into(box: Box[Shape]): ...

   my_box = Box(Square())
   look_into(my_box)  # OK, but mypy would complain here for an invariant type

Here the underscore prefix for ``_content`` is significant. Without an
underscore prefix, the class would be invariant, as the attribute would
be understood as a public, mutable attribute (a single underscore prefix
has no special significance for mypy in most other contexts). By declaring
the attribute as ``Final``, the class could still be made covariant:

.. code-block:: python

   from typing import Final

   class Box[T]:  # this type is implicitly covariant
       def __init__(self, content: T) -> None:
           self.content: Final = content

       def get_content(self) -> T:
           return self.content

When using the legacy syntax, mypy assumes that all user-defined generics
are invariant by default. To declare a given generic class as covariant or
contravariant, use type variables defined with special keyword arguments
``covariant`` or ``contravariant``. For example (Python 3.11 or earlier):

.. code-block:: python

   from typing import Generic, TypeVar

   T_co = TypeVar('T_co', covariant=True)

   class Box(Generic[T_co]):  # this type is declared covariant
       def __init__(self, content: T_co) -> None:
           self._content = content

       def get_content(self) -> T_co:
           return self._content

   def look_into(box: Box[Shape]): ...

   my_box = Box(Square())
   look_into(my_box)  # OK, but mypy would complain here for an invariant type

.. _value-constrained-type-variables:
.. _type-variable-value-restriction:

Value-constrained type variables
*********************************

By default, a type variable can be replaced with any type -- or any type that
is a subtype of the upper bound, which defaults to ``object``. However, sometimes
it's useful to have a type variable that can only have some specific types
as its value. A typical example is a type variable that can only have values
``str`` and ``bytes``. This lets us define a function that can concatenate
two strings or bytes objects, but it can't be called with other argument
types (Python 3.12 syntax):

.. code-block:: python

   def concat[S: (str, bytes)](x: S, y: S) -> S:
       return x + y

   concat('a', 'b')    # Okay
   concat(b'a', b'b')  # Okay
   concat(1, 2)        # Error!


The same thing is also possibly using the legacy syntax (Python 3.11 or earlier):

.. code-block:: python

   from typing import TypeVar

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

   def concat(x: AnyStr, y: AnyStr) -> AnyStr:
       return x + y

No matter which syntax you use, such a type variable is called a
value-constrained type variable (the allowed types are accessible at runtime
via ``TypeVar.__constraints__``). Importantly, this is different from a union type,
since combinations of ``str`` and ``bytes`` are not accepted:

.. code-block:: python

   concat('string', b'bytes')   # Error!

In this case, this is exactly what we want, since it's not possible
to concatenate a string and a bytes object! If we tried to use
a union type, the type checker would complain about this possibility:

.. code-block:: python

   def union_concat(x: str | bytes, y: str | bytes) -> str | bytes:
       return x + y  # Error: can't concatenate str and bytes

Another interesting special case is calling ``concat()`` with a
subtype of ``str``:

.. code-block:: python

    class S(str): pass

    ss = concat(S('foo'), S('bar'))
    reveal_type(ss)  # Revealed type is "builtins.str"

You may expect that the type of ``ss`` is ``S``, but the type is
actually ``str``: a subtype gets promoted to one of the valid values
for the type variable, which in this case is ``str``.

This is thus subtly different from using ``str | bytes`` as an upper bound,
where the return type would be ``S`` (see :ref:`type-variable-upper-bound`).
Using a value constraint is correct for ``concat``, since ``concat``
actually returns a ``str`` instance in the above example:

.. code-block:: python

    >>> print(type(ss))
    <class 'str'>

You can also use type variables with a restricted set of possible
values when defining a generic class. For example, the type
:py:class:`Pattern[S] <typing.Pattern>` is used for the return
value of :py:func:`re.compile`, where ``S`` can be either ``str``
or ``bytes``. Regular expressions can be based on a string or a
bytes pattern.

A type variable may not have both value constraints and an upper bound.

Note that you may come across :py:data:`~typing.AnyStr` imported from
:py:mod:`typing`. This feature is now deprecated, but it means the same
as our definition of ``AnyStr`` above.

.. _declaring-decorators:

Declaring decorators
********************

Decorators are typically functions that take a function as an argument and
return another function. Describing this behaviour in terms of types can
be a little tricky; we'll show how you can use type variables and a special
kind of type variable called a *parameter specification* to do so.

Suppose we have the following decorator, not type annotated yet,
that preserves the original function's signature and merely prints the decorated
function's name:

.. code-block:: python

   def printing_decorator(func):
       def wrapper(*args, **kwds):
           print("Calling", func)
           return func(*args, **kwds)
       return wrapper

We can use it to decorate function ``add_forty_two``:

.. code-block:: python

   # A decorated function.
   @printing_decorator
   def add_forty_two(value: int) -> int:
       return value + 42

   a = add_forty_two(3)

Since ``printing_decorator`` is not type-annotated, the following won't get type checked:

.. code-block:: python

   reveal_type(a)        # Revealed type is "Any"
   add_forty_two('foo')  # No type checker error :(

This is a sorry state of affairs! If you run with ``--strict``, mypy will
even alert you to this fact:
``Untyped decorator makes function "add_forty_two" untyped``

Note that class decorators are handled differently than function decorators in
mypy: decorating a class does not erase its type, even if the decorator has
incomplete type annotations.

Here's how one could annotate the decorator (Python 3.12 syntax):

.. code-block:: python

   from collections.abc import Callable
   from typing import Any, cast

   # A decorator that preserves the signature.
   def printing_decorator[F: Callable[..., Any]](func: F) -> F:
       def wrapper(*args, **kwds):
           print("Calling", func)
           return func(*args, **kwds)
       return cast(F, wrapper)

   @printing_decorator
   def add_forty_two(value: int) -> int:
       return value + 42

   a = add_forty_two(3)
   reveal_type(a)      # Revealed type is "builtins.int"
   add_forty_two('x')  # Argument 1 to "add_forty_two" has incompatible type "str"; expected "int"

Here is the example using the legacy syntax (Python 3.11 and earlier):

.. code-block:: python

   from collections.abc import Callable
   from typing import Any, TypeVar, cast

   F = TypeVar('F', bound=Callable[..., Any])

   # A decorator that preserves the signature.
   def printing_decorator(func: F) -> F:
       def wrapper(*args, **kwds):
           print("Calling", func)
           return func(*args, **kwds)
       return cast(F, wrapper)

   @printing_decorator
   def add_forty_two(value: int) -> int:
       return value + 42

   a = add_forty_two(3)
   reveal_type(a)      # Revealed type is "builtins.int"
   add_forty_two('x')  # Argument 1 to "add_forty_two" has incompatible type "str"; expected "int"

This still has some shortcomings. First, we need to use the unsafe
:py:func:`~typing.cast` to convince mypy that ``wrapper()`` has the same
signature as ``func`` (see :ref:`casts <casts>`).

Second, the ``wrapper()`` function is not tightly type checked, although
wrapper functions are typically small enough that this is not a big
problem. This is also the reason for the :py:func:`~typing.cast` call in the
``return`` statement in ``printing_decorator()``.

However, we can use a parameter specification, introduced using ``**P``,
for a more faithful type annotation (Python 3.12 syntax):

.. code-block:: python

   from collections.abc import Callable

   def printing_decorator[**P, T](func: Callable[P, T]) -> Callable[P, T]:
       def wrapper(*args: P.args, **kwds: P.kwargs) -> T:
           print("Calling", func)
           return func(*args, **kwds)
       return wrapper

The same is possible using the legacy syntax with :py:class:`~typing.ParamSpec`
(Python 3.11 and earlier):

.. code-block:: python

   from collections.abc import Callable
   from typing import TypeVar
   from typing_extensions import ParamSpec

   P = ParamSpec('P')
   T = TypeVar('T')

   def printing_decorator(func: Callable[P, T]) -> Callable[P, T]:
       def wrapper(*args: P.args, **kwds: P.kwargs) -> T:
           print("Calling", func)
           return func(*args, **kwds)
       return wrapper

Parameter specifications also allow you to describe decorators that
alter the signature of the input function (Python 3.12 syntax):

.. code-block:: python

   from collections.abc import Callable

   # We reuse 'P' in the return type, but replace 'T' with 'str'
   def stringify[**P, T](func: Callable[P, T]) -> Callable[P, str]:
       def wrapper(*args: P.args, **kwds: P.kwargs) -> str:
           return str(func(*args, **kwds))
       return wrapper

    @stringify
    def add_forty_two(value: int) -> int:
        return value + 42

    a = add_forty_two(3)
    reveal_type(a)      # Revealed type is "builtins.str"
    add_forty_two('x')  # error: Argument 1 to "add_forty_two" has incompatible type "str"; expected "int"

Here is the above example using the legacy syntax (Python 3.11 and earlier):

.. code-block:: python

   from collections.abc import Callable
   from typing import TypeVar
   from typing_extensions import ParamSpec

   P = ParamSpec('P')
   T = TypeVar('T')

   # We reuse 'P' in the return type, but replace 'T' with 'str'
   def stringify(func: Callable[P, T]) -> Callable[P, str]:
       def wrapper(*args: P.args, **kwds: P.kwargs) -> str:
           return str(func(*args, **kwds))
       return wrapper

You can also insert an argument in a decorator (Python 3.12 syntax):

.. code-block:: python

    from collections.abc import Callable
    from typing import Concatenate

    def printing_decorator[**P, T](func: Callable[P, T]) -> Callable[Concatenate[str, P], T]:
        def wrapper(msg: str, /, *args: P.args, **kwds: P.kwargs) -> T:
            print("Calling", func, "with", msg)
            return func(*args, **kwds)
        return wrapper

    @printing_decorator
    def add_forty_two(value: int) -> int:
        return value + 42

    a = add_forty_two('three', 3)

Here is the same function using the legacy syntax (Python 3.11 and earlier):

.. code-block:: python

    from collections.abc import Callable
    from typing import TypeVar
    from typing_extensions import Concatenate, ParamSpec

    P = ParamSpec('P')
    T = TypeVar('T')

    def printing_decorator(func: Callable[P, T]) -> Callable[Concatenate[str, P], T]:
        def wrapper(msg: str, /, *args: P.args, **kwds: P.kwargs) -> T:
            print("Calling", func, "with", msg)
            return func(*args, **kwds)
        return wrapper

.. _decorator-factories:

Decorator factories
-------------------

Functions that take arguments and return a decorator (also called second-order decorators), are
similarly supported via generics (Python 3.12 syntax):

.. code-block:: python

    from collections.abc import Callable
    from typing import Any

    def route[F: Callable[..., Any]](url: str) -> Callable[[F], F]:
        ...

    @route(url='/')
    def index(request: Any) -> str:
        return 'Hello world'

Note that mypy infers that ``F`` is used to make the ``Callable`` return value
of ``route`` generic, instead of making ``route`` itself generic, since ``F`` is
only used in the return type. Python has no explicit syntax to mark that ``F``
is only bound in the return value.

Here is the example using the legacy syntax (Python 3.11 and earlier):

.. code-block:: python

    from collections.abc import Callable
    from typing import Any, TypeVar

    F = TypeVar('F', bound=Callable[..., Any])

    def route(url: str) -> Callable[[F], F]:
        ...

    @route(url='/')
    def index(request: Any) -> str:
        return 'Hello world'

Sometimes the same decorator supports both bare calls and calls with arguments. This can be
achieved by combining with :py:func:`@overload <typing.overload>` (Python 3.12 syntax):

.. code-block:: python

    from collections.abc import Callable
    from typing import Any, overload

    # Bare decorator usage
    @overload
    def atomic[F: Callable[..., Any]](func: F, /) -> F: ...
    # Decorator with arguments
    @overload
    def atomic[F: Callable[..., Any]](*, savepoint: bool = True) -> Callable[[F], F]: ...

    # Implementation
    def atomic(func: Callable[..., Any] | None = None, /, *, savepoint: bool = True):
        def decorator(func: Callable[..., Any]):
            ...  # Code goes here
        if __func is not None:
            return decorator(__func)
        else:
            return decorator

    # Usage
    @atomic
    def func1() -> None: ...

    @atomic(savepoint=False)
    def func2() -> None: ...

Here is the decorator from the example using the legacy syntax
(Python 3.11 and earlier):

.. code-block:: python

    from collections.abc import Callable
    from typing import Any, Optional, TypeVar, overload

    F = TypeVar('F', bound=Callable[..., Any])

    # Bare decorator usage
    @overload
    def atomic(func: F, /) -> F: ...
    # Decorator with arguments
    @overload
    def atomic(*, savepoint: bool = True) -> Callable[[F], F]: ...

    # Implementation
    def atomic(func: Optional[Callable[..., Any]] = None, /, *, savepoint: bool = True):
        ...  # Same as above

Generic protocols
*****************

Mypy supports generic protocols (see also :ref:`protocol-types`). Several
:ref:`predefined protocols <predefined_protocols>` are generic, such as
:py:class:`Iterable[T] <collections.abc.Iterable>`, and you can define additional
generic protocols. Generic protocols mostly follow the normal rules for
generic classes. Example (Python 3.12 syntax):

.. code-block:: python

   from typing import Protocol

   class Box[T](Protocol):
       content: T

   def do_stuff(one: Box[str], other: Box[bytes]) -> None:
       ...

   class StringWrapper:
       def __init__(self, content: str) -> None:
           self.content = content

   class BytesWrapper:
       def __init__(self, content: bytes) -> None:
           self.content = content

   do_stuff(StringWrapper('one'), BytesWrapper(b'other'))  # OK

   x: Box[float] = ...
   y: Box[int] = ...
   x = y  # Error -- Box is invariant

Here is the definition of ``Box`` from the above example using the legacy
syntax (Python 3.11 and earlier):

.. code-block:: python

   from typing import Protocol, TypeVar

   T = TypeVar('T')

   class Box(Protocol[T]):
       content: T

Note that ``class ClassName(Protocol[T])`` is allowed as a shorthand for
``class ClassName(Protocol, Generic[T])`` when using the legacy syntax,
as per :pep:`PEP 544: Generic protocols <544#generic-protocols>`.
This form is only valid when using the legacy syntax.

When using the legacy syntax, there is an important difference between
generic protocols and ordinary generic classes: mypy checks that the
declared variances of generic type variables in a protocol match how
they are used in the protocol definition.  The protocol in this example
is rejected, since the type variable ``T`` is used covariantly as
a return type, but the type variable is invariant:

.. code-block:: python

   from typing import Protocol, TypeVar

   T = TypeVar('T')

   class ReadOnlyBox(Protocol[T]):  # error: Invariant type variable "T" used in protocol where covariant one is expected
       def content(self) -> T: ...

This example correctly uses a covariant type variable:

.. code-block:: python

   from typing import Protocol, TypeVar

   T_co = TypeVar('T_co', covariant=True)

   class ReadOnlyBox(Protocol[T_co]):  # OK
       def content(self) -> T_co: ...

   ax: ReadOnlyBox[float] = ...
   ay: ReadOnlyBox[int] = ...
   ax = ay  # OK -- ReadOnlyBox is covariant

See :ref:`variance-of-generics` for more about variance.

Generic protocols can also be recursive. Example (Python 3.12 syntax):

.. code-block:: python

   class Linked[T](Protocol):
       val: T
       def next(self) -> 'Linked[T]': ...

   class L:
       val: int
       def next(self) -> 'L': ...

   def last(seq: Linked[T]) -> T: ...

   result = last(L())
   reveal_type(result)  # Revealed type is "builtins.int"

Here is the definition of ``Linked`` using the legacy syntax
(Python 3.11 and earlier):

.. code-block:: python

   from typing import TypeVar

   T = TypeVar('T')

   class Linked(Protocol[T]):
       val: T
       def next(self) -> 'Linked[T]': ...

.. _generic-type-aliases:

Generic type aliases
********************

Type aliases can be generic. In this case they can be used in two ways.
First, subscripted aliases are equivalent to original types with substituted type
variables. Second, unsubscripted aliases are treated as original types with type
parameters replaced with ``Any``.

The ``type`` statement introduced in Python 3.12 is used to define generic
type aliases (it also supports non-generic type aliases):

.. code-block:: python

    from collections.abc import Callable, Iterable

    type TInt[S] = tuple[int, S]
    type UInt[S] = S | int
    type CBack[S] = Callable[..., S]

    def response(query: str) -> UInt[str]:  # Same as str | int
        ...
    def activate[S](cb: CBack[S]) -> S:        # Same as Callable[..., S]
        ...
    table_entry: TInt  # Same as tuple[int, Any]

    type Vec[T: (int, float, complex)] = Iterable[tuple[T, T]]

    def inproduct[T: (int, float, complex)](v: Vec[T]) -> T:
        return sum(x*y for x, y in v)

    def dilate[T: (int, float, complex)](v: Vec[T], scale: T) -> Vec[T]:
        return ((x * scale, y * scale) for x, y in v)

    v1: Vec[int] = []      # Same as Iterable[tuple[int, int]]
    v2: Vec = []           # Same as Iterable[tuple[Any, Any]]
    v3: Vec[int, int] = [] # Error: Invalid alias, too many type arguments!

There is also a legacy syntax that relies on ``TypeVar``.
Here the number of type arguments must match the number of free type variables
in the generic type alias definition. A type variables is free if it's not
a type parameter of a surrounding class or function. Example (following
:pep:`PEP 484: Type aliases <484#type-aliases>`, Python 3.11 and earlier):

.. code-block:: python

    from typing import TypeVar, Iterable, Union, Callable

    S = TypeVar('S')

    TInt = tuple[int, S]  # 1 type parameter, since only S is free
    UInt = Union[S, int]
    CBack = Callable[..., S]

    def response(query: str) -> UInt[str]:  # Same as Union[str, int]
        ...
    def activate(cb: CBack[S]) -> S:        # Same as Callable[..., S]
        ...
    table_entry: TInt  # Same as tuple[int, Any]

    T = TypeVar('T', int, float, complex)

    Vec = Iterable[tuple[T, T]]

    def inproduct(v: Vec[T]) -> T:
        return sum(x*y for x, y in v)

    def dilate(v: Vec[T], scale: T) -> Vec[T]:
        return ((x * scale, y * scale) for x, y in v)

    v1: Vec[int] = []      # Same as Iterable[tuple[int, int]]
    v2: Vec = []           # Same as Iterable[tuple[Any, Any]]
    v3: Vec[int, int] = [] # Error: Invalid alias, too many type arguments!

Type aliases can be imported from modules just like other names. An
alias can also target another alias, although building complex chains
of aliases is not recommended -- this impedes code readability, thus
defeating the purpose of using aliases.  Example (Python 3.12 syntax):

.. code-block:: python

    from example1 import AliasType
    from example2 import Vec

    # AliasType and Vec are type aliases (Vec as defined above)

    def fun() -> AliasType:
        ...

    type OIntVec = Vec[int] | None

Type aliases defined using the ``type`` statement are not valid as
base classes, and they can't be used to construct instances:

.. code-block:: python

    from example1 import AliasType
    from example2 import Vec

    # AliasType and Vec are type aliases (Vec as defined above)

    class NewVec[T](Vec[T]):  # Error: not valid as base class
        ...

    x = AliasType()  # Error: can't be used to create instances

Here are examples using the legacy syntax (Python 3.11 and earlier):

.. code-block:: python

    from typing import TypeVar, Generic, Optional
    from example1 import AliasType
    from example2 import Vec

    # AliasType and Vec are type aliases (Vec as defined above)

    def fun() -> AliasType:
        ...

    OIntVec = Optional[Vec[int]]

    T = TypeVar('T')

    # Old-style type aliases can be used as base classes and you can
    # construct instances using them

    class NewVec(Vec[T]):
        ...

    x = AliasType()

    for i, j in NewVec[int]():
        ...

Using type variable bounds or value constraints in generic aliases has
the same effect as in generic classes and functions.


Differences between the new and old syntax
******************************************

There are a few notable differences between the new (Python 3.12 and later)
and the old syntax for generic classes, functions and type aliases, beyond
the obvious syntactic differences:

 * Type variables defined using the old syntax create definitions at runtime
   in the surrounding namespace, whereas the type variables defined using the
   new syntax are only defined within the class, function or type variable
   that uses them.
 * Type variable definitions can be shared when using the old syntax, but
   the new syntax doesn't support this.
 * When using the new syntax, the variance of class type variables is always
   inferred.
 * Type aliases defined using the new syntax can contain forward references
   and recursive references without using string literal escaping. The
   same is true for the bounds and constraints of type variables.
 * The new syntax lets you define a generic alias where the definition doesn't
   contain a reference to a type parameter. This is occasionally useful, at
   least when conditionally defining type aliases.
 * Type aliases defined using the new syntax can't be used as base classes
   and can't be used to construct instances, unlike aliases defined using the
   old syntax.


Generic class internals
***********************

You may wonder what happens at runtime when you index a generic class.
Indexing returns a *generic alias* to the original class that returns instances
of the original class on instantiation (Python 3.12 syntax):

.. code-block:: python

   >>> class Stack[T]: ...
   >>> Stack
   __main__.Stack
   >>> Stack[int]
   __main__.Stack[int]
   >>> instance = Stack[int]()
   >>> instance.__class__
   __main__.Stack

Here is the same example using the legacy syntax (Python 3.11 and earlier):

.. code-block:: python

   >>> from typing import TypeVar, Generic
   >>> T = TypeVar('T')
   >>> class Stack(Generic[T]): ...
   >>> Stack
   __main__.Stack
   >>> Stack[int]
   __main__.Stack[int]
   >>> instance = Stack[int]()
   >>> instance.__class__
   __main__.Stack

Generic aliases can be instantiated or subclassed, similar to real
classes, but the above examples illustrate that type variables are
erased at runtime. Generic ``Stack`` instances are just ordinary
Python objects, and they have no extra runtime overhead or magic due
to being generic, other than the ``Generic`` base class that overloads
the indexing operator using ``__class_getitem__``. ``typing.Generic``
is included as an implicit base class even when using the new syntax:

.. code-block:: python

   >>> class Stack[T]: ...
   >>> Stack.mro()
   [<class '__main__.Stack'>, <class 'typing.Generic'>, <class 'object'>]

Note that in Python 3.8 and earlier, the built-in types
:py:class:`list`, :py:class:`dict` and others do not support indexing.
This is why we have the aliases :py:class:`~typing.List`,
:py:class:`~typing.Dict` and so on in the :py:mod:`typing`
module. Indexing these aliases gives you a generic alias that
resembles generic aliases constructed by directly indexing the target
class in more recent versions of Python:

.. code-block:: python

   >>> # Prefer the 'list[int]' syntax
   >>> from typing import List
   >>> List[int]
   typing.List[int]

Note that the generic aliases in ``typing`` don't support constructing
instances, unlike the corresponding built-in classes:

.. code-block:: python

   >>> list[int]()
   []
   >>> from typing import List
   >>> List[int]()
   Traceback (most recent call last):
   ...
   TypeError: Type List cannot be instantiated; use list() instead
