with and Custom Context Managers

Scenario: A file, lock, or connection must be released even when work fails.

New words, in plain English

with always calls exit after a successful enter. Returning truthy from __exit__ suppresses an exception, so normally return false. @contextmanager can express setup before yield and cleanup in finally.

Analogy: A Python program is like a clear set of instructions for a careful helper: names label things, indentation groups steps, and errors explain where the helper became confused.

A small, real example

from contextlib import contextmanager
@contextmanager
def opened(path):
    handle = open(path)
    try:
        yield handle
    finally:
        handle.close()
Tip: Use existing context managers such as open, locks, and database transactions before writing your own.
Goal: Practice this idea in the py-context-managers challenge at /labs/python. Fix the broken program, run it yourself, then use check to prove the real end state.