=========================================
:mod:`!typing` --- Support for type hints
=========================================

.. testsetup:: *

   import typing
   from dataclasses import dataclass
   from typing import *

.. module:: typing
   :synopsis: Support for type hints (see :pep:`484`).

.. versionadded:: 3.5

**Source code:** :source:`Lib/typing.py`

.. note::

   The Python runtime does not enforce function and variable type annotations.
   They can be used by third party tools such as :term:`type checkers <static type checker>`,
   IDEs, linters, etc.

--------------

This module provides runtime support for type hints.

Consider the function below::

   def surface_area_of_cube(edge_length: float) -> str:
       return f"The surface area of the cube is {6 * edge_length ** 2}."

The function ``surface_area_of_cube`` takes an argument expected to
be an instance of :class:`float`, as indicated by the :term:`type hint`
``edge_length: float``. The function is expected to return an instance
of :class:`str`, as indicated by the ``-> str`` hint.

While type hints can be simple classes like :class:`float` or :class:`str`,
they can also be more complex. The :mod:`typing` module provides a vocabulary of
more advanced type hints.

New features are frequently added to the ``typing`` module.
The :pypi:`typing_extensions` package
provides backports of these new features to older versions of Python.

.. seealso::

   `Typing cheat sheet <https://mypy.readthedocs.io/en/stable/cheat_sheet_py3.html>`_
       A quick overview of type hints (hosted at the mypy docs)

   Type System Reference section of `the mypy docs <https://mypy.readthedocs.io/en/stable/index.html>`_
      The Python typing system is standardised via PEPs, so this reference
      should broadly apply to most Python type checkers. (Some parts may still
      be specific to mypy.)

   `Static Typing with Python <https://typing.python.org/en/latest/>`_
      Type-checker-agnostic documentation written by the community detailing
      type system features, useful typing related tools and typing best
      practices.

.. _relevant-peps:

Specification for the Python Type System
========================================

The canonical, up-to-date specification of the Python type system can be
found at `Specification for the Python type system <https://typing.python.org/en/latest/spec/index.html>`_.

.. _type-aliases:

Type aliases
============

A type alias is defined using the :keyword:`type` statement, which creates
an instance of :class:`TypeAliasType`. In this example,
``Vector`` and ``list[float]`` will be treated equivalently by static type
checkers::

   type Vector = list[float]

   def scale(scalar: float, vector: Vector) -> Vector:
       return [scalar * num for num in vector]

   # passes type checking; a list of floats qualifies as a Vector.
   new_vector = scale(2.0, [1.0, -4.2, 5.4])

Type aliases are useful for simplifying complex type signatures. For example::

   from collections.abc import Sequence

   type ConnectionOptions = dict[str, str]
   type Address = tuple[str, int]
   type Server = tuple[Address, ConnectionOptions]

   def broadcast_message(message: str, servers: Sequence[Server]) -> None:
       ...

   # The static type checker will treat the previous type signature as
   # being exactly equivalent to this one.
   def broadcast_message(
       message: str,
       servers: Sequence[tuple[tuple[str, int], dict[str, str]]]
   ) -> None:
       ...

The :keyword:`type` statement is new in Python 3.12. For backwards
compatibility, type aliases can also be created through simple assignment::

   Vector = list[float]

Or marked with :data:`TypeAlias` to make it explicit that this is a type alias,
not a normal variable assignment::

   from typing import TypeAlias

   Vector: TypeAlias = list[float]

.. _distinct:

NewType
=======

Use the :class:`NewType` helper to create distinct types::

   from typing import NewType

   UserId = NewType('UserId', int)
   some_id = UserId(524313)

The static type checker will treat the new type as if it were a subclass
of the original type. This is useful in helping catch logical errors::

   def get_user_name(user_id: UserId) -> str:
       ...

   # passes type checking
   user_a = get_user_name(UserId(42351))

   # fails type checking; an int is not a UserId
   user_b = get_user_name(-1)

You may still perform all ``int`` operations on a variable of type ``UserId``,
but the result will always be of type ``int``. This lets you pass in a
``UserId`` wherever an ``int`` might be expected, but will prevent you from
accidentally creating a ``UserId`` in an invalid way::

   # 'output' is of type 'int', not 'UserId'
   output = UserId(23413) + UserId(54341)

Note that these checks are enforced only by the static type checker. At runtime,
the statement ``Derived = NewType('Derived', Base)`` will make ``Derived`` a
callable that immediately returns whatever parameter you pass it. That means
the expression ``Derived(some_value)`` does not create a new class or introduce
much overhead beyond that of a regular function call.

More precisely, the expression ``some_value is Derived(some_value)`` is always
true at runtime.

It is invalid to create a subtype of ``Derived``::

   from typing import NewType

   UserId = NewType('UserId', int)

   # Fails at runtime and does not pass type checking
   class AdminUserId(UserId): pass

However, it is possible to create a :class:`NewType` based on a 'derived' ``NewType``::

   from typing import NewType

   UserId = NewType('UserId', int)

   ProUserId = NewType('ProUserId', UserId)

and typechecking for ``ProUserId`` will work as expected.

See :pep:`484` for more details.

.. note::

   Recall that the use of a type alias declares two types to be *equivalent* to
   one another. Doing ``type Alias = Original`` will make the static type checker
   treat ``Alias`` as being *exactly equivalent* to ``Original`` in all cases.
   This is useful when you want to simplify complex type signatures.

   In contrast, ``NewType`` declares one type to be a *subtype* of another.
   Doing ``Derived = NewType('Derived', Original)`` will make the static type
   checker treat ``Derived`` as a *subclass* of ``Original``, which means a
   value of type ``Original`` cannot be used in places where a value of type
   ``Derived`` is expected. This is useful when you want to prevent logic
   errors with minimal runtime cost.

.. versionadded:: 3.5.2

.. versionchanged:: 3.10
   ``NewType`` is now a class rather than a function.  As a result, there is
   some additional runtime cost when calling ``NewType`` over a regular
   function.

.. versionchanged:: 3.11
   The performance of calling ``NewType`` has been restored to its level in
   Python 3.9.

.. _annotating-callables:

Annotating callable objects
===========================

Functions -- or other :term:`callable` objects -- can be annotated using
:class:`collections.abc.Callable` or deprecated :data:`typing.Callable`.
``Callable[[int], str]`` signifies a function that takes a single parameter
of type :class:`int` and returns a :class:`str`.

For example:

.. testcode::

   from collections.abc import Callable, Awaitable

   def feeder(get_next_item: Callable[[], str]) -> None:
       ...  # Body

   def async_query(on_success: Callable[[int], None],
                   on_error: Callable[[int, Exception], None]) -> None:
       ...  # Body

   async def on_update(value: str) -> None:
       ...  # Body

   callback: Callable[[str], Awaitable[None]] = on_update

.. index:: single: ...; ellipsis literal

The subscription syntax must always be used with exactly two values: the
argument list and the return type.  The argument list must be a list of types,
a :class:`ParamSpec`, :data:`Concatenate`, or an ellipsis (``...``). The return type must
be a single type.

If a literal ellipsis ``...`` is given as the argument list, it indicates that
a callable with any arbitrary parameter list would be acceptable:

.. testcode::

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

   x: Callable[..., str]
   x = str     # OK
   x = concat  # Also OK

``Callable`` cannot express complex signatures such as functions that take a
variadic number of arguments, :ref:`overloaded functions <overload>`, or
functions that have keyword-only parameters. However, these signatures can be
expressed by defining a :class:`Protocol` class with a
:meth:`~object.__call__` method:

.. testcode::

   from collections.abc import Iterable
   from typing import Protocol

   class Combiner(Protocol):
       def __call__(self, *vals: bytes, maxlen: int | None = None) -> list[bytes]: ...

   def batch_proc(data: Iterable[bytes], cb_results: Combiner) -> bytes:
       for item in data:
           ...

   def good_cb(*vals: bytes, maxlen: int | None = None) -> list[bytes]:
       ...
   def bad_cb(*vals: bytes, maxitems: int | None) -> list[bytes]:
       ...

   batch_proc([], good_cb)  # OK
   batch_proc([], bad_cb)   # Error! Argument 2 has incompatible type because of
                            # different name and kind in the callback

Callables which take other callables as arguments may indicate that their
parameter types are dependent on each other using :class:`ParamSpec`.
Additionally, if that callable adds or removes arguments from other
callables, the :data:`Concatenate` operator may be used.  They
take the form ``Callable[ParamSpecVariable, ReturnType]`` and
``Callable[Concatenate[Arg1Type, Arg2Type, ..., ParamSpecVariable], ReturnType]``
respectively.

.. versionchanged:: 3.10
   ``Callable`` now supports :class:`ParamSpec` and :data:`Concatenate`.
   See :pep:`612` for more details.

.. seealso::
   The documentation for :class:`ParamSpec` and :class:`Concatenate` provides
   examples of usage in ``Callable``.

.. _generics:

Generics
========

Since type information about objects kept in containers cannot be statically
inferred in a generic way, many container classes in the standard library support
subscription to denote the expected types of container elements.

.. testcode::

   from collections.abc import Mapping, Sequence

   class Employee: ...

   # Sequence[Employee] indicates that all elements in the sequence
   # must be instances of "Employee".
   # Mapping[str, str] indicates that all keys and all values in the mapping
   # must be strings.
   def notify_by_email(employees: Sequence[Employee],
                       overrides: Mapping[str, str]) -> None: ...

Generic functions and classes can be parameterized by using
:ref:`type parameter syntax <type-params>`::

   from collections.abc import Sequence

   def first[T](l: Sequence[T]) -> T:  # Function is generic over the TypeVar "T"
       return l[0]

Or by using the :class:`TypeVar` factory directly::

   from collections.abc import Sequence
   from typing import TypeVar

   U = TypeVar('U')                  # Declare type variable "U"

   def second(l: Sequence[U]) -> U:  # Function is generic over the TypeVar "U"
       return l[1]

.. versionchanged:: 3.12
   Syntactic support for generics is new in Python 3.12.

.. _annotating-tuples:

Annotating tuples
=================

For most containers in Python, the typing system assumes that all elements in
the container will be of the same type. For example::

   from collections.abc import Mapping

   # Type checker will infer that all elements in ``x`` are meant to be ints
   x: list[int] = []

   # Type checker error: ``list`` only accepts a single type argument:
   y: list[int, str] = [1, 'foo']

   # Type checker will infer that all keys in ``z`` are meant to be strings,
   # and that all values in ``z`` are meant to be either strings or ints
   z: Mapping[str, str | int] = {}

:class:`list` only accepts one type argument, so a type checker would emit an
error on the ``y`` assignment above. Similarly,
:class:`~collections.abc.Mapping` only accepts two type arguments: the first
indicates the type of the keys, and the second indicates the type of the
values.

Unlike most other Python containers, however, it is common in idiomatic Python
code for tuples to have elements which are not all of the same type. For this
reason, tuples are special-cased in Python's typing system. :class:`tuple`
accepts *any number* of type arguments::

   # OK: ``x`` is assigned to a tuple of length 1 where the sole element is an int
   x: tuple[int] = (5,)

   # OK: ``y`` is assigned to a tuple of length 2;
   # element 1 is an int, element 2 is a str
   y: tuple[int, str] = (5, "foo")

   # Error: the type annotation indicates a tuple of length 1,
   # but ``z`` has been assigned to a tuple of length 3
   z: tuple[int] = (1, 2, 3)

.. index:: single: ...; ellipsis literal

To denote a tuple which could be of *any* length, and in which all elements are
of the same type ``T``, use the literal ellipsis ``...``: ``tuple[T, ...]``.
To denote an empty tuple, use
``tuple[()]``. Using plain ``tuple`` as an annotation is equivalent to using
``tuple[Any, ...]``::

   x: tuple[int, ...] = (1, 2)
   # These reassignments are OK: ``tuple[int, ...]`` indicates x can be of any length
   x = (1, 2, 3)
   x = ()
   # This reassignment is an error: all elements in ``x`` must be ints
   x = ("foo", "bar")

   # ``y`` can only ever be assigned to an empty tuple
   y: tuple[()] = ()

   z: tuple = ("foo", "bar")
   # These reassignments are OK: plain ``tuple`` is equivalent to ``tuple[Any, ...]``
   z = (1, 2, 3)
   z = ()

.. _type-of-class-objects:

The type of class objects
=========================

A variable annotated with ``C`` may accept a value of type ``C``. In
contrast, a variable annotated with ``type[C]`` (or deprecated
:class:`typing.Type[C] <Type>`) may accept values that are classes
themselves -- specifically, it will accept the *class object* of ``C``. For
example::

   a = 3         # Has type ``int``
   b = int       # Has type ``type[int]``
   c = type(a)   # Also has type ``type[int]``

Note that ``type[C]`` is covariant::

   class User: ...
   class ProUser(User): ...
   class TeamUser(User): ...

   def make_new_user(user_class: type[User]) -> User:
       # ...
       return user_class()

   make_new_user(User)      # OK
   make_new_user(ProUser)   # Also OK: ``type[ProUser]`` is a subtype of ``type[User]``
   make_new_user(TeamUser)  # Still fine
   make_new_user(User())    # Error: expected ``type[User]`` but got ``User``
   make_new_user(int)       # Error: ``type[int]`` is not a subtype of ``type[User]``

The only legal parameters for :class:`type` are classes, :data:`Any`,
:ref:`type variables <generics>`, and unions of any of these types.
For example::

   def new_non_team_user(user_class: type[BasicUser | ProUser]): ...

   new_non_team_user(BasicUser)  # OK
   new_non_team_user(ProUser)    # OK
   new_non_team_user(TeamUser)   # Error: ``type[TeamUser]`` is not a subtype
                                 # of ``type[BasicUser | ProUser]``
   new_non_team_user(User)       # Also an error

``type[Any]`` is equivalent to :class:`type`, which is the root of Python's
:ref:`metaclass hierarchy <metaclasses>`.


.. _annotating-generators-and-coroutines:

Annotating generators and coroutines
====================================

A generator can be annotated using the generic type
:class:`Generator[YieldType, SendType, ReturnType] <collections.abc.Generator>`.
For example::

   def echo_round() -> Generator[int, float, str]:
       sent = yield 0
       while sent >= 0:
           sent = yield round(sent)
       return 'Done'

Note that unlike many other generic classes in the standard library,
the ``SendType`` of :class:`~collections.abc.Generator` behaves
contravariantly, not covariantly or invariantly.

The ``SendType`` and ``ReturnType`` parameters default to :const:`!None`::

   def infinite_stream(start: int) -> Generator[int]:
       while True:
           yield start
           start += 1

It is also possible to set these types explicitly::

   def infinite_stream(start: int) -> Generator[int, None, None]:
       while True:
           yield start
           start += 1

Simple generators that only ever yield values can also be annotated
as having a return type of either
:class:`Iterable[YieldType] <collections.abc.Iterable>`
or :class:`Iterator[YieldType] <collections.abc.Iterator>`::

   def infinite_stream(start: int) -> Iterator[int]:
       while True:
           yield start
           start += 1

Async generators are handled in a similar fashion, but don't
expect a ``ReturnType`` type argument
(:class:`AsyncGenerator[YieldType, SendType] <collections.abc.AsyncGenerator>`).
The ``SendType`` argument defaults to :const:`!None`, so the following definitions
are equivalent::

   async def infinite_stream(start: int) -> AsyncGenerator[int]:
       while True:
           yield start
           start = await increment(start)

   async def infinite_stream(start: int) -> AsyncGenerator[int, None]:
       while True:
           yield start
           start = await increment(start)

As in the synchronous case,
:class:`AsyncIterable[YieldType] <collections.abc.AsyncIterable>`
and :class:`AsyncIterator[YieldType] <collections.abc.AsyncIterator>` are
available as well::

   async def infinite_stream(start: int) -> AsyncIterator[int]:
       while True:
           yield start
           start = await increment(start)

Coroutines can be annotated using
:class:`Coroutine[YieldType, SendType, ReturnType] <collections.abc.Coroutine>`.
Generic arguments correspond to those of :class:`~collections.abc.Generator`,
for example::

   from collections.abc import Coroutine
   c: Coroutine[list[str], str, int]  # Some coroutine defined elsewhere
   x = c.send('hi')                   # Inferred type of 'x' is list[str]
   async def bar() -> None:
       y = await c                    # Inferred type of 'y' is int

