mirror of https://github.com/python/cpython
[3.13] gh-123523: Rework typing documentation for generators and coroutines, and link to it from `collections.abc` docs (GH-123544) (#123790)
gh-123523: Rework typing documentation for generators and coroutines, and link to it from `collections.abc` docs (GH-123544)
(cherry picked from commit 56e4a417ce
)
Co-authored-by: Stanislav Terliakov <50529348+sterliakov@users.noreply.github.com>
This commit is contained in:
parent
905288824d
commit
e62cb77c25
|
@ -216,6 +216,9 @@ Collections Abstract Base Classes -- Detailed Descriptions
|
|||
|
||||
ABC for classes that provide the :meth:`~object.__call__` method.
|
||||
|
||||
See :ref:`annotating-callables` for details on how to use
|
||||
:class:`!Callable` in type annotations.
|
||||
|
||||
.. class:: Iterable
|
||||
|
||||
ABC for classes that provide the :meth:`~container.__iter__` method.
|
||||
|
@ -253,6 +256,9 @@ Collections Abstract Base Classes -- Detailed Descriptions
|
|||
:meth:`~generator.send`,
|
||||
:meth:`~generator.throw` and :meth:`~generator.close` methods.
|
||||
|
||||
See :ref:`annotating-generators-and-coroutines`
|
||||
for details on using :class:`!Generator` in type annotations.
|
||||
|
||||
.. versionadded:: 3.5
|
||||
|
||||
.. class:: Sequence
|
||||
|
@ -331,6 +337,11 @@ Collections Abstract Base Classes -- Detailed Descriptions
|
|||
Using ``isinstance(gencoro, Coroutine)`` for them will return ``False``.
|
||||
Use :func:`inspect.isawaitable` to detect them.
|
||||
|
||||
See :ref:`annotating-generators-and-coroutines`
|
||||
for details on using :class:`!Coroutine` in type annotations.
|
||||
The variance and order of type parameters correspond to those of
|
||||
:class:`Generator`.
|
||||
|
||||
.. versionadded:: 3.5
|
||||
|
||||
.. class:: AsyncIterable
|
||||
|
@ -352,6 +363,9 @@ Collections Abstract Base Classes -- Detailed Descriptions
|
|||
ABC for :term:`asynchronous generator` classes that implement the protocol
|
||||
defined in :pep:`525` and :pep:`492`.
|
||||
|
||||
See :ref:`annotating-generators-and-coroutines`
|
||||
for details on using :class:`!AsyncGenerator` in type annotations.
|
||||
|
||||
.. versionadded:: 3.6
|
||||
|
||||
.. class:: Buffer
|
||||
|
|
|
@ -208,7 +208,7 @@ Annotating callable objects
|
|||
===========================
|
||||
|
||||
Functions -- or other :term:`callable` objects -- can be annotated using
|
||||
:class:`collections.abc.Callable` or :data:`typing.Callable`.
|
||||
:class:`collections.abc.Callable` or deprecated :data:`typing.Callable`.
|
||||
``Callable[[int], str]`` signifies a function that takes a single parameter
|
||||
of type :class:`int` and returns a :class:`str`.
|
||||
|
||||
|
@ -401,7 +401,7 @@ The type of class objects
|
|||
=========================
|
||||
|
||||
A variable annotated with ``C`` may accept a value of type ``C``. In
|
||||
contrast, a variable annotated with ``type[C]`` (or
|
||||
contrast, a variable annotated with ``type[C]`` (or deprecated
|
||||
:class:`typing.Type[C] <Type>`) may accept values that are classes
|
||||
themselves -- specifically, it will accept the *class object* of ``C``. For
|
||||
example::
|
||||
|
@ -441,6 +441,87 @@ For example::
|
|||
``type[Any]`` is equivalent to :class:`type`, which is the root of Python's
|
||||
:ref:`metaclass hierarchy <metaclasses>`.
|
||||
|
||||
|
||||
.. _annotating-generators-and-coroutines:
|
||||
|
||||
Annotating generators and coroutines
|
||||
====================================
|
||||
|
||||
A generator can be annotated using the generic type
|
||||
:class:`Generator[YieldType, SendType, ReturnType] <collections.abc.Generator>`.
|
||||
For example::
|
||||
|
||||
def echo_round() -> Generator[int, float, str]:
|
||||
sent = yield 0
|
||||
while sent >= 0:
|
||||
sent = yield round(sent)
|
||||
return 'Done'
|
||||
|
||||
Note that unlike many other generic classes in the standard library,
|
||||
the ``SendType`` of :class:`~collections.abc.Generator` behaves
|
||||
contravariantly, not covariantly or invariantly.
|
||||
|
||||
The ``SendType`` and ``ReturnType`` parameters default to :const:`!None`::
|
||||
|
||||
def infinite_stream(start: int) -> Generator[int]:
|
||||
while True:
|
||||
yield start
|
||||
start += 1
|
||||
|
||||
It is also possible to set these types explicitly::
|
||||
|
||||
def infinite_stream(start: int) -> Generator[int, None, None]:
|
||||
while True:
|
||||
yield start
|
||||
start += 1
|
||||
|
||||
Simple generators that only ever yield values can also be annotated
|
||||
as having a return type of either
|
||||
:class:`Iterable[YieldType] <collections.abc.Iterable>`
|
||||
or :class:`Iterator[YieldType] <collections.abc.Iterator>`::
|
||||
|
||||
def infinite_stream(start: int) -> Iterator[int]:
|
||||
while True:
|
||||
yield start
|
||||
start += 1
|
||||
|
||||
Async generators are handled in a similar fashion, but don't
|
||||
expect a ``ReturnType`` type argument
|
||||
(:class:`AsyncGenerator[YieldType, SendType] <collections.abc.AsyncGenerator>`).
|
||||
The ``SendType`` argument defaults to :const:`!None`, so the following definitions
|
||||
are equivalent::
|
||||
|
||||
async def infinite_stream(start: int) -> AsyncGenerator[int]:
|
||||
while True:
|
||||
yield start
|
||||
start = await increment(start)
|
||||
|
||||
async def infinite_stream(start: int) -> AsyncGenerator[int, None]:
|
||||
while True:
|
||||
yield start
|
||||
start = await increment(start)
|
||||
|
||||
As in the synchronous case,
|
||||
:class:`AsyncIterable[YieldType] <collections.abc.AsyncIterable>`
|
||||
and :class:`AsyncIterator[YieldType] <collections.abc.AsyncIterator>` are
|
||||
available as well::
|
||||
|
||||
async def infinite_stream(start: int) -> AsyncIterator[int]:
|
||||
while True:
|
||||
yield start
|
||||
start = await increment(start)
|
||||
|
||||
Coroutines can be annotated using
|
||||
:class:`Coroutine[YieldType, SendType, ReturnType] <collections.abc.Coroutine>`.
|
||||
Generic arguments correspond to those of :class:`~collections.abc.Generator`,
|
||||
for example::
|
||||
|
||||
from collections.abc import Coroutine
|
||||
c: Coroutine[list[str], str, int] # Some coroutine defined elsewhere
|
||||
x = c.send('hi') # Inferred type of 'x' is list[str]
|
||||
async def bar() -> None:
|
||||
y = await c # Inferred type of 'y' is int
|
||||
|
||||
.. _user-defined-generics:
|
||||
|
||||
User-defined generic types
|
||||
|
@ -3318,14 +3399,9 @@ Aliases to built-in types
|
|||
Deprecated alias to :class:`dict`.
|
||||
|
||||
Note that to annotate arguments, it is preferred
|
||||
to use an abstract collection type such as :class:`Mapping`
|
||||
to use an abstract collection type such as :class:`~collections.abc.Mapping`
|
||||
rather than to use :class:`dict` or :class:`!typing.Dict`.
|
||||
|
||||
This type can be used as follows::
|
||||
|
||||
def count_words(text: str) -> Dict[str, int]:
|
||||
...
|
||||
|
||||
.. deprecated:: 3.9
|
||||
:class:`builtins.dict <dict>` now supports subscripting (``[]``).
|
||||
See :pep:`585` and :ref:`types-genericalias`.
|
||||
|
@ -3335,16 +3411,9 @@ Aliases to built-in types
|
|||
Deprecated alias to :class:`list`.
|
||||
|
||||
Note that to annotate arguments, it is preferred
|
||||
to use an abstract collection type such as :class:`Sequence` or
|
||||
:class:`Iterable` rather than to use :class:`list` or :class:`!typing.List`.
|
||||
|
||||
This type may be used as follows::
|
||||
|
||||
def vec2[T: (int, float)](x: T, y: T) -> List[T]:
|
||||
return [x, y]
|
||||
|
||||
def keep_positives[T: (int, float)](vector: Sequence[T]) -> List[T]:
|
||||
return [item for item in vector if item > 0]
|
||||
to use an abstract collection type such as
|
||||
:class:`~collections.abc.Sequence` or :class:`~collections.abc.Iterable`
|
||||
rather than to use :class:`list` or :class:`!typing.List`.
|
||||
|
||||
.. deprecated:: 3.9
|
||||
:class:`builtins.list <list>` now supports subscripting (``[]``).
|
||||
|
@ -3355,8 +3424,8 @@ Aliases to built-in types
|
|||
Deprecated alias to :class:`builtins.set <set>`.
|
||||
|
||||
Note that to annotate arguments, it is preferred
|
||||
to use an abstract collection type such as :class:`AbstractSet`
|
||||
rather than to use :class:`set` or :class:`!typing.Set`.
|
||||
to use an abstract collection type such as :class:`collections.abc.Set`
|
||||
rather than to use :class:`set` or :class:`typing.Set`.
|
||||
|
||||
.. deprecated:: 3.9
|
||||
:class:`builtins.set <set>` now supports subscripting (``[]``).
|
||||
|
@ -3552,11 +3621,6 @@ Aliases to container ABCs in :mod:`collections.abc`
|
|||
|
||||
Deprecated alias to :class:`collections.abc.Mapping`.
|
||||
|
||||
This type can be used as follows::
|
||||
|
||||
def get_position_in_index(word_list: Mapping[str, int], word: str) -> int:
|
||||
return word_list[word]
|
||||
|
||||
.. deprecated:: 3.9
|
||||
:class:`collections.abc.Mapping` now supports subscripting (``[]``).
|
||||
See :pep:`585` and :ref:`types-genericalias`.
|
||||
|
@ -3620,14 +3684,9 @@ Aliases to asynchronous ABCs in :mod:`collections.abc`
|
|||
|
||||
Deprecated alias to :class:`collections.abc.Coroutine`.
|
||||
|
||||
The variance and order of type variables
|
||||
correspond to those of :class:`Generator`, for example::
|
||||
|
||||
from collections.abc import Coroutine
|
||||
c: Coroutine[list[str], str, int] # Some coroutine defined elsewhere
|
||||
x = c.send('hi') # Inferred type of 'x' is list[str]
|
||||
async def bar() -> None:
|
||||
y = await c # Inferred type of 'y' is int
|
||||
See :ref:`annotating-generators-and-coroutines`
|
||||
for details on using :class:`collections.abc.Coroutine`
|
||||
and ``typing.Coroutine`` in type annotations.
|
||||
|
||||
.. versionadded:: 3.5.3
|
||||
|
||||
|
@ -3639,40 +3698,9 @@ Aliases to asynchronous ABCs in :mod:`collections.abc`
|
|||
|
||||
Deprecated alias to :class:`collections.abc.AsyncGenerator`.
|
||||
|
||||
An async generator can be annotated by the generic type
|
||||
``AsyncGenerator[YieldType, SendType]``. For example::
|
||||
|
||||
async def echo_round() -> AsyncGenerator[int, float]:
|
||||
sent = yield 0
|
||||
while sent >= 0.0:
|
||||
rounded = await round(sent)
|
||||
sent = yield rounded
|
||||
|
||||
Unlike normal generators, async generators cannot return a value, so there
|
||||
is no ``ReturnType`` type parameter. As with :class:`Generator`, the
|
||||
``SendType`` behaves contravariantly.
|
||||
|
||||
The ``SendType`` defaults to :const:`!None`::
|
||||
|
||||
async def infinite_stream(start: int) -> AsyncGenerator[int]:
|
||||
while True:
|
||||
yield start
|
||||
start = await increment(start)
|
||||
|
||||
It is also possible to set this type explicitly::
|
||||
|
||||
async def infinite_stream(start: int) -> AsyncGenerator[int, None]:
|
||||
while True:
|
||||
yield start
|
||||
start = await increment(start)
|
||||
|
||||
Alternatively, annotate your generator as having a return type of
|
||||
either ``AsyncIterable[YieldType]`` or ``AsyncIterator[YieldType]``::
|
||||
|
||||
async def infinite_stream(start: int) -> AsyncIterator[int]:
|
||||
while True:
|
||||
yield start
|
||||
start = await increment(start)
|
||||
See :ref:`annotating-generators-and-coroutines`
|
||||
for details on using :class:`collections.abc.AsyncGenerator`
|
||||
and ``typing.AsyncGenerator`` in type annotations.
|
||||
|
||||
.. versionadded:: 3.6.1
|
||||
|
||||
|
@ -3754,40 +3782,9 @@ Aliases to other ABCs in :mod:`collections.abc`
|
|||
|
||||
Deprecated alias to :class:`collections.abc.Generator`.
|
||||
|
||||
A generator can be annotated by the generic type
|
||||
``Generator[YieldType, SendType, ReturnType]``. For example::
|
||||
|
||||
def echo_round() -> Generator[int, float, str]:
|
||||
sent = yield 0
|
||||
while sent >= 0:
|
||||
sent = yield round(sent)
|
||||
return 'Done'
|
||||
|
||||
Note that unlike many other generics in the typing module, the ``SendType``
|
||||
of :class:`Generator` behaves contravariantly, not covariantly or
|
||||
invariantly.
|
||||
|
||||
The ``SendType`` and ``ReturnType`` parameters default to :const:`!None`::
|
||||
|
||||
def infinite_stream(start: int) -> Generator[int]:
|
||||
while True:
|
||||
yield start
|
||||
start += 1
|
||||
|
||||
It is also possible to set these types explicitly::
|
||||
|
||||
def infinite_stream(start: int) -> Generator[int, None, None]:
|
||||
while True:
|
||||
yield start
|
||||
start += 1
|
||||
|
||||
Alternatively, annotate your generator as having a return type of
|
||||
either ``Iterable[YieldType]`` or ``Iterator[YieldType]``::
|
||||
|
||||
def infinite_stream(start: int) -> Iterator[int]:
|
||||
while True:
|
||||
yield start
|
||||
start += 1
|
||||
See :ref:`annotating-generators-and-coroutines`
|
||||
for details on using :class:`collections.abc.Generator`
|
||||
and ``typing.Generator`` in type annotations.
|
||||
|
||||
.. deprecated:: 3.9
|
||||
:class:`collections.abc.Generator` now supports subscripting (``[]``).
|
||||
|
|
Loading…
Reference in New Issue