I'm using Python 3.7.4 and this block of code (MWE):
import asyncio
async def foo(x):
await asyncio.sleep(1)
return [i for i in range(10)]
async def big_foo():
dict_of_lists = {'A': [i for i in range(10)], 'B': [i for i in range(10)]}
return {
key: [
item
for list_item in dict_of_lists[key]
for item in await foo(list_item)
]
for key in ['A', 'B']
}
Throws the error:
File "filename.py", line 13
item
^
SyntaxError: asynchronous comprehension outside of an asynchronous function
The error message doesn't help a lot because it is indeed inside an asynchronous function.
I solved the issue by defining explicit for loops instead of a comprehension, like this:
async def big_foo():
dict_of_lists = {'A': [i for i in range(10)], 'B': [i for i in range(10)]}
var = {}
for key in ['A', 'B']:
var[key] = []
for list_item in dict_of_lists[key]:
for item in await foo(list_item):
var[key].append(item)
return var
It bugs me that removing the dictionary outer loop also removes the error.
This works (it doesn't accomplish what I need obviously):
async def other_foo():
dict_of_lists = {'A': [i for i in range(10)]}
return [
item
for list_item in dict_of_lists['A']
for item in await foo(list_item)
]
I have found the answer. Quoting a co-worker:
The interior comprehension is asynchronous. The exterior one isn't. The function is asynchronous. The error is triggered because you are defining as an asynchronous comprehension inside of a non-asynchronous context - the error message is indeed wrong and it's a know bug.
https://bugs.python.org/issue33346
I fixed it by setting an
async forin the exterior comprehension. Like this:
async def big_foo():
dict_of_lists = {'A': [i for i in range(10)], 'B': [i for i in range(10)]}
return {
key: [
item
for list_item in dict_of_lists[key]
for item in await foo(list_item)
]
async for key in ['A', 'B']
}
While this removes the mentioned SyntaxError it introduces a TypeError: 'async for' requires an object with __aiter__ method, got tuple. So the solution would be to define a wraper for it, but it looks more like a hack than a proper solution.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With