.. _user-defined-generics:

User-defined generic types
==========================

A user-defined class can be defined as a generic class.

::

   from logging import Logger

   class LoggedVar[T]:
       def __init__(self, value: T, name: str, logger: Logger) -> None:
           self.name = name
           self.logger = logger
           self.value = value

       def set(self, new: T) -> None:
           self.log('Set ' + repr(self.value))
           self.value = new

       def get(self) -> T:
           self.log('Get ' + repr(self.value))
           return self.value

       def log(self, message: str) -> None:
           self.logger.info('%s: %s', self.name, message)

This syntax indicates that the class ``LoggedVar`` is parameterised around a
single :ref:`type variable <typevar>` ``T`` . This also makes ``T`` valid as
a type within the class body.

Generic classes implicitly inherit from :class:`Generic`. For compatibility
with Python 3.11 and lower, it is also possible to inherit explicitly from
:class:`Generic` to indicate a generic class::

   from typing import TypeVar, Generic

   T = TypeVar('T')

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

Generic classes have :meth:`~object.__class_getitem__` methods, meaning they
can be parameterised at runtime (e.g. ``LoggedVar[int]`` below)::

   from collections.abc import Iterable

   def zero_all_vars(vars: Iterable[LoggedVar[int]]) -> None:
       for var in vars:
           var.set(0)

A generic type can have any number of type variables. All varieties of
:class:`TypeVar` are permissible as parameters for a generic type::

   from typing import TypeVar, Generic, Sequence

   class WeirdTrio[T, B: Sequence[bytes], S: (int, str)]:
       ...

   OldT = TypeVar('OldT', contravariant=True)
   OldB = TypeVar('OldB', bound=Sequence[bytes], covariant=True)
   OldS = TypeVar('OldS', int, str)

   class OldWeirdTrio(Generic[OldT, OldB, OldS]):
       ...

Each type variable argument to :class:`Generic` must be distinct.
This is thus invalid::

   from typing import TypeVar, Generic
   ...

   class Pair[M, M]:  # SyntaxError
       ...

   T = TypeVar('T')

   class Pair(Generic[T, T]):   # INVALID
       ...

Generic classes can also inherit from other classes::

   from collections.abc import Sized

   class LinkedList[T](Sized):
       ...

When inheriting from generic classes, some type parameters could be fixed::

    from collections.abc import Mapping

    class MyDict[T](Mapping[str, T]):
        ...

In this case ``MyDict`` has a single parameter, ``T``.

Using a generic class without specifying type parameters assumes
:data:`Any` for each position. In the following example, ``MyIterable`` is
not generic but implicitly inherits from ``Iterable[Any]``:

.. testcode::

   from collections.abc import Iterable

   class MyIterable(Iterable): # Same as Iterable[Any]
       ...

User-defined generic type aliases are also supported. Examples::

   from collections.abc import Iterable

   type Response[S] = Iterable[S] | int

   # Return type here is same as Iterable[str] | int
   def response(query: str) -> Response[str]:
       ...

   type Vec[T] = Iterable[tuple[T, T]]

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

For backward compatibility, generic type aliases can also be created
through a simple assignment::

   from collections.abc import Iterable
   from typing import TypeVar

   S = TypeVar("S")
   Response = Iterable[S] | int

.. versionchanged:: 3.7
    :class:`Generic` no longer has a custom metaclass.

.. versionchanged:: 3.12
   Syntactic support for generics and type aliases is new in version 3.12.
   Previously, generic classes had to explicitly inherit from :class:`Generic`
   or contain a type variable in one of their bases.

User-defined generics for parameter expressions are also supported via parameter
specification variables in the form ``[**P]``.  The behavior is consistent
with type variables' described above as parameter specification variables are
treated by the :mod:`!typing` module as a specialized type variable.  The one exception
to this is that a list of types can be used to substitute a :class:`ParamSpec`::

   >>> class Z[T, **P]: ...  # T is a TypeVar; P is a ParamSpec
   ...
   >>> Z[int, [dict, float]]
   __main__.Z[int, [dict, float]]

Classes generic over a :class:`ParamSpec` can also be created using explicit
inheritance from :class:`Generic`. In this case, ``**`` is not used::

   from typing import ParamSpec, Generic

   P = ParamSpec('P')

   class Z(Generic[P]):
       ...

Another difference between :class:`TypeVar` and :class:`ParamSpec` is that a
generic with only one parameter specification variable will accept
parameter lists in the forms ``X[[Type1, Type2, ...]]`` and also
``X[Type1, Type2, ...]`` for aesthetic reasons.  Internally, the latter is converted
to the former, so the following are equivalent::

   >>> class X[**P]: ...
   ...
   >>> X[int, str]
   __main__.X[[int, str]]
   >>> X[[int, str]]
   __main__.X[[int, str]]

Note that generics with :class:`ParamSpec` may not have correct
``__parameters__`` after substitution in some cases because they
are intended primarily for static type checking.

.. versionchanged:: 3.10
   :class:`Generic` can now be parameterized over parameter expressions.
   See :class:`ParamSpec` and :pep:`612` for more details.

A user-defined generic class can have ABCs as base classes without a metaclass
conflict. Generic metaclasses are not supported. The outcome of parameterizing
generics is cached, and most types in the :mod:`!typing` module are :term:`hashable` and
comparable for equality.


The :data:`Any` type
====================

A special kind of type is :data:`Any`. A static type checker will treat
every type as being compatible with :data:`Any` and :data:`Any` as being
compatible with every type.

This means that it is possible to perform any operation or method call on a
value of type :data:`Any` and assign it to any variable::

   from typing import Any

   a: Any = None
   a = []          # OK
   a = 2           # OK

   s: str = ''
   s = a           # OK

   def foo(item: Any) -> int:
       # Passes type checking; 'item' could be any type,
       # and that type might have a 'bar' method
       item.bar()
       ...

Notice that no type checking is performed when assigning a value of type
:data:`Any` to a more precise type. For example, the static type checker did
not report an error when assigning ``a`` to ``s`` even though ``s`` was
declared to be of type :class:`str` and receives an :class:`int` value at
runtime!

Furthermore, all functions without a return type or parameter types will
implicitly default to using :data:`Any`::

   def legacy_parser(text):
       ...
       return data

   # A static type checker will treat the above
   # as having the same signature as:
   def legacy_parser(text: Any) -> Any:
       ...
       return data

This behavior allows :data:`Any` to be used as an *escape hatch* when you
need to mix dynamically and statically typed code.

Contrast the behavior of :data:`Any` with the behavior of :class:`object`.
Similar to :data:`Any`, every type is a subtype of :class:`object`. However,
unlike :data:`Any`, the reverse is not true: :class:`object` is *not* a
subtype of every other type.

That means when the type of a value is :class:`object`, a type checker will
reject almost all operations on it, and assigning it to a variable (or using
it as a return value) of a more specialized type is a type error. For example::

   def hash_a(item: object) -> int:
       # Fails type checking; an object does not have a 'magic' method.
       item.magic()
       ...

   def hash_b(item: Any) -> int:
       # Passes type checking
       item.magic()
       ...

   # Passes type checking, since ints and strs are subclasses of object
   hash_a(42)
   hash_a("foo")

   # Passes type checking, since Any is compatible with all types
   hash_b(42)
   hash_b("foo")

Use :class:`object` to indicate that a value could be any type in a typesafe
manner. Use :data:`Any` to indicate that a value is dynamically typed.


Nominal vs structural subtyping
===============================

Initially :pep:`484` defined the Python static type system as using
*nominal subtyping*. This means that a class ``A`` is allowed where
a class ``B`` is expected if and only if ``A`` is a subclass of ``B``.

This requirement previously also applied to abstract base classes, such as
:class:`~collections.abc.Iterable`. The problem with this approach is that a class had
to be explicitly marked to support them, which is unpythonic and unlike
what one would normally do in idiomatic dynamically typed Python code.
For example, this conforms to :pep:`484`::

   from collections.abc import Sized, Iterable, Iterator

   class Bucket(Sized, Iterable[int]):
       ...
       def __len__(self) -> int: ...
       def __iter__(self) -> Iterator[int]: ...

:pep:`544` solves this problem by allowing users to write
the above code without explicit base classes in the class definition,
allowing ``Bucket`` to be implicitly considered a subtype of both ``Sized``
and ``Iterable[int]`` by static type checkers. This is known as
*structural subtyping* (or static duck-typing)::

   from collections.abc import Iterator, Iterable

   class Bucket:  # Note: no base classes
       ...
       def __len__(self) -> int: ...
       def __iter__(self) -> Iterator[int]: ...

   def collect(items: Iterable[int]) -> int: ...
   result = collect(Bucket())  # Passes type check

Moreover, by subclassing a special class :class:`Protocol`, a user
can define new custom protocols to fully enjoy structural subtyping
(see examples below).

Module contents
===============

The ``typing`` module defines the following classes, functions and decorators.

Special typing primitives
-------------------------

Special types
"""""""""""""

These can be used as types in annotations. They do not support subscription
using ``[]``.

.. data:: Any

   Special type indicating an unconstrained type.

   * Every type is compatible with :data:`Any`.
   * :data:`Any` is compatible with every type.

   .. versionchanged:: 3.11
      :data:`Any` can now be used as a base class. This can be useful for
      avoiding type checker errors with classes that can duck type anywhere or
      are highly dynamic.

.. data:: AnyStr

   A :ref:`constrained type variable <typing-constrained-typevar>`.

   Definition::

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

   ``AnyStr`` is meant to be used for functions that may accept :class:`str` or
   :class:`bytes` arguments but cannot allow the two to mix.

   For example::

      def concat(a: AnyStr, b: AnyStr) -> AnyStr:
          return a + b

      concat("foo", "bar")    # OK, output has type 'str'
      concat(b"foo", b"bar")  # OK, output has type 'bytes'
      concat("foo", b"bar")   # Error, cannot mix str and bytes

   Note that, despite its name, ``AnyStr`` has nothing to do with the
   :class:`Any` type, nor does it mean "any string". In particular, ``AnyStr``
   and ``str | bytes`` are different from each other and have different use
   cases::

      # Invalid use of AnyStr:
      # The type variable is used only once in the function signature,
      # so cannot be "solved" by the type checker
      def greet_bad(cond: bool) -> AnyStr:
          return "hi there!" if cond else b"greetings!"

      # The better way of annotating this function:
      def greet_proper(cond: bool) -> str | bytes:
          return "hi there!" if cond else b"greetings!"

   .. deprecated-removed:: 3.13 3.18
      Deprecated in favor of the new :ref:`type parameter syntax <type-params>`.
      Use ``class A[T: (str, bytes)]: ...`` instead of importing ``AnyStr``. See
      :pep:`695` for more details.

      In Python 3.16, ``AnyStr`` will be removed from ``typing.__all__``, and
      deprecation warnings will be emitted at runtime when it is accessed or
      imported from ``typing``. ``AnyStr`` will be removed from ``typing``
      in Python 3.18.

.. data:: LiteralString

   Special type that includes only literal strings.

   Any string
   literal is compatible with ``LiteralString``, as is another
   ``LiteralString``. However, an object typed as just ``str`` is not.
   A string created by composing ``LiteralString``-typed objects
   is also acceptable as a ``LiteralString``.

   Example:

   .. testcode::

      def run_query(sql: LiteralString) -> None:
          ...

      def caller(arbitrary_string: str, literal_string: LiteralString) -> None:
          run_query("SELECT * FROM students")  # OK
          run_query(literal_string)  # OK
          run_query("SELECT * FROM " + literal_string)  # OK
          run_query(arbitrary_string)  # type checker error
          run_query(  # type checker error
              f"SELECT * FROM students WHERE name = {arbitrary_string}"
          )

   ``LiteralString`` is useful for sensitive APIs where arbitrary user-generated
   strings could generate problems. For example, the two cases above
   that generate type checker errors could be vulnerable to an SQL
   injection attack.

   See :pep:`675` for more details.

   .. versionadded:: 3.11

.. data:: Never
          NoReturn

   :data:`!Never` and :data:`!NoReturn` represent the
   `bottom type <https://en.wikipedia.org/wiki/Bottom_type>`_,
   a type that has no members.

   They can be used to indicate that a function never returns,
   such as :func:`sys.exit`::

      from typing import Never  # or NoReturn

      def stop() -> Never:
          raise RuntimeError('no way')

   Or to define a function that should never be
   called, as there are no valid arguments, such as
   :func:`assert_never`::

      from typing import Never  # or NoReturn

      def never_call_me(arg: Never) -> None:
          pass

      def int_or_str(arg: int | str) -> None:
          never_call_me(arg)  # type checker error
          match arg:
              case int():
                  print("It's an int")
              case str():
                  print("It's a str")
              case _:
                  never_call_me(arg)  # OK, arg is of type Never (or NoReturn)

   :data:`!Never` and :data:`!NoReturn` have the same meaning in the type system
   and static type checkers treat both equivalently.

   .. versionadded:: 3.6.2

      Added :data:`NoReturn`.

   .. versionadded:: 3.11

      Added :data:`Never`.

.. data:: Self

   Special type to represent the current enclosed class.

   For example::

      from typing import Self, reveal_type

      class Foo:
          def return_self(self) -> Self:
              ...
              return self

      class SubclassOfFoo(Foo): pass

      reveal_type(Foo().return_self())  # Revealed type is "Foo"
      reveal_type(SubclassOfFoo().return_self())  # Revealed type is "SubclassOfFoo"

   This annotation is semantically equivalent to the following,
   albeit in a more succinct fashion::

      from typing import TypeVar

      Self = TypeVar("Self", bound="Foo")

      class Foo:
          def return_self(self: Self) -> Self:
              ...
              return self

   In general, if something returns ``self``, as in the above examples, you
   should use ``Self`` as the return annotation. If ``Foo.return_self`` was
   annotated as returning ``"Foo"``, then the type checker would infer the
   object returned from ``SubclassOfFoo.return_self`` as being of type ``Foo``
   rather than ``SubclassOfFoo``.

   Other common use cases include:

   - :class:`classmethod`\s that are used as alternative constructors and return instances
     of the ``cls`` parameter.
   - Annotating an :meth:`~object.__enter__` method which returns self.

   You should not use ``Self`` as the return annotation if the method is not
   guaranteed to return an instance of a subclass when the class is
   subclassed::

      class Eggs:
          # Self would be an incorrect return annotation here,
          # as the object returned is always an instance of Eggs,
          # even in subclasses
          def returns_eggs(self) -> "Eggs":
              return Eggs()

   See :pep:`673` for more details.

   .. versionadded:: 3.11

.. data:: TypeAlias

   Special annotation for explicitly declaring a :ref:`type alias <type-aliases>`.

   For example::

      from typing import TypeAlias

      Factors: TypeAlias = list[int]

   ``TypeAlias`` is particularly useful on older Python versions for annotating
   aliases that make use of forward references, as it can be hard for type
   checkers to distinguish these from normal variable assignments:

   .. testcode::

      from typing import Generic, TypeAlias, TypeVar

      T = TypeVar("T")

      # "Box" does not exist yet,
      # so we have to use quotes for the forward reference on Python <3.12.
      # Using ``TypeAlias`` tells the type checker that this is a type alias declaration,
      # not a variable assignment to a string.
      BoxOfStrings: TypeAlias = "Box[str]"

      class Box(Generic[T]):
          @classmethod
          def make_box_of_strings(cls) -> BoxOfStrings: ...

   See :pep:`613` for more details.

   .. versionadded:: 3.10

   .. deprecated:: 3.12
      :data:`TypeAlias` is deprecated in favor of the :keyword:`type` statement,
      which creates instances of :class:`TypeAliasType`
      and which natively supports forward references.
      Note that while :data:`TypeAlias` and :class:`TypeAliasType` serve
      similar purposes and have similar names, they are distinct and the
      latter is not the type of the former.
      Removal of :data:`TypeAlias` is not currently planned, but users
      are encouraged to migrate to :keyword:`type` statements.

Special forms
"""""""""""""

These can be used as types in annotations. They all support subscription using
``[]``, but each has a unique syntax.

