[Python-Dev] PEP 492: async/await in Python; version 4

Stefan Behnel stefan_ml at behnel.de
Fri May 1 19:10:06 CEST 2015


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




More information about the Python-Dev mailing list