On Wed, Nov 30, 2016 at 7:10 PM, Ian Kelly <ian.g.ke...@gmail.com> wrote: > On Tue, Nov 29, 2016 at 8:22 PM, Chris Angelico <ros...@gmail.com> wrote: >> Interestingly, I can't do that in a list comp: >> >>>>> [x async for x in aiterable] >> File "<stdin>", line 1 >> [x async for x in aiterable] >> ^ >> SyntaxError: invalid syntax >> >> Not sure why. > > Because you tried to use an async comprehension outside of a coroutine. > > py> [x async for x in y] > File "<stdin>", line 1 > [x async for x in y] > ^ > SyntaxError: invalid syntax > py> async def foo(): > ... [x async for x in y] > ... > > The same is true for async generator expressions. The documentation is > clear that this is illegal for the async for statement: > > https://docs.python.org/3.6/reference/compound_stmts.html#the-async-for-statement
Hmm. The thing is, comprehensions and generators are implemented with their own nested functions. So I would expect that their use of async is independent of the function they're in. But maybe we have a bug here? >>> async def spam(): ... def ham(): ... async for i in x: ... pass ... >>> def ham(): ... async for i in x: File "<stdin>", line 2 async for i in x: ^ SyntaxError: invalid syntax >>> def ham(): ... async def spam(): ... async for i in x: ... pass ... >>> Clearly the second one is correct to throw SyntaxError, and the third is correctly acceptable. But the first one, ISTM, should be an error too. > Yeah, that's what I would expect. (x async for x in foo) is > essentially a no-op, just like its synchronous equivalent; it takes an > asynchronous iterator and produces an equivalent asynchronous > iterator. Meanwhile, list() can't consume an async iterator because > the list constructor isn't a coroutine. I don't think it's generally > possible to "synchronify" an async iterator other than to materialize > it. E.g.: > > def alist(aiterable): > result = [] > async for value in aiterable: > result.append(value) > return result > > And I find it a little disturbing that I actually can't see a better > way to build a list from an async iterator than that. Oh. Oops. That materialization was exactly what I intended to happen with the comprehension. Problem: Your version doesn't work either, although I think it probably _does_ work if you declare that as "async def alist". Shows you just how well I understand Python's asyncness, doesn't it? ChrisA -- https://mail.python.org/mailman/listinfo/python-list