gabriel119435
gabriel119435

Reputation: 6812

how to dynamically build a list of coroutines for async.gather?

at the documentation, we have:

async def main():
    await asyncio.gather(
      factorial("A", 2),
      factorial("B", 3),
      factorial("C", 4),
    )
asyncio.run(main())

if i wanted the number of coroutines to be parameter of main, how it should be implement? I tried

async def main(count):
    coroutines = [factorial(str(i),i) for i in range(count)]
    await asyncio.gather(coroutines)
asyncio.run(main(3))

but got:

TypeError: unhashable type: 'list'
sys:1: RuntimeWarning: coroutine 'factorial' was never awaited

Upvotes: 0

Views: 1371

Answers (1)

larsks
larsks

Reputation: 311685

Look at how you're calling asyncio.gather in the first example:

await asyncio.gather(factorial("A", 2), factorial("B", 3), factorial("C", 4))

You're passing three arguments. But in your second example, you're trying to pass in a single argument (a list of coroutines):

await asyncio.gather(coroutines)

This isn't an equivalent call. asyncio.gather doesn't expect any of its arguments to be a list, which is why you're getting that "unhashable type" error message (it's trying to use the argument as a dictionary key or some other operation that requires a hashable value).

The equivalent call would be:

await asyncio.gather(*coroutines)

The * operator "unpacks" the list into multiple arguments.

The relevant documentation is here.

Upvotes: 3

Related Questions