On Wed, Nov 30, 2016 at 1:20 AM, Chris Angelico <ros...@gmail.com> wrote: > 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 looks like a bug to me. Note that 'await' results in a clear error in the first case: >>> async def ham(): ... def spam(): ... await foo ... File "<stdin>", line 3 SyntaxError: 'await' outside async function >> 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". Yes, that's what I meant. -- https://mail.python.org/mailman/listinfo/python-list