Unit 3.6 · about 4 h
15 / 324Context managers, exceptions and deterministic cleanup
Deterministic cleanup separates scripts from services. Tracebacks are the primary diagnostic; the hierarchy decides their quality.
- implement
You can now
- Implement a resource-owning context manager in class and
@contextmanagerforms, with cleanup proven on success and exception paths. - Derive the cleanup sequence for nested managers with failing handlers.
- Design a small exception hierarchy that preserves cause and maps to actionable command-line errors.
Covers
- Context managers, ownership and deterministic cleanup
- Exception hierarchies, chaining, cleanup and actionable messages
Study, in this order
6 steps
- Context managersStas' Python Cookbook - selected path
Classes and Objects: Context managers (the
@contextmanageropened()pattern withtry/finally);nullcontextfor conditionalwithblocks - Exceptions and error handlingStas' Python Cookbook - selected path
Raising and catching (
try/except/else/finally); Re-raising and chaining (raisefrom,from None); Custom exceptions; Good habits - The try statementPython language reference
Section 8.4 with 8.4.2
except*: groups split across clauses;elseruns only without exceptions;finallyalways runs - The with statementPython language reference
Section 8.5:
__enter__and__exit__protocol; a true__exit__return suppresses the exception - Exception ChainingAlgoMaster Python - structured revision
The Exception Chaining lesson and its exercise; trace
__cause__versus__context__ - Context ManagersAlgoMaster Python - structured revision
The Context Managers lesson and Exercise: Context Managers; then the
withStatement lesson
Focus on
- Exceptions in the
withbody are thrown into the@contextmanagergenerator at theyieldpoint; thefinallyclause still runs before propagation. __exit__returning true suppresses; anything falsy re-raises. Swallowing by accident hides the failure the caller must see.raise New from ekeeps the cause;from Nonehides context deliberately. A bareraisere-raises the same exception with its traceback.ExceptionGroupsplits acrossexcept*clauses since Python 3.11: handled members are removed and the rest keeps propagating.
Reproduce closed-book
@contextmanager owning a temp file plus a two-level ConfigError hierarchy with a CLI exit-code map. Prove the file closes on an inner ValueError and that the mapped error keeps its __cause__.Traps
- A bare
except: swallowsKeyboardInterruptandSystemExit. CatchExceptionat broadest, and re-raise what you do not handle. - An exception raised in
finallyor in__exit__replaces the in-flight one. Keep cleanup paths total and narrow. - Catching an
ExceptionGroupwithexceptinstead ofexcept*. Plainexceptmatches the whole group object and never the members.
Practice
AlgoMaster Python: Exercise: Context Managers
Exercises 1 to 5, especially Exercise 3: Close a File After an Exception and Exercise 5: Build a Generator Context Manager
Then prove cleanup on the exception path in your own file.
AlgoMaster Python: Exercise: Exception Chaining
Exercises 1 to 5: implicit context, raise from a cause, from None, the two traceback bridge sentences, and a cause that differs from the context
Draw the __cause__ chain for each answer.
Self-test
-
Where does an exception raised in a
withbody surface inside a@contextmanagergenerator?At theyieldpoint, as if theyieldraised it.try/finallyaround theyieldruns cleanup, then the exception propagates unless caught. -
What is the difference between
raise E from e,raise E from Noneand bareraise?from esets__cause__and shows both tracebacks;from Nonesuppresses the context; bareraisere-raises the active exception unchanged. -
except* ValueErrorhandles half anExceptionGroup. What happens to the rest?The remaining members propagate as a group.except*subtracts matches; unmatched members keep traveling. -
When does the
elseclause oftryrun, and what is it for?Only when no exception occurred. It separates code that must not be protected from the risky block, so its own failures stay distinct.
Completion criterion
Stop when
Your manager closes the resource on success, exception and inner-raise paths, and your hierarchy maps each failure to one actionable message with its cause intact.
Mark passed, then open 3.7 Only mark this when you can do it without notes.Leads to
- 3.8 Imports, virtual environments and src-layout packaging Console entry points consume the error-to-exit-code mapping.
- 5.4 Debuggers, logs, traces and competing hypotheses Read tracebacks and chains as evidence before editing.
Comes after
- 3.4 Iterators, generators and lazy pipelinesPair generator cleanup with deterministic closing.
Resources for this unit
- Stas' Python Cookbook - selected path Run Part I on dictionaries, iteration, functions, closures, decorators, classes and context managers; Part II on modules, files, paths, environment and arguments; and Part IV on versions, dependencies, packaging and code quality. Finish by building one src-layout package from a blank directory.
- Python language reference Check Data model, Execution model, Import system and Exceptions whenever a claim depends on Python semantics. These pages are the authority when the course and a runtime observation disagree.
- AlgoMaster Python - structured revision Use Functions, Modules and Packages, OOP, Advanced OOP, Exception Handling, Iterators and Generators, Type Hints and Annotations only after the cookbook pass. Open it for recall practice or a diagnosed weak mechanism, not as a second complete course.
Also in this section
- Packaging Python Projects Follow the packaging tutorial once from a blank directory, using a src layout, pyproject.toml, an isolated build and a clean-environment installation test.
- dataclasses - data classes Read the
@dataclassparameters (eq,order,frozen,slots),field()withdefault_factory, frozen instances, post-init processing,replace,asdictandastuple. Use for the validated frozen dataclass in attributes-protocols-dataclasses. - typing - type hints and protocols Read Protocols for structural typing and
runtime_checkablelimits, Generics forTypeVargenerics, andassert_typefor narrowing checks. Use for theProtocoland narrowing parts of type-hints-protocols; PEP 695 syntax itself is in the language reference. - gc - cycle garbage collector Read the cycle collector interface:
collect,get_count,garbageanddisable/enable. Use for the cycle-collection and measurement parts of refcounting-gc-weakrefs. - weakref - weak references Read weak-reference objects (
refcallbacks,proxyobjects) and theWeakValueDictionaryexample. Use for the weak-reference part of refcounting-gc-weakrefs.