Async generators and async for loops
Posted: Sat Jan 06, 2018 4:15 pm
Hi all,
I was hitting an issue related to the use of 'async for', which I simplified into a minimal test case which I couldn't resolve, and then checked against python3.6, where I found there was no error in the approach, although I can't see which of the differences with Micropython uasyncio I have failed to keep track of.
I understood from the comment about "async for" in https://github.com/micropython/micropyt ... ifferences that it should be equivalent to the adoption of PEP492, lined up with Python3.6 but I guess the coroutine itself doesn't end up with the 'duck typing' of an asynchronous iterator itself, somehow, (since coroutines are generators in Micropython?).
Is there anything I should be doing differently to make asynchronous generators work with async for?
The test case is viewable at https://gist.github.com/cefn/e32496544a ... 9f4b59b6e3 and I get the results below. This is all based on Unix Micropython straight from Github head at the time of writing, and with uasyncio installed via micropython -m upip install micropython-uasyncio after trashing ~/.micropython
I attempted to resolve this by creating a wrapper object which was compliant with PEP492...
But this results in an error which suggests it needs to be an ordinary iterable within async for.
Does anyone know is there something obvious that I have missed?
I was hitting an issue related to the use of 'async for', which I simplified into a minimal test case which I couldn't resolve, and then checked against python3.6, where I found there was no error in the approach, although I can't see which of the differences with Micropython uasyncio I have failed to keep track of.
I understood from the comment about "async for" in https://github.com/micropython/micropyt ... ifferences that it should be equivalent to the adoption of PEP492, lined up with Python3.6 but I guess the coroutine itself doesn't end up with the 'duck typing' of an asynchronous iterator itself, somehow, (since coroutines are generators in Micropython?).
Is there anything I should be doing differently to make asynchronous generators work with async for?
The test case is viewable at https://gist.github.com/cefn/e32496544a ... 9f4b59b6e3 and I get the results below. This is all based on Unix Micropython straight from Github head at the time of writing, and with uasyncio installed via micropython -m upip install micropython-uasyncio after trashing ~/.micropython
Code: Select all
gist$ python3.6
Python 3.6.3 (default, Oct 3 2017, 21:45:48)
[GCC 7.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from async_for_tester import results; print(results)
[0, 1, 2, 3, 4, 5, 6, 7]
>>>
gist$ micropython
MicroPython v1.9.3-238-g42c4dd09 on 2018-01-03; linux version
Use Ctrl-D to exit, Ctrl-E for paste mode
>>> from async_for_tester import results; print(results)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "async_for_tester.py", line 27, in <module>
File "/home/cefn/.micropython/lib/uasyncio/core.py", line 149, in run_until_complete
File "/home/cefn/.micropython/lib/uasyncio/core.py", line 138, in run_forever
File "/home/cefn/.micropython/lib/uasyncio/core.py", line 97, in run_forever
File "/home/cefn/.micropython/lib/uasyncio/core.py", line 146, in _run_and_stop
File "async_for_tester.py", line 15, in aggregate
AttributeError: 'generator' object has no attribute '__aiter__'
Code: Select all
class CoroWrapper:
def __init__(self, coro):
self._it = iter(coro)
def __aiter__(self):
return self
async def __anext__(self):
try:
next(self._it) # skip spurious entries
value = next(self._it)
except StopIteration:
raise StopAsyncIteration
return value
Code: Select all
gist$ micropython
MicroPython v1.9.3-238-g42c4dd09 on 2018-01-03; linux version
Use Ctrl-D to exit, Ctrl-E for paste mode
>>> from async_for_tester import results; print(results)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "async_for_tester.py", line 43, in <module>
File "/home/cefn/.micropython/lib/uasyncio/core.py", line 149, in run_until_complete
File "/home/cefn/.micropython/lib/uasyncio/core.py", line 138, in run_forever
File "/home/cefn/.micropython/lib/uasyncio/core.py", line 97, in run_forever
File "/home/cefn/.micropython/lib/uasyncio/core.py", line 146, in _run_and_stop
File "async_for_tester.py", line 31, in aggregate
TypeError: 'CoroWrapper' object is not iterable