@@ -8,17 +8,23 @@ Tasks and coroutines
88Coroutines
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 `,
1621instead of the original ``yield `` syntax.
1722
1823The word "coroutine", like the word "generator", is used for two
1924different (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
3137Things 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
5562using the :func: `async ` function or the :meth: `BaseEventLoop.create_task `
5663method.
@@ -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
0 commit comments