.. class:: Union

   Union type; ``Union[X, Y]`` is equivalent to ``X | Y`` and means either X or Y.

   To define a union, use e.g. ``Union[int, str]`` or the shorthand ``int | str``. Using that shorthand is recommended. Details:

   * The arguments must be types and there must be at least one.

   * Unions of unions are flattened, e.g.::

       Union[Union[int, str], float] == Union[int, str, float]

     However, this does not apply to unions referenced through a type
     alias, to avoid forcing evaluation of the underlying :class:`TypeAliasType`::

       type A = Union[int, str]
       Union[A, float] != Union[int, str, float]

   * Unions of a single argument vanish, e.g.::

       Union[int] == int  # The constructor actually returns int

   * Redundant arguments are skipped, e.g.::

       Union[int, str, int] == Union[int, str] == int | str

   * When comparing unions, the argument order is ignored, e.g.::

       Union[int, str] == Union[str, int]

   * You cannot subclass or instantiate a ``Union``.

   * You cannot write ``Union[X][Y]``.

   .. versionchanged:: 3.7
      Don't remove explicit subclasses from unions at runtime.

   .. versionchanged:: 3.10
      Unions can now be written as ``X | Y``. See
      :ref:`union type expressions<types-union>`.

   .. versionchanged:: 3.14
      :class:`types.UnionType` is now an alias for :class:`Union`, and both
      ``Union[int, str]`` and ``int | str`` create instances of the same class.
      To check whether an object is a ``Union`` at runtime, use
      ``isinstance(obj, Union)``. For compatibility with earlier versions of
      Python, use
      ``get_origin(obj) is typing.Union or get_origin(obj) is types.UnionType``.

.. data:: Optional

   ``Optional[X]`` is equivalent to ``X | None`` (or ``Union[X, None]``).

   Note that this is not the same concept as an optional argument,
   which is one that has a default.  An optional argument with a
   default does not require the ``Optional`` qualifier on its type
   annotation just because it is optional. For example::

      def foo(arg: int = 0) -> None:
          ...

   On the other hand, if an explicit value of ``None`` is allowed, the
   use of ``Optional`` is appropriate, whether the argument is optional
   or not. For example::

      def foo(arg: Optional[int] = None) -> None:
          ...

   .. versionchanged:: 3.10
      Optional can now be written as ``X | None``. See
      :ref:`union type expressions<types-union>`.

.. data:: Concatenate

   Special form for annotating higher-order functions.

   .. index:: single: ...; ellipsis literal

   ``Concatenate`` can be used in conjunction with :ref:`Callable <annotating-callables>` and
   :class:`ParamSpec` to annotate a higher-order callable which adds, removes,
   or transforms parameters of another
   callable.  Usage is in the form
   ``Concatenate[Arg1Type, Arg2Type, ..., ParamSpecVariable]``. ``Concatenate``
   is currently only valid when used as the first argument to a :ref:`Callable <annotating-callables>`.
   The last parameter to ``Concatenate`` must be a :class:`ParamSpec` or
   ellipsis (``...``).

   For example, to annotate a decorator ``with_lock`` which provides a
   :class:`threading.Lock` to the decorated function,  ``Concatenate`` can be
   used to indicate that ``with_lock`` expects a callable which takes in a
   ``Lock`` as the first argument, and returns a callable with a different type
   signature.  In this case, the :class:`ParamSpec` indicates that the returned
   callable's parameter types are dependent on the parameter types of the
   callable being passed in::

      from collections.abc import Callable
      from threading import Lock
      from typing import Concatenate

      # Use this lock to ensure that only one thread is executing a function
      # at any time.
      my_lock = Lock()

      def with_lock[**P, R](f: Callable[Concatenate[Lock, P], R]) -> Callable[P, R]:
          '''A type-safe decorator which provides a lock.'''
          def inner(*args: P.args, **kwargs: P.kwargs) -> R:
              # Provide the lock as the first argument.
              return f(my_lock, *args, **kwargs)
          return inner

      @with_lock
      def sum_threadsafe(lock: Lock, numbers: list[float]) -> float:
          '''Add a list of numbers together in a thread-safe manner.'''
          with lock:
              return sum(numbers)

      # We don't need to pass in the lock ourselves thanks to the decorator.
      sum_threadsafe([1.1, 2.2, 3.3])

   .. versionadded:: 3.10

   .. seealso::

      * :pep:`612` -- Parameter Specification Variables (the PEP which introduced
        ``ParamSpec`` and ``Concatenate``)
      * :class:`ParamSpec`
      * :ref:`annotating-callables`

.. data:: Literal

   Special typing form to define "literal types".

   ``Literal`` can be used to indicate to type checkers that the
   annotated object has a value equivalent to one of the
   provided literals.

   For example::

      def validate_simple(data: Any) -> Literal[True]:  # always returns True
          ...

      type Mode = Literal['r', 'rb', 'w', 'wb']
      def open_helper(file: str, mode: Mode) -> str:
          ...

      open_helper('/some/path', 'r')      # Passes type check
      open_helper('/other/path', 'typo')  # Error in type checker

   ``Literal[...]`` cannot be subclassed. At runtime, an arbitrary value
   is allowed as type argument to ``Literal[...]``, but type checkers may
   impose restrictions. See :pep:`586` for more details about literal types.

   Additional details:

   * The arguments must be literal values and there must be at least one.

   * Nested ``Literal`` types are flattened, e.g.::

      assert Literal[Literal[1, 2], 3] == Literal[1, 2, 3]

     However, this does not apply to ``Literal`` types referenced through a type
     alias, to avoid forcing evaluation of the underlying :class:`TypeAliasType`::

      type A = Literal[1, 2]
      assert Literal[A, 3] != Literal[1, 2, 3]

   * Redundant arguments are skipped, e.g.::

      assert Literal[1, 2, 1] == Literal[1, 2]

   * When comparing literals, the argument order is ignored, e.g.::

      assert Literal[1, 2] == Literal[2, 1]

   * You cannot subclass or instantiate a ``Literal``.

   * You cannot write ``Literal[X][Y]``.

   .. versionadded:: 3.8

   .. versionchanged:: 3.9.1
      ``Literal`` now de-duplicates parameters.  Equality comparisons of
      ``Literal`` objects are no longer order dependent. ``Literal`` objects
      will now raise a :exc:`TypeError` exception during equality comparisons
      if one of their parameters are not :term:`hashable`.

.. data:: ClassVar

   Special type construct to mark class variables.

   As introduced in :pep:`526`, a variable annotation wrapped in ClassVar
   indicates that a given attribute is intended to be used as a class variable
   and should not be set on instances of that class. Usage::

      class Starship:
          stats: ClassVar[dict[str, int]] = {} # class variable
          damage: int = 10                     # instance variable

   :data:`ClassVar` accepts only types and cannot be further subscribed.

   :data:`ClassVar` is not a class itself, and should not
   be used with :func:`isinstance` or :func:`issubclass`.
   :data:`ClassVar` does not change Python runtime behavior, but
   it can be used by third-party type checkers. For example, a type checker
   might flag the following code as an error::

      enterprise_d = Starship(3000)
      enterprise_d.stats = {} # Error, setting class variable on instance
      Starship.stats = {}     # This is OK

   .. versionadded:: 3.5.3

   .. versionchanged:: 3.13

      :data:`ClassVar` can now be nested in :data:`Final` and vice versa.

.. data:: Final

   Special typing construct to indicate final names to type checkers.

   Final names cannot be reassigned in any scope. Final names declared in class
   scopes cannot be overridden in subclasses.

   For example::

      MAX_SIZE: Final = 9000
      MAX_SIZE += 1  # Error reported by type checker

      class Connection:
          TIMEOUT: Final[int] = 10

      class FastConnector(Connection):
          TIMEOUT = 1  # Error reported by type checker

   There is no runtime checking of these properties. See :pep:`591` for
   more details.

   .. versionadded:: 3.8

   .. versionchanged:: 3.13

      :data:`Final` can now be nested in :data:`ClassVar` and vice versa.

.. data:: Required

   Special typing construct to mark a :class:`TypedDict` key as required.

   This is mainly useful for ``total=False`` TypedDicts. See :class:`TypedDict`
   and :pep:`655` for more details.

   .. versionadded:: 3.11

.. data:: NotRequired

   Special typing construct to mark a :class:`TypedDict` key as potentially
   missing.

   See :class:`TypedDict` and :pep:`655` for more details.

   .. versionadded:: 3.11

.. data:: ReadOnly

   A special typing construct to mark an item of a :class:`TypedDict` as read-only.

   For example::

      class Movie(TypedDict):
         title: ReadOnly[str]
         year: int

      def mutate_movie(m: Movie) -> None:
         m["year"] = 1999  # allowed
         m["title"] = "The Matrix"  # typechecker error

   There is no runtime checking for this property.

   See :class:`TypedDict` and :pep:`705` for more details.

   .. versionadded:: 3.13

.. data:: Annotated

   Special typing form to add context-specific metadata to an annotation.

   Add metadata ``x`` to a given type ``T`` by using the annotation
   ``Annotated[T, x]``. Metadata added using ``Annotated`` can be used by
   static analysis tools or at runtime. At runtime, the metadata is stored
   in a :attr:`!__metadata__` attribute.

   If a library or tool encounters an annotation ``Annotated[T, x]`` and has
   no special logic for the metadata, it should ignore the metadata and simply
   treat the annotation as ``T``. As such, ``Annotated`` can be useful for code
   that wants to use annotations for purposes outside Python's static typing
   system.

   Using ``Annotated[T, x]`` as an annotation still allows for static
   typechecking of ``T``, as type checkers will simply ignore the metadata ``x``.
   In this way, ``Annotated`` differs from the
   :deco:`no_type_check` decorator, which can also be used for
   adding annotations outside the scope of the typing system, but
   completely disables typechecking for a function or class.

   The responsibility of how to interpret the metadata
   lies with the tool or library encountering an
   ``Annotated`` annotation. A tool or library encountering an ``Annotated`` type
   can scan through the metadata elements to determine if they are of interest
   (e.g., using :func:`isinstance`).

   .. describe:: Annotated[<type>, <metadata>]

   Here is an example of how you might use ``Annotated`` to add metadata to
   type annotations if you were doing range analysis:

   .. testcode::

      @dataclass
      class ValueRange:
          lo: int
          hi: int

      T1 = Annotated[int, ValueRange(-10, 5)]
      T2 = Annotated[T1, ValueRange(-20, 3)]

   The first argument to ``Annotated`` must be a valid type. Multiple metadata
   elements can be supplied as ``Annotated`` supports variadic arguments. The
   order of the metadata elements is preserved and matters for equality checks::

      @dataclass
      class ctype:
           kind: str

      a1 = Annotated[int, ValueRange(3, 10), ctype("char")]
      a2 = Annotated[int, ctype("char"), ValueRange(3, 10)]

      assert a1 != a2  # Order matters

   It is up to the tool consuming the annotations to decide whether the
   client is allowed to add multiple metadata elements to one annotation and how to
   merge those annotations.

   Nested ``Annotated`` types are flattened. The order of the metadata elements
   starts with the innermost annotation::

      assert Annotated[Annotated[int, ValueRange(3, 10)], ctype("char")] == Annotated[
          int, ValueRange(3, 10), ctype("char")
      ]

   However, this does not apply to ``Annotated`` types referenced through a type
   alias, to avoid forcing evaluation of the underlying :class:`TypeAliasType`::

      type From3To10[T] = Annotated[T, ValueRange(3, 10)]
      assert Annotated[From3To10[int], ctype("char")] != Annotated[
         int, ValueRange(3, 10), ctype("char")
      ]

   Duplicated metadata elements are not removed::

      assert Annotated[int, ValueRange(3, 10)] != Annotated[
          int, ValueRange(3, 10), ValueRange(3, 10)
      ]

   ``Annotated`` can be used with nested and generic aliases:

     .. testcode::

        @dataclass
        class MaxLen:
            value: int

        type Vec[T] = Annotated[list[tuple[T, T]], MaxLen(10)]

        # When used in a type annotation, a type checker will treat "V" the same as
        # ``Annotated[list[tuple[int, int]], MaxLen(10)]``:
        type V = Vec[int]

   ``Annotated`` cannot be used with an unpacked :class:`TypeVarTuple`::

        type Variadic[*Ts] = Annotated[*Ts, Ann1] = Annotated[T1, T2, T3, ..., Ann1]  # NOT valid

   where ``T1``, ``T2``, ... are :class:`TypeVars <TypeVar>`. This is invalid as
   only one type should be passed to Annotated.

   By default, :func:`get_type_hints` strips the metadata from annotations.
   Pass ``include_extras=True`` to have the metadata preserved:

     .. doctest::

        >>> from typing import Annotated, get_type_hints
        >>> def func(x: Annotated[int, "metadata"]) -> None: pass
        ...
        >>> get_type_hints(func)
        {'x': <class 'int'>, 'return': <class 'NoneType'>}
        >>> get_type_hints(func, include_extras=True)
        {'x': typing.Annotated[int, 'metadata'], 'return': <class 'NoneType'>}

   At runtime, the metadata associated with an ``Annotated`` type can be
   retrieved via the :attr:`!__metadata__` attribute:

     .. doctest::

        >>> from typing import Annotated
        >>> X = Annotated[int, "very", "important", "metadata"]
        >>> X
        typing.Annotated[int, 'very', 'important', 'metadata']
        >>> X.__metadata__
        ('very', 'important', 'metadata')

   If you want to retrieve the original type wrapped by ``Annotated``, use the
   :attr:`!__origin__` attribute:

     .. doctest::

        >>> from typing import Annotated, get_origin
        >>> Password = Annotated[str, "secret"]
        >>> Password.__origin__
        <class 'str'>

   Note that using :func:`get_origin` will return ``Annotated`` itself:

     .. doctest::

        >>> get_origin(Password)
        typing.Annotated

   .. seealso::

      :pep:`593` - Flexible function and variable annotations
         The PEP introducing ``Annotated`` to the standard library.

   .. versionadded:: 3.9


.. data:: TypeForm

   A special form representing the value that results from evaluating a
   type expression.

   This value encodes the information supplied in the type expression, and
   it represents the type described by that type expression.

   When used in a type expression, ``TypeForm`` describes a set of type form
   objects. It accepts a single type argument, which must be a valid type
   expression. ``TypeForm[T]`` describes the set of all type form objects that
   represent the type ``T`` or types assignable to ``T``.

   ``TypeForm(obj)`` simply returns ``obj`` unchanged. This is useful for
   explicitly marking a value as a type form for static type checkers.

   Example::

      from typing import Any, TypeForm

      def cast[T](typ: TypeForm[T], value: Any) -> T: ...

      reveal_type(cast(int, "x"))  # Revealed type is "int"

   See :pep:`747` for details.

   .. versionadded:: 3.15


.. data:: TypeIs

   Special typing construct for marking user-defined type predicate functions.

   ``TypeIs`` can be used to annotate the return type of a user-defined
   type predicate function.  ``TypeIs`` only accepts a single type argument.
   At runtime, functions marked this way should return a boolean and take at
   least one positional argument.

   ``TypeIs`` 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 predicate"::

      def is_str(val: str | float):
          # "isinstance" type predicate
          if isinstance(val, str):
              # Type of ``val`` is narrowed to ``str``
              ...
          else:
              # Else, type of ``val`` is narrowed to ``float``.
              ...

   Sometimes it would be convenient to use a user-defined boolean function
   as a type predicate.  Such a function should use ``TypeIs[...]`` or
   :data:`TypeGuard` as its return type to alert static type checkers to
   this intention.  ``TypeIs`` usually has more intuitive behavior than
   ``TypeGuard``, but it cannot be used when the input and output types
   are incompatible (e.g., ``list[object]`` to ``list[int]``) or when the
   function does not return ``True`` for all instances of the narrowed type.

   Using  ``-> TypeIs[NarrowedType]`` 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 intersection of the argument's original type and ``NarrowedType``.
   3. If the return value is ``False``, the type of its argument
      is narrowed to exclude ``NarrowedType``.

   For example::

        from typing import assert_type, final, TypeIs

        class Parent: pass
        class Child(Parent): pass
        @final
        class Unrelated: pass

        def is_parent(val: object) -> TypeIs[Parent]:
            return isinstance(val, Parent)

        def run(arg: Child | Unrelated):
            if is_parent(arg):
                # Type of ``arg`` is narrowed to the intersection
                # of ``Parent`` and ``Child``, which is equivalent to
                # ``Child``.
                assert_type(arg, Child)
            else:
                # Type of ``arg`` is narrowed to exclude ``Parent``,
                # so only ``Unrelated`` is left.
                assert_type(arg, Unrelated)

   The type inside ``TypeIs`` must be consistent with the type of the
   function's argument; if it is not, static type checkers will raise
   an error.  An incorrectly written ``TypeIs`` function can lead to
   unsound behavior in the type system; it is the user's responsibility
   to write such functions in a type-safe manner.

   If a ``TypeIs`` function is a class or instance method, then the type in
   ``TypeIs`` maps to the type of the second parameter (after ``cls`` or
   ``self``).

   In short, the form ``def foo(arg: TypeA) -> TypeIs[TypeB]: ...``,
   means that if ``foo(arg)`` returns ``True``, then ``arg`` is an instance
   of ``TypeB``, and if it returns ``False``, it is not an instance of ``TypeB``.

   ``TypeIs`` also works with type variables.  For more information, see
   :pep:`742` (Narrowing types with ``TypeIs``).

   .. versionadded:: 3.13


