mirror of
https://github.com/python/cpython.git
synced 2025-09-27 18:59:43 +00:00
[3.11] gh-103921: Improve typing documentation (GH-104642) (#105007)
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
This commit is contained in:
parent
dcfa8165ad
commit
d34e58a1d5
2 changed files with 190 additions and 158 deletions
|
@ -136,6 +136,13 @@ Type aliases are useful for simplifying complex type signatures. For example::
|
||||||
Note that ``None`` as a type hint is a special case and is replaced by
|
Note that ``None`` as a type hint is a special case and is replaced by
|
||||||
``type(None)``.
|
``type(None)``.
|
||||||
|
|
||||||
|
Type aliases may be marked with :data:`TypeAlias` to make it explicit that
|
||||||
|
the statement is a type alias declaration, not a normal variable assignment::
|
||||||
|
|
||||||
|
from typing import TypeAlias
|
||||||
|
|
||||||
|
Vector: TypeAlias = list[float]
|
||||||
|
|
||||||
.. _distinct:
|
.. _distinct:
|
||||||
|
|
||||||
NewType
|
NewType
|
||||||
|
@ -367,7 +374,7 @@ You can use multiple inheritance with :class:`Generic`::
|
||||||
class LinkedList(Sized, Generic[T]):
|
class LinkedList(Sized, Generic[T]):
|
||||||
...
|
...
|
||||||
|
|
||||||
When inheriting from generic classes, some type variables could be fixed::
|
When inheriting from generic classes, some type parameters could be fixed::
|
||||||
|
|
||||||
from collections.abc import Mapping
|
from collections.abc import Mapping
|
||||||
from typing import TypeVar
|
from typing import TypeVar
|
||||||
|
@ -387,7 +394,7 @@ not generic but implicitly inherits from ``Iterable[Any]``::
|
||||||
|
|
||||||
class MyIterable(Iterable): # Same as Iterable[Any]
|
class MyIterable(Iterable): # Same as Iterable[Any]
|
||||||
|
|
||||||
User defined generic type aliases are also supported. Examples::
|
User-defined generic type aliases are also supported. Examples::
|
||||||
|
|
||||||
from collections.abc import Iterable
|
from collections.abc import Iterable
|
||||||
from typing import TypeVar
|
from typing import TypeVar
|
||||||
|
@ -423,7 +430,6 @@ to this is that a list of types can be used to substitute a :class:`ParamSpec`::
|
||||||
>>> Z[int, [dict, float]]
|
>>> Z[int, [dict, float]]
|
||||||
__main__.Z[int, (<class 'dict'>, <class 'float'>)]
|
__main__.Z[int, (<class 'dict'>, <class 'float'>)]
|
||||||
|
|
||||||
|
|
||||||
Furthermore, a generic with only one parameter specification variable will accept
|
Furthermore, a generic with only one parameter specification variable will accept
|
||||||
parameter lists in the forms ``X[[Type1, Type2, ...]]`` and also
|
parameter lists in the forms ``X[[Type1, Type2, ...]]`` and also
|
||||||
``X[Type1, Type2, ...]`` for aesthetic reasons. Internally, the latter is converted
|
``X[Type1, Type2, ...]`` for aesthetic reasons. Internally, the latter is converted
|
||||||
|
@ -1249,7 +1255,8 @@ These can be used as types in annotations using ``[]``, each having a unique syn
|
||||||
Building generic types
|
Building generic types
|
||||||
""""""""""""""""""""""
|
""""""""""""""""""""""
|
||||||
|
|
||||||
These are not used in annotations. They are building blocks for creating generic types.
|
The following objects are not used directly in annotations. Instead, they are building blocks
|
||||||
|
for creating generic types.
|
||||||
|
|
||||||
.. class:: Generic
|
.. class:: Generic
|
||||||
|
|
||||||
|
@ -1275,7 +1282,7 @@ These are not used in annotations. They are building blocks for creating generic
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return default
|
return default
|
||||||
|
|
||||||
.. class:: TypeVar
|
.. class:: TypeVar(name, *constraints, bound=None, covariant=False, contravariant=False)
|
||||||
|
|
||||||
Type variable.
|
Type variable.
|
||||||
|
|
||||||
|
@ -1287,7 +1294,8 @@ These are not used in annotations. They are building blocks for creating generic
|
||||||
|
|
||||||
Type variables exist primarily for the benefit of static type
|
Type variables exist primarily for the benefit of static type
|
||||||
checkers. They serve as the parameters for generic types as well
|
checkers. They serve as the parameters for generic types as well
|
||||||
as for generic function definitions. See :class:`Generic` for more
|
as for generic function and type alias definitions.
|
||||||
|
See :class:`Generic` for more
|
||||||
information on generic types. Generic functions work as follows::
|
information on generic types. Generic functions work as follows::
|
||||||
|
|
||||||
def repeat(x: T, n: int) -> Sequence[T]:
|
def repeat(x: T, n: int) -> Sequence[T]:
|
||||||
|
@ -1308,6 +1316,11 @@ These are not used in annotations. They are building blocks for creating generic
|
||||||
Note that type variables can be *bound*, *constrained*, or neither, but
|
Note that type variables can be *bound*, *constrained*, or neither, but
|
||||||
cannot be both bound *and* constrained.
|
cannot be both bound *and* constrained.
|
||||||
|
|
||||||
|
Created type variables may be explicitly marked covariant or contravariant by passing
|
||||||
|
``covariant=True`` or ``contravariant=True``.
|
||||||
|
By default, type variables are invariant.
|
||||||
|
See :pep:`484` and :pep:`695` for more details.
|
||||||
|
|
||||||
Bound type variables and constrained type variables have different
|
Bound type variables and constrained type variables have different
|
||||||
semantics in several important ways. Using a *bound* type variable means
|
semantics in several important ways. Using a *bound* type variable means
|
||||||
that the ``TypeVar`` will be solved using the most specific type possible::
|
that the ``TypeVar`` will be solved using the most specific type possible::
|
||||||
|
@ -1329,7 +1342,7 @@ These are not used in annotations. They are building blocks for creating generic
|
||||||
U = TypeVar('U', bound=str|bytes) # Can be any subtype of the union str|bytes
|
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
|
V = TypeVar('V', bound=SupportsAbs) # Can be anything with an __abs__ method
|
||||||
|
|
||||||
.. _typing-constrained-typevar:
|
.. _typing-constrained-typevar:
|
||||||
|
|
||||||
Using a *constrained* type variable, however, means that the ``TypeVar``
|
Using a *constrained* type variable, however, means that the ``TypeVar``
|
||||||
can only ever be solved as being exactly one of the constraints given::
|
can only ever be solved as being exactly one of the constraints given::
|
||||||
|
@ -1342,29 +1355,46 @@ These are not used in annotations. They are building blocks for creating generic
|
||||||
|
|
||||||
c = concatenate('one', b'two') # error: type variable 'A' can be either str or bytes in a function call, but not both
|
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`. In general,
|
At runtime, ``isinstance(x, T)`` will raise :exc:`TypeError`.
|
||||||
:func:`isinstance` and :func:`issubclass` should not be used with types.
|
|
||||||
|
|
||||||
Type variables may be marked covariant or contravariant by passing
|
.. attribute:: __name__
|
||||||
``covariant=True`` or ``contravariant=True``. See :pep:`484` for more
|
|
||||||
details. By default, type variables are invariant.
|
|
||||||
|
|
||||||
.. class:: TypeVarTuple
|
The name of the type variable.
|
||||||
|
|
||||||
|
.. attribute:: __covariant__
|
||||||
|
|
||||||
|
Whether the type var has been marked as covariant.
|
||||||
|
|
||||||
|
.. attribute:: __contravariant__
|
||||||
|
|
||||||
|
Whether the type var has been marked as contravariant.
|
||||||
|
|
||||||
|
.. attribute:: __bound__
|
||||||
|
|
||||||
|
The bound of the type variable, if any.
|
||||||
|
|
||||||
|
.. attribute:: __constraints__
|
||||||
|
|
||||||
|
A tuple containing the constraints of the type variable, if any.
|
||||||
|
|
||||||
|
.. class:: TypeVarTuple(name)
|
||||||
|
|
||||||
Type variable tuple. A specialized form of :class:`type variable <TypeVar>`
|
Type variable tuple. A specialized form of :class:`type variable <TypeVar>`
|
||||||
that enables *variadic* generics.
|
that enables *variadic* generics.
|
||||||
|
|
||||||
|
Usage::
|
||||||
|
|
||||||
|
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
|
A normal type variable enables parameterization with a single type. A type
|
||||||
variable tuple, in contrast, allows parameterization with an
|
variable tuple, in contrast, allows parameterization with an
|
||||||
*arbitrary* number of types by acting like an *arbitrary* number of type
|
*arbitrary* number of types by acting like an *arbitrary* number of type
|
||||||
variables wrapped in a tuple. For example::
|
variables wrapped in a tuple. For example::
|
||||||
|
|
||||||
T = TypeVar('T')
|
|
||||||
Ts = TypeVarTuple('Ts')
|
|
||||||
|
|
||||||
def move_first_element_to_last(tup: tuple[T, *Ts]) -> tuple[*Ts, T]:
|
|
||||||
return (*tup[1:], tup[0])
|
|
||||||
|
|
||||||
# T is bound to int, Ts is bound to ()
|
# T is bound to int, Ts is bound to ()
|
||||||
# Return value is (1,), which has type tuple[int]
|
# Return value is (1,), which has type tuple[int]
|
||||||
move_first_element_to_last(tup=(1,))
|
move_first_element_to_last(tup=(1,))
|
||||||
|
@ -1400,7 +1430,7 @@ These are not used in annotations. They are building blocks for creating generic
|
||||||
Type variable tuples can be used in the same contexts as normal type
|
Type variable tuples can be used in the same contexts as normal type
|
||||||
variables. For example, in class definitions, arguments, and return types::
|
variables. For example, in class definitions, arguments, and return types::
|
||||||
|
|
||||||
Shape = TypeVarTuple('Shape')
|
Shape = TypeVarTuple("Shape")
|
||||||
class Array(Generic[*Shape]):
|
class Array(Generic[*Shape]):
|
||||||
def __getitem__(self, key: tuple[*Shape]) -> float: ...
|
def __getitem__(self, key: tuple[*Shape]) -> float: ...
|
||||||
def __abs__(self) -> "Array[*Shape]": ...
|
def __abs__(self) -> "Array[*Shape]": ...
|
||||||
|
@ -1445,6 +1475,10 @@ These are not used in annotations. They are building blocks for creating generic
|
||||||
|
|
||||||
See :pep:`646` for more details on type variable tuples.
|
See :pep:`646` for more details on type variable tuples.
|
||||||
|
|
||||||
|
.. attribute:: __name__
|
||||||
|
|
||||||
|
The name of the type variable tuple.
|
||||||
|
|
||||||
.. versionadded:: 3.11
|
.. versionadded:: 3.11
|
||||||
|
|
||||||
.. class:: ParamSpec(name, *, bound=None, covariant=False, contravariant=False)
|
.. class:: ParamSpec(name, *, bound=None, covariant=False, contravariant=False)
|
||||||
|
@ -1510,6 +1544,10 @@ These are not used in annotations. They are building blocks for creating generic
|
||||||
``P.args`` and ``P.kwargs`` are instances respectively of
|
``P.args`` and ``P.kwargs`` are instances respectively of
|
||||||
:class:`ParamSpecArgs` and :class:`ParamSpecKwargs`.
|
:class:`ParamSpecArgs` and :class:`ParamSpecKwargs`.
|
||||||
|
|
||||||
|
.. attribute:: __name__
|
||||||
|
|
||||||
|
The name of the parameter specification.
|
||||||
|
|
||||||
Parameter specification variables created with ``covariant=True`` or
|
Parameter specification variables created with ``covariant=True`` or
|
||||||
``contravariant=True`` can be used to declare covariant or contravariant
|
``contravariant=True`` can be used to declare covariant or contravariant
|
||||||
generic types. The ``bound`` argument is also accepted, similar to
|
generic types. The ``bound`` argument is also accepted, similar to
|
||||||
|
@ -1672,6 +1710,8 @@ These are not used in annotations. They are building blocks for declaring types.
|
||||||
|
|
||||||
Protocol classes can be generic, for example::
|
Protocol classes can be generic, for example::
|
||||||
|
|
||||||
|
T = TypeVar("T")
|
||||||
|
|
||||||
class GenProto(Protocol[T]):
|
class GenProto(Protocol[T]):
|
||||||
def meth(self) -> T:
|
def meth(self) -> T:
|
||||||
...
|
...
|
||||||
|
|
|
@ -1177,17 +1177,9 @@ class ParamSpec(_Final, _Immutable, _BoundVarianceMixin, _PickleUsingNameMixin,
|
||||||
'''Add two numbers together.'''
|
'''Add two numbers together.'''
|
||||||
return x + y
|
return x + y
|
||||||
|
|
||||||
Parameter specification variables defined with covariant=True or
|
|
||||||
contravariant=True can be used to declare covariant or contravariant
|
|
||||||
generic types. These keyword arguments are valid, but their actual semantics
|
|
||||||
are yet to be decided. See PEP 612 for details.
|
|
||||||
|
|
||||||
Parameter specification variables can be introspected. e.g.:
|
Parameter specification variables can be introspected. e.g.:
|
||||||
|
|
||||||
P.__name__ == 'P'
|
P.__name__ == 'P'
|
||||||
P.__bound__ == None
|
|
||||||
P.__covariant__ == False
|
|
||||||
P.__contravariant__ == False
|
|
||||||
|
|
||||||
Note that only parameter specification variables defined in global scope can
|
Note that only parameter specification variables defined in global scope can
|
||||||
be pickled.
|
be pickled.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue