Messa
Messa

Reputation: 25191

asyncio.gather throws RuntimeError: Task got bad yield

I want to run a few tasks "in parallel" using asyncio.gather():

import asyncio

async def foo():
    return 42

async def main():
    results = await asyncio.gather(foo() for i in range(10))
    print(results)

asyncio.run(main())

But it fails with RuntimeError: Task got bad yield:

/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/events.py:88: RuntimeWarning: coroutine 'foo' was never awaited
  self._context.run(self._callback, *self._args)
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/runners.py", line 43, in run
    return loop.run_until_complete(main)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/base_events.py", line 583, in run_until_complete
    return future.result()
  File "<stdin>", line 2, in main
  File "<stdin>", line 2, in <genexpr>
RuntimeError: Task got bad yield: <coroutine object foo at 0x10555bd40>

Upvotes: 12

Views: 3657

Answers (1)

Messa
Messa

Reputation: 25191

The function asyncio.gather() accepts each task as separate argument. Like this:

await asyncio.gather(task1, task2, task3)

So the solution is to replace

    results = await asyncio.gather(foo() for i in range(10))

with

    results = await asyncio.gather(*[foo() for i in range(10)])

Upvotes: 26

Related Questions