On Sun, Aug 29, 2021 at 2:01 PM Serhiy Storchaka <storchaka@gmail.com> wrote:
29.08.21 23:16, Brett Cannon пише:
If you look at
https://github.com/python/cpython/blob/b11a951f16f0603d98de24fee5c023df83ea5...
< https://github.com/python/cpython/blob/b11a951f16f0603d98de24fee5c023df83ea5...
you will see that `async for` requires that the iterator returned from `__aiter__` define `__anext__`. But if you look at aiter() which uses PyObject_GetAiter() from
https://github.com/python/cpython/blob/f0a6fde8827d5d4f7a1c741ab1a8b206b66ff...
< https://github.com/python/cpython/blob/f0a6fde8827d5d4f7a1c741ab1a8b206b66ff...
and PyAiter_Check() from
https://github.com/python/cpython/blob/f0a6fde8827d5d4f7a1c741ab1a8b206b66ff...
< https://github.com/python/cpython/blob/f0a6fde8827d5d4f7a1c741ab1a8b206b66ff...
you will notice that aiter() requires `__anext__` *and* `__aiter__` on the async iterator that gets returned from __aiter__.
Now the docs for aiter() at https://docs.python.org/3.10/library/functions.html#aiter <https://docs.python.org/3.10/library/functions.html#aiter> points out that the async iterator is expected to define both methods as does the glossary definition for "asynchronous iterator" (https://docs.python.org/3.8/glossary.html#term-asynchronous-iterator <https://docs.python.org/3.8/glossary.html#term-asynchronous-iterator>).
So my question is whether the discrepancy between what `async for` expects and what `aiter()` expects on purpose? https://bugs.python.org/issue31861 <https://bugs.python.org/issue31861> was the issue for creating aiter() and I didn't notice a discussion of this difference. The key reason I'm asking is this does cause a deviation compared to the relationship between `for` and `iter()` (which does not require `__iter__` to be defined on the iterator, although collections.abc.Iterator does). It also makes the glossary definition being linked from
https://docs.python.org/3.10/reference/compound_stmts.html#the-async-for-sta...
< https://docs.python.org/3.10/reference/compound_stmts.html#the-async-for-sta...
incorrect.
PyIter_Check() only checks existence of __next__, not __iter__ (perhaps for performance reasons).
Or maybe no one thought to require __iter__ for iterators?
I just ported changes from PyPy in SQLite tests (https://github.com/python/cpython/pull/28021) because a test class with __next__ but without __iter__ passed tests on CPython but failed on PyPy.
I'm going to wait to hear from anyone who may have been involved with implementing aiter() and `async for` before proposing various ways to align them with iter() and `for`.