LIFE rules¶
LIFE rules are planned. None of them is implemented today, and nothing on this page is available to run.
LIFE rules address construction, resource ownership, cleanup, and the implicit temporal dependencies that arise during object initialization and destruction.
The domain rests on the idea that a resource should have an owner whose scope
decides when acquisition and release happen, rather than leaving release to
garbage collection or to whichever branch happens to run.
PEP 343 introduced the with statement as
Python's mechanism for that, and the
contextlib documentation
covers the tools built on it.
| ID | Rule | Default | Concern |
|---|---|---|---|
| LIFE001 | Import time side effect | on | hazard |
| LIFE002 | Constructor does work | on | review |
| LIFE003 | Post construction setup | on | review |
| LIFE004 | Traceback retention | observe | hazard |
| LIFE005 | Finalizer dependent release | observe | hazard |
| LIFE006 | Unbounded cache | observe | hazard |
| LIFE007 | Temporal coupling | on | review |
| LIFE008 | Import time resource construction | on | hazard |
| LIFE009 | Import time exit hook | on | hazard |
| LIFE010 | Application finalizer | on | hazard |
| LIFE011 | Overridable call during init | on | hazard |
| LIFE012 | Callback during construction | on | hazard |
| LIFE013 | Self escapes before invariant | on | hazard |
| LIFE014 | Constructor is an operation | on | hazard |
| LIFE015 | Construction bypasses invariant path | on | hazard |
| LIFE016 | Dataclass has a behavior-heavy lifecycle | on | review |
| LIFE017 | Manual resource management | on | hazard |
Rule detail¶
LIFE001 Import time side effect¶
Claim. risk
Detection/default. Module body performs I/O, network or filesystem work
Message template. Importing {module} performs {effects}, giving module loading an operational side effect.
LIFE002 Constructor does work¶
Claim. design
Detection/default. __init__ performs I/O or non-trivial computation
Message template. {class}.__init__ performs {effects}, so constructing the object has operational behavior.
LIFE003 Post construction setup¶
Claim. design
Detection/default. ≥2 setup-style methods called before first use
Message template. {class} requires {setup_count} setup calls before first use, creating an implicit construction sequence.
LIFE004 Traceback retention¶
Claim. risk
Detection/default. Instance holds an object with __traceback__
Message template. {instance} retains an exception traceback and therefore the frames and locals reachable from it.
LIFE005 Finalizer dependent release¶
Claim. risk
Detection/default. File or socket closed by GC rather than explicitly
Message template. Resource {resource} was closed by garbage collection rather than an explicit owner.
LIFE006 Unbounded cache¶
Claim. risk
Detection/default. lru_cache(maxsize=None) reaching N entries
Message template. Unbounded cache {name} reached {entries} entries during observation.
LIFE007 Temporal coupling¶
Claim. design
Detection/default. cg + nam
Message template. {type} requires the ordered calls {sequence} before it becomes usable.
LIFE008 Import time resource construction¶
Claim. risk
Detection/default. Module-level construction of clients, connections, pools, executors, threads or processes
Message template. Client() is constructed during import, giving it process-wide lifetime without an explicit owner.
LIFE009 Import time exit hook¶
Claim. risk
Detection/default. atexit.register() executed during import
Message template. Importing this module registers process-global cleanup behavior through atexit.
LIFE010 Application finalizer¶
Claim. risk
Detection/default. Application class defines __del__
Message template. Connection.__del__ hides resource cleanup behind garbage-collection timing instead of an explicit owner.
LIFE011 Overridable call during init¶
Claim. risk
Detection/default. Constructor calls an overridable instance method
Message template. Base.__init__ calls overridable configure() before subclass state is guaranteed to exist.
LIFE012 Callback during construction¶
Claim. risk
Detection/default. Constructor invokes a caller-provided callback with the object under construction
Message template. Service.__init__ passes self to a callback before all fields are initialized.
LIFE013 Self escapes before invariant¶
Claim. risk
Detection/default. self is registered, stored, scheduled or passed externally before construction completes
Message template. self escapes to registry.register() after only four of seven constructor fields are established.
LIFE014 Constructor is an operation¶
Claim. risk
Detection/default. own + eff + (cf or shp)
Message template. Service.init establishes 11 fields, performs two effect categories and contains five branches, so construction has become an operation.
LIFE015 Construction bypasses invariant path¶
Claim. risk
Detection/default. Alternative construction assigns invariant-bearing fields without using the validated construction path.
Message template. {factory} constructs {type} without the invariant checks used by {validated_path}.
LIFE016 Dataclass has a behavior-heavy lifecycle¶
Claim. design
Detection/default. A dataclass owns several transitions, effects, or lifecycle hooks beyond value behavior.
Message template. {class} is declared as a dataclass but owns {transition_count} transitions and {effect_count} effects, so it no longer behaves as a simple data value.
LIFE017 Manual resource management¶
Claim. risk
Detection/default. A resource is acquired and released manually on paths that a context manager could own.
Message template. {symbol} manually acquires and releases {resource} across {path_count} paths, leaving cleanup dependent on control flow.