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

Skip to content

Commit 8874342

Browse files
authored
bpo-32258: Replace 'yield from' to 'await' in asyncio docs (#4779)
* Replace 'yield from' to 'await' in asyncio docs * Fix docstrings
1 parent abae67e commit 8874342

9 files changed

Lines changed: 79 additions & 82 deletions

File tree

Doc/library/asyncio-dev.rst

Lines changed: 25 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,11 @@ is called.
8181
If you wait for a future, you should check early if the future was cancelled to
8282
avoid useless operations. Example::
8383

84-
@coroutine
85-
def slow_operation(fut):
84+
async def slow_operation(fut):
8685
if fut.cancelled():
8786
return
8887
# ... slow computation ...
89-
yield from fut
88+
await fut
9089
# ...
9190

9291
The :func:`shield` function can also be used to ignore cancellation.
@@ -99,7 +98,7 @@ Concurrency and multithreading
9998

10099
An event loop runs in a thread and executes all callbacks and tasks in the same
101100
thread. While a task is running in the event loop, no other task is running in
102-
the same thread. But when the task uses ``yield from``, the task is suspended
101+
the same thread. But when the task uses ``await``, the task is suspended
103102
and the event loop executes the next task.
104103

105104
To schedule a callback from a different thread, the
@@ -192,8 +191,7 @@ Example with the bug::
192191

193192
import asyncio
194193

195-
@asyncio.coroutine
196-
def test():
194+
async def test():
197195
print("never scheduled")
198196

199197
test()
@@ -270,10 +268,9 @@ traceback where the task was created. Output in debug mode::
270268
There are different options to fix this issue. The first option is to chain the
271269
coroutine in another coroutine and use classic try/except::
272270

273-
@asyncio.coroutine
274-
def handle_exception():
271+
async def handle_exception():
275272
try:
276-
yield from bug()
273+
await bug()
277274
except Exception:
278275
print("exception consumed")
279276

@@ -300,34 +297,30 @@ Chain coroutines correctly
300297
--------------------------
301298

302299
When a coroutine function calls other coroutine functions and tasks, they
303-
should be chained explicitly with ``yield from``. Otherwise, the execution is
300+
should be chained explicitly with ``await``. Otherwise, the execution is
304301
not guaranteed to be sequential.
305302

306303
Example with different bugs using :func:`asyncio.sleep` to simulate slow
307304
operations::
308305

309306
import asyncio
310307

311-
@asyncio.coroutine
312-
def create():
313-
yield from asyncio.sleep(3.0)
308+
async def create():
309+
await asyncio.sleep(3.0)
314310
print("(1) create file")
315311

316-
@asyncio.coroutine
317-
def write():
318-
yield from asyncio.sleep(1.0)
312+
async def write():
313+
await asyncio.sleep(1.0)
319314
print("(2) write into file")
320315

321-
@asyncio.coroutine
322-
def close():
316+
async def close():
323317
print("(3) close file")
324318

325-
@asyncio.coroutine
326-
def test():
319+
async def test():
327320
asyncio.ensure_future(create())
328321
asyncio.ensure_future(write())
329322
asyncio.ensure_future(close())
330-
yield from asyncio.sleep(2.0)
323+
await asyncio.sleep(2.0)
331324
loop.stop()
332325

333326
loop = asyncio.get_event_loop()
@@ -359,24 +352,22 @@ The loop stopped before the ``create()`` finished, ``close()`` has been called
359352
before ``write()``, whereas coroutine functions were called in this order:
360353
``create()``, ``write()``, ``close()``.
361354

362-
To fix the example, tasks must be marked with ``yield from``::
355+
To fix the example, tasks must be marked with ``await``::
363356

364-
@asyncio.coroutine
365-
def test():
366-
yield from asyncio.ensure_future(create())
367-
yield from asyncio.ensure_future(write())
368-
yield from asyncio.ensure_future(close())
369-
yield from asyncio.sleep(2.0)
357+
async def test():
358+
await asyncio.ensure_future(create())
359+
await asyncio.ensure_future(write())
360+
await asyncio.ensure_future(close())
361+
await asyncio.sleep(2.0)
370362
loop.stop()
371363

372364
Or without ``asyncio.ensure_future()``::
373365

374-
@asyncio.coroutine
375-
def test():
376-
yield from create()
377-
yield from write()
378-
yield from close()
379-
yield from asyncio.sleep(2.0)
366+
async def test():
367+
await create()
368+
await write()
369+
await close()
370+
await asyncio.sleep(2.0)
380371
loop.stop()
381372

382373

Doc/library/asyncio-protocol.rst

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -488,8 +488,9 @@ Coroutines can be scheduled in a protocol method using :func:`ensure_future`,
488488
but there is no guarantee made about the execution order. Protocols are not
489489
aware of coroutines created in protocol methods and so will not wait for them.
490490

491-
To have a reliable execution order, use :ref:`stream objects <asyncio-streams>` in a
492-
coroutine with ``yield from``. For example, the :meth:`StreamWriter.drain`
491+
To have a reliable execution order,
492+
use :ref:`stream objects <asyncio-streams>` in a
493+
coroutine with ``await``. For example, the :meth:`StreamWriter.drain`
493494
coroutine can be used to wait until the write buffer is flushed.
494495

495496

@@ -589,7 +590,7 @@ received data and close the connection::
589590

590591
:meth:`Transport.close` can be called immediately after
591592
:meth:`WriteTransport.write` even if data are not sent yet on the socket: both
592-
methods are asynchronous. ``yield from`` is not needed because these transport
593+
methods are asynchronous. ``await`` is not needed because these transport
593594
methods are not coroutines.
594595

595596
.. seealso::

Doc/library/asyncio-queue.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ Queue
2424
A queue, useful for coordinating producer and consumer coroutines.
2525

2626
If *maxsize* is less than or equal to zero, the queue size is infinite. If
27-
it is an integer greater than ``0``, then ``yield from put()`` will block
27+
it is an integer greater than ``0``, then ``await put()`` will block
2828
when the queue reaches *maxsize*, until an item is removed by :meth:`get`.
2929

3030
Unlike the standard library :mod:`queue`, you can reliably know this Queue's

Doc/library/asyncio-stream.rst

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ StreamWriter
208208
The intended use is to write::
209209

210210
w.write(data)
211-
yield from w.drain()
211+
await w.drain()
212212

213213
When the size of the transport buffer reaches the high-water limit (the
214214
protocol is paused), block until the size of the buffer is drained down
@@ -301,15 +301,14 @@ TCP echo client using the :func:`asyncio.open_connection` function::
301301

302302
import asyncio
303303

304-
@asyncio.coroutine
305-
def tcp_echo_client(message, loop):
306-
reader, writer = yield from asyncio.open_connection('127.0.0.1', 8888,
307-
loop=loop)
304+
async def tcp_echo_client(message, loop):
305+
reader, writer = await asyncio.open_connection('127.0.0.1', 8888,
306+
loop=loop)
308307

309308
print('Send: %r' % message)
310309
writer.write(message.encode())
311310

312-
data = yield from reader.read(100)
311+
data = await reader.read(100)
313312
print('Received: %r' % data.decode())
314313

315314
print('Close the socket')
@@ -335,16 +334,15 @@ TCP echo server using the :func:`asyncio.start_server` function::
335334

336335
import asyncio
337336

338-
@asyncio.coroutine
339-
def handle_echo(reader, writer):
340-
data = yield from reader.read(100)
337+
async def handle_echo(reader, writer):
338+
data = await reader.read(100)
341339
message = data.decode()
342340
addr = writer.get_extra_info('peername')
343341
print("Received %r from %r" % (message, addr))
344342

345343
print("Send: %r" % message)
346344
writer.write(data)
347-
yield from writer.drain()
345+
await writer.drain()
348346

349347
print("Close the client socket")
350348
writer.close()
@@ -387,13 +385,13 @@ Simple example querying HTTP headers of the URL passed on the command line::
387385
connect = asyncio.open_connection(url.hostname, 443, ssl=True)
388386
else:
389387
connect = asyncio.open_connection(url.hostname, 80)
390-
reader, writer = yield from connect
388+
reader, writer = await connect
391389
query = ('HEAD {path} HTTP/1.0\r\n'
392390
'Host: {hostname}\r\n'
393391
'\r\n').format(path=url.path or '/', hostname=url.hostname)
394392
writer.write(query.encode('latin-1'))
395393
while True:
396-
line = yield from reader.readline()
394+
line = await reader.readline()
397395
if not line:
398396
break
399397
line = line.decode('latin1').rstrip()
@@ -428,19 +426,18 @@ Coroutine waiting until a socket receives data using the
428426
import asyncio
429427
from socket import socketpair
430428

431-
@asyncio.coroutine
432-
def wait_for_data(loop):
429+
async def wait_for_data(loop):
433430
# Create a pair of connected sockets
434431
rsock, wsock = socketpair()
435432

436433
# Register the open socket to wait for data
437-
reader, writer = yield from asyncio.open_connection(sock=rsock, loop=loop)
434+
reader, writer = await asyncio.open_connection(sock=rsock, loop=loop)
438435

439436
# Simulate the reception of data from the network
440437
loop.call_soon(wsock.send, 'abc'.encode())
441438

442439
# Wait for data
443-
data = yield from reader.read(100)
440+
data = await reader.read(100)
444441

445442
# Got data, we are done: close the socket
446443
print("Received:", data.decode())

Doc/library/asyncio-subprocess.rst

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -347,21 +347,20 @@ wait for the subprocess exit. The subprocess is created by the
347347
def process_exited(self):
348348
self.exit_future.set_result(True)
349349

350-
@asyncio.coroutine
351-
def get_date(loop):
350+
async def get_date(loop):
352351
code = 'import datetime; print(datetime.datetime.now())'
353352
exit_future = asyncio.Future(loop=loop)
354353

355354
# Create the subprocess controlled by the protocol DateProtocol,
356355
# redirect the standard output into a pipe
357-
create = loop.subprocess_exec(lambda: DateProtocol(exit_future),
358-
sys.executable, '-c', code,
359-
stdin=None, stderr=None)
360-
transport, protocol = yield from create
356+
transport, protocol = await loop.subprocess_exec(
357+
lambda: DateProtocol(exit_future),
358+
sys.executable, '-c', code,
359+
stdin=None, stderr=None)
361360

362361
# Wait for the subprocess exit using the process_exited() method
363362
# of the protocol
364-
yield from exit_future
363+
await exit_future
365364

366365
# Close the stdout pipe
367366
transport.close()
@@ -398,16 +397,16 @@ function::
398397
code = 'import datetime; print(datetime.datetime.now())'
399398

400399
# Create the subprocess, redirect the standard output into a pipe
401-
create = asyncio.create_subprocess_exec(sys.executable, '-c', code,
402-
stdout=asyncio.subprocess.PIPE)
403-
proc = yield from create
400+
proc = await asyncio.create_subprocess_exec(
401+
sys.executable, '-c', code,
402+
stdout=asyncio.subprocess.PIPE)
404403

405404
# Read one line of output
406-
data = yield from proc.stdout.readline()
405+
data = await proc.stdout.readline()
407406
line = data.decode('ascii').rstrip()
408407

409408
# Wait for the subprocess exit
410-
yield from proc.wait()
409+
await proc.wait()
411410
return line
412411

413412
if sys.platform == "win32":

Doc/library/asyncio-task.rst

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,7 @@ Task functions
515515
Example::
516516

517517
for f in as_completed(fs):
518-
result = yield from f # The 'yield from' may raise
518+
result = await f # The 'await' may raise
519519
# Use result
520520

521521
.. note::
@@ -630,11 +630,11 @@ Task functions
630630

631631
The statement::
632632

633-
res = yield from shield(something())
633+
res = await shield(something())
634634

635635
is exactly equivalent to the statement::
636636

637-
res = yield from something()
637+
res = await something()
638638

639639
*except* that if the coroutine containing it is cancelled, the task running
640640
in ``something()`` is not cancelled. From the point of view of
@@ -647,7 +647,7 @@ Task functions
647647
combine ``shield()`` with a try/except clause, as follows::
648648

649649
try:
650-
res = yield from shield(something())
650+
res = await shield(something())
651651
except CancelledError:
652652
res = None
653653

@@ -690,7 +690,7 @@ Task functions
690690

691691
Usage::
692692

693-
done, pending = yield from asyncio.wait(fs)
693+
done, pending = await asyncio.wait(fs)
694694

695695
.. note::
696696

@@ -714,7 +714,7 @@ Task functions
714714

715715
This function is a :ref:`coroutine <coroutine>`, usage::
716716

717-
result = yield from asyncio.wait_for(fut, 60.0)
717+
result = await asyncio.wait_for(fut, 60.0)
718718

719719
.. versionchanged:: 3.4.3
720720
If the wait is cancelled, the future *fut* is now also cancelled.

Lib/asyncio/coroutines.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@ def _is_debug_mode():
1919
# If you set _DEBUG to true, @coroutine will wrap the resulting
2020
# generator objects in a CoroWrapper instance (defined below). That
2121
# instance will log a message when the generator is never iterated
22-
# over, which may happen when you forget to use "yield from" with a
23-
# coroutine call. Note that the value of the _DEBUG flag is taken
22+
# over, which may happen when you forget to use "await" or "yield from"
23+
# with a coroutine call.
24+
# Note that the value of the _DEBUG flag is taken
2425
# when the decorator is used, so to be of any use it must be set
2526
# before you define your coroutines. A downside of using this feature
2627
# is that tracebacks show entries for the CoroWrapper.__next__ method

Lib/asyncio/futures.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ class Future:
5959
# The value must also be not-None, to enable a subclass to declare
6060
# that it is not compatible by setting this to None.
6161
# - It is set by __iter__() below so that Task._step() can tell
62-
# the difference between `yield from Future()` (correct) vs.
62+
# the difference between
63+
# `await Future()` or`yield from Future()` (correct) vs.
6364
# `yield Future()` (incorrect).
6465
_asyncio_future_blocking = False
6566

@@ -236,7 +237,7 @@ def __iter__(self):
236237
if not self.done():
237238
self._asyncio_future_blocking = True
238239
yield self # This tells Task to wait for completion.
239-
assert self.done(), "yield from wasn't used with future"
240+
assert self.done(), "await wasn't used with future"
240241
return self.result() # May raise too.
241242

242243
__await__ = __iter__ # make compatible with 'await' expression

0 commit comments

Comments
 (0)