.. data:: TypeGuard

   Special typing construct for marking user-defined type predicate functions.

   Type predicate functions are user-defined functions that return whether their
   argument is an instance of a particular type.
   ``TypeGuard`` works similarly to :data:`TypeIs`, but has subtly different
   effects on type checking behavior (see below).

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

   ``TypeGuard`` also works with type variables.  See :pep:`647` for more details.

   For example::

         def is_str_list(val: list[object]) -> TypeGuard[list[str]]:
             '''Determines whether all objects in the list are strings'''
             return all(isinstance(x, str) for x in val)

         def func1(val: list[object]):
             if is_str_list(val):
                 # Type of ``val`` is narrowed to ``list[str]``.
                 print(" ".join(val))
             else:
                 # Type of ``val`` remains as ``list[object]``.
                 print("Not a list of strings!")

   ``TypeIs`` and ``TypeGuard`` differ in the following ways:

   * ``TypeIs`` requires the narrowed type to be a subtype of the input type, while
     ``TypeGuard`` does not.  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.
   * When a ``TypeGuard`` function returns ``True``, type checkers narrow the type of the
     variable to exactly the ``TypeGuard`` type. When a ``TypeIs`` function returns ``True``,
     type checkers can infer a more precise type combining the previously known type of the
     variable with the ``TypeIs`` type. (Technically, this is known as an intersection type.)
   * When a ``TypeGuard`` function returns ``False``, type checkers cannot narrow the type of
     the variable at all. When a ``TypeIs`` function returns ``False``, type checkers can narrow
     the type of the variable to exclude the ``TypeIs`` type.

   .. versionadded:: 3.10


.. data:: Unpack

   Typing operator to conceptually mark an object as having been unpacked.

   For example, using the unpack operator ``*`` on a
   :ref:`type variable tuple <typevartuple>` is equivalent to using ``Unpack``
   to mark the type variable tuple as having been unpacked::

      Ts = TypeVarTuple('Ts')
      tup: tuple[*Ts]
      # Effectively does:
      tup: tuple[Unpack[Ts]]

   In fact, ``Unpack`` can be used interchangeably with ``*`` in the context
   of :class:`typing.TypeVarTuple <TypeVarTuple>` and
   :class:`builtins.tuple <tuple>` types. You might see ``Unpack`` being used
   explicitly in older versions of Python, where ``*`` couldn't be used in
   certain places::

      # In older versions of Python, TypeVarTuple and Unpack
      # are located in the `typing_extensions` backports package.
      from typing_extensions import TypeVarTuple, Unpack

      Ts = TypeVarTuple('Ts')
      tup: tuple[*Ts]         # Syntax error on Python <= 3.10!
      tup: tuple[Unpack[Ts]]  # Semantically equivalent, and backwards-compatible

   ``Unpack`` can also be used along with :class:`typing.TypedDict` for typing
   ``**kwargs`` in a function signature::

      from typing import TypedDict, Unpack

      class Movie(TypedDict):
          name: str
          year: int

      # This function expects two keyword arguments - `name` of type `str`
      # and `year` of type `int`.
      def foo(**kwargs: Unpack[Movie]): ...

   See :pep:`692` for more details on using ``Unpack`` for ``**kwargs`` typing.

   .. versionadded:: 3.11

