Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Aggregating an async generator to a tuple

In trying to aggregate the results from an asynchronous generator, like so:

async def result_tuple():
    async def result_generator():
        # some await things happening in here
        yield 1
        yield 2
    return tuple(num async for num in result_generator())

I get a

TypeError: 'async_generator' object is not iterable

when executing the async for line.

But PEP 530 seems to suggest that it should be valid:

Asynchronous Comprehensions

We propose to allow using async for inside list, set and dict comprehensions. Pending PEP 525 approval, we can also allow creation of asynchronous generator expressions.

Examples:

  • set comprehension: {i async for i in agen()};
  • list comprehension: [i async for i in agen()];
  • dict comprehension: {i: i ** 2 async for i in agen()};
  • generator expression: (i ** 2 async for i in agen()).

What's going on, and how can I aggregate an asynchronous generator into a single tuple?

like image 779
carver Avatar asked Sep 11 '18 23:09

carver


People also ask

Does Python support asynchronous programming?

asyncio is used as a foundation for multiple Python asynchronous frameworks that provide high-performance network and web-servers, database connection libraries, distributed task queues, etc. asyncio is often a perfect fit for IO-bound and high-level structured network code.

Is Python synchronous or asynchronous?

There are two basic types of methods in the Parallels Python API: synchronous and asynchronous. When a synchronous method is invoked, it completes executing before returning to the caller. An asynchronous method starts a job in the background and returns to the caller immediately.

What are async generators?

Async generator functions behave similarly to generator functions: the generator function returns an object that has a next() function, and calling next() executes the generator function until the next yield . The difference is that an async iterator's next() function returns a promise.

Should I use async await in Python?

The async/await keywords They simplify asynchronous programming in Python. The async keyword is used to create a Python coroutine. The await keyword suspends execution of a coroutine until it completes and returns the result data. The await keywords only works within an async function.


1 Answers

In the PEP excerpt, the comprehensions are listed side-by-side in the same bullet list, but the generator expression is very different from the others.

There is no such thing as a "tuple comprehension". The argument to tuple() makes an asynchronous generator:

tuple(num async for num in result_generator())

The line is equivalent to tuple(result_generator()). The tuple then tries to iterate over the generator synchronously and raises the TypeError.

The other comprehensions will work, though, as the question expected. So it's possible to generate a tuple by first aggregating to a list, like so:

async def result_tuple():
    async def result_generator():
        # some await things happening in here
        yield 1
        yield 2
    return tuple([num async for num in result_generator()])
like image 180
carver Avatar answered Sep 25 '22 02:09

carver