contextmanager, suppress and nullcontext
Remove the try/finally in announce and run again. The 'end risky' line disappears when the body fails.
contextlib lets you write your own with blocks using a generator and @contextmanager, and gives tools for common jobs: suppress to ignore an error, ExitStack to manage a changing number of resources, closing, redirect_stdout and nullcontext.
Change the code and press Run (Ctrl+Enter). Predict what will happen first, then break it on purpose and read what changes. Your edits are saved and match the lesson page.
Ready for more? This phase has 6 hands-on exercises with automatic checks.
Practice questions
Write the code in the editor, run it, then open the model answer to compare.
Write a @contextmanager named banner(title) that prints === title === before the block and === end === after it (in finally). Use it around one print.
Use suppress so that deleting a missing key from a dictionary does not raise: del data["zzz"], then print data.
Write a @contextmanager named temporary_value(box, key, value) that sets box[key] = value for the block and restores the old value afterwards. Show the dictionary before, inside and after.
Explain it without notes
What does the with statement guarantee, and how do __enter__ and __exit__ fit in?
How does @contextmanager turn a generator into a context manager, and what must you do around the yield?
When would you use ExitStack?
What do suppress, nullcontext and closing each do?
Expected output
start job
working on JOB
end job
start risky
end risky
caught: boom
suppress swallowed the error
processing
start locked
processing
end locked