Source code for scverse_backends._settings

"""Per-host backend settings backed by a thread-safe ContextVar."""

from __future__ import annotations

from contextlib import contextmanager
from contextvars import ContextVar
from typing import TYPE_CHECKING, Any

if TYPE_CHECKING:
    from collections.abc import Generator

    from scverse_backends._registry import _Registry


[docs] class Settings: """Per-host settings exposing ``.backend`` and ``.use_backend()``. Each ``BackendDispatcher`` owns one ``_Settings`` with its own ``ContextVar`` so host libraries' active backends are isolated. """
[docs] def __init__(self, registry: _Registry) -> None: self._registry = registry # Each instance gets its own ContextVar; the var name is purely for # debugging/repr — the actual storage is per-instance. self._backend_var: ContextVar[str] = ContextVar( f"{registry.host_name}_backend", default="cpu", )
@property def backend(self) -> str: """The active backend name (default ``'cpu'``). Set to a registered backend name or alias (e.g. ``'cuda'``). Aliases are resolved to the canonical name on assignment. """ return self._backend_var.get() @backend.setter def backend(self, value: str) -> None: canonical, _ = self._registry.require_backend(value) self._backend_var.set(canonical)
[docs] @contextmanager def use_backend(self, backend: str) -> Generator[None, None, None]: """Temporarily set the backend within a context. Examples -------- >>> with settings.use_backend("cuda"): ... ... """ canonical, _ = self._registry.require_backend(backend) token = self._backend_var.set(canonical) try: yield finally: self._backend_var.reset(token)
[docs] def available_backends(self) -> list[str]: """Return canonical names of all discovered backends.""" self._registry._ensure_discovered() return sorted(self._registry._backends.keys())
[docs] def get_backend(self, name: str) -> Any | None: """Look up a backend by name or alias.""" return self._registry.get_backend(name)
_Settings = Settings