Building generic types and type aliases
"""""""""""""""""""""""""""""""""""""""

The following classes should not be used directly as annotations.
Their intended purpose is to be building blocks
for creating generic types and type aliases.

These objects can be created through special syntax
(:ref:`type parameter lists <type-params>` and the :keyword:`type` statement).
For compatibility with Python 3.11 and earlier, they can also be created
without the dedicated syntax, as documented below.

.. class:: Generic

   Abstract base class for generic types.

   A generic type is typically declared by adding a list of type parameters
   after the class name::

      class Mapping[KT, VT]:
          def __getitem__(self, key: KT) -> VT:
              ...
              # Etc.

   Such a class implicitly inherits from ``Generic``.
   The runtime semantics of this syntax are discussed in the
   :ref:`Language Reference <generic-classes>`.

   This class can then be used as follows::

      def lookup_name[X, Y](mapping: Mapping[X, Y], key: X, default: Y) -> Y:
          try:
              return mapping[key]
          except KeyError:
              return default

   Here the brackets after the function name indicate a
   :ref:`generic function <generic-functions>`.

   For backwards compatibility, generic classes can also be
   declared by explicitly inheriting from
   ``Generic``. In this case, the type parameters must be declared
   separately::

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

      class Mapping(Generic[KT, VT]):
          def __getitem__(self, key: KT) -> VT:
              ...
              # Etc.

.. _typevar:

.. class:: TypeVar(name, *constraints, bound=None, covariant=False, contravariant=False, infer_variance=False, default=typing.NoDefault)

   Type variable.

   The preferred way to construct a type variable is via the dedicated syntax
   for :ref:`generic functions <generic-functions>`,
   :ref:`generic classes <generic-classes>`, and
   :ref:`generic type aliases <generic-type-aliases>`::

      class Sequence[T]:  # T is a TypeVar
          ...

   This syntax can also be used to create bounded and constrained type
   variables::

      class StrSequence[S: str]:  # S is a TypeVar with a `str` upper bound;
          ...                     # we can say that S is "bounded by `str`"


      class StrOrBytesSequence[A: (str, bytes)]:  # A is a TypeVar constrained to str or bytes
          ...

   However, if desired, reusable type variables can also be constructed manually, like so::

      T = TypeVar('T')  # Can be anything
      S = TypeVar('S', bound=str)  # Can be any subtype of str
      A = TypeVar('A', str, bytes)  # Must be exactly str or bytes

   Type variables exist primarily for the benefit of static type
   checkers.  They serve as the parameters for generic types as well
   as for generic function and type alias definitions.
   See :class:`Generic` for more
   information on generic types.  Generic functions work as follows::

      def repeat[T](x: T, n: int) -> Sequence[T]:
          """Return a list containing n references to x."""
          return [x]*n


      def print_capitalized[S: str](x: S) -> S:
          """Print x capitalized, and return x."""
          print(x.capitalize())
          return x


      def concatenate[A: (str, bytes)](x: A, y: A) -> A:
          """Add two strings or bytes objects together."""
          return x + y

   Note that type variables can be *bounded*, *constrained*, or neither, but
   cannot be both bounded *and* constrained.

   The variance of type variables is inferred by type checkers when they are created
   through the :ref:`type parameter syntax <type-params>` or when
   ``infer_variance=True`` is passed.
   Manually created type variables may be explicitly marked covariant or contravariant by passing
   ``covariant=True`` or ``contravariant=True``.
   By default, manually created type variables are invariant.
   See :pep:`484` and :pep:`695` for more details.

   Bounded type variables and constrained type variables have different
   semantics in several important ways. Using a *bounded* type variable means
   that the ``TypeVar`` will be solved using the most specific type possible::

      x = print_capitalized('a string')
      reveal_type(x)  # revealed type is str

      class StringSubclass(str):
          pass

      y = print_capitalized(StringSubclass('another string'))
      reveal_type(y)  # revealed type is StringSubclass

      z = print_capitalized(45)  # error: int is not a subtype of str

   The upper bound of a type variable can be a concrete type, abstract type
   (ABC or Protocol), or even a union of types::

      # Can be anything with an __abs__ method
      def print_abs[T: SupportsAbs](arg: T) -> None:
          print("Absolute value:", abs(arg))

      U = TypeVar('U', bound=str|bytes)  # Can be any subtype of the union str|bytes
      V = TypeVar('V', bound=SupportsAbs)  # Can be anything with an __abs__ method

   .. _typing-constrained-typevar:

   Using a *constrained* type variable, however, means that the ``TypeVar``
   can only ever be solved as being exactly one of the constraints given::

      a = concatenate('one', 'two')
      reveal_type(a)  # revealed type is str

      b = concatenate(StringSubclass('one'), StringSubclass('two'))
      reveal_type(b)  # revealed type is str, despite StringSubclass being passed in

      c = concatenate('one', b'two')  # error: type variable 'A' can be either str or bytes in a function call, but not both

   At runtime, ``isinstance(x, T)`` will raise :exc:`TypeError`.

   .. attribute:: __name__

      The name of the type variable.

   .. attribute:: __covariant__

      Whether the type var has been explicitly marked as covariant.

   .. attribute:: __contravariant__

      Whether the type var has been explicitly marked as contravariant.

   .. attribute:: __infer_variance__

      Whether the type variable's variance should be inferred by type checkers.

      .. versionadded:: 3.12

   .. attribute:: __bound__

      The upper bound of the type variable, if any.

      .. versionchanged:: 3.12

         For type variables created through :ref:`type parameter syntax <type-params>`,
         the bound is evaluated only when the attribute is accessed, not when
         the type variable is created (see :ref:`lazy-evaluation`).

   .. method:: evaluate_bound

      An :term:`evaluate function` corresponding to the :attr:`~TypeVar.__bound__` attribute.
      When called directly, this method supports only the :attr:`~annotationlib.Format.VALUE`
      format, which is equivalent to accessing the :attr:`~TypeVar.__bound__` attribute directly,
      but the method object can be passed to :func:`annotationlib.call_evaluate_function`
      to evaluate the value in a different format.

      .. versionadded:: 3.14

   .. attribute:: __constraints__

      A tuple containing the constraints of the type variable, if any.

      .. versionchanged:: 3.12

         For type variables created through :ref:`type parameter syntax <type-params>`,
         the constraints are evaluated only when the attribute is accessed, not when
         the type variable is created (see :ref:`lazy-evaluation`).

   .. method:: evaluate_constraints

      An :term:`evaluate function` corresponding to the :attr:`~TypeVar.__constraints__` attribute.
      When called directly, this method supports only the :attr:`~annotationlib.Format.VALUE`
      format, which is equivalent to accessing the :attr:`~TypeVar.__constraints__` attribute directly,
      but the method object can be passed to :func:`annotationlib.call_evaluate_function`
      to evaluate the value in a different format.

      .. versionadded:: 3.14

   .. attribute:: __default__

      The default value of the type variable, or :data:`typing.NoDefault` if it
      has no default.

      .. versionadded:: 3.13

   .. method:: evaluate_default

      An :term:`evaluate function` corresponding to the :attr:`~TypeVar.__default__` attribute.
      When called directly, this method supports only the :attr:`~annotationlib.Format.VALUE`
      format, which is equivalent to accessing the :attr:`~TypeVar.__default__` attribute directly,
      but the method object can be passed to :func:`annotationlib.call_evaluate_function`
      to evaluate the value in a different format.

      .. versionadded:: 3.14

   .. method:: has_default()

      Return whether or not the type variable has a default value. This is equivalent
      to checking whether :attr:`__default__` is not the :data:`typing.NoDefault`
      singleton, except that it does not force evaluation of the
      :ref:`lazily evaluated <lazy-evaluation>` default value.

      .. versionadded:: 3.13

   .. versionchanged:: 3.12

      Type variables can now be declared using the
      :ref:`type parameter <type-params>` syntax introduced by :pep:`695`.
      The ``infer_variance`` parameter was added.

   .. versionchanged:: 3.13

      Support for default values was added.

.. _typevartuple:

.. class:: TypeVarTuple(name, *, default=typing.NoDefault)

   Type variable tuple. A specialized form of :ref:`type variable <typevar>`
   that enables *variadic* generics.

   Type variable tuples can be declared in :ref:`type parameter lists <type-params>`
   using a single asterisk (``*``) before the name::

      def move_first_element_to_last[T, *Ts](tup: tuple[T, *Ts]) -> tuple[*Ts, T]:
          return (*tup[1:], tup[0])

   Or by explicitly invoking the ``TypeVarTuple`` constructor::

      T = TypeVar("T")
      Ts = TypeVarTuple("Ts")

      def move_first_element_to_last(tup: tuple[T, *Ts]) -> tuple[*Ts, T]:
          return (*tup[1:], tup[0])

   A normal type variable enables parameterization with a single type. A type
   variable tuple, in contrast, allows parameterization with an
   *arbitrary* number of types by acting like an *arbitrary* number of type
   variables wrapped in a tuple. For example::

      # T is bound to int, Ts is bound to ()
      # Return value is (1,), which has type tuple[int]
      move_first_element_to_last(tup=(1,))

      # T is bound to int, Ts is bound to (str,)
      # Return value is ('spam', 1), which has type tuple[str, int]
      move_first_element_to_last(tup=(1, 'spam'))

      # T is bound to int, Ts is bound to (str, float)
      # Return value is ('spam', 3.0, 1), which has type tuple[str, float, int]
      move_first_element_to_last(tup=(1, 'spam', 3.0))

      # This fails to type check (and fails at runtime)
      # because tuple[()] is not compatible with tuple[T, *Ts]
      # (at least one element is required)
      move_first_element_to_last(tup=())

   Note the use of the unpacking operator ``*`` in ``tuple[T, *Ts]``.
   Conceptually, you can think of ``Ts`` as a tuple of type variables
   ``(T1, T2, ...)``. ``tuple[T, *Ts]`` would then become
   ``tuple[T, *(T1, T2, ...)]``, which is equivalent to
   ``tuple[T, T1, T2, ...]``. (Note that in older versions of Python, you might
   see this written using :data:`Unpack <Unpack>` instead, as
   ``Unpack[Ts]``.)

   Type variable tuples must *always* be unpacked. This helps distinguish type
   variable tuples from normal type variables::

      x: Ts          # Not valid
      x: tuple[Ts]   # Not valid
      x: tuple[*Ts]  # The correct way to do it

   Type variable tuples can be used in the same contexts as normal type
   variables. For example, in class definitions, arguments, and return types::

      class Array[*Shape]:
          def __getitem__(self, key: tuple[*Shape]) -> float: ...
          def __abs__(self) -> "Array[*Shape]": ...
          def get_shape(self) -> tuple[*Shape]: ...

   Type variable tuples can be happily combined with normal type variables:

   .. testcode::

      class Array[DType, *Shape]:  # This is fine
          pass

      class Array2[*Shape, DType]:  # This would also be fine
          pass

      class Height: ...
      class Width: ...

      float_array_1d: Array[float, Height] = Array()     # Totally fine
      int_array_2d: Array[int, Height, Width] = Array()  # Yup, fine too

   However, note that at most one type variable tuple may appear in a single
   list of type arguments or type parameters::

      x: tuple[*Ts, *Ts]            # Not valid
      class Array[*Shape, *Shape]:  # Not valid
          pass

   Finally, an unpacked type variable tuple can be used as the type annotation
   of ``*args``::

      def call_soon[*Ts](
          callback: Callable[[*Ts], None],
          *args: *Ts
      ) -> None:
          ...
          callback(*args)

   In contrast to non-unpacked annotations of ``*args`` - e.g. ``*args: int``,
   which would specify that *all* arguments are ``int`` - ``*args: *Ts``
   enables reference to the types of the *individual* arguments in ``*args``.
   Here, this allows us to ensure the types of the ``*args`` passed
   to ``call_soon`` match the types of the (positional) arguments of
   ``callback``.

   See :pep:`646` for more details on type variable tuples.

   .. attribute:: __name__

      The name of the type variable tuple.

   .. attribute:: __default__

      The default value of the type variable tuple, or :data:`typing.NoDefault` if it
      has no default.

      .. versionadded:: 3.13

   .. method:: evaluate_default

      An :term:`evaluate function` corresponding to the :attr:`~TypeVarTuple.__default__` attribute.
      When called directly, this method supports only the :attr:`~annotationlib.Format.VALUE`
      format, which is equivalent to accessing the :attr:`~TypeVarTuple.__default__` attribute directly,
      but the method object can be passed to :func:`annotationlib.call_evaluate_function`
      to evaluate the value in a different format.

      .. versionadded:: 3.14

   .. method:: has_default()

      Return whether or not the type variable tuple has a default value. This is equivalent
      to checking whether :attr:`__default__` is not the :data:`typing.NoDefault`
      singleton, except that it does not force evaluation of the
      :ref:`lazily evaluated <lazy-evaluation>` default value.

      .. versionadded:: 3.13

   .. versionadded:: 3.11

   .. versionchanged:: 3.12

      Type variable tuples can now be declared using the
      :ref:`type parameter <type-params>` syntax introduced by :pep:`695`.

   .. versionchanged:: 3.13

      Support for default values was added.

.. class:: ParamSpec(name, *, bound=None, covariant=False, contravariant=False, default=typing.NoDefault)

   Parameter specification variable.  A specialized version of
   :ref:`type variables <typevar>`.

   In :ref:`type parameter lists <type-params>`, parameter specifications
   can be declared with two asterisks (``**``)::

      type IntFunc[**P] = Callable[P, int]

   For compatibility with Python 3.11 and earlier, ``ParamSpec`` objects
   can also be created as follows::

      P = ParamSpec('P')

   Parameter specification variables exist primarily for the benefit of static
   type checkers.  They are used to forward the parameter types of one
   callable to another callable -- a pattern commonly found in higher order
   functions and decorators.  They are only valid when used in ``Concatenate``,
   or as the first argument to ``Callable``, or as parameters for user-defined
   Generics.  See :class:`Generic` for more information on generic types.

   For example, to add basic logging to a function, one can create a decorator
   ``add_logging`` to log function calls.  The parameter specification variable
   tells the type checker that the callable passed into the decorator and the
   new callable returned by it have inter-dependent type parameters::

      from collections.abc import Callable
      import logging

      def add_logging[T, **P](f: Callable[P, T]) -> Callable[P, T]:
          '''A type-safe decorator to add logging to a function.'''
          def inner(*args: P.args, **kwargs: P.kwargs) -> T:
              logging.info(f'{f.__name__} was called')
              return f(*args, **kwargs)
          return inner

      @add_logging
      def add_two(x: float, y: float) -> float:
          '''Add two numbers together.'''
          return x + y

   Without ``ParamSpec``, the simplest way to annotate this previously was to
   use a :class:`TypeVar` with upper bound ``Callable[..., Any]``.  However this
   causes two problems:

   1. The type checker can't type check the ``inner`` function because
      ``*args`` and ``**kwargs`` have to be typed :data:`Any`.
   2. :func:`~cast` may be required in the body of the ``add_logging``
      decorator when returning the ``inner`` function, or the static type
      checker must be told to ignore the ``return inner``.

   .. attribute:: args
   .. attribute:: kwargs

      Since ``ParamSpec`` captures both positional and keyword parameters,
      ``P.args`` and ``P.kwargs`` can be used to split a ``ParamSpec`` into its
      components.  ``P.args`` represents the tuple of positional parameters in a
      given call and should only be used to annotate ``*args``.  ``P.kwargs``
      represents the mapping of keyword parameters to their values in a given call,
      and should be only be used to annotate ``**kwargs``.  Both
      attributes require the annotated parameter to be in scope. At runtime,
      ``P.args`` and ``P.kwargs`` are instances respectively of
      :class:`ParamSpecArgs` and :class:`ParamSpecKwargs`.

   .. attribute:: __name__

      The name of the parameter specification.

   .. attribute:: __default__

      The default value of the parameter specification, or :data:`typing.NoDefault` if it
      has no default.

      .. versionadded:: 3.13

   .. method:: evaluate_default

      An :term:`evaluate function` corresponding to the :attr:`~ParamSpec.__default__` attribute.
      When called directly, this method supports only the :attr:`~annotationlib.Format.VALUE`
      format, which is equivalent to accessing the :attr:`~ParamSpec.__default__` attribute directly,
      but the method object can be passed to :func:`annotationlib.call_evaluate_function`
      to evaluate the value in a different format.

      .. versionadded:: 3.14

   .. method:: has_default()

      Return whether or not the parameter specification has a default value. This is equivalent
      to checking whether :attr:`__default__` is not the :data:`typing.NoDefault`
      singleton, except that it does not force evaluation of the
      :ref:`lazily evaluated <lazy-evaluation>` default value.

      .. versionadded:: 3.13

   Parameter specification variables created with ``covariant=True`` or
   ``contravariant=True`` can be used to declare covariant or contravariant
   generic types.  The ``bound`` argument is also accepted, similar to
   :class:`TypeVar`.  However the actual semantics of these keywords are yet to
   be decided.

   .. versionadded:: 3.10

   .. versionchanged:: 3.12

      Parameter specifications can now be declared using the
      :ref:`type parameter <type-params>` syntax introduced by :pep:`695`.

   .. versionchanged:: 3.13

      Support for default values was added.

   .. note::
      Only parameter specification variables defined in global scope can
      be pickled.

   .. seealso::
      * :pep:`612` -- Parameter Specification Variables (the PEP which introduced
        ``ParamSpec`` and ``Concatenate``)
      * :data:`Concatenate`
      * :ref:`annotating-callables`

.. data:: ParamSpecArgs
          ParamSpecKwargs

   Arguments and keyword arguments attributes of a :class:`ParamSpec`. The
   ``P.args`` attribute of a ``ParamSpec`` is an instance of ``ParamSpecArgs``,
   and ``P.kwargs`` is an instance of ``ParamSpecKwargs``. They are intended
   for runtime introspection and have no special meaning to static type checkers.

   Calling :func:`get_origin` on either of these objects will return the
   original ``ParamSpec``:

   .. doctest::

      >>> from typing import ParamSpec, get_origin
      >>> P = ParamSpec("P")
      >>> get_origin(P.args) is P
      True
      >>> get_origin(P.kwargs) is P
      True

   .. versionadded:: 3.10


.. class:: TypeAliasType(name, value, *, type_params=(), qualname=None)

   The type of type aliases created through the :keyword:`type` statement.

   Example:

   .. doctest::

      >>> type Alias = int
      >>> type(Alias)
      <class 'typing.TypeAliasType'>

   .. versionadded:: 3.12

   .. attribute:: __name__

      The name of the type alias:

      .. doctest::

         >>> type Alias = int
         >>> Alias.__name__
         'Alias'

   .. attribute:: __qualname__

      The :term:`qualified name` of the type alias:

      .. doctest::

        >>> class Class:
        ...     type Alias = int
        ...
        >>> Class.Alias.__qualname__
        'Class.Alias'

      .. versionadded:: 3.15

   .. attribute:: __module__

      The name of the module in which the type alias was defined::

         >>> type Alias = int
         >>> Alias.__module__
         '__main__'

   .. attribute:: __type_params__

      The type parameters of the type alias, or an empty tuple if the alias is
      not generic:

      .. doctest::

         >>> type ListOrSet[T] = list[T] | set[T]
         >>> ListOrSet.__type_params__
         (T,)
         >>> type NotGeneric = int
         >>> NotGeneric.__type_params__
         ()

   .. attribute:: __value__

      The type alias's value. This is :ref:`lazily evaluated <lazy-evaluation>`,
      so names used in the definition of the alias are not resolved until the
      ``__value__`` attribute is accessed:

      .. doctest::

         >>> type Mutually = Recursive
         >>> type Recursive = Mutually
         >>> Mutually
         Mutually
         >>> Recursive
         Recursive
         >>> Mutually.__value__
         Recursive
         >>> Recursive.__value__
         Mutually

   .. method:: evaluate_value

      An :term:`evaluate function` corresponding to the :attr:`__value__` attribute.
      When called directly, this method supports only the :attr:`~annotationlib.Format.VALUE`
      format, which is equivalent to accessing the :attr:`__value__` attribute directly,
      but the method object can be passed to :func:`annotationlib.call_evaluate_function`
      to evaluate the value in a different format:

      .. doctest::

         >>> type Alias = undefined
         >>> Alias.__value__
         Traceback (most recent call last):
         ...
         NameError: name 'undefined' is not defined
         >>> from annotationlib import Format, call_evaluate_function
         >>> Alias.evaluate_value(Format.VALUE)
         Traceback (most recent call last):
         ...
         NameError: name 'undefined' is not defined
         >>> call_evaluate_function(Alias.evaluate_value, Format.FORWARDREF)
         ForwardRef('undefined')

      .. versionadded:: 3.14

   .. rubric:: Unpacking

   Type aliases support star unpacking using the ``*Alias`` syntax.
   This is equivalent to using ``Unpack[Alias]`` directly:

   .. doctest::

      >>> type Alias = tuple[int, str]
      >>> type Unpacked = tuple[bool, *Alias]
      >>> Unpacked.__value__
      tuple[bool, typing.Unpack[Alias]]

   .. versionadded:: 3.14


Other special directives
""""""""""""""""""""""""

These functions and classes should not be used directly as annotations.
Their intended purpose is to be building blocks for creating and declaring
types.

.. class:: NamedTuple

   Typed version of :func:`collections.namedtuple`.

   Usage::

       class Employee(NamedTuple):
           name: str
           id: int

   This is equivalent to::

       Employee = collections.namedtuple('Employee', ['name', 'id'])

   To give a field a default value, you can assign to it in the class body::

      class Employee(NamedTuple):
          name: str
          id: int = 3

      employee = Employee('Guido')
      assert employee.id == 3

   Fields with a default value must come after any fields without a default.

   The resulting class has an extra attribute ``__annotations__`` giving a
   dict that maps the field names to the field types.  (The field names are in
   the ``_fields`` attribute and the default values are in the
   ``_field_defaults`` attribute, both of which are part of the :func:`~collections.namedtuple`
   API.)

   ``NamedTuple`` subclasses can also have docstrings and methods::

      class Employee(NamedTuple):
          """Represents an employee."""
          name: str
          id: int = 3

          def __repr__(self) -> str:
              return f'<Employee {self.name}, id={self.id}>'

   ``NamedTuple`` subclasses can be generic::

      class Group[T](NamedTuple):
          key: T
          group: list[T]

   Backward-compatible usage::

       # For creating a generic NamedTuple on Python 3.11
       T = TypeVar("T")

       class Group(NamedTuple, Generic[T]):
           key: T
           group: list[T]

       # A functional syntax is also supported
       Employee = NamedTuple('Employee', [('name', str), ('id', int)])

   .. versionchanged:: 3.6
      Added support for :pep:`526` variable annotation syntax.

   .. versionchanged:: 3.6.1
      Added support for default values, methods, and docstrings.

   .. versionchanged:: 3.8
      The ``_field_types`` and ``__annotations__`` attributes are
      now regular dictionaries instead of instances of ``OrderedDict``.

   .. versionchanged:: 3.9
      Removed the ``_field_types`` attribute in favor of the more
      standard ``__annotations__`` attribute which has the same information.

   .. versionchanged:: 3.9
      ``NamedTuple`` is now a function rather than a class.
      It can still be used as a class base, as described above.

   .. versionchanged:: 3.11
      Added support for generic namedtuples.

   .. versionchanged:: 3.14
      Using :func:`super` (and the ``__class__`` :term:`closure variable`) in methods of ``NamedTuple`` subclasses
      is unsupported and causes a :class:`TypeError`.

.. class:: NewType(name, tp)

   Helper class to create low-overhead :ref:`distinct types <distinct>`.

   A ``NewType`` is considered a distinct type by a typechecker. At runtime,
   however, calling a ``NewType`` returns its argument unchanged.

   Usage::

      UserId = NewType('UserId', int)  # Declare the NewType "UserId"
      first_user = UserId(1)  # "UserId" returns the argument unchanged at runtime

   .. attribute:: __module__

      The name of the module in which the new type is defined.

   .. attribute:: __name__

      The name of the new type.

   .. attribute:: __supertype__

      The type that the new type is based on.

   .. versionadded:: 3.5.2

   .. versionchanged:: 3.10
      ``NewType`` is now a class rather than a function.

.. class:: Protocol(Generic)

   Base class for protocol classes.

   Protocol classes are defined like this::

      class Proto(Protocol):
          def meth(self) -> int:
              ...

   Such classes are primarily used with static type checkers that recognize
   structural subtyping (static duck-typing), for example::

      class C:
          def meth(self) -> int:
              return 0

      def func(x: Proto) -> int:
          return x.meth()

      func(C())  # Passes static type check

   See :pep:`544` for more details. Protocol classes decorated with
   :func:`runtime_checkable` (described later) act as simple-minded runtime
   protocols that check only the presence of given attributes, ignoring their
   type signatures. Protocol classes without this decorator cannot be used
   as the second argument to :func:`isinstance` or :func:`issubclass`.

   Protocol classes can be generic, for example::

      class GenProto[T](Protocol):
          def meth(self) -> T:
              ...

   In code that needs to be compatible with Python 3.11 or older, generic
   Protocols can be written as follows::

      T = TypeVar("T")

      class GenProto(Protocol[T]):
          def meth(self) -> T:
              ...

   .. versionadded:: 3.8

   .. deprecated-removed:: 3.15 3.20
      It is deprecated to call :func:`isinstance` and :func:`issubclass` checks on
      protocol classes that were not explicitly decorated with :func:`!runtime_checkable`
      but that inherit from a runtime-checkable protocol class. This will throw
      a :exc:`TypeError` in Python 3.20.

.. decorator:: runtime_checkable

   Mark a protocol class as a runtime protocol.

   Such a protocol can be used with :func:`isinstance` and :func:`issubclass`.
   This allows a simple-minded structural check, very similar to "one trick ponies"
   in :mod:`collections.abc` such as :class:`~collections.abc.Iterable`.  For example::

      @runtime_checkable
      class Closable(Protocol):
          def close(self): ...

      assert isinstance(open('/some/file'), Closable)

      @runtime_checkable
      class Named(Protocol):
          name: str

      import threading
      assert isinstance(threading.Thread(name='Bob'), Named)

   Runtime checkability of protocols is not inherited. A subclass of a runtime-checkable protocol
   is only runtime-checkable if it is explicitly marked as such, regardless of class hierarchy::

      @runtime_checkable
      class Iterable(Protocol):
          def __iter__(self): ...

      # Without @runtime_checkable, Reversible would no longer be runtime-checkable.
      @runtime_checkable
      class Reversible(Iterable, Protocol):
          def __reversed__(self): ...

   This decorator raises :exc:`TypeError` when applied to a non-protocol class.

   .. note::

        :func:`!runtime_checkable` will check only the presence of the required
        methods or attributes, not their type signatures or types.
        For example, :class:`ssl.SSLObject`
        is a class, therefore it passes an :func:`issubclass`
        check against :ref:`Callable <annotating-callables>`. However, the
        ``ssl.SSLObject.__init__`` method exists only to raise a
        :exc:`TypeError` with a more informative message, therefore making
        it impossible to call (instantiate) :class:`ssl.SSLObject`.

   .. note::

        An :func:`isinstance` check against a runtime-checkable protocol can be
        surprisingly slow compared to an ``isinstance()`` check against
        a non-protocol class. Consider using alternative idioms such as
        :func:`hasattr` calls for structural checks in performance-sensitive
        code.

   .. versionadded:: 3.8

   .. versionchanged:: 3.12
      The internal implementation of :func:`isinstance` checks against
      runtime-checkable protocols now uses :func:`inspect.getattr_static`
      to look up attributes (previously, :func:`hasattr` was used).
      As a result, some objects which used to be considered instances
      of a runtime-checkable protocol may no longer be considered instances
      of that protocol on Python 3.12+, and vice versa.
      Most users are unlikely to be affected by this change.

   .. versionchanged:: 3.12
      The members of a runtime-checkable protocol are now considered "frozen"
      at runtime as soon as the class has been created. Monkey-patching
      attributes onto a runtime-checkable protocol will still work, but will
      have no impact on :func:`isinstance` checks comparing objects to the
      protocol. See :ref:`What's new in Python 3.12 <whatsnew-typing-py312>`
      for more details.

   .. deprecated-removed:: 3.15 3.20
      It is deprecated to call :func:`isinstance` and :func:`issubclass` checks on
      protocol classes that were not explicitly decorated with :func:`!runtime_checkable`
      but that inherit from a runtime-checkable protocol class. This will throw
      a :exc:`TypeError` in Python 3.20.

.. class:: TypedDict(dict)

   Special construct to add type hints to a dictionary.
   At runtime ":class:`!TypedDict` instances" are simply :class:`dicts <dict>`.

   ``TypedDict`` declares a dictionary type that expects all of its
   instances to have a certain set of keys, where each key is
   associated with a value of a consistent type. This expectation
   is not checked at runtime but is only enforced by type checkers.
   Usage::

      class Point2D(TypedDict):
          x: int
          y: int
          label: str

      a: Point2D = {'x': 1, 'y': 2, 'label': 'good'}  # OK
      b: Point2D = {'z': 3, 'label': 'bad'}           # Fails type check

      assert Point2D(x=1, y=2, label='first') == dict(x=1, y=2, label='first')

   An alternative way to create a ``TypedDict`` is by using
   function-call syntax. The second argument must be a literal :class:`dict`::

      Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str})

   This functional syntax allows defining keys which are not valid
   :ref:`identifiers <identifiers>`, for example because they are
   keywords or contain hyphens, or when key names must not be
   :ref:`mangled <private-name-mangling>` like regular private names::

      # raises SyntaxError
      class Point2D(TypedDict):
          in: int  # 'in' is a keyword
          x-y: int  # name with hyphens

      class Definition(TypedDict):
          __schema: str  # mangled to `_Definition__schema`

      # OK, functional syntax
      Point2D = TypedDict('Point2D', {'in': int, 'x-y': int})
      Definition = TypedDict('Definition', {'__schema': str})  # not mangled

   By default, all keys must be present in a ``TypedDict``. It is possible to
   mark individual keys as non-required using :data:`NotRequired`::

      class Point2D(TypedDict):
          x: int
          y: int
          label: NotRequired[str]

      # Alternative syntax
      Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': NotRequired[str]})

   This means that a ``Point2D`` ``TypedDict`` can have the ``label``
   key omitted.

   It is also possible to mark all keys as non-required by default
   by specifying a totality of ``False``::

      class Point2D(TypedDict, total=False):
          x: int
          y: int

      # Alternative syntax
      Point2D = TypedDict('Point2D', {'x': int, 'y': int}, total=False)

   This means that a ``Point2D`` ``TypedDict`` can have any of the keys
   omitted. A type checker is only expected to support a literal ``False`` or
   ``True`` as the value of the ``total`` argument. ``True`` is the default,
   and makes all items defined in the class body required.

   Individual keys of a ``total=False`` ``TypedDict`` can be marked as
   required using :data:`Required`::

      class Point2D(TypedDict, total=False):
          x: Required[int]
          y: Required[int]
          label: str

      # Alternative syntax
      Point2D = TypedDict('Point2D', {
          'x': Required[int],
          'y': Required[int],
          'label': str
      }, total=False)

   It is possible for a ``TypedDict`` type to inherit from one or more other ``TypedDict`` types
   using the class-based syntax.
   Usage::

      class Point3D(Point2D):
          z: int

   ``Point3D`` has three items: ``x``, ``y`` and ``z``. It is equivalent to this
   definition::

      class Point3D(TypedDict):
          x: int
          y: int
          z: int

   A ``TypedDict`` cannot inherit from a non-\ ``TypedDict`` class,
   except for :class:`Generic`. For example::

      class X(TypedDict):
          x: int

      class Y(TypedDict):
          y: int

      class Z(object): pass  # A non-TypedDict class

      class XY(X, Y): pass  # OK

      class XZ(X, Z): pass  # raises TypeError

   A ``TypedDict`` can be generic::

      class Group[T](TypedDict):
          key: T
          group: list[T]

   To create a generic ``TypedDict`` that is compatible with Python 3.11
   or lower, inherit from :class:`Generic` explicitly:

   .. testcode::

      T = TypeVar("T")

      class Group(TypedDict, Generic[T]):
          key: T
          group: list[T]

   A ``TypedDict`` can be introspected via annotations dicts
   (see :ref:`annotations-howto` for more information on annotations best practices),
   :attr:`__total__`, :attr:`__required_keys__`, and :attr:`__optional_keys__`.

   .. attribute:: __total__

      ``Point2D.__total__`` gives the value of the ``total`` argument.
      Example:

      .. doctest::

         >>> from typing import TypedDict
         >>> class Point2D(TypedDict): pass
         >>> Point2D.__total__
         True
         >>> class Point2D(TypedDict, total=False): pass
         >>> Point2D.__total__
         False
         >>> class Point3D(Point2D): pass
         >>> Point3D.__total__
         True

      This attribute reflects *only* the value of the ``total`` argument
      to the current ``TypedDict`` class, not whether the class is semantically
      total. For example, a ``TypedDict`` with ``__total__`` set to ``True`` may
      have keys marked with :data:`NotRequired`, or it may inherit from another
      ``TypedDict`` with ``total=False``. Therefore, it is generally better to use
      :attr:`__required_keys__` and :attr:`__optional_keys__` for introspection.

   .. attribute:: __required_keys__

      .. versionadded:: 3.9

   .. attribute:: __optional_keys__

      ``Point2D.__required_keys__`` and ``Point2D.__optional_keys__`` return
      :class:`frozenset` objects containing required and non-required keys, respectively.

      Keys marked with :data:`Required` will always appear in ``__required_keys__``
      and keys marked with :data:`NotRequired` will always appear in ``__optional_keys__``.

      For backwards compatibility with Python 3.10 and below,
      it is also possible to use inheritance to declare both required and
      non-required keys in the same ``TypedDict`` . This is done by declaring a
      ``TypedDict`` with one value for the ``total`` argument and then
      inheriting from it in another ``TypedDict`` with a different value for
      ``total``:

      .. doctest::

         >>> class Point2D(TypedDict, total=False):
         ...     x: int
         ...     y: int
         ...
         >>> class Point3D(Point2D):
         ...     z: int
         ...
         >>> Point3D.__required_keys__ == frozenset({'z'})
         True
         >>> Point3D.__optional_keys__ == frozenset({'x', 'y'})
         True

      .. versionadded:: 3.9

      .. note::

         If ``from __future__ import annotations`` is used or if annotations
         are given as strings, annotations are not evaluated when the
         ``TypedDict`` is defined. Therefore, the runtime introspection that
         ``__required_keys__`` and ``__optional_keys__`` rely on may not work
         properly, and the values of the attributes may be incorrect.

   Support for :data:`ReadOnly` is reflected in the following attributes:

   .. attribute:: __readonly_keys__

      A :class:`frozenset` containing the names of all read-only keys. Keys
      are read-only if they carry the :data:`ReadOnly` qualifier.

      .. versionadded:: 3.13

   .. attribute:: __mutable_keys__

      A :class:`frozenset` containing the names of all mutable keys. Keys
      are mutable if they do not carry the :data:`ReadOnly` qualifier.

      .. versionadded:: 3.13

   See the `TypedDict <https://typing.python.org/en/latest/spec/typeddict.html#typeddict>`_ section in the typing documentation for more examples and detailed rules.

   .. versionadded:: 3.8

   .. versionchanged:: 3.9
      ``TypedDict`` is now a function rather than a class.
      It can still be used as a class base, as described above.

   .. versionchanged:: 3.11
      Added support for marking individual keys as :data:`Required` or :data:`NotRequired`.
      See :pep:`655`.

   .. versionchanged:: 3.11
      Added support for generic ``TypedDict``\ s.

   .. versionchanged:: 3.13
      Removed support for the keyword-argument method of creating ``TypedDict``\ s.

   .. versionchanged:: 3.13
      Support for the :data:`ReadOnly` qualifier was added.


Protocols
---------

The following protocols are provided by the :mod:`!typing` module. All are decorated
with :deco:`runtime_checkable`.

.. class:: SupportsAbs

    An ABC with one abstract method ``__abs__`` that is covariant
    in its return type.

.. class:: SupportsBytes

    An ABC with one abstract method ``__bytes__``.

.. class:: SupportsComplex

    An ABC with one abstract method ``__complex__``.

.. class:: SupportsFloat

    An ABC with one abstract method ``__float__``.

.. class:: SupportsIndex

    An ABC with one abstract method ``__index__``.

    .. versionadded:: 3.8

.. class:: SupportsInt

    An ABC with one abstract method ``__int__``.

.. class:: SupportsRound

    An ABC with one abstract method ``__round__``
    that is covariant in its return type.

.. _typing-io:

ABCs and Protocols for working with I/O
---------------------------------------

.. class:: IO[AnyStr]
           TextIO
           BinaryIO

   Generic class ``IO[AnyStr]`` and its subclasses ``TextIO(IO[str])``
   and ``BinaryIO(IO[bytes])``
   represent the types of I/O streams such as returned by
   :func:`open`. Please note that these classes are not protocols, and
   their interface is fairly broad.

The protocols :class:`io.Reader` and :class:`io.Writer` offer a simpler
alternative for argument types, when only the ``read()`` or ``write()``
methods are accessed, respectively::

   def read_and_write(reader: Reader[str], writer: Writer[bytes]):
       data = reader.read()
       writer.write(data.encode())

Also consider using :class:`collections.abc.Iterable` for iterating over
the lines of an input stream::

   def read_config(stream: Iterable[str]):
       for line in stream:
           ...

Functions and decorators
------------------------

.. function:: cast(typ, val)

   Cast a value to a type.

   This returns the value unchanged.  To the type checker this
   signals that the return value has the designated type, but at
   runtime we intentionally don't check anything (we want this
   to be as fast as possible).

.. function:: assert_type(val, typ, /)

   Ask a static type checker to confirm that *val* has an inferred type of *typ*.

   At runtime this does nothing: it returns the first argument unchanged with no
   checks or side effects, no matter the actual type of the argument.

   When a static type checker encounters a call to ``assert_type()``, it
   emits an error if the value is not of the specified type::

       def greet(name: str) -> None:
           assert_type(name, str)  # OK, inferred type of `name` is `str`
           assert_type(name, int)  # type checker error

   This function is useful for ensuring the type checker's understanding of a
   script is in line with the developer's intentions::

       def complex_function(arg: object):
           # Do some complex type-narrowing logic,
           # after which we hope the inferred type will be `int`
           ...
           # Test whether the type checker correctly understands our function
           assert_type(arg, int)

   .. versionadded:: 3.11

.. function:: assert_never(arg, /)

   Ask a static type checker to confirm that a line of code is unreachable.

   Example::

       def int_or_str(arg: int | str) -> None:
           match arg:
               case int():
                   print("It's an int")
               case str():
                   print("It's a str")
               case _ as unreachable:
                   assert_never(unreachable)

   Here, the annotations allow the type checker to infer that the
   last case can never execute, because ``arg`` is either
   an :class:`int` or a :class:`str`, and both options are covered by
   earlier cases.

   If a type checker finds that a call to ``assert_never()`` is
   reachable, it will emit an error. For example, if the type annotation
   for ``arg`` was instead ``int | str | float``, the type checker would
   emit an error pointing out that ``unreachable`` is of type :class:`float`.
   For a call to ``assert_never`` to pass type checking, the inferred type of
   the argument passed in must be the bottom type, :data:`Never`, and nothing
   else.

   At runtime, this throws an exception when called.

   .. seealso::
      `Unreachable Code and Exhaustiveness Checking
      <https://typing.python.org/en/latest/guides/unreachable.html>`__ has more
      information about exhaustiveness checking with static typing.

   .. versionadded:: 3.11

.. function:: reveal_type(obj, /)

   Ask a static type checker to reveal the inferred type of an expression.

   When a static type checker encounters a call to this function,
   it emits a diagnostic with the inferred type of the argument. For example::

      x: int = 1
      reveal_type(x)  # Revealed type is "builtins.int"

   This can be useful when you want to debug how your type checker
   handles a particular piece of code.

   At runtime, this function prints the runtime type of its argument to
   :data:`sys.stderr` and returns the argument unchanged (allowing the call to
   be used within an expression)::

      x = reveal_type(1)  # prints "Runtime type is int"
      print(x)  # prints "1"

   Note that the runtime type may be different from (more or less specific
   than) the type statically inferred by a type checker.

   Most type checkers support ``reveal_type()`` anywhere, even if the
   name is not imported from ``typing``. Importing the name from
   ``typing``, however, allows your code to run without runtime errors and
   communicates intent more clearly.

   .. versionadded:: 3.11

.. decorator:: dataclass_transform(*, eq_default=True, order_default=False, \
                                   kw_only_default=False, frozen_default=False, \
                                   field_specifiers=(), **kwargs)

   Decorator to mark an object as providing
   :func:`dataclass <dataclasses.dataclass>`-like behavior.

   ``dataclass_transform`` may be used to
   decorate a class, metaclass, or a function that is itself a decorator.
   The presence of ``@dataclass_transform()`` tells a static type checker that the
   decorated object performs runtime "magic" that
   transforms a class in a similar way to
   :deco:`dataclasses.dataclass`.

   Example usage with a decorator function:

   .. testcode::

      @dataclass_transform()
      def create_model[T](cls: type[T]) -> type[T]:
          ...
          return cls

      @create_model
      class CustomerModel:
          id: int
          name: str

   On a base class::

      @dataclass_transform()
      class ModelBase: ...

      class CustomerModel(ModelBase):
          id: int
          name: str

   On a metaclass::

      @dataclass_transform()
      class ModelMeta(type): ...

      class ModelBase(metaclass=ModelMeta): ...

      class CustomerModel(ModelBase):
          id: int
          name: str

   The ``CustomerModel`` classes defined above will
   be treated by type checkers similarly to classes created with
   :deco:`dataclasses.dataclass`.
   For example, type checkers will assume these classes have
   ``__init__`` methods that accept ``id`` and ``name``.

   The decorated class, metaclass, or function may accept the following bool
   arguments which type checkers will assume have the same effect as they
   would have on the
   :deco:`dataclasses.dataclass` decorator: ``init``,
   ``eq``, ``order``, ``unsafe_hash``, ``frozen``, ``match_args``,
   ``kw_only``, and ``slots``. It must be possible for the value of these
   arguments (``True`` or ``False``) to be statically evaluated.

   The arguments to the ``dataclass_transform`` decorator can be used to
   customize the default behaviors of the decorated class, metaclass, or
   function:

   :param bool eq_default:
       Indicates whether the ``eq`` parameter is assumed to be
       ``True`` or ``False`` if it is omitted by the caller.
       Defaults to ``True``.

   :param bool order_default:
       Indicates whether the ``order`` parameter is
       assumed to be ``True`` or ``False`` if it is omitted by the caller.
       Defaults to ``False``.

   :param bool kw_only_default:
       Indicates whether the ``kw_only`` parameter is
       assumed to be ``True`` or ``False`` if it is omitted by the caller.
       Defaults to ``False``.

   :param bool frozen_default:
       Indicates whether the ``frozen`` parameter is
       assumed to be ``True`` or ``False`` if it is omitted by the caller.
       Defaults to ``False``.

       .. versionadded:: 3.12

   :param field_specifiers:
       Specifies a static list of supported classes
       or functions that describe fields, similar to :func:`dataclasses.field`.
       Defaults to ``()``.
   :type field_specifiers: tuple[Callable[..., Any], ...]

   :param Any \**kwargs:
       Arbitrary other keyword arguments are accepted in order to allow for
       possible future extensions.

   Type checkers recognize the following optional parameters on field
   specifiers:

   .. list-table:: **Recognised parameters for field specifiers**
      :header-rows: 1
      :widths: 20 80

      * - Parameter name
        - Description
      * - ``init``
        - Indicates whether the field should be included in the
          synthesized ``__init__`` method. If unspecified, ``init`` defaults to
          ``True``.
      * - ``default``
        - Provides the default value for the field.
      * - ``default_factory``
        - Provides a runtime callback that returns the
          default value for the field. If neither ``default`` nor
          ``default_factory`` are specified, the field is assumed to have no
          default value and must be provided a value when the class is
          instantiated.
      * - ``factory``
        - An alias for the ``default_factory`` parameter on field specifiers.
      * - ``kw_only``
        - Indicates whether the field should be marked as
          keyword-only. If ``True``, the field will be keyword-only. If
          ``False``, it will not be keyword-only. If unspecified, the value of
          the ``kw_only`` parameter on the object decorated with
          ``dataclass_transform`` will be used, or if that is unspecified, the
          value of ``kw_only_default`` on ``dataclass_transform`` will be used.
      * - ``alias``
        - Provides an alternative name for the field. This alternative
          name is used in the synthesized ``__init__`` method.

   At runtime, this decorator records its arguments in the
   ``__dataclass_transform__`` attribute on the decorated object.
   It has no other runtime effect.

   See :pep:`681` for more details.

   .. versionadded:: 3.11

.. _overload:

.. decorator:: overload

   Decorator for creating overloaded functions and methods.

   The ``@overload`` decorator allows describing functions and methods
   that support multiple different combinations of argument types. A series
   of ``@overload``-decorated definitions must be followed by exactly one
   non-``@overload``-decorated definition (for the same function/method).

   ``@overload``-decorated definitions are for the benefit of the
   type checker only, since they will be overwritten by the
   non-``@overload``-decorated definition. The non-``@overload``-decorated
   definition, meanwhile, will be used at
   runtime but should be ignored by a type checker.  At runtime, calling
   an ``@overload``-decorated function directly will raise
   :exc:`NotImplementedError`.

   An example of overload that gives a more
   precise type than can be expressed using a union or a type variable:

   .. testcode::

      @overload
      def process(response: None) -> None:
          ...
      @overload
      def process(response: int) -> tuple[int, str]:
          ...
      @overload
      def process(response: bytes) -> str:
          ...
      def process(response):
          ...  # actual implementation goes here

   See :pep:`484` for more details and comparison with other typing semantics.

   .. versionchanged:: 3.11
      Overloaded functions can now be introspected at runtime using
      :func:`get_overloads`.


.. function:: get_overloads(func)

   Return a sequence of :deco:`overload`-decorated definitions for
   *func*.

   *func* is the function object for the implementation of the
   overloaded function. For example, given the definition of ``process`` in
   the documentation for :deco:`overload`,
   ``get_overloads(process)`` will return a sequence of three function objects
   for the three defined overloads. If called on a function with no overloads,
   ``get_overloads()`` returns an empty sequence.

   ``get_overloads()`` can be used for introspecting an overloaded function at
   runtime.

   .. versionadded:: 3.11


.. function:: clear_overloads()

   Clear all registered overloads in the internal registry.

   This can be used to reclaim the memory used by the registry.

   .. versionadded:: 3.11


.. decorator:: final

   Decorator to indicate final methods and final classes.

   Decorating a method with ``@final`` indicates to a type checker that the
   method cannot be overridden in a subclass. Decorating a class with ``@final``
   indicates that it cannot be subclassed.

   For example::

      class Base:
          @final
          def done(self) -> None:
              ...
      class Sub(Base):
          def done(self) -> None:  # Error reported by type checker
              ...

      @final
      class Leaf:
          ...
      class Other(Leaf):  # Error reported by type checker
          ...

   There is no runtime checking of these properties. See :pep:`591` for
   more details.

   .. versionadded:: 3.8

   .. versionchanged:: 3.11
      The decorator will now attempt to set a ``__final__`` attribute to ``True``
      on the decorated object. Thus, a check like
      ``if getattr(obj, "__final__", False)`` can be used at runtime
      to determine whether an object ``obj`` has been marked as final.
      If the decorated object does not support setting attributes,
      the decorator returns the object unchanged without raising an exception.


.. decorator:: no_type_check

   Decorator to indicate that annotations are not type hints.

   This works as a class or function :term:`decorator`.  With a class, it
   applies recursively to all methods and classes defined in that class
   (but not to methods defined in its superclasses or subclasses). Type
   checkers will ignore all annotations in a function or class with this
   decorator.

   ``@no_type_check`` mutates the decorated object in place.

.. decorator:: override

   Decorator to indicate that a method in a subclass is intended to override a
   method or attribute in a superclass.

   Type checkers should emit an error if a method decorated with ``@override``
   does not, in fact, override anything.
   This helps prevent bugs that may occur when a base class is changed without
   an equivalent change to a child class.

   For example:

   .. testcode::

      class Base:
          def log_status(self) -> None:
              ...

      class Sub(Base):
          @override
          def log_status(self) -> None:  # Okay: overrides Base.log_status
              ...

          @override
          def done(self) -> None:  # Error reported by type checker
              ...

   There is no runtime checking of this property.

   The decorator will attempt to set an ``__override__`` attribute to ``True`` on
   the decorated object. Thus, a check like
   ``if getattr(obj, "__override__", False)`` can be used at runtime to determine
   whether an object ``obj`` has been marked as an override.  If the decorated object
   does not support setting attributes, the decorator returns the object unchanged
   without raising an exception.

   See :pep:`698` for more details.

   .. versionadded:: 3.12


.. decorator:: type_check_only

   Decorator to mark a class or function as unavailable at runtime.

   This decorator is itself not available at runtime. It is mainly
   intended to mark classes that are defined in type stub files if
   an implementation returns an instance of a private class::

      @type_check_only
      class Response:  # private or not available at runtime
          code: int
          def get_header(self, name: str) -> str: ...

      def fetch_response() -> Response: ...

   Note that returning instances of private classes is not recommended.
   It is usually preferable to make such classes public.

Introspection helpers
---------------------

.. function:: get_type_hints(obj, globalns=None, localns=None, include_extras=False)

   Return a dictionary containing type hints for a function, method, module,
   class object, or other callable object.

   This is often the same as ``obj.__annotations__``, but this function makes
   the following changes to the annotations dictionary:

   * Forward references encoded as string literals or :class:`ForwardRef`
     objects are handled by evaluating them in *globalns*, *localns*, and
     (where applicable) *obj*'s :ref:`type parameter <type-params>` namespace.
     If *globalns* or *localns* is not given, appropriate namespace
     dictionaries are inferred from *obj*.
   * ``None`` is replaced with :class:`types.NoneType`.
   * If :deco:`no_type_check` has been applied to *obj*, an
     empty dictionary is returned.
   * If *obj* is a class ``C``, the function returns a dictionary that merges
     annotations from ``C``'s base classes with those on ``C`` directly. This
     is done by traversing :attr:`C.__mro__ <type.__mro__>` and iteratively
     combining
     ``__annotations__`` dictionaries. Annotations on classes appearing
     earlier in the :term:`method resolution order` always take precedence over
     annotations on classes appearing later in the method resolution order.
   * The function recursively replaces all occurrences of
     ``Annotated[T, ...]``, ``Required[T]``, ``NotRequired[T]``, and ``ReadOnly[T]``
     with ``T``, unless *include_extras* is set to ``True`` (see
     :class:`Annotated` for more information).

   See also :func:`annotationlib.get_annotations`, a lower-level function that
   returns annotations more directly.

   .. caution::

      This function may execute arbitrary code contained in annotations.
      See :ref:`annotationlib-security` for more information.

   .. note::

      If any forward references in the annotations of *obj* are not resolvable
      or are not valid Python code, this function will raise an exception
      such as :exc:`NameError`. For example, this can happen with imported
      :ref:`type aliases <type-aliases>` that include forward references,
      or with names imported under :data:`if TYPE_CHECKING <TYPE_CHECKING>`.

   .. note::

      Calling :func:`get_type_hints` on an instance is not supported.
      To retrieve annotations for an instance, call
      :func:`get_type_hints` on the instance's class instead
      (for example, ``get_type_hints(type(obj))``).

   .. versionchanged:: 3.9
      Added ``include_extras`` parameter as part of :pep:`593`.
      See the documentation on :data:`Annotated` for more information.

   .. versionchanged:: 3.11
      Previously, ``Optional[t]`` was added for function and method annotations
      if a default value equal to ``None`` was set.
      Now the annotation is returned unchanged.

   .. versionchanged:: 3.14
      Calling :func:`get_type_hints` on instances is no longer supported.
      Some instances were accepted in earlier versions as an undocumented
      implementation detail.

.. function:: get_origin(tp)

   Get the unsubscripted version of a type: for a typing object of the form
   ``X[Y, Z, ...]`` return ``X``.

   If ``X`` is a typing-module alias for a builtin or
   :mod:`collections` class, it will be normalized to the original class.
   If ``X`` is an instance of :class:`ParamSpecArgs` or :class:`ParamSpecKwargs`,
   return the underlying :class:`ParamSpec`.
   Return ``None`` for unsupported objects.

   Examples:

   .. testcode::

      assert get_origin(str) is None
      assert get_origin(Dict[str, int]) is dict
      assert get_origin(Union[int, str]) is Union
      assert get_origin(Annotated[str, "metadata"]) is Annotated
      P = ParamSpec('P')
      assert get_origin(P.args) is P
      assert get_origin(P.kwargs) is P

   .. versionadded:: 3.8

.. function:: get_args(tp)

   Get type arguments with all substitutions performed: for a typing object
   of the form ``X[Y, Z, ...]`` return ``(Y, Z, ...)``.

   If ``X`` is a union or :class:`Literal` contained in another
   generic type, the order of ``(Y, Z, ...)`` may be different from the order
   of the original arguments ``[Y, Z, ...]`` due to type caching.
   Return ``()`` for unsupported objects.

   Examples:

   .. testcode::

      assert get_args(int) == ()
      assert get_args(Dict[int, str]) == (int, str)
      assert get_args(Union[int, str]) == (int, str)

   .. versionadded:: 3.8

.. function:: get_protocol_members(tp)

   Return the set of members defined in a :class:`Protocol`.

   .. doctest::

      >>> from typing import Protocol, get_protocol_members
      >>> class P(Protocol):
      ...     def a(self) -> str: ...
      ...     b: int
      >>> get_protocol_members(P) == frozenset({'a', 'b'})
      True

   Raise :exc:`TypeError` for arguments that are not Protocols.

   .. versionadded:: 3.13

.. function:: is_protocol(tp)

   Determine if a type is a :class:`Protocol`.

   For example::

      class P(Protocol):
          def a(self) -> str: ...
          b: int

      is_protocol(P)    # => True
      is_protocol(int)  # => False

   .. versionadded:: 3.13

.. function:: is_typeddict(tp)

   Check if a type is a :class:`TypedDict`.

   For example:

   .. testcode::

      class Film(TypedDict):
          title: str
          year: int

      assert is_typeddict(Film)
      assert not is_typeddict(list | str)

      # TypedDict is a factory for creating typed dicts,
      # not a typed dict itself
      assert not is_typeddict(TypedDict)

   .. versionadded:: 3.10

.. class:: ForwardRef

   Class used for internal typing representation of string forward references.

   For example, ``List["SomeClass"]`` is implicitly transformed into
   ``List[ForwardRef("SomeClass")]``.  :class:`!ForwardRef` should not be instantiated by
   a user, but may be used by introspection tools.

   .. note::
      :pep:`585` generic types such as ``list["SomeClass"]`` will not be
      implicitly transformed into ``list[ForwardRef("SomeClass")]`` and thus
      will not automatically resolve to ``list[SomeClass]``.

   .. versionadded:: 3.7.4

   .. versionchanged:: 3.14
      This is now an alias for :class:`annotationlib.ForwardRef`. Several undocumented
      behaviors of this class have been changed; for example, after a ``ForwardRef`` has
      been evaluated, the evaluated value is no longer cached.

.. function:: evaluate_forward_ref(forward_ref, *, owner=None, globals=None, locals=None, type_params=None, format=annotationlib.Format.VALUE)

   Evaluate an :class:`annotationlib.ForwardRef` as a :term:`type hint`.

   This is similar to calling :meth:`annotationlib.ForwardRef.evaluate`,
   but unlike that method, :func:`!evaluate_forward_ref` also
   recursively evaluates forward references nested within the type hint.

   See the documentation for :meth:`annotationlib.ForwardRef.evaluate` for
   the meaning of the *owner*, *globals*, *locals*, *type_params*, and *format* parameters.

   .. caution::

      This function may execute arbitrary code contained in annotations.
      See :ref:`annotationlib-security` for more information.

   .. versionadded:: 3.14

.. data:: NoDefault

   A sentinel object used to indicate that a type parameter has no default
   value. For example:

   .. doctest::

      >>> T = TypeVar("T")
      >>> T.__default__ is typing.NoDefault
      True
      >>> S = TypeVar("S", default=None)
      >>> S.__default__ is None
      True

   .. versionadded:: 3.13

Constant
--------

.. data:: TYPE_CHECKING

   A special constant that is assumed to be ``True`` by 3rd party static
   type checkers. It's ``False`` at runtime.

   A module which is expensive to import, and which only contain types
   used for typing annotations, can be safely imported inside an
   ``if TYPE_CHECKING:`` block.  This prevents the module from actually
   being imported at runtime; annotations aren't eagerly evaluated
   (see :pep:`649`) so using undefined symbols in annotations is
   harmless--as long as you don't later examine them.
   Your static type analysis tool will set ``TYPE_CHECKING`` to
   ``True`` during static type analysis, which means the module will
   be imported and the types will be checked properly during such analysis.

   Usage::

      if TYPE_CHECKING:
          import expensive_mod

      def fun(arg: expensive_mod.SomeType) -> None:
          local_var: expensive_mod.AnotherType = other_fun()

   If you occasionally need to examine type annotations at runtime
   which may contain undefined symbols, use
   :meth:`annotationlib.get_annotations` with a ``format`` parameter
   of :attr:`annotationlib.Format.STRING` or
   :attr:`annotationlib.Format.FORWARDREF` to safely retrieve the
   annotations without raising :exc:`NameError`.

   .. versionadded:: 3.5.2

.. _generic-concrete-collections:
.. _deprecated-aliases:

Deprecated aliases
------------------

This module defines several deprecated aliases to pre-existing
standard library classes. These were originally included in the :mod:`!typing`
module in order to support parameterizing these generic classes using ``[]``.
However, the aliases became redundant in Python 3.9 when the
corresponding pre-existing classes were enhanced to support ``[]`` (see
:pep:`585`).

The redundant types are deprecated as of Python 3.9. However, while the aliases
may be removed at some point, removal of these aliases is not currently
planned. As such, no deprecation warnings are currently issued by the
interpreter for these aliases.

If at some point it is decided to remove these deprecated aliases, a
deprecation warning will be issued by the interpreter for at least two releases
prior to removal. The aliases are guaranteed to remain in the :mod:`!typing` module
without deprecation warnings until at least Python 3.14.

Type checkers are encouraged to flag uses of the deprecated types if the
program they are checking targets a minimum Python version of 3.9 or newer.

.. _corresponding-to-built-in-types:

Aliases to built-in types
"""""""""""""""""""""""""

.. class:: Dict(dict, MutableMapping[KT, VT])

   Deprecated alias to :class:`dict`.

   Note that to annotate arguments, it is preferred
   to use an abstract collection type such as :class:`~collections.abc.Mapping`
   rather than to use :class:`dict` or :class:`!typing.Dict`.

   .. deprecated:: 3.9
      :class:`builtins.dict <dict>` now supports subscripting (``[]``).
      See :pep:`585` and :ref:`types-genericalias`.

.. class:: List(list, MutableSequence[T])

   Deprecated alias to :class:`list`.

   Note that to annotate arguments, it is preferred
   to use an abstract collection type such as
   :class:`~collections.abc.Sequence` or :class:`~collections.abc.Iterable`
   rather than to use :class:`list` or :class:`!typing.List`.

   .. deprecated:: 3.9
      :class:`builtins.list <list>` now supports subscripting (``[]``).
      See :pep:`585` and :ref:`types-genericalias`.

.. class:: Set(set, MutableSet[T])

   Deprecated alias to :class:`builtins.set <set>`.

   Note that to annotate arguments, it is preferred
   to use an abstract collection type such as :class:`collections.abc.Set`
   rather than to use :class:`set` or :class:`typing.Set`.

   .. deprecated:: 3.9
      :class:`builtins.set <set>` now supports subscripting (``[]``).
      See :pep:`585` and :ref:`types-genericalias`.

.. class:: FrozenSet(frozenset, AbstractSet[T_co])

   Deprecated alias to :class:`builtins.frozenset <frozenset>`.

   .. deprecated:: 3.9
      :class:`builtins.frozenset <frozenset>`
      now supports subscripting (``[]``).
      See :pep:`585` and :ref:`types-genericalias`.

.. data:: Tuple

   Deprecated alias for :class:`tuple`.

   :class:`tuple` and ``Tuple`` are special-cased in the type system; see
   :ref:`annotating-tuples` for more details.

   .. deprecated:: 3.9
      :class:`builtins.tuple <tuple>` now supports subscripting (``[]``).
      See :pep:`585` and :ref:`types-genericalias`.

.. class:: Type(Generic[CT_co])

   Deprecated alias to :class:`type`.

   See :ref:`type-of-class-objects` for details on using :class:`type` or
   ``typing.Type`` in type annotations.

   .. versionadded:: 3.5.2

   .. deprecated:: 3.9
      :class:`builtins.type <type>` now supports subscripting (``[]``).
      See :pep:`585` and :ref:`types-genericalias`.

.. _corresponding-to-types-in-collections:

Aliases to types in :mod:`collections`
""""""""""""""""""""""""""""""""""""""

.. class:: DefaultDict(collections.defaultdict, MutableMapping[KT, VT])

   Deprecated alias to :class:`collections.defaultdict`.

   .. versionadded:: 3.5.2

   .. deprecated:: 3.9
      :class:`collections.defaultdict` now supports subscripting (``[]``).
      See :pep:`585` and :ref:`types-genericalias`.

.. class:: OrderedDict(collections.OrderedDict, MutableMapping[KT, VT])

   Deprecated alias to :class:`collections.OrderedDict`.

   .. versionadded:: 3.7.2

   .. deprecated:: 3.9
      :class:`collections.OrderedDict` now supports subscripting (``[]``).
      See :pep:`585` and :ref:`types-genericalias`.

.. class:: ChainMap(collections.ChainMap, MutableMapping[KT, VT])

   Deprecated alias to :class:`collections.ChainMap`.

   .. versionadded:: 3.6.1

   .. deprecated:: 3.9
      :class:`collections.ChainMap` now supports subscripting (``[]``).
      See :pep:`585` and :ref:`types-genericalias`.

.. class:: Counter(collections.Counter, Dict[T, int])

   Deprecated alias to :class:`collections.Counter`.

   .. versionadded:: 3.6.1

   .. deprecated:: 3.9
      :class:`collections.Counter` now supports subscripting (``[]``).
      See :pep:`585` and :ref:`types-genericalias`.

.. class:: Deque(deque, MutableSequence[T])

   Deprecated alias to :class:`collections.deque`.

   .. versionadded:: 3.6.1

   .. deprecated:: 3.9
      :class:`collections.deque` now supports subscripting (``[]``).
      See :pep:`585` and :ref:`types-genericalias`.

.. _other-concrete-types:

Aliases to other concrete types
"""""""""""""""""""""""""""""""

.. class:: Pattern
           Match

   Deprecated aliases corresponding to the return types from
   :func:`re.compile` and :func:`re.match`.

   These types (and the corresponding functions) are generic over
   :data:`AnyStr`. ``Pattern`` can be specialised as ``Pattern[str]`` or
   ``Pattern[bytes]``; ``Match`` can be specialised as ``Match[str]`` or
   ``Match[bytes]``.

   .. deprecated:: 3.9
      Classes ``Pattern`` and ``Match`` from :mod:`re` now support ``[]``.
      See :pep:`585` and :ref:`types-genericalias`.

.. class:: Text

   Deprecated alias for :class:`str`.

   ``Text`` is provided to supply a forward
   compatible path for Python 2 code: in Python 2, ``Text`` is an alias for
   ``unicode``.

   Use ``Text`` to indicate that a value must contain a unicode string in
   a manner that is compatible with both Python 2 and Python 3::

       def add_unicode_checkmark(text: Text) -> Text:
           return text + u' \u2713'

   .. versionadded:: 3.5.2

   .. deprecated:: 3.11
      Python 2 is no longer supported, and most type checkers also no longer
      support type checking Python 2 code. Removal of the alias is not
      currently planned, but users are encouraged to use
      :class:`str` instead of ``Text``.

.. _abstract-base-classes:
.. _corresponding-to-collections-in-collections-abc:

Aliases to container ABCs in :mod:`collections.abc`
"""""""""""""""""""""""""""""""""""""""""""""""""""

