Stefan,

I don't like the idea of combining __next__ and __anext__.
In this case explicit is better than implicit.  __next__
returning coroutines is a perfectly normal thing for a
normal 'for' loop (it wouldn't to anything with them),
whereas 'async for' will interpret that differently, and
will try to await those coroutines.

Yury

On 2015-05-01 1:10 PM, Stefan Behnel wrote:
Guido van Rossum schrieb am 01.05.2015 um 17:28:
On Fri, May 1, 2015 at 5:39 AM, Stefan Behnel wrote:

Yury Selivanov schrieb am 30.04.2015 um 03:30:
Asynchronous Iterators and "async for"
--------------------------------------

An *asynchronous iterable* is able to call asynchronous code in its
*iter* implementation, and *asynchronous iterator* can call
asynchronous code in its *next* method.  To support asynchronous
iteration:

1. An object must implement an  ``__aiter__`` method returning an
    *awaitable* resulting in an *asynchronous iterator object*.

2. An *asynchronous iterator object* must implement an ``__anext__``
    method returning an *awaitable*.

3. To stop iteration ``__anext__`` must raise a ``StopAsyncIteration``
    exception.
What this section does not explain, AFAICT, nor the section on design
considerations, is why the iterator protocol needs to be duplicated
entirely. Can't we just assume (or even validate) that any 'regular'
iterator returned from "__aiter__()" (as opposed to "__iter__()") properly
obeys to the new protocol? Why additionally duplicate "__next__()" and
"StopIteration"?

ISTM that all this really depends on is that "__next__()" returns an
awaitable. Renaming the method doesn't help with that guarantee.

This is an astute observation. I think its flaw (if any) is the situation
where we want a single object to be both a regular iterator and an async
iterator (say when migrating code to the new world). The __next__ method
might want to return a result while __anext__ has to return an awaitable.
The solution to that would be to have __aiter__ return an instance of a
different class than __iter__, but that's not always convenient.
My personal gut feeling is that this case would best be handled by a
generic wrapper class. Both are well defined protocols, so I don't expect
people to change all of their classes and instead return a wrapped object
either from __iter__() or __aiter__(), depending on which they want to
optimise for, or which will eventually turn out to be easier to wrap.

But that's trying to predict the [Ff]uture, obviously. It just feels like
unnecessary complexity for now. And we already have a type slot for
__next__ ("tp_iternext"), but not for __anext__.

Stefan


_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/yselivanov.ml%40gmail.com

_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to