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 lenient current_scope_id(), which falls back to PROCESS_SCOPE. Pass the raising resolve_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

__init__

Build an empty registry.

clear

Drop every value.

get

Return a scope's value, or None.

get_or_create

Return a scope's value, building it on miss.

pop

Remove and return a scope's value.

resolve

Return the scope to act on.

scope_ids

Return every scope currently holding a value.

scope_lock

Return the lock guarding one scope.

set

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.

factory runs while the registry lock is held, so it must be cheap and must not re-enter this registry. Expensive construction belongs under scope_lock() with an explicit get() / 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 Lock objects are negligible.

Parameters:

scope_id (str | None) – Scope to lock; defaults to the current one.

Returns:

That scope’s lock.

Return type:

allocate_lock

ScopeRegistry.set(value, scope_id=None)[source]#

Store a scope’s value, replacing any previous one.

Parameters:
  • value (T) – The value to store.

  • scope_id (str | None) – Scope to write; defaults to the current one.

Return type:

None