CodeNebula
Python📦Standard Libraryintermediate

`contextlib` — Context Manager Utilities

Python · Standard Library · Run with python3

Explanation

`contextlib` provides utilities for creating and composing context managers. `@contextmanager` turns a generator function into a context manager. `suppress(*exceptions)` silences specific exceptions. `ExitStack` dynamically composes a variable number of context managers. `nullcontext` is a no-op context manager useful as a conditional placeholder. `closing` wraps objects with a `close()` method.

Real-World Scenario

An integration test needs to open a variable number of temporary files (count known only at runtime). `ExitStack` opens each file and registers it — all are guaranteed closed when the `with` block exits, even if some openings fail mid-loop. ```python import contextlib import tempfile from pathlib import Path # suppress — clean alternative to try/except/pass with contextlib.suppress(FileNotFoundError): Path("nonexistent_file.txt").unlink() print("File removed or didn't exist") # ExitStack — dynamic set of context managers with contextlib.ExitStack() as stack: temps = [ stack.enter_context(tempfile.NamedTemporaryFile(suffix=".txt")) for _ in range(3) ] for i, f in enumerate(temps): f.write(f"File {i}".encode()) f.flush() print(f"Created {len(temps)} temp files") # All closed automatically here # Reusable context manager factory @contextlib.contextmanager def temp_directory(): import tempfile, shutil d = tempfile.mkdtemp() try: yield Path(d) finally: shutil.rmtree(d) ```

Quick Snippet

snippet.py
import contextlib
import tempfile
from pathlib import Path

# suppress — clean alternative to try/except/pass
with contextlib.suppress(FileNotFoundError):
    Path("nonexistent_file.txt").unlink()
print("File removed or didn't exist")

# ExitStack — dynamic set of context managers
with contextlib.ExitStack() as stack:
    temps = [
        stack.enter_context(tempfile.NamedTemporaryFile(suffix=".txt"))
        for _ in range(3)
    ]
    for i, f in enumerate(temps):
        f.write(f"File {i}".encode())
        f.flush()
    print(f"Created {len(temps)} temp files")
    # All closed automatically here

# Reusable context manager factory
@contextlib.contextmanager
def temp_directory():
    import tempfile, shutil
    d = tempfile.mkdtemp()
    try:
        yield Path(d)
    finally:
        shutil.rmtree(d)

Full Example

contextlib_basics.py
# Compile: python3 contextlib_basics.py
# Output:
# File removed or didn't exist
# Created 3 temp files

import contextlib
import tempfile
from pathlib import Path

with contextlib.suppress(FileNotFoundError):
    Path("nonexistent_file.txt").unlink()
print("File removed or didn't exist")

with contextlib.ExitStack() as stack:
    temps = [
        stack.enter_context(tempfile.NamedTemporaryFile(suffix=".txt"))
        for _ in range(3)
    ]
    for i, f in enumerate(temps):
        f.write(f"File {i}".encode())
        f.flush()
    print(f"Created {len(temps)} temp files")

@contextlib.contextmanager
def temp_directory():
    import shutil
    d = tempfile.mkdtemp()
    try:
        yield Path(d)
    finally:
        shutil.rmtree(d)

with temp_directory() as td:
    (td / "test.txt").write_text("hello")
    files = list(td.glob("*"))
    print(f"Files in temp dir: {[f.name for f in files]}")
print("Temp dir cleaned up")
Run command
python3 contextlib_basics.py