8000 Typing docs: improve the guidance on annotating tuples (#106021) · python/cpython@968435d · GitHub
[go: up one dir, main page]

Skip to content

Commit 968435d

Browse files
authored
Typing docs: improve the guidance on annotating tuples (#106021)
1 parent 37c5c40 commit 968435d

File tree

1 file changed

+72
-21
lines changed

1 file changed

+72
-21
lines changed

Doc/library/typing.rst

Lines changed: 72 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,68 @@ Or by using the :class:`TypeVar` factory directly::
346346
.. versionchanged:: 3.12
347347
Syntactic support for generics is new in Python 3.12.
348348

349+
.. _annotating-tuples:
350+
351+
Annotating tuples
352+
=================
353+
354+
For most containers in Python, the typing system assumes that all elements in
355+
the container will be of the same type. For example::
356+
357+
from collections.abc import Mapping
358+
359+
# Type checker will infer that all elements in ``x`` are meant to be ints
360+
x: list[int] = []
361+
362+
# Type checker error: ``list`` only accepts a single type argument:
363+
y: list[int, str] = [1, 'foo']
364+
365+
# Type checker will infer that all keys in ``y`` are meant to be strings,
366+
# and that all values in ``y`` are meant to be either strings or ints
367+
z: Mapping[str, str | int] = {}
368+
369+
:class:`list` only accepts one type argument, so a type checker would emit an
370+
error on the ``y`` assignment above. Similarly,
371+
:class:`~collections.abc.Mapping` only accepts two type arguments: the first
372+
indicates the type of the keys, and the second indicates the type of the
373+
values.
374+
375+
Unlike most other Python containers, however, it is common in idiomatic Python
376+
code for tuples to have elements which are not all of the same type. For this
377+
reason, tuples are special-cased in Python's typing system. :class:`tuple`
378+
accepts *any number* of type arguments::
379+
380+
# OK: ``x`` is assigned to a tuple of length 1 where the sole element is an int
381+
x: tuple[int] = (5,)
382+
383+
# OK: ``y`` is assigned to a tuple of length 2;
384+
# element 1 is an int, element 2 is a str
385+
y: tuple[int, str] = (5, "foo")
386+
387+
# Error: the type annotation indicates a tuple of length 1,
388+
# but ``z`` has been assigned to a tuple of length 3
389+
z: tuple[int] = (1, 2, 3)
390+
391+
To denote a tuple which could be of *any* length, and in which all elements are
392+
of the same type ``T``, use ``tuple[T, ...]``. To denote an empty tuple, use
393+
``tuple[()]``. Using plain ``tuple`` as an annotation is equivalent to using
394+
``tuple[Any, ...]``::
395+
396+
x: tuple[int, ...] = (1, 2)
397+
# These reassignments are OK: ``tuple[int, ...]`` indicates x can be of any length
398+
x = (1, 2, 3)
399+
x = ()
400+
# This reassignment is an error: all elements in ``x`` must be ints
401+
x = ("foo", "bar")
402+
403+
# ``y`` can only ever be assigned to an empty tuple
404+
y: tuple[()] = ()
405+
406+
z: tuple = ("foo", "bar")
407+
# These reassignments are OK: plain ``tuple`` is equivalent to ``tuple[Any, ...]``
408+
z = (1, 2, 3)
409+
z = ()
410+
349411
.. _user-defined-generics:
350412

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

880-
.. data:: Tuple
881-
882-
Deprecated alias for :class:`tuple`.
883-
884-
``Tuple[X, Y]`` is the type of a tuple of two items
885-
with the first item of type X and the second of type Y. The type of
886-
the empty tuple can be written as ``Tuple[()]``.
887-
888-
Example: ``Tuple[T1, T2]`` is a tuple of two elements corresponding
889-
to type variables T1 and T2. ``Tuple[int, float, str]`` is a tuple
890-
of an int, a float and a string.
891-
892-
To specify a variable-length tuple of homogeneous type,
893-
use literal ellipsis, e.g. ``Tuple[int, ...]``. A plain ``Tuple`` annotation
894-
is equivalent to ``tuple``, ``Tuple[Any, ...]``, or ``tuple[Any, ...]``.
895-
896-
.. deprecated:: 3.9
897-
:class:`builtins.tuple <tuple>` now supports subscripting (``[]``).
898-
See :pep:`585` and :ref:`types-genericalias`.
899-
900942
.. data:: Union
901943

902944
Union type; ``Union[X, Y]`` is equivalent to ``X | Y`` and means either X or Y.
@@ -3136,7 +3178,16 @@ Aliases to built-in types
31363178
now supports subscripting (``[]``).
31373179
See :pep:`585` and :ref:`types-genericalias`.
31383180

3139-
.. note:: :data:`Tuple` is a special form.
3181+
.. data:: Tuple
3182+
3183+
Deprecated alias for :class:`tuple`.
3184+
3185+
:class:`tuple` and ``Tuple`` are special-cased in the type system; see
3186+
:ref:`annotating-tuples` for more details.
3187+
3188+
.. deprecated:: 3.9
3189+
:class:`builtins.tuple <tuple>` now supports subscripting (``[]``).
3190+
See :pep:`585` and :ref:`types-genericalias`.
31403191

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

0 commit comments

Comments
 (0)
0