Message337150
There are some tricky subtleties here around the distinction between list/dict/set comprehensions and generator expressions.
For list/dict/set comprehensions, they're evaluated eagerly, so an async comprehension can only occur in async context. For generator expressions, they're evaluated lazily, so you can write an async generator expression inside a non-async context. *Consuming* the async generator will require an async context, but all the expression itself does is instantiate an object, and that's synchronous.
(Like Guido, I'm not 100% sure that it's useful to support async generator expressions inside sync contexts, but we've already shipped it, so I'll assume we're going to keep it.)
So, I would expect the rule to be, precisely: if an async list/dict/set comprehension occurs inside either a list/dict/set comprehension or a generator expression, that should force the enclosing expression to become async.
So this is a synchronous comprehension, even though it has an async generator expression in it, and must occur inside an 'async def':
[(i async for i in range(j)) for j in range(n)]
And this is an async generator expression, which can legally be placed inside a regular 'def' (but can only be consumed inside an 'async def'):
([i async for i in range(j)] for j in range(n))
This might be what Yury/Serhiy/etc. already had in mind, but it's complicated enough that it seemed like it's worth spelling out in detail... |
|
Date |
User |
Action |
Args |
2019-03-04 21:16:45 | njs | set | recipients:
+ njs, gvanrossum, ericvw, asvetlov, serhiy.storchaka, yselivanov, levkivskyi, pablogsal, xtreak |
2019-03-04 21:16:45 | njs | set | messageid: <1551734205.63.0.122132244562.issue33346@roundup.psfhosted.org> |
2019-03-04 21:16:45 | njs | link | issue33346 messages |
2019-03-04 21:16:45 | njs | create | |
|