🎓 A1Learner
🔍

Python The contextlib Module

contextlib is a standard library module full of context manager helpers.

A manager as a generator

The decorator does the class work for you. The yield line marks where the block runs.

from contextlib import contextmanager

@contextmanager
def shout():
    print("BEFORE")
    yield
    print("AFTER")

with shout():
    print("middle")

try and finally guard the yield

Wrap yield in try and finally for safe cleanup. The finally part runs even on an error.

from contextlib import contextmanager

@contextmanager
def careful():
    print("Start")
    try:
        yield
    finally:
        print("Always runs")

try:
    with careful():
        raise ValueError("demo error")
except ValueError:
    print("Caught outside")

suppress() ignores a known error

To suppress an error means to let it happen quietly. Use it only for errors you expect.

from contextlib import suppress

with suppress(ValueError):
    number = int("not a number")
print("Carried on")

closing() wraps a close() method

Some objects have close() but no __enter__ or __exit__. The closing helper bridges that gap.

from contextlib import closing

class Jar:
    def close(self):
        print("Jar closed")

with closing(Jar()) as jar:
    print("Using the jar")

Example

from contextlib import contextmanager, suppress

@contextmanager
def tag(name):
    print(f"<{name}>")
    try:
        yield
    finally: print(f"</{name}>")

with tag("section"):
    print("Hello inside")

with suppress(FileNotFoundError):
    open("no_such_file.txt").read()

print("No crash")

Key points

  • contextlib: a standard library module full of context manager helpers
  • Use @contextlib.contextmanager to turn a generator function into a context manager
  • The code before yield runs when the block starts
  • The code after yield runs when the block ends
  • Use suppress(...) to ignore listed errors that you know are harmless
  • Use closing(x) to wrap an object that has close() but no manager methods

In this example, tag is the Tag manager from the last lesson. It now takes six lines, counting the decorator line. The print before the try runs on entry. The yield is where the block runs. The finally line prints the closing label on exit. The second with block uses suppress with FileNotFoundError. The named file does not exist, so open raises that error. The suppress helper swallows it quietly. The last line prints to prove the program carried on.

Note

suppress() hides only the error types you list.

Any other error still spreads as usual.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Python Playground

Exercise

In a function decorated with @contextmanager, where does cleanup code belong?