async enumeration - possible?
Ian Kelly
ian.g.kelly at gmail.com
Wed Nov 30 03:39:42 EST 2016
On Wed, Nov 30, 2016 at 1:20 AM, Chris Angelico <rosuav at 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.
More information about the Python-list
mailing list