[Python-checkins] bpo-32258: Replace 'yield from' to 'await' in asyncio docs (#4779)

Andrew Svetlov webhook-mailer at python.org
Mon Dec 11 10:35:56 EST 2017


https://github.com/python/cpython/commit/8874342cf332c3aa3d845155cc4b41b00c2d9e9d
commit: 8874342cf332c3aa3d845155cc4b41b00c2d9e9d
branch: master
author: Andrew Svetlov <andrew.svetlov at gmail.com>
committer: GitHub <noreply at github.com>
date: 2017年12月11日T17:35:49+02:00
summary:
bpo-32258: Replace 'yield from' to 'await' in asyncio docs (#4779)
* Replace 'yield from' to 'await' in asyncio docs
* Fix docstrings
files:
M Doc/library/asyncio-dev.rst
M Doc/library/asyncio-protocol.rst
M Doc/library/asyncio-queue.rst
M Doc/library/asyncio-stream.rst
M Doc/library/asyncio-subprocess.rst
M Doc/library/asyncio-task.rst
M Lib/asyncio/coroutines.py
M Lib/asyncio/futures.py
M Lib/asyncio/locks.py
diff --git a/Doc/library/asyncio-dev.rst b/Doc/library/asyncio-dev.rst
index b9735de2078..100fff561c5 100644
--- a/Doc/library/asyncio-dev.rst
+++ b/Doc/library/asyncio-dev.rst
@@ -81,12 +81,11 @@ is called.
 If you wait for a future, you should check early if the future was cancelled to
 avoid useless operations. Example::
 
- @coroutine
- def slow_operation(fut):
+ async def slow_operation(fut):
 if fut.cancelled():
 return
 # ... slow computation ...
- yield from fut
+ await fut
 # ...
 
 The :func:`shield` function can also be used to ignore cancellation.
@@ -99,7 +98,7 @@ Concurrency and multithreading
 
 An event loop runs in a thread and executes all callbacks and tasks in the same
 thread. While a task is running in the event loop, no other task is running in
-the same thread. But when the task uses ``yield from``, the task is suspended
+the same thread. But when the task uses ``await``, the task is suspended
 and the event loop executes the next task.
 
 To schedule a callback from a different thread, the
@@ -192,8 +191,7 @@ Example with the bug::
 
 import asyncio
 
- @asyncio.coroutine
- def test():
+ async def test():
 print("never scheduled")
 
 test()
@@ -270,10 +268,9 @@ traceback where the task was created. Output in debug mode::
 There are different options to fix this issue. The first option is to chain the
 coroutine in another coroutine and use classic try/except::
 
- @asyncio.coroutine
- def handle_exception():
+ async def handle_exception():
 try:
- yield from bug()
+ await bug()
 except Exception:
 print("exception consumed")
 
@@ -300,7 +297,7 @@ Chain coroutines correctly
 --------------------------
 
 When a coroutine function calls other coroutine functions and tasks, they
-should be chained explicitly with ``yield from``. Otherwise, the execution is
+should be chained explicitly with ``await``. Otherwise, the execution is
 not guaranteed to be sequential.
 
 Example with different bugs using :func:`asyncio.sleep` to simulate slow
@@ -308,26 +305,22 @@ operations::
 
 import asyncio
 
- @asyncio.coroutine
- def create():
- yield from asyncio.sleep(3.0)
+ async def create():
+ await asyncio.sleep(3.0)
 print("(1) create file")
 
- @asyncio.coroutine
- def write():
- yield from asyncio.sleep(1.0)
+ async def write():
+ await asyncio.sleep(1.0)
 print("(2) write into file")
 
- @asyncio.coroutine
- def close():
+ async def close():
 print("(3) close file")
 
- @asyncio.coroutine
- def test():
+ async def test():
 asyncio.ensure_future(create())
 asyncio.ensure_future(write())
 asyncio.ensure_future(close())
- yield from asyncio.sleep(2.0)
+ await asyncio.sleep(2.0)
 loop.stop()
 
 loop = asyncio.get_event_loop()
@@ -359,24 +352,22 @@ The loop stopped before the ``create()`` finished, ``close()`` has been called
 before ``write()``, whereas coroutine functions were called in this order:
 ``create()``, ``write()``, ``close()``.
 
-To fix the example, tasks must be marked with ``yield from``::
+To fix the example, tasks must be marked with ``await``::
 
- @asyncio.coroutine
- def test():
- yield from asyncio.ensure_future(create())
- yield from asyncio.ensure_future(write())
- yield from asyncio.ensure_future(close())
- yield from asyncio.sleep(2.0)
+ async def test():
+ await asyncio.ensure_future(create())
+ await asyncio.ensure_future(write())
+ await asyncio.ensure_future(close())
+ await asyncio.sleep(2.0)
 loop.stop()
 
 Or without ``asyncio.ensure_future()``::
 
- @asyncio.coroutine
- def test():
- yield from create()
- yield from write()
- yield from close()
- yield from asyncio.sleep(2.0)
+ async def test():
+ await create()
+ await write()
+ await close()
+ await asyncio.sleep(2.0)
 loop.stop()
 
 
diff --git a/Doc/library/asyncio-protocol.rst b/Doc/library/asyncio-protocol.rst
index af462009fa8..a4b0d594933 100644
--- a/Doc/library/asyncio-protocol.rst
+++ b/Doc/library/asyncio-protocol.rst
@@ -488,8 +488,9 @@ Coroutines can be scheduled in a protocol method using :func:`ensure_future`,
 but there is no guarantee made about the execution order. Protocols are not
 aware of coroutines created in protocol methods and so will not wait for them.
 
-To have a reliable execution order, use :ref:`stream objects <asyncio-streams>` in a
-coroutine with ``yield from``. For example, the :meth:`StreamWriter.drain`
+To have a reliable execution order,
+use :ref:`stream objects <asyncio-streams>` in a
+coroutine with ``await``. For example, the :meth:`StreamWriter.drain`
 coroutine can be used to wait until the write buffer is flushed.
 
 
@@ -589,7 +590,7 @@ received data and close the connection::
 
 :meth:`Transport.close` can be called immediately after
 :meth:`WriteTransport.write` even if data are not sent yet on the socket: both
-methods are asynchronous. ``yield from`` is not needed because these transport
+methods are asynchronous. ``await`` is not needed because these transport
 methods are not coroutines.
 
 .. seealso::
diff --git a/Doc/library/asyncio-queue.rst b/Doc/library/asyncio-queue.rst
index ea787550082..65497f29d89 100644
--- a/Doc/library/asyncio-queue.rst
+++ b/Doc/library/asyncio-queue.rst
@@ -24,7 +24,7 @@ Queue
 A queue, useful for coordinating producer and consumer coroutines.
 
 If *maxsize* is less than or equal to zero, the queue size is infinite. If
- it is an integer greater than ``0``, then ``yield from put()`` will block
+ it is an integer greater than ``0``, then ``await put()`` will block
 when the queue reaches *maxsize*, until an item is removed by :meth:`get`.
 
 Unlike the standard library :mod:`queue`, you can reliably know this Queue's
diff --git a/Doc/library/asyncio-stream.rst b/Doc/library/asyncio-stream.rst
index 78091d62a71..6d5cbbc5bd5 100644
--- a/Doc/library/asyncio-stream.rst
+++ b/Doc/library/asyncio-stream.rst
@@ -208,7 +208,7 @@ StreamWriter
 The intended use is to write::
 
 w.write(data)
- yield from w.drain()
+ await w.drain()
 
 When the size of the transport buffer reaches the high-water limit (the
 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::
 
 import asyncio
 
- @asyncio.coroutine
- def tcp_echo_client(message, loop):
- reader, writer = yield from asyncio.open_connection('127.0.0.1', 8888,
- loop=loop)
+ async def tcp_echo_client(message, loop):
+ reader, writer = await asyncio.open_connection('127.0.0.1', 8888,
+ loop=loop)
 
 print('Send: %r' % message)
 writer.write(message.encode())
 
- data = yield from reader.read(100)
+ data = await reader.read(100)
 print('Received: %r' % data.decode())
 
 print('Close the socket')
@@ -335,16 +334,15 @@ TCP echo server using the :func:`asyncio.start_server` function::
 
 import asyncio
 
- @asyncio.coroutine
- def handle_echo(reader, writer):
- data = yield from reader.read(100)
+ async def handle_echo(reader, writer):
+ data = await reader.read(100)
 message = data.decode()
 addr = writer.get_extra_info('peername')
 print("Received %r from %r" % (message, addr))
 
 print("Send: %r" % message)
 writer.write(data)
- yield from writer.drain()
+ await writer.drain()
 
 print("Close the client socket")
 writer.close()
@@ -387,13 +385,13 @@ Simple example querying HTTP headers of the URL passed on the command line::
 connect = asyncio.open_connection(url.hostname, 443, ssl=True)
 else:
 connect = asyncio.open_connection(url.hostname, 80)
- reader, writer = yield from connect
+ reader, writer = await connect
 query = ('HEAD {path} HTTP/1.0\r\n'
 'Host: {hostname}\r\n'
 '\r\n').format(path=url.path or '/', hostname=url.hostname)
 writer.write(query.encode('latin-1'))
 while True:
- line = yield from reader.readline()
+ line = await reader.readline()
 if not line:
 break
 line = line.decode('latin1').rstrip()
@@ -428,19 +426,18 @@ Coroutine waiting until a socket receives data using the
 import asyncio
 from socket import socketpair
 
- @asyncio.coroutine
- def wait_for_data(loop):
+ async def wait_for_data(loop):
 # Create a pair of connected sockets
 rsock, wsock = socketpair()
 
 # Register the open socket to wait for data
- reader, writer = yield from asyncio.open_connection(sock=rsock, loop=loop)
+ reader, writer = await asyncio.open_connection(sock=rsock, loop=loop)
 
 # Simulate the reception of data from the network
 loop.call_soon(wsock.send, 'abc'.encode())
 
 # Wait for data
- data = yield from reader.read(100)
+ data = await reader.read(100)
 
 # Got data, we are done: close the socket
 print("Received:", data.decode())
diff --git a/Doc/library/asyncio-subprocess.rst b/Doc/library/asyncio-subprocess.rst
index 1c1d0be918d..280b7640037 100644
--- a/Doc/library/asyncio-subprocess.rst
+++ b/Doc/library/asyncio-subprocess.rst
@@ -347,21 +347,20 @@ wait for the subprocess exit. The subprocess is created by the
 def process_exited(self):
 self.exit_future.set_result(True)
 
- @asyncio.coroutine
- def get_date(loop):
+ async def get_date(loop):
 code = 'import datetime; print(datetime.datetime.now())'
 exit_future = asyncio.Future(loop=loop)
 
 # Create the subprocess controlled by the protocol DateProtocol,
 # redirect the standard output into a pipe
- create = loop.subprocess_exec(lambda: DateProtocol(exit_future),
- sys.executable, '-c', code,
- stdin=None, stderr=None)
- transport, protocol = yield from create
+ transport, protocol = await loop.subprocess_exec(
+ lambda: DateProtocol(exit_future),
+ sys.executable, '-c', code,
+ stdin=None, stderr=None)
 
 # Wait for the subprocess exit using the process_exited() method
 # of the protocol
- yield from exit_future
+ await exit_future
 
 # Close the stdout pipe
 transport.close()
@@ -398,16 +397,16 @@ function::
 code = 'import datetime; print(datetime.datetime.now())'
 
 # Create the subprocess, redirect the standard output into a pipe
- create = asyncio.create_subprocess_exec(sys.executable, '-c', code,
- stdout=asyncio.subprocess.PIPE)
- proc = yield from create
+ proc = await asyncio.create_subprocess_exec(
+ sys.executable, '-c', code,
+ stdout=asyncio.subprocess.PIPE)
 
 # Read one line of output
- data = yield from proc.stdout.readline()
+ data = await proc.stdout.readline()
 line = data.decode('ascii').rstrip()
 
 # Wait for the subprocess exit
- yield from proc.wait()
+ await proc.wait()
 return line
 
 if sys.platform == "win32":
diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst
index 3656f793deb..a8a0a8e85ef 100644
--- a/Doc/library/asyncio-task.rst
+++ b/Doc/library/asyncio-task.rst
@@ -515,7 +515,7 @@ Task functions
 Example::
 
 for f in as_completed(fs):
- result = yield from f # The 'yield from' may raise
+ result = await f # The 'await' may raise
 # Use result
 
 .. note::
@@ -630,11 +630,11 @@ Task functions
 
 The statement::
 
- res = yield from shield(something())
+ res = await shield(something())
 
 is exactly equivalent to the statement::
 
- res = yield from something()
+ res = await something()
 
 *except* that if the coroutine containing it is cancelled, the task running
 in ``something()`` is not cancelled. From the point of view of
@@ -647,7 +647,7 @@ Task functions
 combine ``shield()`` with a try/except clause, as follows::
 
 try:
- res = yield from shield(something())
+ res = await shield(something())
 except CancelledError:
 res = None
 
@@ -690,7 +690,7 @@ Task functions
 
 Usage::
 
- done, pending = yield from asyncio.wait(fs)
+ done, pending = await asyncio.wait(fs)
 
 .. note::
 
@@ -714,7 +714,7 @@ Task functions
 
 This function is a :ref:`coroutine <coroutine>`, usage::
 
- result = yield from asyncio.wait_for(fut, 60.0)
+ result = await asyncio.wait_for(fut, 60.0)
 
 .. versionchanged:: 3.4.3
 If the wait is cancelled, the future *fut* is now also cancelled.
diff --git a/Lib/asyncio/coroutines.py b/Lib/asyncio/coroutines.py
index d7e6b4c1ccb..bca7fe3a537 100644
--- a/Lib/asyncio/coroutines.py
+++ b/Lib/asyncio/coroutines.py
@@ -19,8 +19,9 @@ def _is_debug_mode():
 # If you set _DEBUG to true, @coroutine will wrap the resulting
 # generator objects in a CoroWrapper instance (defined below). That
 # instance will log a message when the generator is never iterated
- # over, which may happen when you forget to use "yield from" with a
- # coroutine call. Note that the value of the _DEBUG flag is taken
+ # over, which may happen when you forget to use "await" or "yield from"
+ # with a coroutine call.
+ # Note that the value of the _DEBUG flag is taken
 # when the decorator is used, so to be of any use it must be set
 # before you define your coroutines. A downside of using this feature
 # is that tracebacks show entries for the CoroWrapper.__next__ method
diff --git a/Lib/asyncio/futures.py b/Lib/asyncio/futures.py
index b805f99896d..d46a295197b 100644
--- a/Lib/asyncio/futures.py
+++ b/Lib/asyncio/futures.py
@@ -59,7 +59,8 @@ class Future:
 # The value must also be not-None, to enable a subclass to declare
 # that it is not compatible by setting this to None.
 # - It is set by __iter__() below so that Task._step() can tell
- # the difference between `yield from Future()` (correct) vs.
+ # the difference between
+ # `await Future()` or`yield from Future()` (correct) vs.
 # `yield Future()` (incorrect).
 _asyncio_future_blocking = False
 
@@ -236,7 +237,7 @@ def __iter__(self):
 if not self.done():
 self._asyncio_future_blocking = True
 yield self # This tells Task to wait for completion.
- assert self.done(), "yield from wasn't used with future"
+ assert self.done(), "await wasn't used with future"
 return self.result() # May raise too.
 
 __await__ = __iter__ # make compatible with 'await' expression
diff --git a/Lib/asyncio/locks.py b/Lib/asyncio/locks.py
index 54f62585983..61938373509 100644
--- a/Lib/asyncio/locks.py
+++ b/Lib/asyncio/locks.py
@@ -23,6 +23,10 @@ class _ContextManager:
 
 with lock:
 <block>
+
+ Deprecated, use 'async with' statement:
+ async with lock:
+ <block>
 """
 
 def __init__(self, lock):
@@ -64,6 +68,9 @@ def __iter__(self):
 # <block>
 # finally:
 # lock.release()
+ # Deprecated, use 'async with' statement:
+ # async with lock:
+ # <block>
 warnings.warn("'with (yield from lock)' is deprecated "
 "use 'async with lock' instead",
 DeprecationWarning, stacklevel=2)
@@ -113,16 +120,16 @@ class Lock(_ContextManagerMixin):
 release() call resets the state to unlocked; first coroutine which
 is blocked in acquire() is being processed.
 
- acquire() is a coroutine and should be called with 'yield from'.
+ acquire() is a coroutine and should be called with 'await'.
 
- Locks also support the context management protocol. '(yield from lock)'
- should be used as the context manager expression.
+ Locks also support the asynchronous context management protocol.
+ 'async with lock' statement should be used.
 
 Usage:
 
 lock = Lock()
 ...
- yield from lock
+ await lock.acquire()
 try:
 ...
 finally:
@@ -132,13 +139,13 @@ class Lock(_ContextManagerMixin):
 
 lock = Lock()
 ...
- with (yield from lock):
+ async with lock:
 ...
 
 Lock objects can be tested for locking state:
 
 if not lock.locked():
- yield from lock
+ await lock.acquire()
 else:
 # lock is acquired
 ...


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /