Skip to content Skip to sidebar Skip to footer

Implementing An Asynchronous Iterator

Per PEP-492 I am trying to implement an asynchronous iterator, such that I can do e.g. async for foo in bar: ... Here is a trivial example, similar to the one in the docs, wi

Solution 1:

If you read a little further down the documentation it mentions that (emphasis mine):

PEP 492 was accepted in CPython 3.5.0 with __aiter__ defined as a method, that was expected to return an awaitable resolving to an asynchronous iterator.

In 3.5.2 (as PEP 492 was accepted on a provisional basis) the __aiter__ protocol was updated to return asynchronous iterators directly.

Therefore for versions prior to 3.5.2 (released 2016/6/27) the documentation is slightly out of step with how to write a working asynchronous iterator. The fixed version for 3.5.0 and 3.5.1 looks like:

classTestImplementation:
    asyncdef__aiter__(self):
  # ^ notereturn self
    asyncdef__anext__(self):
        raise StopAsyncIteration

This was introduced on closing bug #27243 and is a little clearer in the data model documentation, which also suggests a way of writing backwards compatible code.

Solution 2:

Asynchronous iterators have been implemented in Python 3.6 - see PEP-525

Then you don't need your TestImplementation at all in order to use async for. You can just use yield (example taken from PEP-525):

asyncdefticker(delay, to):
    """Yield numbers from 0 to `to` every `delay` seconds."""for i inrange(to):
        yield i
        await asyncio.sleep(delay)

You can then use async for as you would expect:

asyncfor i in ticker(1, 10):                                                                     
    print(f'Tick #{i}')

Post a Comment for "Implementing An Asynchronous Iterator"