[Python-checkins] cpython (3.5): Issue #26923: Fix asyncio.Gather to refuse being cancelled once all children
yury.selivanov
python-checkins at python.org
Fri Oct 21 17:25:10 EDT 2016
https://hg.python.org/cpython/rev/b1aa485fad1b
changeset: 104620:b1aa485fad1b
branch: 3.5
parent: 104615:9feff7ba89b2
user: Yury Selivanov <yury at magic.io>
date: Fri Oct 21 17:22:17 2016 -0400
summary:
Issue #26923: Fix asyncio.Gather to refuse being cancelled once all children are done.
Patch by Johannes Ebke.
files:
Lib/asyncio/tasks.py | 6 ++-
Lib/test/test_asyncio/test_tasks.py | 30 +++++++++++++++++
Misc/NEWS | 4 ++
3 files changed, 38 insertions(+), 2 deletions(-)
diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py
--- a/Lib/asyncio/tasks.py
+++ b/Lib/asyncio/tasks.py
@@ -592,9 +592,11 @@
def cancel(self):
if self.done():
return False
+ ret = False
for child in self._children:
- child.cancel()
- return True
+ if child.cancel():
+ ret = True
+ return ret
def gather(*coros_or_futures, loop=None, return_exceptions=False):
diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py
--- a/Lib/test/test_asyncio/test_tasks.py
+++ b/Lib/test/test_asyncio/test_tasks.py
@@ -1899,6 +1899,36 @@
def test_cancel_wait_for(self):
self._test_cancel_wait_for(60.0)
+ def test_cancel_gather(self):
+ """Ensure that a gathering future refuses to be cancelled once all
+ children are done"""
+ loop = asyncio.new_event_loop()
+ self.addCleanup(loop.close)
+
+ fut = asyncio.Future(loop=loop)
+ # The indirection fut->child_coro is needed since otherwise the
+ # gathering task is done at the same time as the child future
+ def child_coro():
+ return (yield from fut)
+ gather_future = asyncio.gather(child_coro(), loop=loop)
+ gather_task = asyncio.ensure_future(gather_future, loop=loop)
+
+ cancel_result = None
+ def cancelling_callback(_):
+ nonlocal cancel_result
+ cancel_result = gather_task.cancel()
+ fut.add_done_callback(cancelling_callback)
+
+ fut.set_result(42) # calls the cancelling_callback after fut is done()
+
+ # At this point the task should complete.
+ loop.run_until_complete(gather_task)
+
+ # Python issue #26923: asyncio.gather drops cancellation
+ self.assertEqual(cancel_result, False)
+ self.assertFalse(gather_task.cancelled())
+ self.assertEqual(gather_task.result(), [42])
+
class GatherTestsBase:
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -398,6 +398,10 @@
- Issue #27972: Prohibit Tasks to await on themselves.
+- Issue #26923: Fix asyncio.Gather to refuse being cancelled once all
+ children are done.
+ Patch by Johannes Ebke.
+
IDLE
----
--
Repository URL: https://hg.python.org/cpython
More information about the Python-checkins
mailing list