8000 [3.12] gh-123523: Rework typing documentation for generators and coro… · python/cpython@7e51091 · GitHub
[go: up one dir, main page]

Skip to content

Commit 7e51091

Browse files
[3.12] gh-123523: Rework typing documentation for generators and coroutines, and link to it from collections.abc docs (#123544) (#123792)
Co-authored-by: Stanislav Terliakov <50529348+sterliakov@users.noreply.github.com>
1 parent 9468242 commit 7e51091

File tree

2 files changed

+97
-89
lines changed

2 files changed

+97
-89
lines changed

Doc/library/collections.abc.rst

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

217217
ABC for classes that provide the :meth:`~object.__call__` method.
218218

219+
See :ref:`annotating-callables` for details on how to use
220+
:class:`!Callable` in type annotations.
221+
219222
.. class:: Iterable
220223

221224
ABC for classes that provide the :meth:`~container.__iter__` method.
@@ -253,6 +256,9 @@ Collections Abstract Base Classes -- Detailed Descriptions
253256
:meth:`~generator.send`,
254257
:meth:`~generator.throw` and :meth:`~generator.close` methods.
255258

259+
See :ref:`annotating-generators-and-coroutines`
260+
for details on using :class:`!Generator` in type annotations.
261+
256262
.. versionadded:: 3.5
257263

258264
.. class:: Sequence
@@ -331,6 +337,11 @@ Collections Abstract Base Classes -- Detailed Descriptions
331337
Using ``isinstance(gencoro, Coroutine)`` for them will return ``False``.
332338
Use :func:`inspect.isawaitable` to detect them.
333339

340+
See :ref:`annotating-generators-and-coroutines`
341+
for details on using :class:`!Coroutine` in type annotations.
342+
The variance and order of type parameters correspond to those of
343+
:class:`Generator`.
344+
334345
.. versionadded:: 3.5
335346

336347
.. class:: AsyncIterable
@@ -352,6 +363,9 @@ Collections Abstract Base Classes -- Detailed Descriptions
352363
ABC for :term:`asynchronous generator` classes that implement the protocol
353364
defined in :pep:`525` and :pep:`492`.
354365

366+
See :ref:`annotating-generators-and-coroutines`
367+
for details on using :class:`!AsyncGenerator` in type annotations.
368+
355369
.. versionadded:: 3.6
356370

357371
.. class:: Buffer

Doc/library/typing.rst

Lines changed: 83 additions & 89 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,72 @@ 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+
If your generator will only yield values, set the ``SendType`` and
465+
``ReturnType`` to ``None``::
466+
467+
def infinite_stream(start: int) -> Generator[int, None, None]:
468+
while True:
469+
yield start
470+
start += 1
471+
472+
Alternatively, annotate your generator as having a return type of
473+
either ``Iterable[YieldType]`` or ``Iterator[YieldType]``::
474+
475+
def infinite_stream(start: int) -> Iterator[int]:
476+
while True:
477+
yield start
478+
start += 1
479+
480+
Async generators are handled in a similar fashion, but don't
481+
expect a ``ReturnType`` type argument
482+
(:class:`AsyncGenerator[YieldType, SendType] <collections.abc.AsyncGenerator>`)::
483+
484+
async def infinite_stream(start: int) -> AsyncGenerator[int, None]:
485+
while True:
486+
yield start
487+
start = await increment(start)
488+
489+
As in the synchronous case,
490+
:class:`AsyncIterable[YieldType] <collections.abc.AsyncIterable>`
491+
and :class:`AsyncIterator[YieldType] <collections.abc.AsyncIterator>` are
492+
available as well::
493+
494+
async def infinite_stream(start: int) -> AsyncIterator[int]:
495+
while True:
496+
yield start
497+
start = await increment(start)
498+
499+
Coroutines can be annotated using
500+
:class:`Coroutine[YieldType, SendType, ReturnType] <collections.abc.Coroutine>`.
501+
Generic arguments correspond to those of :class:`~collections.abc.Generator`,
502+
for example::
503+
504+
from collections.abc import Coroutine
505+
c: Coroutine[list[str], str, int] # Some coroutine defined elsewhere
506+
x = c.send('hi') # Inferred type of 'x' is list[str]
507+
async def bar() -> None:
508+
y = await c # Inferred type of 'y' is int
509+
444510
.. _user-defined-generics:
445511

446512
User-defined generic types
@@ -3073,14 +3139,9 @@ Aliases to built-in types
30733139
Deprecated alias to :class:`dict`.
30743140

30753141
Note that to annotate arguments, it is preferred
3076-
to use an abstract collection type such as :class:`Mapping`
3142+
to use an abstract collection type such as :class:`~collections.abc.Mapping`
30773143
rather than to use :class:`dict` or :class:`!typing.Dict`.
30783144

3079-
This type can be used as follows::
3080-
3081-
def count_words(text: str) -> Dict[str, int]:
3082-
...
3083-
30843145
.. deprecated:: 3.9
30853146
:class:`builtins.dict <dict>` now supports subscripting (``[]``).
30863147
See :pep:`585` and :ref:`types-genericalias`.
@@ -3090,16 +3151,9 @@ Aliases to built-in types
30903151
Deprecated alias to :class:`list`.
30913152

30923153
Note that to annotate arguments, it is preferred
3093-
to use an abstract collection type such as :class:`Sequence` or
3094-
:class:`Iterable` rather than to use :class:`list` or :class:`!typing.List`.
3095-
3096-
This type may be used as follows::
3097-
3098-
def vec2[T: (int, float)](x: T, y: T) -> List[T]:
3099-
return [x, y]
3100-
3101-
def keep_positives[T: (int, float)](vector: Sequence[T]) -> List[T]:
3102-
return [item for item in vector if item > 0]
3154+
to use an abstract collection type such as
3155+
:class:`~collections.abc.Sequence` or :class:`~collections.abc.Iterable`
3156+
rather than to use :class:`list` or :class:`!typing.List`.
31033157

31043158
.. deprecated:: 3.9
31053159
:class:`builtins.list <list>` now supports subscripting (``[]``).
@@ -3110,8 +3164,8 @@ Aliases to built-in types
31103164
Deprecated alias to :class:`builtins.set <set>`.
31113165

31123166
Note that to annotate arguments, it is preferred
3113-
to use an abstract collection type such as :class:`AbstractSet`
3114-
rather than to use :class:`set` or :class:`!typing.Set`.
3167+
to use an abstract collection type such as :class:`collections.abc.Set`
3168+
rather than to use :class:`set` or :class:`typing.Set`.
31153169

31163170
.. deprecated:: 3.9
31173171
:class:`builtins.set <set>` now supports subscripting (``[]``).
@@ -3315,11 +3369,6 @@ Aliases to container ABCs in :mod:`collections.abc`
33153369

33163370
Deprecated alias to :class:`collections.abc.Mapping`.
33173371

3318-
This type can be used as follows::
3319-
3320-
def get_position_in_index(word_list: Mapping[str, int], word: str) -> int:
3321-
return word_list[word]
3322-
33233372
.. deprecated:: 3.9
33243373
:class:`collections.abc.Mapping` now supports subscripting (``[]``).
33253374
See :pep:`585` and :ref:`types-genericalias`.
@@ -3383,14 +3432,9 @@ Aliases to asynchronous ABCs in :mod:`collections.abc`
33833432

33843433
Deprecated alias to :class:`collections.abc.Coroutine`.
33853434

3386-
The variance and order of type variables
3387-
correspond to those of :class:`Generator`, for example::
3388-
3389-
from collections.abc import Coroutine
3390-
c: Coroutine[list[str], str, int] # Some coroutine defined elsewhere
3391-
x = c.send('hi') # Inferred type of 'x' is list[str]
3392-
async def bar() -> None:
3393-
y = await c # Inferred type of 'y' is int
3435+
See :ref:`annotating-generators-and-coroutines`
3436+
for details on using :class:`collections.abc.Coroutine`
3437+
and ``typing.Coroutine`` in type annotations.
33943438

33953439
.. versionadded:: 3.5.3
33963440

@@ -3402,34 +3446,9 @@ Aliases to asynchronous ABCs in :mod:`collections.abc`
34023446

34033447
Deprecated alias to :class:`collections.abc.AsyncGenerator`.
34043448

3405-
An async generator can be annotated by the generic type
3406-
``AsyncGenerator[YieldType, SendType]``. For example::
3407-
3408-
async def echo_round() -> AsyncGenerator[int, float]:
3409-
sent = yield 0
3410-
while sent >= 0.0:
3411-
rounded = await round(sent)
3412-
sent = yield rounded
3413-
3414-
Unlike normal generators, async generators cannot return a value, so there
3415-
is no ``ReturnType`` type parameter. As with :class:`Generator`, the
3416-
``SendType`` behaves contravariantly.
3417-
3418-
If your generator will only yield values, set the ``SendType`` to
3419-
``None``::
3420-
3421-
async def infinite_stream(start: int) -> AsyncGenerator[int, None]:
3422-
while True:
3423-
yield start
3424-
start = await increment(start)
3425-
3426-
Alternatively, annotate your generator as having a return type of
3427-
either ``AsyncIterable[YieldType]`` or ``AsyncIterator[YieldType]``::
3428-
3429-
async def infinite_stream(start: int) -> AsyncIterator[int]:
3430-
while True:
3431-
yield start
3432-
start = await increment(start)
3449+
See :ref:`annotating-generators-and-coroutines`
3450+
for details on using :class:`collections.abc.AsyncGenerator`
3451+
and ``typing.AsyncGenerator`` in type annotations.
34333452

34343453
.. versionadded:: 3.6.1
34353454

@@ -3508,34 +3527,9 @@ Aliases to other ABCs in :mod:`collections.abc`
35083527

35093528
Deprecated alias to :class:`collections.abc.Generator`.
35103529

3511-
A generator can be annotated by the generic type
3512-
``Generator[YieldType, SendType, ReturnType]``. For example::
3513-
3514-
def echo_round() -> Generator[int, float, str]:
3515-
sent = yield 0
3516-
while sent >= 0:
3517-
sent = yield round(sent)
3518-
return 'Done'
3519-
3520-
Note that unlike many other generics in the typing module, the ``SendType``
3521-
of :class:`Generator` behaves contravariantly, not covariantly or
3522-
invariantly.
3523-
3524-
If your generator will only yield values, set the ``SendType`` and
3525-
``ReturnType`` to ``None``::
3526-
3527-
def infinite_stream(start: int) -> Generator[int, None, None]:
3528-
while True:
3529-
yield start
3530-
start += 1
3531-
3532-
Alternatively, annotate your generator as having a return type of
3533-
either ``Iterable[YieldType]`` or ``Iterator[YieldType]``::
3534-
3535-
def infinite_stream(start: int) -> Iterator[int]:
3536-
while True:
3537-
yield start
3538-
start += 1
3530+
See :ref:`annotating-generators-and-coroutines`
3531+
for details on using :class:`collections.abc.Generator`
3532+
and ``typing.Generator`` in type annotations.
35393533

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

0 commit comments

Comments
 (0)
0