Source code for animedex.auth.inmemory_store

"""
In-memory implementation of :class:`~animedex.auth.store.TokenStore`.

Used in two places: by unit tests (so credential paths are
exercisable without OS-level state), and by callers running in a
headless CI environment where the real keyring has no backend
(``plans/02 ยง7`` rules out plain-text disk fallbacks; this in-memory
store is the documented escape hatch for ephemeral processes).
"""

from __future__ import annotations

from typing import Dict, Iterable, Mapping, Optional


[docs] class InMemoryTokenStore: """A :class:`~animedex.auth.store.TokenStore` that lives in process memory. :param initial: Optional pre-populated mapping. Useful for tests that want to assert authenticated behaviour without dispatching through the real keyring. :type initial: Mapping[str, str] or None """
[docs] def __init__(self, initial: Optional[Mapping[str, str]] = None) -> None: self._storage: Dict[str, str] = dict(initial) if initial else {}
[docs] def set(self, backend: str, token: str) -> None: self._storage[backend] = token
[docs] def get(self, backend: str) -> Optional[str]: return self._storage.get(backend)
[docs] def delete(self, backend: str) -> None: self._storage.pop(backend, None)
[docs] def keys(self) -> Iterable[str]: return list(self._storage.keys())
[docs] def selftest() -> bool: """Smoke-test the in-memory store. Round-trips a value, deletes it, confirms the deletion is idempotent, and confirms an absent key reads as ``None``. :return: ``True`` on success. :rtype: bool """ store = InMemoryTokenStore() store.set("_selftest", "value") assert store.get("_selftest") == "value" store.delete("_selftest") store.delete("_selftest") # idempotent assert store.get("_selftest") is None assert InMemoryTokenStore({"a": "b"}).get("a") == "b" return True