New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
GH-85979: Clarify the vague specification of object.__await__ #22320
Conversation
plammens
commented
Sep 19, 2020
•
edited by gvanrossum
edited by gvanrossum
- Issue: Clarify specification of object.__await__ #85979
Hello, and thanks for your contribution! I'm a bot set up to make sure that the project can legally accept this contribution by verifying everyone involved has signed the PSF contributor agreement (CLA). CLA MissingOur records indicate the following people have not signed the CLA: For legal reasons we need all the people listed to sign the CLA before we can look at your contribution. Please follow the steps outlined in the CPython devguide to rectify this issue. If you have recently signed the CLA, please wait at least one business day You can check yourself to see if the CLA has been received. Thanks again for the contribution, we look forward to reviewing it! |
The CI is failing on the |
@aeros could you please check the text? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR @plammens!
You're definitely right that the __await__
docs could use significant clarification, and I think the general direction of the content is correct. That being said, I have some suggestions (mix of technical, grammar, and reST).
Feedback on my technical suggestions from @asvetlov and @1st1 would be appreciated (even if it's just +1/-1); I think it's especially important to get this part of the documentation correct given the large scope that it applies to.
A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated. Once you have made the requested changes, please leave a comment on this pull request containing the phrase |
Co-authored-by: Kyle Stanley <aeros167@gmail.com>
I have made the requested changes; please review again. |
Doc/reference/datamodel.rst
Outdated
:term:`coroutines <coroutine>`, instances of :class:`asyncio.Task`, | ||
:class:`asyncio.Future`, and other :mod:`asyncio` objects to implement | ||
``__await__``; yielding objects from these (e.g. | ||
``return (yield from future)``), rather than yielding objects directly. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're not supposed to use yield from fut
anymore either - you should use await fut
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed.
Doc/reference/datamodel.rst
Outdated
:class:`asyncio.Future`, and other :mod:`asyncio` objects to implement | ||
``__await__``; yielding objects from these (e.g. | ||
``return (yield from future)``), rather than yielding objects directly. | ||
An exception to this is a ``yield None`` (or equivalent bare ``yield``) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think the special case of await asyncio.sleep(0)
via yield None
should be documented here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed.
I think here it makes most sense to have a very minimal comparative discussion of how other async frameworks handle this eg twisted and asyncio are very similar using a Future/Deferred callback/ trampoline pattern. curio and trio use an approach similar to kernel "traps" using @types.coroutine
def _async_yield(v):
return (yield v) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@graingert Could you submit a comment with suggested text that would make you happy about this note and that I can just commit and land?
Doc/reference/datamodel.rst
Outdated
:class:`asyncio.Future`, and other :mod:`asyncio` objects to implement | ||
``__await__``; yielding objects from these (e.g. | ||
``return (yield from future)``), rather than yielding objects directly. | ||
An exception to this is a ``yield None`` (or equivalent bare ``yield``) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed.
Doc/reference/datamodel.rst
Outdated
:term:`coroutines <coroutine>`, instances of :class:`asyncio.Task`, | ||
:class:`asyncio.Future`, and other :mod:`asyncio` objects to implement | ||
``__await__``; yielding objects from these (e.g. | ||
``return (yield from future)``), rather than yielding objects directly. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed.
Doc/reference/datamodel.rst
Outdated
In the case of :mod:`asyncio`, user code should generally be using | ||
:term:`coroutines <coroutine>`, instances of :class:`asyncio.Task`, | ||
:class:`asyncio.Future`, and other :mod:`asyncio` objects to implement |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dask/distributed uses:
def __await__(self): async def _(): ... return _().__await__()To implement Awaitable classes, it's not clear to me if that's an intended use case.
I think it is fine. It would seem reasonable that a given function's implementation can either return the desired result, or call another function that returns the desired result. And if async function are specified to have an __await__()
method, that's what we are doing here.
Just like when you're implementing an iterator, you can either have a method __iter__()
that creates and returns a custom object with a __next__()
method, or you can have __iter__()
be a generator function. Or you can construct some other thing and call its __iter__()
method.
Doc/reference/datamodel.rst
Outdated
In the case of :mod:`asyncio`, user code should generally be using | ||
:term:`coroutines <coroutine>`, instances of :class:`asyncio.Task`, | ||
:class:`asyncio.Future`, and other :mod:`asyncio` objects to implement |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is also slightly inaccurate as asyncio should call
return yield from type(aw).__await__(aw)
orreturn await aw
but actually callsreturn yield from aw.__await__()
I can't disagree, but is this fine point relevant to the docs at hand? We're trying to specify __await__
without referring to asyncio.
There's also exotic objects that are Awaitables but don't have an
__await__
method. I think via c extensions
Can you point to an example? I'm guessing you're referring to extension types that have an tp_as_async->am_await
slot but don't have a Python-visible __await__
callable?
I'm currently still 99% offline I'll be available in a few weeks I think |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed asyncio
implementation details from the note as IMO it is unnecessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Go for it!
Thanks @plammens for the PR, and @kumaraditya303 for merging it |
Thanks @plammens for the PR, and @kumaraditya303 for merging it |
GH-100635 is a backport of this pull request to the 3.11 branch. |
GH-100636 is a backport of this pull request to the 3.10 branch. |
(cherry picked from commit f59c7f8) Co-authored-by: Paolo Lammens <lammenspaolo@gmail.com> Co-authored-by: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com>
(cherry picked from commit f59c7f8) Co-authored-by: Paolo Lammens <lammenspaolo@gmail.com> Co-authored-by: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com>