Source code for spacecore.contextual._state

from __future__ import annotations

from contextlib import contextmanager
from functools import cache
from typing import Any

from ._context import Context
from ._contextual import Contextual
from .._checks import CheckLevel
from ..backend import BackendFamily, BackendOps
from ..backend import ops_registry as _ops_registry


@cache
def _state() -> Contextual:
    """Return the process-wide contextual singleton."""
    # Create the process-wide state lazily, on first use.
    return Contextual()


[docs] def set_context( ctx: Context | BackendFamily | str | None = None, dtype: Any = None, ) -> None: """ Set the process-wide *baseline* SpaceCore context. Visible to every thread and async task. A :func:`use_context` override already in progress keeps winning until its block exits. Parameters ---------- ctx : Context, BackendFamily, str, or None, optional Context or backend specification. dtype : Any, optional Default dtype override. """ state = _state() state.default_ctx = state.normalize_context(ctx, dtype=dtype)
[docs] def get_check_level() -> CheckLevel: """ Return the ambient default validation level applied to new bound objects. Returns ------- CheckLevel The level that seeds a context-bound object constructed without an explicit ``check_level``: the scoped override installed for this thread or task if there is one, otherwise the process-wide baseline. """ return _state().get_check_level()
[docs] def set_check_level(level: CheckLevel | None) -> None: """ Set the ambient default validation level applied to new bound objects. ``check_level`` is a property of the context-bound object (space, operator, functional), not of the :class:`Context`. This sets the process-wide default that seeds a new object when it is constructed without an explicit level. Parameters ---------- level : {"none", "cheap", "standard", "strict"} or None New process-wide baseline. ``None`` restores the built-in default. """ _state().set_check_level(level)
[docs] @contextmanager def use_check_level(level: CheckLevel | None): """ Override the ambient validation level inside a ``with`` block (thread/task-scoped, like :func:`use_context`). Parameters ---------- level : {"none", "cheap", "standard", "strict"} or None Level for the block; ``None`` keeps the ambient one. Yields ------ CheckLevel The level in effect inside the block. """ with _state().scoped_check_level(level) as resolved: yield resolved
[docs] @contextmanager def use_context( ctx: Context | BackendFamily | str | None = None, dtype: Any = None, ): """ Override the default context inside a ``with`` block. The override lives in a :class:`~contextvars.ContextVar`: it is seen by the current thread and asyncio task only, and is undone on exit. Threads started inside the block see the baseline; run them under ``contextvars.copy_context()`` to pass it on. Parameters ---------- ctx : Context, BackendFamily, str, or None, optional Context, or a backend family name such as ``"jax"``. ``None`` keeps the active context and applies only ``dtype``. dtype : dtype-like, optional Dtype for the scoped context; ``None`` keeps the current one. Yields ------ Context The context in effect inside the block. """ with _state().scoped_ctx(ctx, dtype=dtype) as resolved: yield resolved
[docs] def get_context() -> Context: """ Return the currently active default SpaceCore context. Resolves the :func:`use_context` override for this thread / task if one is installed, otherwise the process-wide baseline set by :func:`set_context`. Returns ------- Context Active default context. """ return _state().default_ctx
[docs] def resolve_context_priority( priority_ctx: Context | BackendFamily | str | None = None, *other_ctx: object, ) -> Context: """ Resolve the context assigned to a newly created object. Parameters ---------- priority_ctx : Context, BackendFamily, str, or None, optional Explicit context that takes precedence when provided. *other_ctx : object Objects or contexts used as fallback context sources. Returns ------- Context Resolved context. """ return _state().resolve_context_priority(priority_ctx, *other_ctx)
[docs] def register_ops(ops: type[BackendOps]) -> type[BackendOps]: """ Register a backend in the process-wide registry; registrations are never scoped. Parameters ---------- ops : type of BackendOps Backend class to register. Returns ------- type of BackendOps The registered class. Raises ------ ContextConflictError If the backend family is already registered. """ return _ops_registry.register(ops)
[docs] def normalize_context( ctx: Context | BackendFamily | str | None = None, dtype: Any = None, ) -> Context: """ Normalize a context specification through the process-wide state. Parameters ---------- ctx : Context, BackendFamily, str, or None, optional Context or backend specification. dtype : Any, optional Default dtype override. Returns ------- Context Normalized context. """ return _state().normalize_context(ctx, dtype=dtype)
[docs] def normalize_ops(ops: str | BackendFamily | BackendOps | type[BackendOps] | Context) -> BackendOps: """ Normalize backend operations through the process-wide state. Parameters ---------- ops : str, BackendFamily, BackendOps, type of BackendOps, or Context Backend operations specification. Returns ------- BackendOps Normalized backend operations singleton. """ if isinstance(ops, BackendOps): return ops return _ops_registry.get(ops)