Explain await's purpose, awaitable types, and event loop signaling

This tests whether you understand await as a yield point. A strong answer lists three awaitables (coroutines, Tasks, Futures), explains await yields control to the event loop until completion, and warns that a bare coroutine call does not run it.
WHAT THIS TESTS: This question tests whether you understand the core contract of Python's async/await model. Interviewers want to know if you see await as a cooperative yield point rather than a blocking operation, and whether you can distinguish between the objects that participate in the event loop and regular synchronous values.
A GOOD ANSWER COVERS: First, state the purpose of await: it suspends execution of the current coroutine and yields control back to the event loop so other tasks can run. Second, list the three awaitable types explicitly: coroutine objects created by calling an async def function, Tasks which are scheduled coroutines often created with asyncio.create_task, and Futures which are low-level awaitables representing a future result. Third, explain what happens under the hood: the event loop can switch to another task while this one is paused, and when the awaitable completes, the event loop resumes this coroutine at the await expression. Fourth, mention that simply calling a coroutine function returns a coroutine object but does not execute the body; only awaiting it or wrapping it in a Task schedules it.
COMMON WRONG ANSWERS: A major red flag is saying that await blocks the thread like time.sleep. Another is listing generators or arbitrary iterables as awaitables; while old-style yield from coroutines existed, modern Python has a strict awaitable protocol. Candidates also stumble by claiming that await runs the code immediately in the foreground; the correct view is that it registers a callback with the event loop for resumption. Finally, forgetting that Tasks are awaitables or conflating them with threads shows shallow familiarity with asyncio.
LIKELY FOLLOW-UPS: The interviewer may ask how await differs from yield from, or when you should use asyncio.create_task versus awaiting directly. They might probe what happens if you forget to await a coroutine, or ask how await interacts with blocking IO like database drivers. A senior follow-up could involve the __await__ magic method and how custom awaitables work.
ONE CONCRETE EXAMPLE: Imagine a fetch_data coroutine defined with async def that awaits asyncio.sleep(2). When the coroutine hits await asyncio.sleep(2), it does not block the thread for two seconds. Instead, it yields control to the event loop, which runs other tasks during that window. After roughly two seconds, the sleep future resolves, and the event loop resumes fetch_data right after the await. If you had written fetch_data() without await, you would get a coroutine object with a RuntimeWarning and the sleep would never execute.
Source: docs.python.org
Read the original → docs.python.org
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.