Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[3.12] Typing docs: improve the guidance on annotating tuples (GH-106021) #106027

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 23, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Typing docs: improve the guidance on annotating tuples (GH-106021)
(cherry picked from commit 968435d)

Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
  • Loading branch information
AlexWaygood authored and miss-islington committed Jun 23, 2023
commit 115cdd50932a611ab6748405c207012af585535f
93 changes: 72 additions & 21 deletions 93 Doc/library/typing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,68 @@ Or by using the :class:`TypeVar` factory directly::
.. 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 ``y`` are meant to be strings,
# and that all values in ``y`` 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)

To denote a tuple which could be of *any* length, and in which all elements are
of the same type ``T``, use ``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 = ()

.. _user-defined-generics:

User-defined generic types
Expand Down Expand Up @@ -877,26 +939,6 @@ Special forms
These can be used as types in annotations. They all support subscription using
``[]``, but each has a unique syntax.

.. data:: Tuple

Deprecated alias for :class:`tuple`.

``Tuple[X, Y]`` is the type of a tuple of two items
with the first item of type X and the second of type Y. The type of
the empty tuple can be written as ``Tuple[()]``.

Example: ``Tuple[T1, T2]`` is a tuple of two elements corresponding
to type variables T1 and T2. ``Tuple[int, float, str]`` is a tuple
of an int, a float and a string.

To specify a variable-length tuple of homogeneous type,
use literal ellipsis, e.g. ``Tuple[int, ...]``. A plain ``Tuple`` annotation
is equivalent to ``tuple``, ``Tuple[Any, ...]``, or ``tuple[Any, ...]``.

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

.. data:: Union

Union type; ``Union[X, Y]`` is equivalent to ``X | Y`` and means either X or Y.
Expand Down Expand Up @@ -3091,7 +3133,16 @@ Aliases to built-in types
now supports subscripting (``[]``).
See :pep:`585` and :ref:`types-genericalias`.

.. note:: :data:`Tuple` is a special form.
.. 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`.

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

Expand Down
Morty Proxy This is a proxified and sanitized view of the page, visit original site.