8000 gh-123523: Rework typing documentation for generators and coroutines,… · python/cpython@56e4a41 · GitHub
[go: up one dir, main page]

Skip to content

Commit 56e4a41

Browse files
authored
gh-123523: Rework typing documentation for generators and coroutines, and link to it from collections.abc docs (#123544)
1 parent d343f97 commit 56e4a41

File tree

2 files changed

+112
-101
lines changed

2 files changed

+112
-101
lines changed

Doc/library/collections.abc.rst

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,9 @@ Collections Abstract Base Classes -- Detailed Descriptions
213213

214214
ABC for classes that provide the :meth:`~object.__call__` method.
215215

216+
See :ref:`annotating-callables` for details on how to use
217+
:class:`!Callable` in type annotations.
218+
216219
.. class:: Iterable
217220

218221
ABC for classes that provide the :meth:`~container.__iter__` method.
@@ -250,6 +253,9 @@ Collections Abstract Base Classes -- Detailed Descriptions
250253
:meth:`~generator.send`,
251254
:meth:`~generator.throw` and :meth:`~generator.close` methods.
252255

256+
See :ref:`annotating-generators-and-coroutines`
257+
for details on using :class:`!Generator` in type annotations.
258+
253259
.. versionadded:: 3.5
254260

255261
.. class:: Sequence
@@ -321,6 +327,11 @@ Collections Abstract Base Classes -- Detailed Descriptions
321327
Using ``isinstance(gencoro, Coroutine)`` for them will return ``False``.
322328
Use :func:`inspect.isawaitable` to detect them.
323329

330+
See :ref:`annotating-generators-and-coroutines`
331+
for details on using :class:`!Coroutine` in type annotations.
332+
The variance and order of type parameters correspond to those of
333+
:class:`Generator`.
334+
324335
.. versionadded:: 3.5
325336

326337
.. class:: AsyncIterable
@@ -342,6 +353,9 @@ Collections Abstract Base Classes -- Detailed Descriptions
342353
ABC for :term:`asynchronous generator` classes that implement the protocol
343354
defined in :pep:`525` and :pep:`492`.
344355

356+
See :ref:`annotating-generators-and-coroutines`
357+
for details on using :class:`!AsyncGenerator` in type annotations.
358+
345359
.. versionadded:: 3.6
346360

347361
.. class:: Buffer

Doc/library/typing.rst

Lines changed: 98 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ Annotating callable objects
208208
===========================
209209

210210
Functions -- or other :term:`callable` objects -- can be annotated using
211-
:class:`collections.abc.Callable` or :data:`typing.Callable`.
211+
:class:`collections.abc.Callable` or deprecated :data:`typing.Callable`.
212212
``Callable[[int], str]`` signifies a function that takes a single parameter
213213
of type :class:`int` and returns a :class:`str`.
214214

@@ -401,7 +401,7 @@ The type of class objects
401401
=========================
402402

403403
A variable annotated with ``C`` may accept a value of type ``C``. In
404-
contrast, a variable annotated with ``type[C]`` (or
404+
contrast, a variable annotated with ``type[C]`` (or deprecated
405405
:class:`typing.Type[C] <Type>`) may accept values that are classes
406406
themselves -- specifically, it will accept the *class object* of ``C``. For
407407
example::
@@ -441,6 +441,87 @@ For example::
441441
``type[Any]`` is equivalent to :class:`type`, which is the root of Python's
442442
:ref:`metaclass hierarchy <metaclasses>`.
443443

444+
445+
.. _annotating-generators-and-coroutines:
446+
447+
Annotating generators and coroutines
448+
====================================
449+
450+
A generator can be annotated using the generic type
451+
:class:`Generator[YieldType, SendType, ReturnType] <collections.abc.Generator>`.
452+
For example::
453+
454+
def echo_round() -> Generator[int, float, str]:
455+
sent = yield 0
456+
while sent >= 0:
457+
sent = yield round(sent)
458+
return 'Done'
459+
460+
Note that unlike many other generic classes in the standard library,
461+
the ``SendType`` of :class:`~collections.abc.Generator` behaves
462+
contravariantly, not covariantly or invariantly.
463+
464+
The ``SendType`` and ``ReturnType`` parameters default to :const:`!None`::
465+
466+
def infinite_stream(start: int) -> Generator[int]:
467+
while True:
468+
yield start
469+
start += 1
470+
471+
It is also possible to set these types explicitly::
472+
473+
def infinite_stream(start: int) -> Generator[int, None, None]:
474+
while True:
475+
yield start
476+
start += 1
477+
478+
Simple generators that only ever yield values can also be annotated
479+
as having a return type of either
480+
:class:`Iterable[YieldType] <collections.abc.Iterable>`
481+
or :class:`Iterator[YieldType] <collections.abc.Iterator>`::
482+
483+
def infinite_stream(start: int) -> Iterator[int]:
484+
while True:
485+
yield start
486+
start += 1
487+
488+
Async generators are handled in a similar fashion, but don't
489+
expect a ``ReturnType`` type argument
490+
(:class:`AsyncGenerator[YieldType, SendType] <collections.abc.AsyncGenerator>`).
491+
The ``SendType`` argument defaults to :const:`!None`, so the following definitions
492+
are equivalent::
493+
494+
async def infinite_stream(start: int) -> AsyncGenerator[int]:
495+
while True:
496+
yield start
497+
start = await increment(start)
498+
499+
async def infinite_stream(start: int) -> AsyncGenerator[int, None]:
500+
while True:
501+
yield start
502+
start = await increment(start)
503+
504+
As in the synchronous case,
505+
:class:`AsyncIterable[YieldType] <collections.abc.AsyncIterable>`
506+
and :class:`AsyncIterator[YieldType] <collections.abc.AsyncIterator>` are
507+
available as well::
508+
509+
async def infinite_stream(start: int) -> AsyncIterator[int]:
510+
while True:
511+
yield start
512+
start = await increment(start)
513+
514+
Coroutines can be annotated using
515+
:class:`Coroutine[YieldType, SendType, ReturnType] <collections.abc.Coroutine>`.
516+
Generic arguments correspond to those of :class:`~collections.abc.Generator`,
517+
for example::
518+
519+
from collections.abc import Coroutine
520+
c: Coroutine[list[str], str, int] # Some coroutine defined elsewhere
521+
x = c.send('hi') # Inferred type of 'x' is list[str]
522+
async def bar() -> None:
523+
y = await c # Inferred type of 'y' is int
524+
444525
.. _user-defined-generics:
445526

446527
User-defined generic types
@@ -3318,14 +3399,9 @@ Aliases to built-in types
33183399
Deprecated alias to :class:`dict`.
33193400

33203401
Note that to annotate arguments, it is preferred
3321-
to use an abstract collection type such as :class:`Mapping`
3402+
to use an abstract collection type such as :class:`~collections.abc.Mapping`
33223403
rather than to use :class:`dict` or :class:`!typing.Dict`.
33233404

3324-
This type can be used as follows::
3325-
3326-
def count_words(text: str) -> Dict[str, int]:
3327-
...
3328-
33293405
.. deprecated:: 3.9
33303406
:class:`builtins.dict <dict>` now supports subscripting (``[]``).
33313407
See :pep:`585` and :ref:`types-genericalias`.
@@ -3335,16 +3411,9 @@ Aliases to built-in types
33353411
Deprecated alias to :class:`list`.
33363412

33373413
Note that to annotate arguments, it is preferred
3338-
to use an abstract collection type such as :class:`Sequence` or
3339-
:class:`Iterable` rather than to use :class:`list` or :class:`!typing.List`.
3340-
3341-
This type may be used as follows::
3342-
3343-
def vec2[T: (int, float)](x: T, y: T) -> List[T]:
3344-
return [x, y]
3345-
3346-
def keep_positives[T: (int, float)](vector: Sequence[T]) -> List[T]:
3347-
return [item for item in vector if item > 0]
3414+
to use an abstract collection type such as
3415+
:class:`~collections.abc.Sequence` or :class:`~collections.abc.Iterable`
3416+
rather than to use :class:`list` or :class:`!typing.List`.
33483417

33493418
.. deprecated:: 3.9
33503419
:class:`builtins.list <list>` now supports subscripting (``[]``).
@@ -3355,8 +3424,8 @@ Aliases to built-in types
33553424
Deprecated alias to :class:`builtins.set <set>`.
33563425

33573426
Note that to annotate arguments, it is preferred
3358-
to use an abstract collection type such as :class:`AbstractSet`
3359-
rather than to use :class:`set` or :class:`!typing.Set`.
3427+
to use an abstract collection type such as :class:`collections.abc.Set`
3428+
rather than to use :class:`set` or :class:`typing.Set`.
33603429

33613430
.. deprecated:: 3.9
33623431
:class:`builtins.set <set>` now supports subscripting (``[]``).
@@ -3544,11 +3613,6 @@ Aliases to container ABCs in :mod:`collections.abc`
35443613

35453614
Deprecated alias to :class:`collections.abc.Mapping`.
35463615

3547-
This type can be used as follows::
3548-
3549-
def get_position_in_index(word_list: Mapping[str, int], word: str) -> int:
3550-
return word_list[word]
3551-
35523616
.. deprecated:: 3.9
35533617
:class:`collections.abc.Mapping` now supports subscripting (``[]``).
35543618
See :pep:`585` and :ref:`types-genericalias`.
@@ -3612,14 +3676,9 @@ Aliases to asynchronous ABCs in :mod:`collections.abc`
36123676

36133677
Deprecated alias to :class:`collections.abc.Coroutine`.
36143678

3615-
The variance and order of type variables
3616-
correspond to those of :class:`Generator`, for example::
3617-
3618-
from collections.abc import Coroutine
3619-
c: Coroutine[list[str], str, int] # Some coroutine defined elsewhere
3620-
x = c.send('hi') # Inferred type of 'x' is list[str]
3621-
async def bar() -> None:
3622-
y = await c # Inferred type of 'y' is int
3679+
See :ref:`annotating-generators-and-coroutines`
3680+
for details on using :class:`collections.abc.Coroutine`
3681+
and ``typing.Coroutine`` in type annotations.
36233682

36243683
.. versionadded:: 3.5.3
36253684

@@ -3631,40 +3690,9 @@ Aliases to asynchronous ABCs in :mod:`collections.abc`
36313690

36323691
Deprecated alias to :class:`collections.abc.AsyncGenerator`.
36333692

3634-
An async generator can be annotated by the generic type
3635-
``AsyncGenerator[YieldType, SendType]``. For example::
3636-
3637-
async def echo_round() -> AsyncGenerator[int, float]:
3638-
sent = yield 0
3639-
while sent >= 0.0:
3640-
rounded = await round(sent)
3641-
sent = yield rounded
3642-
3643-
Unlike normal generators, async generators cannot return a value, so there
3644-
is no ``ReturnType`` type parameter. As with :class:`Generator`, the
3645-
``SendType`` behaves contravariantly.
3646-
3647-
The ``SendType`` defaults to :const:`!None`::
3648-
3649-
async def infinite_stream(start: int) -> AsyncGenerator[int]:
3650-
while True:
3651-
yield start
3652-
start = await increment(start)
3653-
3654-
It is also possible to set this type explicitly::
3655-
3656-
async def infinite_stream(start: int) -> AsyncGenerator[int, None]:
3657-
while True:
3658-
yield start
3659-
start = await increment(start)
3660-
3661-
Alternatively, annotate your generator as having a return type of
3662-
either ``AsyncIterable[YieldType]`` or ``AsyncIterator[YieldType]``::
3663-
3664-
async def infinite_stream(start: int) -> AsyncIterator[int]:
3665-
while True:
3666-
yield start
3667-
start = await increment(start)
3693+
See :ref:`annotating-generators-and-coroutines`
3694+
for details on using :class:`collections.abc.AsyncGenerator`
3695+
and ``typing.AsyncGenerator`` in type annotations.
36683696

36693697
.. versionadded:: 3.6.1
36703698

@@ -3746,40 +3774,9 @@ Aliases to other ABCs in :mod:`collections.abc`
37463774

37473775
Deprecated alias to :class:`collections.abc.Generator`.
37483776

3749-
A generator can be annotated by the generic type
3750-
``Generator[YieldType, SendType, ReturnType]``. For example::
3751-
3752-
def echo_round() -> Generator[int, float, str]:
3753-
sent = yield 0
3754-
while sent >= 0:
3755-
sent = yield round(sent)
3756-
return 'Done'
3757-
3758-
Note that unlike many other generics in the typing module, the ``SendType``
3759-
of :class:`Generator` behaves contravariantly, not covariantly or
3760-
invariantly.
3761-
3762-
The ``SendType`` and ``ReturnType`` parameters default to :const:`!None`::
3763-
3764-
def infinite_stream(start: int) -> Generator[int]:
3765-
while True:
3766-
yield start
3767-
start += 1
3768-
3769-
It is also possible to set these types explicitly::
3770-
3771-
def infinite_stream(start: int) -> Generator[int, None, None]:
3772-
while True:
3773-
yield start
3774-
start += 1
3775-
3776-
Alternatively, annotate your generator as having a return type of
3777-
either ``Iterable[YieldType]`` or ``Iterator[YieldType]``::
3778-
3779-
def infinite_stream(start: int) -> Iterator[int]:
3780-
while True:
3781-
yield start
3782-
start += 1
3777+
See :ref:`annotating-generators-and-coroutines`
3778+
for details on using :class:`collections.abc.Generator`
3779+
and ``typing.Generator`` in type annotations.
37833780

37843781
.. deprecated:: 3.9
37853782
:class:`collections.abc.Generator` now supports subscripting (``[]``).

0 commit comments

Comments
 (0)
0