.. class:: AbstractSet(Collection[T_co])

   Deprecated alias to :class:`collections.abc.Set`.

   .. deprecated:: 3.9
      :class:`collections.abc.Set` now supports subscripting (``[]``).
      See :pep:`585` and :ref:`types-genericalias`.

.. class:: ByteString(Sequence[int])

   Deprecated alias to :class:`collections.abc.ByteString`.

   Use ``isinstance(obj, collections.abc.Buffer)`` to test if ``obj``
   implements the :ref:`buffer protocol <bufferobjects>` at runtime. For use in
   type annotations, either use :class:`~collections.abc.Buffer` or a union
   that explicitly specifies the types your code supports (e.g.,
   ``bytes | bytearray | memoryview``).

   :class:`!ByteString` was originally intended to be an abstract class that
   would serve as a supertype of both :class:`bytes` and :class:`bytearray`.
   However, since the ABC never had any methods, knowing that an object was an
   instance of :class:`!ByteString` never actually told you anything useful
   about the object. Other common buffer types such as :class:`memoryview` were
   also never understood as subtypes of :class:`!ByteString` (either at runtime
   or by static type checkers).

   See :pep:`PEP 688 <688#current-options>` for more details.

   .. deprecated-removed:: 3.9 3.17

.. class:: Collection(Sized, Iterable[T_co], Container[T_co])

   Deprecated alias to :class:`collections.abc.Collection`.

   .. versionadded:: 3.6

   .. deprecated:: 3.9
      :class:`collections.abc.Collection` now supports subscripting (``[]``).
      See :pep:`585` and :ref:`types-genericalias`.

