Nested Context Managers in Python 2026
Managing multiple resources (files, database connections, locks, etc.) simultaneously is common in real-world functions. In 2026, using nested context managers correctly is essential for writing safe, clean, and resource-efficient code.
TL;DR — Key Takeaways 2026
- Use multiple
withstatements to manage several resources safely - Prefer
contextlib.ExitStackfor dynamic numbers of context managers - Nested context managers ensure proper cleanup even if exceptions occur
- Always handle resources in the correct order (LIFO)
1. Basic Nested Context Managers
# Demo file so this example runs as-is
with open("input.txt", "w") as f:
f.write("first line\nsecond line\n")
# Simple nested with statements
with open("input.txt", "r") as infile:
with open("output.txt", "w") as outfile:
for line in infile:
outfile.write(line.upper())
2. Cleaner Nested Contexts with ExitStack (Recommended)
from contextlib import ExitStack
def process_multiple_files(file_paths):
with ExitStack() as stack:
files = [stack.enter_context(open(path, "r")) for path in file_paths]
# Now safely work with all files
for f in files:
content = f.read()
# process content...
3. Real-World Example with Database and File
from contextlib import ExitStack
async def export_user_data(user_id: int, output_path: str):
with ExitStack() as stack:
# Open database session
db_session = stack.enter_context(get_db_session())
# Open output file
output_file = stack.enter_context(open(output_path, "w"))
# Both resources are safely managed
user_data = await db_session.get_user(user_id)
output_file.write(str(user_data))
# Both will be closed automatically, even if an exception occurs
4. Best Practices for Nested Contexts in 2026
- Use
ExitStackwhen the number of context managers is dynamic - Keep nesting shallow — extract complex logic into separate functions
- Always use context managers for resources that need cleanup
- Order matters: resources are cleaned up in reverse order of acquisition
- Combine with
async withfor asynchronous context managers
Managing Several Resources at Once
Many tasks need more than one resource, such as an input file and an output file, or a database connection and a lock. You can nest with statements, but Python also allows several managers in one statement, separated by commas. Since Python 3.10 you can put them in parentheses across several lines.
Managers are entered from left to right and exited in reverse order. If entering the second one fails, the first is still closed properly. This ordering matters when one resource depends on another.
When the number of resources is only known at runtime, such as a list of files chosen by the user, contextlib.ExitStack collects them. Every resource registered with enter_context is closed when the stack exits, again in reverse order.
ExitStack also accepts plain callbacks, which is useful for clean-up steps that are not context managers.
Worked Example: Entering and Exiting in Order
We use a small tracing manager to show the order in which nested resources open and close.
from contextlib import contextmanager, ExitStack
@contextmanager
def resource(name):
print("open", name)
try:
yield name
finally:
print("close", name)
with (
resource("input") as src,
resource("output") as dst,
):
print("working with", src, "and", dst)
with ExitStack() as stack:
names = [stack.enter_context(resource(n)) for n in ["a", "b", "c"]]
print("all open:", names)
The input opens before the output, and the output closes first. With ExitStack, a, b and c open in order and close as c, b, a. The reverse order ensures that a resource is never closed while a later one may still need it.
Practical Tips
Order managers so that each one depends only on those before it, for example a connection before a cursor. The reverse exit order then closes them safely.
When an ExitStack must survive beyond one block, stack.pop_all() moves its resources to a new stack that the caller can close later.
Common Mistakes
- Deep nesting that pushes the real work far to the right.
- Opening a dynamic list of files in a loop without ExitStack.
- Assuming managers close in the order they were opened.
- Using the parenthesised form on Python versions before 3.10.
Quick Summary
- Several managers can share one with statement.
- They exit in reverse order.
- ExitStack handles a dynamic number of resources.
- ExitStack also runs plain callbacks.
Conclusion
Nested context managers are a powerful tool for managing multiple resources safely. In 2026, using ExitStack and proper nesting patterns is considered best practice for writing robust, exception-safe functions that handle resources correctly.
Next steps:
- Review your functions that manage multiple resources and refactor them using
ExitStack