Skip to content
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

Merged
merged 9 commits into from Dec 31, 2022

Conversation

plammens
Copy link
Contributor

@plammens plammens commented Sep 19, 2020

@the-knights-who-say-ni
Copy link

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 Missing

Our records indicate the following people have not signed the CLA:

@plammens

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
before our records are updated.

You can check yourself to see if the CLA has been received.

Thanks again for the contribution, we look forward to reviewing it!

@plammens
Copy link
Contributor Author

plammens commented Nov 3, 2020

The CI is failing on the Misc/NEWS.d check, is there any way I can add the skip news label myself?

@plammens plammens changed the title bpo-41813: Clarify the vague specification of object.__await__ bpo-41813: Clarify the vague specification of object.__await__ [skip news] Nov 3, 2020
@plammens plammens changed the title bpo-41813: Clarify the vague specification of object.__await__ [skip news] bpo-41813: Clarify the vague specification of object.__await__ Nov 3, 2020
@asvetlov
Copy link
Contributor

asvetlov commented Nov 4, 2020

@aeros could you please check the text?
It looks correct for me but I'm not a native speaker...

@aeros aeros self-requested a review November 8, 2020 23:32
Copy link
Member

@aeros aeros left a 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.

Doc/reference/datamodel.rst Outdated Show resolved Hide resolved
@bedevere-bot
Copy link

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 I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

Co-authored-by: Kyle Stanley <aeros167@gmail.com>
Doc/reference/datamodel.rst Outdated Show resolved Hide resolved
Doc/reference/datamodel.rst Outdated Show resolved Hide resolved
@plammens
Copy link
Contributor Author

I have made the requested changes; please review again.

@bedevere-bot
Copy link

Thanks for making the requested changes!

@aeros, @asvetlov: please review the changes made to this pull request.

: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.
Copy link
Contributor

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

Copy link
Member

Choose a reason for hiding this comment

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

Agreed.

: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``)
Copy link
Contributor

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

Copy link
Member

Choose a reason for hiding this comment

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

Agreed.

@graingert
Copy link
Contributor

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)

Copy link
Member

@gvanrossum gvanrossum left a 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?

: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``)
Copy link
Member

Choose a reason for hiding this comment

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

Agreed.

: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.
Copy link
Member

Choose a reason for hiding this comment

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

Agreed.

Comment on lines 2626 to 2628
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
Copy link
Member

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.

Comment on lines 2626 to 2628
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
Copy link
Member

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) or return await aw but actually calls return 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?

@graingert
Copy link
Contributor

@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?

I'm currently still 99% offline I'll be available in a few weeks I think

@kumaraditya303 kumaraditya303 dismissed asvetlov’s stale review November 27, 2022 17:23

needs to be re-reviewed

@gvanrossum gvanrossum changed the title bpo-41813: Clarify the vague specification of object.__await__ GH-85979: Clarify the vague specification of object.__await__ Nov 28, 2022
@kumaraditya303 kumaraditya303 dismissed aeros’s stale review December 16, 2022 11:17

needs to be re-reviewed

Copy link
Contributor

@kumaraditya303 kumaraditya303 left a 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.

Copy link
Contributor

@kumaraditya303 kumaraditya303 left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Member

@gvanrossum gvanrossum left a comment

Choose a reason for hiding this comment

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

Go for it!

@kumaraditya303 kumaraditya303 merged commit f59c7f8 into python:main Dec 31, 2022
15 checks passed
@kumaraditya303 kumaraditya303 added needs backport to 3.10 only security fixes needs backport to 3.11 bug and security fixes labels Dec 31, 2022
@miss-islington
Copy link
Contributor

Thanks @plammens for the PR, and @kumaraditya303 for merging it 🌮🎉.. I'm working now to backport this PR to: 3.10.
🐍🍒🤖

@miss-islington
Copy link
Contributor

Thanks @plammens for the PR, and @kumaraditya303 for merging it 🌮🎉.. I'm working now to backport this PR to: 3.11.
🐍🍒🤖

@bedevere-bot
Copy link

GH-100635 is a backport of this pull request to the 3.11 branch.

@bedevere-bot bedevere-bot removed the needs backport to 3.11 bug and security fixes label Dec 31, 2022
@bedevere-bot
Copy link

GH-100636 is a backport of this pull request to the 3.10 branch.

miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Dec 31, 2022
…-22320)

(cherry picked from commit f59c7f8)

Co-authored-by: Paolo Lammens <lammenspaolo@gmail.com>
Co-authored-by: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com>
@bedevere-bot bedevere-bot removed the needs backport to 3.10 only security fixes label Dec 31, 2022
miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Dec 31, 2022
…-22320)

(cherry picked from commit f59c7f8)

Co-authored-by: Paolo Lammens <lammenspaolo@gmail.com>
Co-authored-by: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com>
miss-islington added a commit that referenced this pull request Dec 31, 2022
(cherry picked from commit f59c7f8)

Co-authored-by: Paolo Lammens <lammenspaolo@gmail.com>
Co-authored-by: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com>
miss-islington added a commit that referenced this pull request Dec 31, 2022
(cherry picked from commit f59c7f8)

Co-authored-by: Paolo Lammens <lammenspaolo@gmail.com>
Co-authored-by: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs Documentation in the Doc dir skip news topic-asyncio
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet