Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 66f8828

Browse files
committed
Issue #24439: Improve PEP 492 related docs.
Patch by Martin Panter.
1 parent fcba972 commit 66f8828

12 files changed

Lines changed: 184 additions & 90 deletions

File tree

Doc/glossary.rst

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -169,18 +169,19 @@ Glossary
169169
statement by defining :meth:`__enter__` and :meth:`__exit__` methods.
170170
See :pep:`343`.
171171

172-
coroutine function
173-
A function which returns a :term:`coroutine` object. It is defined
174-
with an :keyword:`async def` keyword, and may contain :keyword:`await`,
175-
:keyword:`async for`, and :keyword:`async with` keywords. Introduced
176-
by :pep:`492`.
177-
178172
coroutine
179173
Coroutines is a more generalized form of subroutines. Subroutines are
180-
entered at one point and exited at another point. Coroutines, can be
181-
entered, exited, and resumed at many different points. See
182-
:keyword:`await` expressions, and :keyword:`async for` and
183-
:keyword:`async with` statements. See also :pep:`492`.
174+
entered at one point and exited at another point. Coroutines can be
175+
entered, exited, and resumed at many different points. They can be
176+
implemented with the :keyword:`async def` statement. See also
177+
:pep:`492`.
178+
179+
coroutine function
180+
A function which returns a :term:`coroutine` object. A coroutine
181+
function may be defined with the :keyword:`async def` statement,
182+
and may contain :keyword:`await`, :keyword:`async for`, and
183+
:keyword:`async with` keywords. These were introduced
184+
by :pep:`492`.
184185

185186
CPython
186187
The canonical implementation of the Python programming language, as

Doc/library/asyncio-task.rst

Lines changed: 54 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,23 @@ Tasks and coroutines
88
Coroutines
99
----------
1010

11-
A coroutine is a generator that follows certain conventions. For
12-
documentation purposes, all coroutines should be decorated with
13-
``@asyncio.coroutine``, but this cannot be strictly enforced.
14-
15-
Coroutines use the ``yield from`` syntax introduced in :pep:`380`,
11+
Coroutines used with :mod:`asyncio` may be implemented using the
12+
:keyword:`async def` statement, or by using :term:`generators <generator>`.
13+
The :keyword:`async def` type of coroutine was added in Python 3.5, and
14+
is recommended if there is no need to support older Python versions.
15+
16+
Generator-based coroutines should be decorated with :func:`@asyncio.coroutine
17+
<asyncio.coroutine>`, although this is not strictly enforced.
18+
The decorator enables compatibility with :keyword:`async def` coroutines,
19+
and also serves as documentation. Generator-based
20+
coroutines use the ``yield from`` syntax introduced in :pep:`380`,
1621
instead of the original ``yield`` syntax.
1722

1823
The word "coroutine", like the word "generator", is used for two
1924
different (though related) concepts:
2025

