Comments inlined: On Thu, Sep 2, 2021 at 6:23 PM Guido van Rossum <gu...@python.org> wrote:
> First of all, we should ping Yury, who implemented `async for` about 6 > years ago (see PEP 492), and Joshua Bronson, who implemented aiter() and > anext() about 5 months ago (see https://bugs.python.org/issue31861). I've > CC'ed them here. > Looks like PyAiter_Check was added along with the aiter/anext builtins. I agree it's unnecessary to check for __aiter__ in it, so I let's just fix it. > > My own view: > > A. iter() doesn't check that the thing returned implements __next__, > because it's not needed -- iterators having an __iter__ methor is a > convention, not a requirement. > Yeah. > You shouldn't implement __iter__ returning something that doesn't > implement __iter__ itself, because then "for x in iter(a)" would fail even > though "for x in a" works. But you get an error, and anyone who implements > something like that (or uses it) deserves what they get. People know about > this convention and the ABC enforces it, so in practice it will be very > rare that someone gets bitten by this. > > B. aiter() shouldn't need to check either, for exactly the same reason. I > *suspect* (but do not know) that the extra check for the presence of > __iter__ is simply an attempt by the implementer to enforce the convention. > There is no *need* other than ensuring that "async for x in aiter(a)" works > when "async for x in a" works. > I agree. > > Note that PEP 525, which defines async generators, seems to imply that an > __aiter__ returning self is always necessary, but I don't think it gives a > reason. > PEP 525 implies that specifically for asynchronous generators, not iterators. That's due to the fact that synchronous generators return self from their __iter__. > > I do notice there's some backwards compatibility issue related to > __aiter__, alluded to in both PEP 492 ( > https://www.python.org/dev/peps/pep-0492/#api-design-and-implementation-revisions) > and PEP 525 ( > https://www.python.org/dev/peps/pep-0525/#aiter-and-anext-builtins). So > it's *possible* that it has to do with this (maybe really old code > implementing the 3.5 version of __aiter__ would be caught out by the extra > check) but I don't think it is. Hopefully Yury and/or Joshua remembers? > That wasn't related. In the first iteration of PEP 492, __aiter__ was required to be a coroutine. Some time after shipping 3.5.0 I realized that that would complicate asynchronous generators for no reason (and I think there were also some bigger problems than just complicating them). So I updated the PEP to change __aiter__ return type from `Awaitable[AsyncIterator]` to `AsyncIterator`. ceval code was changed to call __aiter__ and see if the object that it returned had __anext__. If not, it tried to await on it. Bottom line: let's fix PyAiter_Check to only look for __anext__. It's a new function so we can still fix it to reflect PyIter_Check and not worry about anything. Yury
_______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/BRHMOFPEKGQCCKEKEEKGSYDR6NOPMRCC/ Code of Conduct: http://python.org/psf/codeofconduct/