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

Commit 15f4bba

Browse filesBrowse files
[3.11] Typing docs: improve the guidance on annotating tuples (GH-106021) (#106029)
Typing docs: improve the guidance on annotating tuples (GH-106021) (cherry picked from commit 968435d) Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
1 parent 581d262 commit 15f4bba
Copy full SHA for 15f4bba

File tree

1 file changed

+72
-21
lines changed
Filter options

1 file changed

+72
-21
lines changed

‎Doc/library/typing.rst

Copy file name to clipboardExpand all lines: Doc/library/typing.rst
+72-21Lines changed: 72 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,68 @@ called :class:`TypeVar`.
324324
def first(l: Sequence[T]) -> T: # Function is generic over the TypeVar "T"
325325
return l[0]
326326

327+
.. _annotating-tuples:
328+
329+
Annotating tuples
330+
=================
331+
332+
For most containers in Python, the typing system assumes that all elements in
333+
the container will be of the same type. For example::
334+
335+
from collections.abc import Mapping
336+
337+
# Type checker will infer that all elements in ``x`` are meant to be ints
338+
x: list[int] = []
339+
340+
# Type checker error: ``list`` only accepts a single type argument:
341+
y: list[int, str] = [1, 'foo']
342+
343+
# Type checker will infer that all keys in ``y`` are meant to be strings,
344+
# and that all values in ``y`` are meant to be either strings or ints
345+
z: Mapping[str, str | int] = {}
346+
347+
:class:`list` only accepts one type argument, so a type checker would emit an
348+
error on the ``y`` assignment above. Similarly,
349+
:class:`~collections.abc.Mapping` only accepts two type arguments: the first
350+
indicates the type of the keys, and the second indicates the type of the
351+
values.
352+
353+
Unlike most other Python containers, however, it is common in idiomatic Python
354+
code for tuples to have elements which are not all of the same type. For this
355+
reason, tuples are special-cased in Python's typing system. :class:`tuple`
356+
accepts *any number* of type arguments::
357+
358+
# OK: ``x`` is assigned to a tuple of length 1 where the sole element is an int
359+
x: tuple[int] = (5,)
360+
361+
# OK: ``y`` is assigned to a tuple of length 2;
362+
# element 1 is an int, element 2 is a str
363+
y: tuple[int, str] = (5, "foo")
364+
365+
# Error: the type annotation indicates a tuple of length 1,
366+
# but ``z`` has been assigned to a tuple of length 3
367+
z: tuple[int] = (1, 2, 3)
368+
369+
To denote a tuple which could be of *any* length, and in which all elements are
370+
of the same type ``T``, use ``tuple[T, ...]``. To denote an empty tuple, use
371+
``tuple[()]``. Using plain ``tuple`` as an annotation is equivalent to using
372+
``tuple[Any, ...]``::
373+
374+
x: tuple[int, ...] = (1, 2)
375+
# These reassignments are OK: ``tuple[int, ...]`` indicates x can be of any length
376+
x = (1, 2, 3)
377+
x = ()
378+
# This reassignment is an error: all elements in ``x`` must be ints
379+
x = ("foo", "bar")
380+
381+
# ``y`` can only ever be assigned to an empty tuple
382+
y: tuple[()] = ()
383+
384+
z: tuple = ("foo", "bar")
385+
# These reassignments are OK: plain ``tuple`` is equivalent to ``tuple[Any, ...]``
386+
z = (1, 2, 3)
387+
z = ()
388+
327389
.. _user-defined-generics:
328390

329391
User-defined generic types
@@ -819,26 +881,6 @@ Special forms
819881
These can be used as types in annotations. They all support subscription using
820882
``[]``, but each has a unique syntax.
821883

822-
.. data:: Tuple
823-
824-
Deprecated alias for :class:`tuple`.
825-
826-
``Tuple[X, Y]`` is the type of a tuple of two items
827-
with the first item of type X and the second of type Y. The type of
828-
the empty tuple can be written as ``Tuple[()]``.
829-
830-
Example: ``Tuple[T1, T2]`` is a tuple of two elements corresponding
831-
to type variables T1 and T2. ``Tuple[int, float, str]`` is a tuple
832-
of an int, a float and a string.
833-
834-
To specify a variable-length tuple of homogeneous type,
835-
use literal ellipsis, e.g. ``Tuple[int, ...]``. A plain ``Tuple`` annotation
836-
is equivalent to ``tuple``, ``Tuple[Any, ...]``, or ``tuple[Any, ...]``.
837-
838-
.. deprecated:: 3.9
839-
:class:`builtins.tuple <tuple>` now supports subscripting (``[]``).
840-
See :pep:`585` and :ref:`types-genericalias`.
841-
842884
.. data:: Union
843885

844886
Union type; ``Union[X, Y]`` is equivalent to ``X | Y`` and means either X or Y.
@@ -2785,7 +2827,16 @@ Aliases to built-in types
27852827
now supports subscripting (``[]``).
27862828
See :pep:`585` and :ref:`types-genericalias`.
27872829

2788-
.. note:: :data:`Tuple` is a special form.
2830+
.. data:: Tuple
2831+
2832+
Deprecated alias for :class:`tuple`.
2833+
2834+
:class:`tuple` and ``Tuple`` are special-cased in the type system; see
2835+
:ref:`annotating-tuples` for more details.
2836+
2837+
.. deprecated:: 3.9
2838+
:class:`builtins.tuple <tuple>` now supports subscripting (``[]``).
2839+
See :pep:`585` and :ref:`types-genericalias`.
27892840

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

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.