Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: awaiting a list of coroutines sequentially

I want to await a list of coroutines sequentially in Python, i.e. I do not want to use asyncio.gather(*coros). The reason for this is that I'm trying to debug my app, so I want to pass a command-line switch to have things to run in a certain order, such that I get consistent behavior each time the app runs.

I tried doing it like this:

if args.sequential:
    fields = [await coro for coro in coros]
else:
    fields = await asyncio.gather(*coros)

But the sequential version doesn't seem to work correctly, i.e. I'm getting this warning:

sys:1: RuntimeWarning: coroutine 'get_fields' was never awaited

What am I doing wrong?

like image 651
James Ko Avatar asked Sep 18 '25 04:09

James Ko


1 Answers

Once coroutine has been created somewhere, asyncio expects it would be awaited before event loop closed (before script finished execution):

import asyncio


async def bla():
    await asyncio.sleep(1)
    print('done')


async def main():
    bla()  # Create coro, but don't await


loop = asyncio.get_event_loop()
loop.run_until_complete(main())

Result:

RuntimeWarning: coroutine 'bla' was never awaited

We need this warning since it's very easy to forget about await while coroutine that was never awaited almost always means mistake.

Since one of your async_op threw an error, some coroutine created earlier was never awaited at the moment script finished. That's why you got warning.

In other words something like this has happened:

async def bla1():
    print('done')


async def bla2():
    raise Exception()


async def main():
    b1 = bla1()

    b2 = bla2()  # but here is exception ...

    await bla1()  # ... and this line was never reached
like image 99
Mikhail Gerasimov Avatar answered Sep 19 '25 19:09

Mikhail Gerasimov