21-
- The function that defines a coroutine (a function definition
26+
- The function that defines a coroutine
27+
(a function definition using :keyword:`async def` or
2228
decorated with ``@asyncio.coroutine``). If disambiguation is needed
2329
we will call this a *coroutine function* (:func:`iscoroutinefunction`
2430
returns ``True``).
@@ -30,27 +36,28 @@ different (though related) concepts:
3036

3137
Things a coroutine can do:
3238

33-
- ``result = yield from future`` -- suspends the coroutine until the
39+
- ``result = await future`` or ``result = yield from future`` --
40+
suspends the coroutine until the
3441
future is done, then returns the future's result, or raises an
3542
exception, which will be propagated. (If the future is cancelled,
3643
it will raise a ``CancelledError`` exception.) Note that tasks are
3744
futures, and everything said about futures also applies to tasks.
3845

39-
- ``result = yield from coroutine`` -- wait for another coroutine to
46+
- ``result = await coroutine`` or ``result = yield from coroutine`` --
47+
wait for another coroutine to
4048
produce a result (or raise an exception, which will be propagated).
4149
The ``coroutine`` expression must be a *call* to another coroutine.
4250

4351
- ``return expression`` -- produce a result to the coroutine that is
44-
waiting for this one using ``yield from``.
52+
waiting for this one using :keyword:`await` or ``yield from``.
4553

4654
- ``raise exception`` -- raise an exception in the coroutine that is
47-
waiting for this one using ``yield from``.
55+
waiting for this one using :keyword:`await` or ``yield from``.
4856

49-
Calling a coroutine does not start its code running -- it is just a
50-
generator, and the coroutine object returned by the call is really a
51-
generator object, which doesn't do anything until you iterate over it.
52-
In the case of a coroutine object, there are two basic ways to start
53-
it running: call ``yield from coroutine`` from another coroutine
57+
Calling a coroutine does not start its code running --
58+
the coroutine object returned by the call doesn't do anything until you
59+
schedule its execution. There are two basic ways to start it running:
60+
call ``await coroutine`` or ``yield from coroutine`` from another coroutine
5461
(assuming the other coroutine is already running!), or schedule its execution
5562
using the :func:`async` function or the :meth:`BaseEventLoop.create_task`
5663
method.
@@ -60,9 +67,15 @@ Coroutines (and tasks) can only run when the event loop is running.
6067

6168
.. decorator:: coroutine
6269

63-
Decorator to mark coroutines.
70+
Decorator to mark generator-based coroutines. This enables
71+
the generator use :keyword:`!yield from` to call :keyword:`async
72+
def` coroutines, and also enables the generator to be called by
73+
:keyword:`async def` coroutines, for instance using an
74+
:keyword:`await` expression.
75+
76+
There is no need to decorate :keyword:`async def` coroutines themselves.
6477

65-
If the coroutine is not yielded from before it is destroyed, an error
78+
If the generator is not yielded from before it is destroyed, an error
6679
message is logged. See :ref:`Detect coroutines never scheduled
6780
<asyncio-coroutine-not-scheduled>`.
6881

@@ -84,8 +97,7 @@ Example of coroutine displaying ``"Hello World"``::
8497

8598
import asyncio
8699

87-
@asyncio.coroutine
88-
def hello_world():
100+
async def hello_world():
89101
print("Hello World!")
90102

91103
loop = asyncio.get_event_loop()
@@ -111,20 +123,30 @@ using the :meth:`sleep` function::
111123
import asyncio
112124
import datetime
113125

114-
@asyncio.coroutine
115-
def display_date(loop):
126+
async def display_date(loop):
116127
end_time = loop.time() + 5.0
117128
while True:
118129
print(datetime.datetime.now())
119130
if (loop.time() + 1.0) >= end_time:
120131
break
121-
yield from asyncio.sleep(1)
132+
await asyncio.sleep(1)
122133

123134
loop = asyncio.get_event_loop()
124135
# Blocking call which returns when the display_date() coroutine is done
125136
loop.run_until_complete(display_date(loop))
126137
loop.close()
127138

139+
The same coroutine implemented using a generator::
140+
141+
@asyncio.coroutine
142+
def display_date(loop):
143+
end_time = loop.time() + 5.0
144+
while True:
145+
print(datetime.datetime.now())
146+
if (loop.time() + 1.0) >= end_time:
147+
break
148+
yield from asyncio.sleep(1)
149+
128150
.. seealso::
129151

130152
The :ref:`display the current date with call_later()
@@ -139,15 +161,13 @@ Example chaining coroutines::
139161

140162
import asyncio
141163

142-
@asyncio.coroutine
143-
def compute(x, y):
164+
async def compute(x, y):
144165
print("Compute %s + %s ..." % (x, y))
145-
yield from asyncio.sleep(1.0)
166+
await asyncio.sleep(1.0)
146167
return x + y
147168

148-
@asyncio.coroutine
149-
def print_sum(x, y):
150-
result = yield from compute(x, y)
169+
async def print_sum(x, y):
170+
result = await compute(x, y)
151171
print("%s + %s = %s" % (x, y, result))
152172

153173
loop = asyncio.get_event_loop()
@@ -550,12 +570,14 @@ Task functions
550570

551571
.. function:: iscoroutine(obj)
552572

553-
Return ``True`` if *obj* is a :ref:`coroutine object <coroutine>`.
573+
Return ``True`` if *obj* is a :ref:`coroutine object <coroutine>`,
574+
which may be based on a generator or an :keyword:`async def` coroutine.
554575

555-
.. function:: iscoroutinefunction(obj)
576+
.. function:: iscoroutinefunction(func)
556577

557-
Return ``True`` if *func* is a decorated :ref:`coroutine function
558-
<coroutine>`.
578+
Return ``True`` if *func* is determined to be a :ref:`coroutine function
579+
<coroutine>`, which may be a decorated generator function or an
580+
:keyword:`async def` function.
559581

560582
.. coroutinefunction:: sleep(delay, result=None, \*, loop=None)
561583

Doc/library/collections.abc.rst

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -154,21 +154,22 @@ ABC Inherits from Abstract Methods Mixin
154154

155155
.. class:: Awaitable
156156

157-
ABC for classes that provide ``__await__`` method. Instances
158-
of such classes can be used in ``await`` expression.
157+
ABC for :term:`awaitable` objects, which can be used in :keyword:`await`
158+
expressions. Custom implementations must provide the :meth:`__await__`
159+
method.
159160

160-
:term:`coroutine` objects and instances of
161-
:class:`~collections.abc.Coroutine` are too instances of this ABC.
161+
:term:`Coroutine` objects and instances of the
162+
:class:`~collections.abc.Coroutine` ABC are all instances of this ABC.
162163

163164
.. versionadded:: 3.5
164165

165166
.. class:: Coroutine
166167

167-
ABC for coroutine compatible classes that implement a subset of
168-
generator methods defined in :pep:`342`, namely:
169-
:meth:`~generator.send`, :meth:`~generator.throw`,
170-
:meth:`~generator.close` methods. :meth:`__await__` must also be
171-
implemented. All :class:`Coroutine` instances are also instances of
168+
ABC for coroutine compatible classes. These implement the
169+
following methods, defined in :ref:`coroutine-objects`:
170+
:meth:`~coroutine.send`, :meth:`~coroutine.throw`, and
171+
:meth:`~coroutine.close`. Custom implementations must also implement
172+
:meth:`__await__`. All :class:`Coroutine` instances are also instances of
172173
:class:`Awaitable`. See also the definition of :term:`coroutine`.
173174

174175
.. versionadded:: 3.5

Doc/library/dis.rst

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -516,12 +516,14 @@ the original TOS1.
516516
Implements ``del TOS1[TOS]``.
517517

518518

519-
**Coroutines opcodes**
519+
**Coroutine opcodes**
520520

521521
.. opcode:: GET_AWAITABLE
522522

523-
Implements ``TOS = get_awaitable(TOS)``; where ``get_awaitable(o)``
524-
returns ``o`` if ``o`` is a coroutine object; or resolved ``o.__await__``.
523+
Implements ``TOS = get_awaitable(TOS)``, where ``get_awaitable(o)``
524+
returns ``o`` if ``o`` is a coroutine object or a generator object with
525+
the CO_ITERABLE_COROUTINE flag, or resolves
526+
``o.__await__``.
525527

526528

527529
.. opcode:: GET_AITER

Doc/library/exceptions.rst

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,8 @@ The following exceptions are the exceptions that are usually raised.
162162

163163
.. exception:: GeneratorExit
164164

165-
Raised when a :term:`generator`\'s :meth:`close` method is called. It
165+
Raised when a :term:`generator` or :term:`coroutine` is closed;
166+
see :meth:`generator.close` and :meth:`coroutine.close`. It
166167
directly inherits from :exc:`BaseException` instead of :exc:`Exception` since
167168
it is technically not an error.
168169

@@ -306,7 +307,8 @@ The following exceptions are the exceptions that are usually raised.
306307
given as an argument when constructing the exception, and defaults
307308
to :const:`None`.
308309

309-
When a generator function returns, a new :exc:`StopIteration` instance is
310+
When a :term:`generator` or :term:`coroutine` function
311+
returns, a new :exc:`StopIteration` instance is
310312
raised, and the value returned by the function is used as the
311313
:attr:`value` parameter to the constructor of the exception.
312314

Doc/library/sys.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1080,7 +1080,7 @@ always available.
10801080
:func:`types.coroutine` or :func:`asyncio.coroutine` will not be
10811081
intercepted).
10821082

1083-
*wrapper* must be either:
1083+
The *wrapper* argument must be either:
10841084

10851085
* a callable that accepts one argument (a coroutine object);
10861086
* ``None``, to reset the wrapper.
@@ -1096,7 +1096,8 @@ always available.
10961096
return wrap(coro)
10971097
sys.set_coroutine_wrapper(wrapper)
10981098

1099-
async def foo(): pass
1099+
async def foo():
1100+
pass
11001101

11011102
# The following line will fail with a RuntimeError, because
11021103
# `wrapper` creates a `wrap(coro)` coroutine:

Doc/library/tulip_coro.png

-544 Bytes
Loading

Doc/library/types.rst

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -281,15 +281,23 @@ Additional Utility Classes and Functions
281281
.. versionadded:: 3.4
282282

283283

284-
Coroutines Utility Functions
285-
----------------------------
284+
Coroutine Utility Functions
285+
---------------------------
286286

287287
.. function:: coroutine(gen_func)
288288

289-
The function transforms a generator function to a :term:`coroutine function`,
290-
so that it returns a :term:`coroutine` object.
289+
This function transforms a :term:`generator` function into a
290+
:term:`coroutine function` which returns a generator-based coroutine.
291+
The generator-based coroutine is still a :term:`generator iterator`,
292+
but is also considered to be a :term:`coroutine` object and is
293+
:term:`awaitable`. However, it may not necessarily implement
294+
the :meth:`__await__` method.
291295

292-
*gen_func* is modified in-place, hence the function can be used as a
293-
decorator.
296+
If *gen_func* is a generator function, it will be modified in-place.
297+
298+
If *gen_func* is not a generator function, it will be wrapped. If it
299+
returns an instance of :class:`collections.abc.Generator`, the instance
300+
will be wrapped in an *awaitable* proxy object. All other types
301+
of objects will be returned as is.
294302

295303
.. versionadded:: 3.5

Doc/reference/compound_stmts.rst

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -666,15 +666,9 @@ can be used to create instance variables with different implementation details.
666666
Coroutines
667667
==========
668668

669-
.. index::
670-
statement: async def
671-
statement: async for
672-
statement: async with
673-
keyword: async
674-
keyword: await
675-
676669
.. versionadded:: 3.5
677670

671+
.. index:: statement: async def
678672
.. _`async def`:
679673

680674
Coroutine function definition
@@ -683,14 +677,23 @@ Coroutine function definition
683677
.. productionlist::
684678
async_funcdef: "async" `funcdef`
685679

680+
.. index::
681+
keyword: async
682+
keyword: await
683+
686684
Execution of Python coroutines can be suspended and resumed at many points
687-
(see :term:`coroutine`.) :keyword:`await` expressions, :keyword:`async for`
688-
and :keyword:`async with` can only be used in their bodies.
685+
(see :term:`coroutine`). In the body of a coroutine, any ``await`` and
686+
``async`` identifiers become reserved keywords; :keyword:`await` expressions,
687+
:keyword:`async for` and :keyword:`async with` can only be used in
688+
coroutine bodies. However, to simplify the parser, these keywords cannot
689+
be used on the same line as a function or coroutine (:keyword:`def`
690+
statement) header.
689691

690692
Functions defined with ``async def`` syntax are always coroutine functions,
691693
even if they do not contain ``await`` or ``async`` keywords.
692694

693-
It is a :exc:`SyntaxError` to use :keyword:`yield` expressions in coroutines.
695+
It is a :exc:`SyntaxError` to use :keyword:`yield` expressions in
696+
``async def`` coroutines.
694697

695698
An example of a coroutine function::
696699

@@ -699,6 +702,7 @@ An example of a coroutine function::
699702
await some_coroutine()
700703

701704

705+
.. index:: statement: async for
702706
.. _`async for`:
703707

704708
The :keyword:`async for` statement
@@ -742,6 +746,7 @@ It is a :exc:`SyntaxError` to use ``async for`` statement outside of an
742746
:keyword:`async def` function.
743747

744748

749+
.. index:: statement: async with
745750
.. _`async with`:
746751

747752
The :keyword:`async with` statement

0 commit comments

Comments
 (0)