diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2015-01-06 00:13:49 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@gmail.com> | 2015-01-06 00:13:49 (GMT) |
commit | c447ba04e78a91c1febe7744b9e6cbcdd3e23360 (patch) | |
tree | 0394193daabdbf3280e89eec0c0ac49d8779f90c /Lib | |
parent | 8c1a4a2326e8a81bd4cc4fb81e51c003059cd687 (diff) | |
download | cpython-c447ba04e78a91c1febe7744b9e6cbcdd3e23360.zip cpython-c447ba04e78a91c1febe7744b9e6cbcdd3e23360.tar.gz cpython-c447ba04e78a91c1febe7744b9e6cbcdd3e23360.tar.bz2 |
Issue #23140, asyncio: Fix cancellation of Process.wait(). Check the state of
the waiter future before setting its result.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/asyncio/subprocess.py | 3 | ||||
-rw-r--r-- | Lib/test/test_asyncio/test_subprocess.py | 28 |
2 files changed, 30 insertions, 1 deletions
diff --git a/Lib/asyncio/subprocess.py b/Lib/asyncio/subprocess.py index f6d6a14..a8ad03c 100644 --- a/Lib/asyncio/subprocess.py +++ b/Lib/asyncio/subprocess.py @@ -96,7 +96,8 @@ class SubprocessStreamProtocol(streams.FlowControlMixin, returncode = self._transport.get_returncode() while self._waiters: waiter = self._waiters.popleft() - waiter.set_result(returncode) + if not waiter.cancelled(): + waiter.set_result(returncode) class Process: diff --git a/Lib/test/test_asyncio/test_subprocess.py b/Lib/test/test_asyncio/test_subprocess.py index d82cbbf..dfe23be 100644 --- a/Lib/test/test_asyncio/test_subprocess.py +++ b/Lib/test/test_asyncio/test_subprocess.py @@ -223,6 +223,34 @@ class SubprocessMixin: self.assertEqual(output.rstrip(), b'3') self.assertEqual(exitcode, 0) + def test_cancel_process_wait(self): + # Issue #23140: cancel Process.wait() + + @asyncio.coroutine + def wait_proc(proc, event): + event.set() + yield from proc.wait() + + @asyncio.coroutine + def cancel_wait(): + proc = yield from asyncio.create_subprocess_exec( + *PROGRAM_BLOCKED, + loop=self.loop) + + # Create an internal future waiting on the process exit + event = asyncio.Event(loop=self.loop) + task = self.loop.create_task(wait_proc(proc, event)) + yield from event.wait() + + # Cancel the future + task.cancel() + + # Kill the process and wait until it is done + proc.kill() + yield from proc.wait() + + self.loop.run_until_complete(cancel_wait()) + if sys.platform != 'win32': # Unix |