Journey
Reliability
This journey follows the boundaries where programs fail, clean up, split into modules, communicate with the outside world, and run concurrent work.
In this journey
- Make failure explicit.
- Control resource and module boundaries.
- Handle operations that outlive one expression.
Make failure explicit.
Robust Python code distinguishes expected absence, broken assumptions, recoverable errors, and domain-specific failures.
Different failure shapes need explicit signals: assertions, recovery, chained causes, or warnings.- Exceptions
Use this example to signal and recover from errors.
- Assertions
Use this example to state internal assumptions.
- Exception Chaining
Use this example to preserve the cause while translating an error.
- Exception Groups
Use this example to handle multiple failures together.
- Custom Exceptions
Use this example to name failures in the language of the problem domain.
- Warnings
Use this example to signal soft problems and deprecations.
Control resource and module boundaries.
Cleanup, deletion, imports, and modules define where responsibilities begin and end.
Reliable programs name their boundaries: resources clean up, modules import, environments constrain runtime.- Context Managers
Use this example to pair setup with reliable cleanup.
- Delete Statements
Use this example to remove names, attributes, and items intentionally.
- Modules
Use this example to split code into importable files.
- Import Aliases
Use this example to make imported names clear at use sites.
- Packages
Use this example to show package directories, `__init__.py`, and public module boundaries.
- Virtual Environments
Use this example to isolate dependencies for a project.
Handle operations that outlive one expression.
I/O, testing, logging, subprocesses, and concurrency require different control boundaries from ordinary expressions.
Async, threaded, test, and logging work cross an operation boundary before evidence comes back.- Async Await
Use this example to await concurrent I/O-shaped work.
- Async Iteration and Context
Use this example to consume async streams and cleanup protocols.
- Logging
Use this example to record operational events without using `print()`.
- Testing
Use this example to write deterministic tests with `unittest` or `pytest`.
- Subprocesses
Use this example to run external commands safely.
- Threads and Processes
Use this example to contrast concurrency choices beyond `asyncio`.
- Networking
Use this example to make HTTP or socket boundaries explicit.