Home / Companies / Mergify / Blog / Post Details
Content Deep Dive

await Is Not a Context Switch: Understanding Python's Coroutines vs Tasks

Blog post from Mergify

Post Details
Company
Date Published
Author
-
Word Count
1,302
Language
English
Hacker News Points
-
Summary

Python's asynchronous programming model is often misunderstood, especially by engineers familiar with JavaScript or C#, due to its unique handling of coroutines and tasks. Unlike these languages where awaiting an async function automatically yields control to the event loop, in Python, awaiting a coroutine does not necessarily introduce concurrency. Instead, concurrency is created only when tasks are explicitly defined using `asyncio.create_task()`. This distinction is crucial for understanding when locking is necessary, as locking should only be considered at actual suspension points where tasks might interleave, not merely at the presence of async functions. Python's design, which evolved from generator-based control flow rather than promises or green threads, provides explicit boundaries between structured control and concurrency. This leads to a more fine-grained control over when and where concurrency occurs, but also to confusion among developers accustomed to other paradigms. Understanding this difference allows for more accurate code reviews and efficient asynchronous code by focusing on true suspension points rather than assuming all async functions are automatic tasks.