(Merge 3.4) Issue #21163, asyncio: Ignore "destroy pending task" warnings for

private tasks in gather().
This commit is contained in:
Victor Stinner 2014-07-16 18:36:58 +02:00
commit 845212af41
1 changed files with 23 additions and 11 deletions

View File

@ -558,21 +558,33 @@ def gather(*coros_or_futures, loop=None, return_exceptions=False):
prevent the cancellation of one child to cause other children to
be cancelled.)
"""
arg_to_fut = {arg: async(arg, loop=loop) for arg in set(coros_or_futures)}
children = [arg_to_fut[arg] for arg in coros_or_futures]
n = len(children)
if n == 0:
if not coros_or_futures:
outer = futures.Future(loop=loop)
outer.set_result([])
return outer
if loop is None:
loop = children[0]._loop
for fut in children:
if fut._loop is not loop:
raise ValueError("futures are tied to different event loops")
arg_to_fut = {}
for arg in set(coros_or_futures):
if not isinstance(arg, futures.Future):
fut = async(arg, loop=loop)
if loop is None:
loop = fut._loop
# The caller cannot control this future, the "destroy pending task"
# warning should not be emitted.
fut._log_destroy_pending = False
else:
fut = arg
if loop is None:
loop = fut._loop
elif fut._loop is not loop:
raise ValueError("futures are tied to different event loops")
arg_to_fut[arg] = fut
children = [arg_to_fut[arg] for arg in coros_or_futures]
nchildren = len(children)
outer = _GatheringFuture(children, loop=loop)
nfinished = 0
results = [None] * n
results = [None] * nchildren
def _done_callback(i, fut):
nonlocal nfinished
@ -595,7 +607,7 @@ def gather(*coros_or_futures, loop=None, return_exceptions=False):
res = fut._result
results[i] = res
nfinished += 1
if nfinished == n:
if nfinished == nchildren:
outer.set_result(results)
for i, fut in enumerate(children):