"Python Async Context Manager: The Complete Guide"
"If your async code opens connections, sessions, or locks without `async with`, you're leaking resources. This complete guide takes you from the sync `with` statement and custom `__enter__`/`__exit__` managers to async context managers with `__aenter__`/`__aexit__` and `@asynccontextmanager` — with…
A Python async context manager is an object that works with async with to guarantee async setup and teardown of a resource — a database connection, an HTTP session, a lock. It implements two coroutine methods, __aenter__ and __aexit__ , which async with awaits automatically, even when the block raises. Here's the whole pattern in six lines: async with AsyncConnection("postgresql://localhost/app") as conn: rows = await conn.fetch("SELECT * FROM users") # connection is closed here — always, even on exception This guide builds up to that: first the sync with statement and the __enter__ / __exit__ protocol, then custom managers two ways, then the async protocol with a real connection-pool pattern, a style decision table, and the mistakes that leak resources. What you'll learn How the with statement maps to __enter__ and __exit__ Writing a custom context manager as a class (and what the exception arguments mean) The @contextmanager decorator shortcut for one-off managers The async protocol: __aenter__ / __aexit__ and async with @asynccontextmanager for decorator-style async managers A realistic async connection-pool pattern (stdlib only) A decision table: which style to use when 5 resource-leaking mistakes and how to avoid them The with statement and __enter__ / __exit__ Every with block is syntactic sugar for a protocol. When Python enters the block it calls __enter__() and binds the result to the as variable; when the block exits — normally *or* via exception — it calls __exit__(exc_type, exc_val, exc_tb) with the exception details (or None s when nothing went wrong). This is why files opened with with open(...) never leak, as our file handling guide shows. Here's a class-based manager that makes the protocol visible: class ManagedFile: def __init__(self,…