.. class:: Container(Generic[T_co])

   Deprecated alias to :class:`collections.abc.Container`.

   .. deprecated:: 3.9
      :class:`collections.abc.Container` now supports subscripting (``[]``).
      See :pep:`585` and :ref:`types-genericalias`.

.. class:: ItemsView(MappingView, AbstractSet[tuple[KT_co, VT_co]])

   Deprecated alias to :class:`collections.abc.ItemsView`.

   .. deprecated:: 3.9
      :class:`collections.abc.ItemsView` now supports subscripting (``[]``).
      See :pep:`585` and :ref:`types-genericalias`.

.. class:: KeysView(MappingView, AbstractSet[KT_co])

   Deprecated alias to :class:`collections.abc.KeysView`.

   .. deprecated:: 3.9
      :class:`collections.abc.KeysView` now supports subscripting (``[]``).
      See :pep:`585` and :ref:`types-genericalias`.

.. class:: Mapping(Collection[KT], Generic[KT, VT_co])

   Deprecated alias to :class:`collections.abc.Mapping`.

   .. deprecated:: 3.9
      :class:`collections.abc.Mapping` now supports subscripting (``[]``).
      See :pep:`585` and :ref:`types-genericalias`.

.. class:: MappingView(Sized)

   Deprecated alias to :class:`collections.abc.MappingView`.

   .. deprecated:: 3.9
      :class:`collections.abc.MappingView` now supports subscripting (``[]``).
      See :pep:`585` and :ref:`types-genericalias`.

