pysepal.solara.scope_registry.ScopeRegistry#
- class pysepal.solara.scope_registry.ScopeRegistry(name, resolver=None)[source]#
A scope-id-keyed store with one locking discipline and a configurable resolver.
- Parameters:
name (str) – Registry name; used in log lines only.
resolver (Callable[[], str] | None) – How to resolve the current scope when a call omits
scope_id. Defaults to the lenientcurrent_scope_id(), which falls back toPROCESS_SCOPE. Pass the raisingresolve_scope_id()for a registry where an unresolved scope must be an error, not a silent shared bucket – e.g. a credential store.
Build an empty registry.
Methods
Build an empty registry.
Drop every value.
Return a scope's value, or None.
Return a scope's value, building it on miss.
Remove and return a scope's value.
Return the scope to act on.
Return every scope currently holding a value.
Return the lock guarding one scope.
Store a scope's value, replacing any previous one.
- ScopeRegistry.__init__(name, resolver=None)[source]#
Build an empty registry.
- Parameters:
name (str)
resolver (Callable[[], str] | None)
- Return type:
None
- ScopeRegistry.clear()[source]#
Drop every value. Scope locks are deliberately kept.
- Return type:
None
- ScopeRegistry.get(scope_id=None)[source]#
Return a scope’s value, or None.
- Parameters:
scope_id (str | None) – Scope to read; defaults to the current one.
- Returns:
The stored value, or None.
- Return type:
T | None
- ScopeRegistry.get_or_create(factory, scope_id=None)[source]#
Return a scope’s value, building it on miss.
factoryruns while the registry lock is held, so it must be cheap and must not re-enter this registry. Expensive construction belongs underscope_lock()with an explicitget()/set().- Parameters:
factory (Callable[[], T]) – Zero-argument callable building the value on first access.
scope_id (str | None) – Scope to read; defaults to the current one.
- Returns:
The stored value.
- Return type:
T
- ScopeRegistry.pop(scope_id=None)[source]#
Remove and return a scope’s value.
- Parameters:
scope_id (str | None) – Scope to drop; defaults to the current one.
- Returns:
The removed value, or None when there was none.
- Return type:
T | None
- ScopeRegistry.resolve(scope_id=None)[source]#
Return the scope to act on.
With no explicit
scope_id, this runs the registry’s resolver – the lenient default, or the strict one it was constructed with (see the class docstring). A strict resolver’s exception propagates as-is.- Parameters:
scope_id (str | None) – An explicit scope, or None to resolve one.
- Returns:
The scope id, never None.
- Return type:
str
- ScopeRegistry.scope_ids()[source]#
Return every scope currently holding a value.
- Returns:
A snapshot tuple; mutating the registry does not affect it.
- Return type:
Tuple[str, …]
- ScopeRegistry.scope_lock(scope_id=None)[source]#
Return the lock guarding one scope.
Per scope on purpose: building a scope’s value can perform blocking network calls, and one global lock would serialise every user’s first render in a multi-user container.
Never removed once handed out: a thread that fetched this lock but has not yet acquired it could otherwise hold an orphan while a fresh lock is handed out for the same scope, letting two threads into the critical section at once. The leaked
Lockobjects are negligible.- Parameters:
scope_id (str | None) – Scope to lock; defaults to the current one.
- Returns:
That scope’s lock.
- Return type:
allocate_lock