You can resolve the RuntimeWarning “Coroutine Was Never Awaited” by running the coroutine object.
It is common to see this warning message when calling a coroutine function but failing to execute the coroutine object that is returned either via asyncio.run() or by awaiting it.
In this tutorial, you will discover how to fix the RuntimeWarning caused by not running a coroutine.
Let’s get started.
RuntimeWarning When Running a Coroutine
It is common for Python developers to get a RuntimeWarning when getting started with asyncio.
The warning looks as follows:
1 |
RuntimeWarning: coroutine '' was never awaited |
Where the name of the coroutine function is between the quotes.
For example, if you tried to run a coroutine function with the name “custom_coro“, then the RuntimeWarning message would look as follows:
1 |
RuntimeWarning: coroutine 'custom_coro' was never awaited |
Don’t worry, you’re not alone.
Many developers get this warning.
Why are you getting this warning and how can we fix it?
Run loops using all CPUs, download your FREE book to learn how.
Why Are You Getting a RuntimeWarning and How to Fix It
If you try to run a coroutine and get a RuntimeWarning, the reason is that the coroutine was not executed.
For example, you may have defined a coroutine function as follows:
1 2 3 |
# define a custom coroutine async def custom_coro(): print('Hello there') |
You may then try to run the coroutine by calling the coroutine function.
For example:
1 2 3 |
... # call the coroutine function custom_coro() |
This will cause the error.
It looks like you are calling the function, but you are not.
The reason is that calling the coroutine function does not run the coroutine.
Instead, it creates a coroutine object.
For example:
1 2 3 |
... # create a coroutine object: coro = custom_coro() |
If this coroutine object is not given an opportunity to run, then Python will report the RuntimeWarning.
To run a coroutine object from a regular Python program, you must pass it to the asyncio.run() function.
This will start the asyncio event loop and execute your provided coroutine.
For example:
1 2 3 |
... # run the coroutine asyncio.run(coro) |
This is often performed on one line using a compound statement.
For example:
1 2 3 |
... # run the coroutine asyncio.run(custom_coro()) |
If you are trying to run a coroutine from within a coroutine, then this can be achieved using the “await” expression.
This will suspend the caller coroutine and run the called coroutine.
For example:
1 2 3 |
... # suspend and run the other coroutine await coro |
This too is typically performed on one line using a compound statement.
For example:
1 2 3 |
... # suspend and run the other coroutine await custom_coro() |
You can learn more about running coroutines in the tutorial:
You now know why the RuntimeWarning is reported. Because you created a coroutine object and did not run it.
You also know how to resolve the warning. By running the coroutine with asyncio.run() or the “await” expression.
Next, let’s look at some worked examples to make this concrete.
Example Running an Asyncio Program
We can explore an example of running a coroutine from a regular Python program.
In this example, we will define a custom coroutine function.
We will then call the coroutine function from a regular Python program.
This will create a coroutine object, but not run it.
The program will end and a RuntimeWarning will be generated.
The complete example is listed below.
1 2 3 4 5 6 7 8 9 10 |
# SuperFastPython.com # example of runtime warning: coroutine was never awaited import asyncio # define a custom coroutine async def custom_coro(): print('Hello there') # create the custom coroutine coro = custom_coro() # generates warning |
Running the example calls the custom coroutine function.
A coroutine object is generated and not executed.
The program ends and a RuntimeWarning is reported indicating that the coroutine was never awaited.
This means that the coroutine was created, but not executed.
1 |
sys:1: RuntimeWarning: coroutine 'custom_coro' was never awaited |
We can update the example to resolve the warning.
This requires that we execute the coroutine object.
This can be achieved by passing it to the asyncio.run() function to execute.
The updated version that resolves the warning and runs the coroutine is listed below.
1 2 3 4 5 6 7 8 9 10 11 12 |
# SuperFastPython.com # example of fixed runtime warning: coroutine was never awaited import asyncio # define a custom coroutine async def custom_coro(): print('Hello there') # create the custom coroutine coro = custom_coro() # run the coroutine in an asyncio program asyncio.run(coro) |
Running the example calls the custom coroutine function.
A coroutine object is created.
The coroutine object is then passed to the asyncio.run() function.
This starts the asyncio event loop and executes the coroutine.
The message is reported.
The coroutine then terminates and the program exits.
This highlights how to resolve the RuntimeWarning when running a coroutine from a regular Python program.
1 |
Hello there |
Next, let’s look at how we may get the warning within an asyncio program and how we can resolve it.
Free Python Asyncio Course
Download your FREE Asyncio PDF cheat sheet and get BONUS access to my free 7-day crash course on the Asyncio API.
Discover how to use the Python asyncio module including how to define, create, and run new coroutines and how to use non-blocking I/O.
Example Calling Coroutine From Coroutine
We can explore an example of running a coroutine from a coroutine.
In this example, we will run our main coroutine normally as an asyncio program.
The main coroutine will create a second coroutine and fail to run it.
The main coroutine will then terminate and the main program will exit without running the second created coroutine.
A RuntimeWarning will be reported, highlighting that a coroutine was created in the asyncio program but never executed.
The complete example is listed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# SuperFastPython.com # example of runtime warning: coroutine was never awaited import asyncio # another coroutine async def other_coro(): print('Hi from other coroutine') # define a custom coroutine async def custom_coro(): # report a message print('Hello there') # create the other coroutine other = other_coro() # generate a warning # create the custom coroutine coro = custom_coro() # run the coroutine in an asyncio program asyncio.run(coro) |
Running the example first creates the main() coroutine and executes it as the entry point into the asyncio program.
The main() coroutine runs and reports a message.
It then creates a second coroutine object by calling the other_coro() function.
The second coroutine is not executed.
The other_coro() terminates and the program exits.
The other coroutine is never executed in the asyncio program and a RuntimeWarning is reported.
1 2 3 4 |
Hello there ...: RuntimeWarning: coroutine 'other_coro' was never awaited self._context.run(self._callback, *self._args) RuntimeWarning: Enable tracemalloc to get the object allocation traceback |
We can update the example to resolve the RuntimeWarning.
This can be achieved by executing the second coroutine object.
One way to do this is to schedule the other coroutine for execution in the event loop and suspend the main() coroutine until the other coroutine is done.
We can do this with an await expression.
The updated version with this change is listed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
# SuperFastPython.com # example of fixed runtime warning: coroutine was never awaited import asyncio # another coroutine async def other_coro(): print('Hi from other coroutine') # define a custom coroutine async def custom_coro(): # report a message print('Hello there') # create the other coroutine other = other_coro() # suspend and run the other coroutine await other # create the custom coroutine coro = custom_coro() # run the coroutine in an asyncio program asyncio.run(coro) |
The main() coroutine runs and reports a message.
It then creates a second coroutine object by calling the other_coro() function.
The main() coroutine then schedules the other coroutine for execution and suspends until it is done.
The other_coro() runs and reports a message, then terminates.
The main() coroutine then resumes and terminates and the program exits.
This highlights how we can resolve the RuntimeWarning caused by failing to execute a coroutine within an asyncio program.
1 2 |
Hello there Hi from other coroutine |
Overwhelmed by the python concurrency APIs?
Find relief, download my FREE Python Concurrency Mind Maps
Further Reading
This section provides additional resources that you may find helpful.
Python Asyncio Books
- Python Asyncio Mastery, Jason Brownlee (my book!)
- Python Asyncio Jump-Start, Jason Brownlee.
- Python Asyncio Interview Questions, Jason Brownlee.
- Asyncio Module API Cheat Sheet
I also recommend the following books:
- Python Concurrency with asyncio, Matthew Fowler, 2022.
- Using Asyncio in Python, Caleb Hattingh, 2020.
- asyncio Recipes, Mohamed Mustapha Tahrioui, 2019.
Guides
APIs
- asyncio — Asynchronous I/O
- Asyncio Coroutines and Tasks
- Asyncio Streams
- Asyncio Subprocesses
- Asyncio Queues
- Asyncio Synchronization Primitives
References
Takeaways
You now know how to fix the RuntimeWarning caused by not running a coroutine.
Do you have any questions?
Ask your questions in the comments below and I will do my best to answer.
Photo by Pavel Anoshin on Unsplash
CheeseCake says
I have tried running your code in Google Colab. It showed different behavior with this error
RuntimeError: asyncio.run() cannot be called from a running event loop
. How to solve this as I read that Notebook has different behavior compared to script?Jason Brownlee says
That error does not sound specific to a notebook. It suggests that you are attempting to start the asyncio event loop from within a running asyncio program.
Perhaps ensure that asyncio.run() is the first and only line in the entry point of your program and see if that makes a difference?