.. class:: MutableMapping(Mapping[KT, VT])

   Deprecated alias to :class:`collections.abc.MutableMapping`.

   .. deprecated:: 3.9
      :class:`collections.abc.MutableMapping`
      now supports subscripting (``[]``).
      See :pep:`585` and :ref:`types-genericalias`.

.. class:: MutableSequence(Sequence[T])

   Deprecated alias to :class:`collections.abc.MutableSequence`.

   .. deprecated:: 3.9
      :class:`collections.abc.MutableSequence`
      now supports subscripting (``[]``).
      See :pep:`585` and :ref:`types-genericalias`.

.. class:: MutableSet(AbstractSet[T])

   Deprecated alias to :class:`collections.abc.MutableSet`.

   .. deprecated:: 3.9
      :class:`collections.abc.MutableSet` now supports subscripting (``[]``).
      See :pep:`585` and :ref:`types-genericalias`.

.. class:: Sequence(Reversible[T_co], Collection[T_co])

   Deprecated alias to :class:`collections.abc.Sequence`.

   .. deprecated:: 3.9
      :class:`collections.abc.Sequence` now supports subscripting (``[]``).
      See :pep:`585` and :ref:`types-genericalias`.

.. class:: ValuesView(MappingView, Collection[_VT_co])

   Deprecated alias to :class:`collections.abc.ValuesView`.

   .. deprecated:: 3.9
      :class:`collections.abc.ValuesView` now supports subscripting (``[]``).
      See :pep:`585` and :ref:`types-genericalias`.

.. _asynchronous-programming:

Aliases to asynchronous ABCs in :mod:`collections.abc`
""""""""""""""""""""""""""""""""""""""""""""""""""""""

.. class:: Coroutine(Awaitable[ReturnType], Generic[YieldType, SendType, ReturnType])

   Deprecated alias to :class:`collections.abc.Coroutine`.

   See :ref:`annotating-generators-and-coroutines`
   for details on using :class:`collections.abc.Coroutine`
   and ``typing.Coroutine`` in type annotations.

   .. versionadded:: 3.5.3

   .. deprecated:: 3.9
      :class:`collections.abc.Coroutine` now supports subscripting (``[]``).
      See :pep:`585` and :ref:`types-genericalias`.

.. class:: AsyncGenerator(AsyncIterator[YieldType], Generic[YieldType, SendType])

   Deprecated alias to :class:`collections.abc.AsyncGenerator`.

   See :ref:`annotating-generators-and-coroutines`
   for details on using :class:`collections.abc.AsyncGenerator`
   and ``typing.AsyncGenerator`` in type annotations.

   .. versionadded:: 3.6.1

   .. deprecated:: 3.9
      :class:`collections.abc.AsyncGenerator`
      now supports subscripting (``[]``).
      See :pep:`585` and :ref:`types-genericalias`.

   .. versionchanged:: 3.13
      The ``SendType`` parameter now has a default.

.. class:: AsyncIterable(Generic[T_co])

   Deprecated alias to :class:`collections.abc.AsyncIterable`.

   .. versionadded:: 3.5.2

   .. deprecated:: 3.9
      :class:`collections.abc.AsyncIterable` now supports subscripting (``[]``).
      See :pep:`585` and :ref:`types-genericalias`.

.. class:: AsyncIterator(AsyncIterable[T_co])

   Deprecated alias to :class:`collections.abc.AsyncIterator`.

   .. versionadded:: 3.5.2

   .. deprecated:: 3.9
      :class:`collections.abc.AsyncIterator` now supports subscripting (``[]``).
      See :pep:`585` and :ref:`types-genericalias`.

.. class:: Awaitable(Generic[T_co])

   Deprecated alias to :class:`collections.abc.Awaitable`.

   .. versionadded:: 3.5.2

   .. deprecated:: 3.9
      :class:`collections.abc.Awaitable` now supports subscripting (``[]``).
      See :pep:`585` and :ref:`types-genericalias`.

.. _corresponding-to-other-types-in-collections-abc:

Aliases to other ABCs in :mod:`collections.abc`
"""""""""""""""""""""""""""""""""""""""""""""""

.. class:: Iterable(Generic[T_co])

   Deprecated alias to :class:`collections.abc.Iterable`.

   .. deprecated:: 3.9
      :class:`collections.abc.Iterable` now supports subscripting (``[]``).
      See :pep:`585` and :ref:`types-genericalias`.

.. class:: Iterator(Iterable[T_co])

   Deprecated alias to :class:`collections.abc.Iterator`.

   .. deprecated:: 3.9
      :class:`collections.abc.Iterator` now supports subscripting (``[]``).
      See :pep:`585` and :ref:`types-genericalias`.

.. data:: Callable

   Deprecated alias to :class:`collections.abc.Callable`.

   See :ref:`annotating-callables` for details on how to use
   :class:`collections.abc.Callable` and ``typing.Callable`` in type annotations.

   .. deprecated:: 3.9
      :class:`collections.abc.Callable` now supports subscripting (``[]``).
      See :pep:`585` and :ref:`types-genericalias`.

   .. versionchanged:: 3.10
      ``Callable`` now supports :class:`ParamSpec` and :data:`Concatenate`.
      See :pep:`612` for more details.

.. class:: Generator(Iterator[YieldType], Generic[YieldType, SendType, ReturnType])

   Deprecated alias to :class:`collections.abc.Generator`.

   See :ref:`annotating-generators-and-coroutines`
   for details on using :class:`collections.abc.Generator`
   and ``typing.Generator`` in type annotations.

   .. deprecated:: 3.9
      :class:`collections.abc.Generator` now supports subscripting (``[]``).
      See :pep:`585` and :ref:`types-genericalias`.

   .. versionchanged:: 3.13
      Default values for the send and return types were added.

.. class:: Hashable

   Deprecated alias to :class:`collections.abc.Hashable`.

   .. deprecated:: 3.12
      Use :class:`collections.abc.Hashable` directly instead.

.. class:: Reversible(Iterable[T_co])

   Deprecated alias to :class:`collections.abc.Reversible`.

   .. deprecated:: 3.9
      :class:`collections.abc.Reversible` now supports subscripting (``[]``).
      See :pep:`585` and :ref:`types-genericalias`.

.. class:: Sized

   Deprecated alias to :class:`collections.abc.Sized`.

   .. deprecated:: 3.12
      Use :class:`collections.abc.Sized` directly instead.

.. _context-manager-types:

Aliases to :mod:`contextlib` ABCs
"""""""""""""""""""""""""""""""""

.. class:: ContextManager(Generic[T_co, ExitT_co])

   Deprecated alias to :class:`contextlib.AbstractContextManager`.

   The first type parameter, ``T_co``, represents the type returned by
   the :meth:`~object.__enter__` method. The optional second type parameter, ``ExitT_co``,
   which defaults to ``bool | None``, represents the type returned by the
   :meth:`~object.__exit__` method.

   .. versionadded:: 3.5.4

   .. deprecated:: 3.9
      :class:`contextlib.AbstractContextManager`
      now supports subscripting (``[]``).
      See :pep:`585` and :ref:`types-genericalias`.

   .. versionchanged:: 3.13
      Added the optional second type parameter, ``ExitT_co``.

.. class:: AsyncContextManager(Generic[T_co, AExitT_co])

   Deprecated alias to :class:`contextlib.AbstractAsyncContextManager`.

   The first type parameter, ``T_co``, represents the type returned by
   the :meth:`~object.__aenter__` method. The optional second type parameter, ``AExitT_co``,
   which defaults to ``bool | None``, represents the type returned by the
   :meth:`~object.__aexit__` method.

   .. versionadded:: 3.6.2

   .. deprecated:: 3.9
      :class:`contextlib.AbstractAsyncContextManager`
      now supports subscripting (``[]``).
      See :pep:`585` and :ref:`types-genericalias`.

   .. versionchanged:: 3.13
      Added the optional second type parameter, ``AExitT_co``.

Deprecation Timeline of Major Features
======================================

Certain features in ``typing`` are deprecated and may be removed in a future
version of Python. The following table summarizes major deprecations for your
convenience. This is subject to change, and not all deprecations are listed.

.. list-table::
   :header-rows: 1

   * - Feature
     - Deprecated in
     - Projected removal
     - PEP/issue
   * - ``typing`` versions of standard collections
     - 3.9
     - Undecided (see :ref:`deprecated-aliases` for more information)
     - :pep:`585`
   * - :class:`typing.ByteString`
     - 3.9
     - 3.17
     - :gh:`91896`
   * - :data:`typing.Text`
     - 3.11
     - Undecided
     - :gh:`92332`
   * - :class:`typing.Hashable` and :class:`typing.Sized`
     - 3.12
     - Undecided
     - :gh:`94309`
   * - :data:`typing.TypeAlias`
     - 3.12
     - Undecided
     - :pep:`695`
   * - :data:`typing.AnyStr`
     - 3.13
     - 3.18
     - :gh:`105578`
