summaryrefslogtreecommitdiffstats
path: root/Lib/asyncio
diff options
context:
space:
mode:
authorYury Selivanov <yury@magic.io>2018-05-29 23:20:01 (GMT)
committerGitHub <noreply@github.com>2018-05-29 23:20:01 (GMT)
commit3b263e65a80cfcb1fc751834372533773ec024a4 (patch)
treebc9c9a1361efdee8025f0f85636fb5e54b2f81cd /Lib/asyncio
parent51bf38f796c74c7dac5a3d09ad0004494470091c (diff)
downloadcpython-3b263e65a80cfcb1fc751834372533773ec024a4.zip
cpython-3b263e65a80cfcb1fc751834372533773ec024a4.tar.gz
cpython-3b263e65a80cfcb1fc751834372533773ec024a4.tar.bz2
bpo-32684: Fix gather to propagate cancel of itself with return_exceptions (GH-7224)
Diffstat (limited to 'Lib/asyncio')
-rw-r--r--Lib/asyncio/tasks.py11
1 files changed, 10 insertions, 1 deletions
diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py
index a294dfb..4cd2c6a 100644
--- a/Lib/asyncio/tasks.py
+++ b/Lib/asyncio/tasks.py
@@ -548,6 +548,7 @@ class _GatheringFuture(futures.Future):
def __init__(self, children, *, loop=None):
super().__init__(loop=loop)
self._children = children
+ self._cancel_requested = False
def cancel(self):
if self.done():
@@ -556,6 +557,11 @@ class _GatheringFuture(futures.Future):
for child in self._children:
if child.cancel():
ret = True
+ if ret:
+ # If any child tasks were actually cancelled, we should
+ # propagate the cancellation request regardless of
+ # *return_exceptions* argument. See issue 32684.
+ self._cancel_requested = True
return ret
@@ -636,7 +642,10 @@ def gather(*coros_or_futures, loop=None, return_exceptions=False):
results[i] = res
nfinished += 1
if nfinished == nchildren:
- outer.set_result(results)
+ if outer._cancel_requested:
+ outer.set_exception(futures.CancelledError())
+ else:
+ outer.set_result(results)
for i, fut in enumerate(children):
fut.add_done_callback(functools.partial(_done_callback, i))