Skip to content

Conversation

@1st1
Copy link
Member

@1st1 1st1 commented Dec 18, 2017

I also believe the this PR makes asyncio.gather() code simpler (besides also making it 10-15% faster).

https://bugs.python.org/issue32355

for arg in coros_or_futures:
if arg not in arg_to_fut:
fut = ensure_future(arg, loop=loop)
if loop is None:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like the check for multiple loops (see line 622) has been removed. Is this intentional?
If it is, you may want to add a test for that.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ensure_future does it. No need to do it twice.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ensure_future validates that the passed in loop argument matches that of the future passed in. If I were to pass 3 futures each having their own different loop, a new _GatheringFuture will be created tied to the loop that was passed to gather (which can be a separate loop as well).

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I understand what you mean by that, ensure_future will make sure that the future/coro passed is bound to the same loop - either current or what was passed in. Thanks for explaining.

for fut in children:
if fut.cancelled():
res = futures.CancelledError()
elif fut._exception is not None:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_exception and _result is not a part of Future public API

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well, old code used it, i'm not adding anything new

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about this for a while. Let's use only public Future API in asyncio. I've updated this PR and will make a new one to fix all remaining places in asyncio.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, it's just one other place where we access Future._exception or Future._result in asyncio -- it's base_events.py. I've fixed it as part of this PR.

if not return_exceptions:
outer.set_exception(res)
if not return_exceptions:
if fut.cancelled():
Copy link
Contributor

@asvetlov asvetlov Dec 18, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both checks can be merged:

exc = fut.exception()
if exc is not None:
    outer.set_exception(exc)

it handles CancelledError too.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, it will raise CancelledError, not return it. We can't merge these checks.

# Future created specifically for 'arg'. Since the caller
# can't control it, disable the "destroy pending task"
# warning.
fut._log_destroy_pending = False
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated question: maybe add log_destroy_pending keyword-only parameter?
Often I want to see cancelled coroutines in logs.

@1st1 1st1 merged commit 36c2c04 into python:master Dec 19, 2017
@1st1 1st1 deleted the faster_gather branch December 19, 2017 12:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants