You can fix a “SyntaxError ‘await’ outside function” by ensuring that all await expressions are within coroutines.
We can get a SyntaxError if we try to await a coroutine or asyncio.Task outside of a coroutine, such as within a function, method, or lambda. When developing asyncio programs, we need to ensure that all of our functions are in fact coroutines so that they can be executed by the asyncio event loop.
In this tutorial, you will discover the SyntaxError ‘await’ outside function and how to fix it.
Let’s get started.
SyntaxError: ‘await’ outside function
It is common to get a SyntaxError referring to “await” when getting started with asyncio.
Specifically, we may be developing an asyncio program and get the error:
- SyntaxError: ‘await’ outside function
The program does not even run.
Instead, the SyntaxError is reported by the Python interpreter before it even begins executing instructions.
Why are we getting this error?
Before we dive into the cause of the SyntaxError, let’s take a look at the “await” expression.
Run loops using all CPUs, download your FREE book to learn how.
What is await?
Await refers to the “await” expression used with coroutines.
It can only be used within a coroutine and is used to yield execution to an awaitable.
Await expression: Suspend the execution of coroutine on an awaitable object. Can only be used inside a coroutine function.
— Python Expressions
An awaitable may be another coroutine or a coroutine wrapped in a Task object for independent execution.
An object that can be used in an await expression. Can be a coroutine or an object with an __await__() method.
— Python Glossary
Put another way, await will cause the caller coroutine to suspend execution at that point and wait for the given awaitable to be done.
The await expression can be used by using the “await” keyword followed by an awaitable.
For example:
1 2 3 |
... # await a coroutine await custom_coroutine() |
This line does a few things.
Firstly, it creates a coroutine object.
It then schedules the coroutine for execution in the asyncio event loop.
The caller then suspends execution and waits for the new coroutine to be done.
The awaitable coroutine may return a value that we may want after the awaitable is done.
This can be assigned as part of the await expression.
For example:
1 2 3 |
... # await a coroutine and store the return value value = await custom_coroutine() |
You can learn more about the await expression in the tutorial:
Why Are We Getting The SyntaxError ‘await’ outside function?
We will get a SyntaxError when we use an “await” expression outside of a coroutine.
For example:
- If we use await in a lambda.
- If we use await in a regular function.
- If we use await in an object method.
- If we use await in a module.
And so on.
We are probably trying to await a coroutine or a task within a function.
This is the most common case.
For example:
1 2 3 4 |
# our function def somefunction(): # await a coroutine await asyncio.sleep(1) |
This will result in a SyntaxError.
An await expression can only ever be used within a coroutine.
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 “SyntaxError: ‘await’ outside function”
We can fix the SyntaxError by ensuring that all of our await expressions are within a coroutine.
Recall that we can define a coroutine using the “async def” expression.
For example:
1 2 3 4 |
# our function async def somefunction(): # await a coroutine await asyncio.sleep(1) |
This will not result in a SyntaxError.
This means that when developing our asyncio programs all of our functions and methods should be defined using an “async def” expression. They must be coroutines in order to use the await expression.
Overwhelmed by the python concurrency APIs?
Find relief, download my FREE Python Concurrency Mind Maps
What is the “async def” Expression?
A coroutine is a function that can be suspended and resumed.
It is often defined as a generalized subroutine.
A subroutine can be executed, starting at one point and finishing at another point. Whereas, a coroutine can be executed then suspended and resumed many times before finally terminating.
coroutine: Coroutines are a more generalized form of subroutines. Subroutines are entered at one point and exited at another point. Coroutines can be entered, exited, and resumed at many different points.
— Python Glossary
The “async def” expression defines a coroutine.
Functions defined with async def syntax are always coroutine functions, even if they do not contain await or async keywords.
— PYTHON COMPOUND STATEMENTS
The async def defines a coroutine expression that returns a coroutine object.
A coroutine function can be used to create a coroutine that may be used as the entry point for an asyncio program by passing it to the asyncio.run() function.
A coroutine may also be scheduled and awaited by another coroutine directly or wrapped in an asyncio.Task object and scheduled independently.
You can learn more about the “async def” expression in the tutorial:
Now that we know how to fix the SyntaxError, let’s look at some worked examples.
Example of SyntaxError: ‘await’ outside function
We can explore an example program that causes a SyntaxError.
In this case, we will print a message, await a coroutine, then report another message.
Because we will attempt to await a coroutine outside of a coroutine, we expect that this program will not run. Instead, we expect it to report a SyntaxError.
The complete example is listed below.
1 2 3 4 5 6 7 8 9 |
# SuperFastPython.com # example of await outside of coroutine import asyncio # entry point of the program print('Main is running') # run a coroutine await asyncio.sleep(1) # report final message print('Main is done') |
Attempting to run the program fails, as we expected.
A SyntaxError is reported highlighting that we attempted to use an await expression outside of a coroutine.
1 |
SyntaxError: 'await' outside function |
Next, let’s look at how we might fix the error.
Example of Fixed SyntaxError: ‘await’ outside function
We can update the example so that we no longer get a SyntaxError.
This can be achieved by moving the await expression into a coroutine.
We can define a new coroutine named main() that contains the program, including the print statements and the await expression.
1 2 3 4 5 6 7 8 |
# define coroutine async def main(): # entry point of the program print('Main is running') # run a coroutine await asyncio.sleep(1) # report final message print('Main is done') |
We can then call the main() coroutine which will create a coroutine object. It will not run the main() coroutine directly.
We can then pass the main() coroutine object to the asyncio.run() function to execute it using the asyncio event loop.
The event loop knows how to run coroutines and how to suspend them when it executes an await expression.
1 2 3 |
... # run the coroutine 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 |
# SuperFastPython.com # example of await within a coroutine import asyncio # define coroutine async def main(): # entry point of the program print('Main is running') # run a coroutine await asyncio.sleep(1) # report final message print('Main is done') # run the coroutine asyncio.run(main()) |
Running the example first creates the main() coroutine object.
It then passes it to the asyncio.run() function. This starts the asyncio event loop and runs the main() coroutine.
The main() coroutine runs and reports a message.
The main() coroutine is then suspended and creates and executes the asyncio.sleep() coroutine. The program then sleeps for one second.
The main() coroutine resumes and reports a final message before terminating.
This highlights how we can fix the SyntaxError by ensuring that the await expression is within a coroutine.
1 2 |
Main is running Main is 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 about the SyntaxError ‘await’ outside function and how to fix it.
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 Holly Chisholm on Unsplash
Do you have any questions?