@@ -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
351413User-defined generic types
@@ -877,26 +939,6 @@ Special forms
877939These 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.
@@ -3091,7 +3133,16 @@ Aliases to built-in types
30913133 now supports subscripting (``[] ``).
30923134 See :pep: `585 ` and :ref: `types-genericalias `.
30933135
3094- .. note :: :data:`Tuple` is a special form.
3136+ .. data :: Tuple
3137+
3138+ Deprecated alias for :class: `tuple `.
3139+
3140+ :class: `tuple ` and ``Tuple `` are special-cased in the type system; see
3141+ :ref: `annotating-tuples ` for more details.
3142+
3143+ .. deprecated :: 3.9
3144+ :class: `builtins.tuple <tuple> ` now supports subscripting (``[] ``).
3145+ See :pep: `585 ` and :ref: `types-genericalias `.
30953146
30963147.. _corresponding-to-types-in-collections :
30973148
0 commit comments