Author njs
Recipients asvetlov, ericvw, gvanrossum, levkivskyi, njs, pablogsal, serhiy.storchaka, xtreak, yselivanov
Date 2019-03-04.21:16:45
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <>
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:45njssetrecipients: + njs, gvanrossum, ericvw, asvetlov, serhiy.storchaka, yselivanov, levkivskyi, pablogsal, xtreak
2019-03-04 21:16:45njssetmessageid: <>
2019-03-04 21:16:45njslinkissue33346 messages
2019-03-04 21:16:45njscreate