On this page
Cleanable๏
Use md.Cleanable from the public package namespace.
- class Cleanable[source]๏
- Purpose:
Abstract base class for objects that own an explicit cleanup lifecycle. This is the single teardown contract shared across the entire runtime.
Responsibilities:
Own the canonical _cleaned lifecycle flag.
Provide check_cleaned() as the one guard for rejecting use-after-clean.
Provide using_cleanup() as a context manager that guarantees exactly one cleanup call on exit.
Require subclasses to implement deterministic teardown.
Contract:
cleanup() must be idempotent.
Subclasses must set _cleaned = True when cleanup completes.
check_cleaned() is the canonical guard for rejecting use-after-clean.
using_cleanup() provides a separate helper context that guarantees one cleanup call on exit.
Every Cleanable starts live: _cleaned is False after __init__.
Owned State:
_cleaned: the live/cleaned flag. The only state this base owns.
- Threading:
The base itself holds no lock; _cleaned is a plain bool. Subclasses that can race cleanup against active work are responsible for their own lock, and the established pattern is to check _cleaned, acquire, then re-check inside the lock. On free-threaded builds that double-check is not optional.
- Lifecycle / Cleanup:
Live on construction, cleaned exactly once. The repository teardown order for subclasses is: clean children, delete owned field references, then clean the logger last. Post-cleanup, an object is assumed unused; prefer letting check_cleaned() raise over silently returning.
- Registration:
Your subclasses bind normally: manifest lookup is an EXACT (module, qualname) match and does not inherit. A regression asserting that a user subclass of Cleanable still binds guards that property.
- Subsystem Context:
One of three utilities/general_base/ base classes, alongside Sync (synchronization base) and AbstractElasticPool (pooling base). This is the most widely inherited type in the codebase: the crystals, the conduit runtime, the spellbook registries, the Nexus/Rift surfaces, and most utilities all descend from it. It hands off to nothing - it is the floor.
- System Context:
Beneath every layer of the DGR and outside the boot order entirely. Cleanup ordering across the runtime (Conduit tears down Meld, Ward, then Creations; Aether cleans frames then resets singleton state) is expressed through this one contract, which is why its idempotence guarantee is load-bearing for the whole system rather than a local convenience.
AGENT_ACCESS: public
- AGENT_PURPOSE:
access: public. Base cleanup contract. Subclass this when your object owns resources that need deterministic teardown; implement cleanup() idempotently and guard live-only methods with check_cleaned(). Your subclasses stay bindable.
- property cleaned: bool๏
Return whether the object has already been cleaned.
Contract:
MONOTONIC latch: reads the _cleaned flag, which only ever moves False -> True. Once this returns True it never returns False again for the object's life.
- Returns:
True when _cleaned has been set.
- Return type:
bool
- property is_cleaned: bool๏
Alias for cleaned.
Contract:
Exact alias: reads the same _cleaned flag as cleaned, with the same monotonic semantics. Both spellings exist because call sites across the runtime use both.
- Returns:
Current cleaned-state flag.
- Return type:
bool
- check_cleaned() None[source]๏
Raise when the object has already been cleaned.
Contract:
Subclasses use this as the standard use-after-clean guard.
No-op while the object is still live.
- Raises:
RuntimeError -- If the object has already been cleaned.
- Returns:
None.
- abstractmethod cleanup() None[source]๏
Release owned resources and mark the object cleaned.
Subclass contract:
Release all resources.
Deregister or finalize any allocations.
Be idempotent (safe to call multiple times).
Set _cleaned = True when teardown completes.
- Raises:
NotImplementedError -- Always on the base; every concrete subclass overrides it.
- Returns:
None.
- async async_cleanup() None[source]๏
Async cleanup hook for subclasses that support asynchronous teardown.
Subclass contract:
Release all resources.
Deregister or finalize any allocations.
Be idempotent (safe to call multiple times).
Preserve the same lifecycle semantics as cleanup() once async teardown completes.
- Raises:
NotImplementedError -- Always on the base; subclasses that support async teardown override it.
- Returns:
None.
- using_cleanup() _CleanupContext[source]๏
Return a helper context manager that guarantees cleanup() on exit.
Contract:
Independent of any context-manager behavior implemented by the owner.
Intended for callers that want deterministic cleanup without relying on the object's own __enter__ / __exit__.
Cleanup runs at most once on exit and its errors propagate; the block's own exception is never suppressed.
- Returns:
Helper context manager bound to this object.
- Return type:
Cleanable._CleanupContext
- async_using_cleanup() _AsyncCleanupContext[source]๏
Return an async context manager that awaits async_cleanup() on exit.
This method itself is NOT async. It returns an object implementing __aenter__ / __aexit__, which is what async with requires.
Contract:
Independent of any context-manager behavior implemented by the owner.
Mirrors using_cleanup() exactly, but drives the async teardown hook.
- Returns:
Async helper context manager bound to this object.
- Return type:
Cleanable._AsyncCleanupContext