You may get a warning when running your asyncio program that looks like: “RuntimeWarning: Enable tracemalloc to get the object allocation traceback“.
This warning is caused by not awaiting a coroutine in an asyncio program and giving a suggestion on how to track down the cause. It can be fixed by awaiting the offending coroutine or suppressed by configuring the filter on the warnings module.
In this tutorial, you will discover the “RuntimeWarning: Enable tracemalloc to get the object allocation traceback” warning in asyncio programs and how to fix and suppress it.
Let’s get started.
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
It is common to get a RuntimeWarning warning when developing asyncio programs.
This is especially common when you are first getting started. You may see RuntimeWarning messages reported in your standard output or standard error.
A common RuntimeWarning is as follows:
1 |
RuntimeWarning: Enable tracemalloc to get the object allocation traceback |
What is this RuntimeWarning all about?
Run loops using all CPUs, download your FREE book to learn how.
What does “Enable tracemalloc” mean?
The “RuntimeWarning: Enable tracemalloc to get the object allocation traceback” is emitted by asyncio programs.
Most commonly it is emitted when an asyncio program creates a coroutine and does not await it.
This means that the coroutine is never run in the asyncio event loop.
Creating and not running a coroutine is a common error in an asyncio program and typically raises a RuntimeWarning with the message:
1 |
RuntimeWarning: coroutine '...' was never awaited |
Where ‘…’ is replaced with the name of the coroutine that was not awaited.
You can learn more about the “RuntimeWarning: coroutine ‘…’ was never awaited” warning in the tutorial:
Along with this warning, the following warning is emitted:
1 |
RuntimeWarning: Enable tracemalloc to get the object allocation traceback |
It is emitted because the Python interpreter is giving us advice on how to track down the cause of the previous RuntimeWarning.
It is suggesting that we use the tools in the tracemalloc module to find the coroutine that was never awaited.
What is tracemalloc?
The tracemalloc module provides tools for debugging Python programs.
Specifically, provides tools for tracing memory allocation in the programs.
The tracemalloc module is a debug tool to trace memory blocks allocated by Python.
— tracemalloc — Trace memory allocations
It is a reasonably sophisticated module and although we may use it directly, we are more likely to use it indirectly via a memory profiling tool applied to our program.
We could instrument our asyncio program with the tracemalloc module to discover the cause of the “RuntimeWarning: coroutine ‘…’ was never awaited” warning, but this is typically not required.
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.
How to Fix The RuntimeWarning
We can fix both RuntimeWarning warnings by awaiting the coroutine that was not awaited.
Specifically, the warnings:
- RuntimeWarning: coroutine ‘…’ was never awaited
- RuntimeWarning: Enable tracemalloc to get the object allocation traceback
When the “RuntimeWarning: coroutine ‘…’ was never awaited” is emitted, it will report the file and line on which the coroutine was created that was never awaited.
We can go directly to this line and await the coroutine or schedule the coroutine in a way that is appropriate for our program.
For example, typically we might call a coroutine like a function, causing both RuntimeWarning warnings to be emitted:
1 2 3 |
... # call the work coroutine work() |
This will create a coroutine object, but not run it in the event loop.
It is equivalent to the following:
1 2 3 |
... # call the work coroutine coro = work() |
We can fix the RuntimeWarning warnings by explicitly awaiting the coroutine.
For example:
1 2 3 |
... # await the work coroutine await work() |
You can learn more about Python coroutines in the tutorial:
We can also schedule the coroutine as an asyncio.Task via the asyncio.create_task() function.
For example:
1 2 3 |
... # schedule the coroutine as a task task = asyncio.create_task(work()) |
You can learn more about asyncio tasks in the tutorial:
And that’s all there is to it.
The coroutine will be given the opportunity to run and the RuntimeWarning warnings will no longer be emitted.
Overwhelmed by the python concurrency APIs?
Find relief, download my FREE Python Concurrency Mind Maps
How to Suppress The RuntimeWarning
It is possible that we don’t care about this warning being emitted.
This could be for many reasons, such as:
- It is emitted by legacy code that we are unable to change.
- It is emitted by a library over which we don’t have control.
- The offending coroutine is not run by design given congratulation settings.
As such, the RuntimeWarning may be a part of the normal operation of our program.
In this case, we can actively suppress the warning in our program.
This can be achieved by ignoring all RuntimeWarning warnings emitted by our program via the warnings module.
We can do this via the warnings.filterwarnings() function and specify the filter of ‘ignore‘ and the category to apply it to as the RuntimeWarning.
For example:
1 2 3 |
... # suppress RuntimeWarning warnings.filterwarnings('ignore', category=RuntimeWarning) |
This will suppress all RuntimeWarning in our asyncio program, and specifically the warnings:
- RuntimeWarning: coroutine ‘…’ was never awaited
- RuntimeWarning: Enable tracemalloc to get the object allocation traceback
Now that we know how to fix and suppress the asyncio RuntimeWarning warnings, let’s look at some worked examples.
Example of RuntimeWarning: Enable tracemalloc
We can explore an example that results in the warning “RuntimeWarning: Enable tracemalloc to get the object allocation traceback“.
In this example, we will define a simple coroutine that sleeps for a moment. We will then call this coroutine from the main coroutine and not await it. This will generate the RuntimeWarning indicating that the coroutine was not awaited and another RuntimeWarning to suggest to use tracemalloc to locate the cause of the fault.
Firstly, we can define a coroutine that sleeps a moment.
1 2 3 4 |
# task that does work async def work(): # block for a moment await asyncio.sleep(1) |
We can then define the main() coroutine that reports a message, creates but does not await the work() coroutine, sleeps for 2 seconds, and reports a done message.
1 2 3 4 5 6 7 8 9 10 |
# main coroutine async def main(): # report a message print('Starting') # run the task work() # block for a moment await asyncio.sleep(2) # report a message print('Done') |
Finally, we can start the asyncio event loop and run the main() coroutine.
1 2 3 |
... # start the event loop asyncio.run(main()) |
Tying this together 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 20 21 22 |
# SuperFastPython.com # example of a never-awaited coroutine import asyncio # task that does work async def work(): # block for a moment await asyncio.sleep(1) # main coroutine async def main(): # report a message print('Starting') # run the task work() # block for a moment await asyncio.sleep(2) # report a message print('Done') # start the event loop asyncio.run(main()) |
Running the example first creates the event loop and runs the main() coroutine.
The main() coroutine runs and reports a print message, then creates but does not run the work() coroutine. It then sleeps for two seconds.
The created but unawaited work() coroutine results in two runtime warnings being generated, as we expected:
- RuntimeWarning: coroutine ‘work’ was never awaited
- RuntimeWarning: Enable tracemalloc to get the object allocation traceback
The main() coroutine resumes and reports a done message before the program terminates.
This highlights how we can develop a program with a coroutine that is not awaited that generates the “RuntimeWarning: Enable tracemalloc to get the object allocation traceback” warning.
1 2 3 4 5 |
Starting ...:15: RuntimeWarning: coroutine 'work' was never awaited work() RuntimeWarning: Enable tracemalloc to get the object allocation traceback Done |
Next, let’s look at how we might fix the RuntimeWarning warnings.
Example of Fixing RuntimeWarning: Enable tracemalloc
We can explore how to fix the program so that the RuntimeWarning warnings are not emitted.
In this case, we will await the work() coroutine after it is created in the main() coroutine.
1 2 3 |
... # run the task await work() |
And that’s it.
Tying this together, 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 20 21 22 |
# SuperFastPython.com # example of fixed never-awaited coroutine import asyncio # task that does work async def work(): # block for a moment await asyncio.sleep(1) # main coroutine async def main(): # report a message print('Starting') # run the task await work() # block for a moment await asyncio.sleep(2) # report a message print('Done') # start asyncio.run(main()) |
Running the example first creates the event loop and runs the main() coroutine.
The main() coroutine runs and reports a print message, then creates and awaits the work() coroutine.
The work() coroutine runs and sleeps for 1 second, before resuming and terminating.
The main() coroutine resumes and then sleeps for two seconds, then reports a final message and terminates the program.
This highlights how we can fix a program by awaiting a coroutine so that the “RuntimeWarning: Enable tracemalloc to get the object allocation traceback” warning is not emitted.
1 2 |
Starting Done |
Next, let’s look at how we might suppress the RuntimeWarning.
Example of Suppressing RuntimeWarning: Enable tracemalloc
We can explore how we might suppress RuntimeWarning warnings so that the “RuntimeWarning: Enable tracemalloc to get the object allocation traceback” is not emitted.
In this case, we will update the first example where the work() coroutine is not awaited. Before starting the asyncio event loop, we will configure the warning system to ignore all RuntimeWarning warnings.
1 2 3 |
... # suppress RuntimeWarning warnings.filterwarnings('ignore', category=RuntimeWarning) |
This will have the effect of suppressing both RuntimeWarning warnings emitted from the program because the coroutine is not awaited.
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 20 21 22 23 24 25 |
# SuperFastPython.com # example of a never-awaited coroutine with suppressed warning import warnings import asyncio # task that does work async def work(): # block for a moment await asyncio.sleep(1) # main coroutine async def main(): # report a message print('Starting') # run the task work() # block for a moment await asyncio.sleep(2) # report a message print('Done') # suppress RuntimeWarning warnings.filterwarnings('ignore', category=RuntimeWarning) # start asyncio.run(main()) |
Running the example first creates the event loop and runs the main() coroutine.
The main() coroutine runs and reports a print message, then creates but does not run the work() coroutine. It then sleeps for two seconds.
The unawaited work() coroutine does cause two RuntimeWarning warnings to be generated internally within asyncio, but the configured filter on the warnings module causes them to be suppressed. Therefore their details are not reported.
The main() coroutine resumes and reports a done message before the program terminates.
This highlights how we can suppress the “RuntimeWarning: Enable tracemalloc to get the object allocation traceback” warning.
1 2 |
Starting Done |
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 the cause, how to fix it, and how to suppress the “RuntimeWarning: Enable tracemalloc to get the object allocation traceback” warning.
Did I make a mistake? See a typo?
I’m a simple humble human. Correct me, please!
Do you have any additional tips?
I’d love to hear about them!
Do you have any questions?
Ask your questions in the comments below and I will do my best to answer.
Photo by engin akyurt on Unsplash
Do you have any questions?