mirror of
https://github.com/python/cpython.git
synced 2025-08-27 04:05:34 +00:00
bpo-32193: Convert asyncio to async/await usage (#4753)
* Convert asyncio/tasks.py to async/await * Convert asyncio/queues.py to async/await * Convert asyncio/test_utils.py to async/await * Convert asyncio/base_subprocess.py to async/await * Convert asyncio/subprocess.py to async/await * Convert asyncio/streams.py to async/await * Fix comments * Convert asyncio/locks.py to async/await * Convert asyncio.sleep to async def * Add a comment * Add missing news * Convert stubs from AbstrctEventLoop to async functions * Convert subprocess_shell/subprocess_exec * Convert connect_read_pipe/connect_write_pip to async/await syntax * Convert create_datagram_endpoint * Convert create_unix_server/create_unix_connection * Get rid of old style coroutines in unix_events.py * Convert selector_events.py to async/await * Convert wait_closed and create_connection * Drop redundant line * Convert base_events.py * Code cleanup * Drop redundant comments * Fix indentation * Add explicit tests for compatibility between old and new coroutines * Convert windows event loop to use async/await * Fix double awaiting of async function * Convert asyncio/locks.py * Improve docstring * Convert tests to async/await * Convert more tests * Convert more tests * Convert more tests * Convert tests * Improve test
This commit is contained in:
parent
ede157331b
commit
5f841b5538
22 changed files with 647 additions and 771 deletions
|
@ -81,9 +81,8 @@ class SubprocessMixin:
|
|||
def test_stdin_stdout(self):
|
||||
args = PROGRAM_CAT
|
||||
|
||||
@asyncio.coroutine
|
||||
def run(data):
|
||||
proc = yield from asyncio.create_subprocess_exec(
|
||||
async def run(data):
|
||||
proc = await asyncio.create_subprocess_exec(
|
||||
*args,
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
|
@ -91,12 +90,12 @@ class SubprocessMixin:
|
|||
|
||||
# feed data
|
||||
proc.stdin.write(data)
|
||||
yield from proc.stdin.drain()
|
||||
await proc.stdin.drain()
|
||||
proc.stdin.close()
|
||||
|
||||
# get output and exitcode
|
||||
data = yield from proc.stdout.read()
|
||||
exitcode = yield from proc.wait()
|
||||
data = await proc.stdout.read()
|
||||
exitcode = await proc.wait()
|
||||
return (exitcode, data)
|
||||
|
||||
task = run(b'some data')
|
||||
|
@ -108,14 +107,13 @@ class SubprocessMixin:
|
|||
def test_communicate(self):
|
||||
args = PROGRAM_CAT
|
||||
|
||||
@asyncio.coroutine
|
||||
def run(data):
|
||||
proc = yield from asyncio.create_subprocess_exec(
|
||||
async def run(data):
|
||||
proc = await asyncio.create_subprocess_exec(
|
||||
*args,
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
loop=self.loop)
|
||||
stdout, stderr = yield from proc.communicate(data)
|
||||
stdout, stderr = await proc.communicate(data)
|
||||
return proc.returncode, stdout
|
||||
|
||||
task = run(b'some data')
|
||||
|
@ -178,14 +176,13 @@ class SubprocessMixin:
|
|||
loop=self.loop)
|
||||
proc = self.loop.run_until_complete(create)
|
||||
|
||||
@asyncio.coroutine
|
||||
def send_signal(proc):
|
||||
async def send_signal(proc):
|
||||
# basic synchronization to wait until the program is sleeping
|
||||
line = yield from proc.stdout.readline()
|
||||
line = await proc.stdout.readline()
|
||||
self.assertEqual(line, b'sleeping\n')
|
||||
|
||||
proc.send_signal(signal.SIGHUP)
|
||||
returncode = (yield from proc.wait())
|
||||
returncode = await proc.wait()
|
||||
return returncode
|
||||
|
||||
returncode = self.loop.run_until_complete(send_signal(proc))
|
||||
|
@ -208,10 +205,9 @@ class SubprocessMixin:
|
|||
def test_stdin_broken_pipe(self):
|
||||
proc, large_data = self.prepare_broken_pipe_test()
|
||||
|
||||
@asyncio.coroutine
|
||||
def write_stdin(proc, data):
|
||||
async def write_stdin(proc, data):
|
||||
proc.stdin.write(data)
|
||||
yield from proc.stdin.drain()
|
||||
await proc.stdin.drain()
|
||||
|
||||
coro = write_stdin(proc, large_data)
|
||||
# drain() must raise BrokenPipeError or ConnectionResetError
|
||||
|
@ -232,8 +228,7 @@ class SubprocessMixin:
|
|||
limit = 10
|
||||
size = (limit * 2 + 1)
|
||||
|
||||
@asyncio.coroutine
|
||||
def test_pause_reading():
|
||||
async def test_pause_reading():
|
||||
code = '\n'.join((
|
||||
'import sys',
|
||||
'sys.stdout.write("x" * %s)' % size,
|
||||
|
@ -242,16 +237,15 @@ class SubprocessMixin:
|
|||
|
||||
connect_read_pipe = self.loop.connect_read_pipe
|
||||
|
||||
@asyncio.coroutine
|
||||
def connect_read_pipe_mock(*args, **kw):
|
||||
transport, protocol = yield from connect_read_pipe(*args, **kw)
|
||||
async def connect_read_pipe_mock(*args, **kw):
|
||||
transport, protocol = await connect_read_pipe(*args, **kw)
|
||||
transport.pause_reading = mock.Mock()
|
||||
transport.resume_reading = mock.Mock()
|
||||
return (transport, protocol)
|
||||
|
||||
self.loop.connect_read_pipe = connect_read_pipe_mock
|
||||
|
||||
proc = yield from asyncio.create_subprocess_exec(
|
||||
proc = await asyncio.create_subprocess_exec(
|
||||
sys.executable, '-c', code,
|
||||
stdin=asyncio.subprocess.PIPE,
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
|
@ -259,7 +253,7 @@ class SubprocessMixin:
|
|||
loop=self.loop)
|
||||
stdout_transport = proc._transport.get_pipe_transport(1)
|
||||
|
||||
stdout, stderr = yield from proc.communicate()
|
||||
stdout, stderr = await proc.communicate()
|
||||
|
||||
# The child process produced more than limit bytes of output,
|
||||
# the stream reader transport should pause the protocol to not
|
||||
|
@ -277,18 +271,17 @@ class SubprocessMixin:
|
|||
def test_stdin_not_inheritable(self):
|
||||
# asyncio issue #209: stdin must not be inheritable, otherwise
|
||||
# the Process.communicate() hangs
|
||||
@asyncio.coroutine
|
||||
def len_message(message):
|
||||
async def len_message(message):
|
||||
code = 'import sys; data = sys.stdin.read(); print(len(data))'
|
||||
proc = yield from asyncio.create_subprocess_exec(
|
||||
proc = await asyncio.create_subprocess_exec(
|
||||
sys.executable, '-c', code,
|
||||
stdin=asyncio.subprocess.PIPE,
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stderr=asyncio.subprocess.PIPE,
|
||||
close_fds=False,
|
||||
loop=self.loop)
|
||||
stdout, stderr = yield from proc.communicate(message)
|
||||
exitcode = yield from proc.wait()
|
||||
stdout, stderr = await proc.communicate(message)
|
||||
exitcode = await proc.wait()
|
||||
return (stdout, exitcode)
|
||||
|
||||
output, exitcode = self.loop.run_until_complete(len_message(b'abc'))
|
||||
|
@ -296,18 +289,18 @@ class SubprocessMixin:
|
|||
self.assertEqual(exitcode, 0)
|
||||
|
||||
def test_empty_input(self):
|
||||
@asyncio.coroutine
|
||||
def empty_input():
|
||||
|
||||
async def empty_input():
|
||||
code = 'import sys; data = sys.stdin.read(); print(len(data))'
|
||||
proc = yield from asyncio.create_subprocess_exec(
|
||||
proc = await asyncio.create_subprocess_exec(
|
||||
sys.executable, '-c', code,
|
||||
stdin=asyncio.subprocess.PIPE,
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stderr=asyncio.subprocess.PIPE,
|
||||
close_fds=False,
|
||||
loop=self.loop)
|
||||
stdout, stderr = yield from proc.communicate(b'')
|
||||
exitcode = yield from proc.wait()
|
||||
stdout, stderr = await proc.communicate(b'')
|
||||
exitcode = await proc.wait()
|
||||
return (stdout, exitcode)
|
||||
|
||||
output, exitcode = self.loop.run_until_complete(empty_input())
|
||||
|
@ -317,9 +310,8 @@ class SubprocessMixin:
|
|||
def test_cancel_process_wait(self):
|
||||
# Issue #23140: cancel Process.wait()
|
||||
|
||||
@asyncio.coroutine
|
||||
def cancel_wait():
|
||||
proc = yield from asyncio.create_subprocess_exec(
|
||||
async def cancel_wait():
|
||||
proc = await asyncio.create_subprocess_exec(
|
||||
*PROGRAM_BLOCKED,
|
||||
loop=self.loop)
|
||||
|
||||
|
@ -327,7 +319,7 @@ class SubprocessMixin:
|
|||
task = self.loop.create_task(proc.wait())
|
||||
self.loop.call_soon(task.cancel)
|
||||
try:
|
||||
yield from task
|
||||
await task
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
|
||||
|
@ -336,20 +328,20 @@ class SubprocessMixin:
|
|||
|
||||
# Kill the process and wait until it is done
|
||||
proc.kill()
|
||||
yield from proc.wait()
|
||||
await proc.wait()
|
||||
|
||||
self.loop.run_until_complete(cancel_wait())
|
||||
|
||||
def test_cancel_make_subprocess_transport_exec(self):
|
||||
@asyncio.coroutine
|
||||
def cancel_make_transport():
|
||||
|
||||
async def cancel_make_transport():
|
||||
coro = asyncio.create_subprocess_exec(*PROGRAM_BLOCKED,
|
||||
loop=self.loop)
|
||||
task = self.loop.create_task(coro)
|
||||
|
||||
self.loop.call_soon(task.cancel)
|
||||
try:
|
||||
yield from task
|
||||
await task
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
|
||||
|
@ -359,15 +351,15 @@ class SubprocessMixin:
|
|||
self.loop.run_until_complete(cancel_make_transport())
|
||||
|
||||
def test_cancel_post_init(self):
|
||||
@asyncio.coroutine
|
||||
def cancel_make_transport():
|
||||
|
||||
async def cancel_make_transport():
|
||||
coro = self.loop.subprocess_exec(asyncio.SubprocessProtocol,
|
||||
*PROGRAM_BLOCKED)
|
||||
task = self.loop.create_task(coro)
|
||||
|
||||
self.loop.call_soon(task.cancel)
|
||||
try:
|
||||
yield from task
|
||||
await task
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
|
||||
|
@ -378,11 +370,11 @@ class SubprocessMixin:
|
|||
test_utils.run_briefly(self.loop)
|
||||
|
||||
def test_close_kill_running(self):
|
||||
@asyncio.coroutine
|
||||
def kill_running():
|
||||
|
||||
async def kill_running():
|
||||
create = self.loop.subprocess_exec(asyncio.SubprocessProtocol,
|
||||
*PROGRAM_BLOCKED)
|
||||
transport, protocol = yield from create
|
||||
transport, protocol = await create
|
||||
|
||||
kill_called = False
|
||||
def kill():
|
||||
|
@ -395,7 +387,7 @@ class SubprocessMixin:
|
|||
proc.kill = kill
|
||||
returncode = transport.get_returncode()
|
||||
transport.close()
|
||||
yield from transport._wait()
|
||||
await transport._wait()
|
||||
return (returncode, kill_called)
|
||||
|
||||
# Ignore "Close running child process: kill ..." log
|
||||
|
@ -408,11 +400,11 @@ class SubprocessMixin:
|
|||
test_utils.run_briefly(self.loop)
|
||||
|
||||
def test_close_dont_kill_finished(self):
|
||||
@asyncio.coroutine
|
||||
def kill_running():
|
||||
|
||||
async def kill_running():
|
||||
create = self.loop.subprocess_exec(asyncio.SubprocessProtocol,
|
||||
*PROGRAM_BLOCKED)
|
||||
transport, protocol = yield from create
|
||||
transport, protocol = await create
|
||||
proc = transport.get_extra_info('subprocess')
|
||||
|
||||
# kill the process (but asyncio is not notified immediately)
|
||||
|
@ -444,8 +436,8 @@ class SubprocessMixin:
|
|||
# Unlike SafeChildWatcher, FastChildWatcher does not pop the
|
||||
# callbacks if waitpid() is called elsewhere. Let's clear them
|
||||
# manually to avoid a warning when the watcher is detached.
|
||||
if sys.platform != 'win32' and \
|
||||
isinstance(self, SubprocessFastWatcherTests):
|
||||
if (sys.platform != 'win32' and
|
||||
isinstance(self, SubprocessFastWatcherTests)):
|
||||
asyncio.get_child_watcher()._callbacks.clear()
|
||||
|
||||
def test_popen_error(self):
|
||||
|
@ -467,8 +459,8 @@ class SubprocessMixin:
|
|||
self.assertEqual(warns, [])
|
||||
|
||||
def test_read_stdout_after_process_exit(self):
|
||||
@asyncio.coroutine
|
||||
def execute():
|
||||
|
||||
async def execute():
|
||||
code = '\n'.join(['import sys',
|
||||
'for _ in range(64):',
|
||||
' sys.stdout.write("x" * 4096)',
|
||||
|
@ -480,11 +472,11 @@ class SubprocessMixin:
|
|||
stdout=asyncio.subprocess.PIPE,
|
||||
loop=self.loop)
|
||||
|
||||
process = yield from fut
|
||||
process = await fut
|
||||
while True:
|
||||
data = yield from process.stdout.read(65536)
|
||||
data = await process.stdout.read(65536)
|
||||
if data:
|
||||
yield from asyncio.sleep(0.3, loop=self.loop)
|
||||
await asyncio.sleep(0.3, loop=self.loop)
|
||||
else:
|
||||
break
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue