Source code for whitecanvas.backend._instance

from contextlib import contextmanager


_INSTALLED_MODULES = {}

_DEFAULT_APP = {
    "pyqtgraph": "qt",
    "vispy": "qt",
}


[docs]class Backend: """The backend of plots.""" _default: str = "matplotlib" def __init__(self, name: "Backend | str | None" = None) -> None: if name is None: name = self._default elif isinstance(name, Backend): name = name._name if ":" in name: name, app = name.split(":", maxsplit=1) # normalize app name if app == "nb": app = "notebook" else: app = _DEFAULT_APP.get(name, "default") if name in _INSTALLED_MODULES: self._mod = _INSTALLED_MODULES[name] else: from importlib import import_module _INSTALLED_MODULES[name] = self._mod = import_module( f"whitecanvas.backend.{name}" ) self._name: str = name self._app: str = app self.__class__._default = name def __repr__(self) -> str: return f"<Backend {self._name!r}>" @property def name(self) -> str: """Name of the backend.""" return self._name @property def app(self) -> str: """Name of the application.""" return self._app
[docs] def has(self, attr: str) -> bool: """Check if the current backend has an object.""" return hasattr(self._mod, attr)
[docs] def get(self, attr: str): """Get an object from the current backend.""" out = getattr(self._mod, attr, None) if out is None: raise RuntimeError(f"Backend {self._name!r} does not have {attr!r}") return out
class DummyObject: def __init__(self, *args, **kwargs): pass class DummyBackendModule: def __init__(self): self.Canvas = DummyObject def __getattr__(self, key): raise RuntimeError(f"Cannot install {key!r} before finishing layouting.") _dummy_backend_module = DummyBackendModule()
[docs]@contextmanager def patch_dummy_backend(): dummy_name = "." while dummy_name in _INSTALLED_MODULES: dummy_name += "." _INSTALLED_MODULES[dummy_name] = _dummy_backend_module try: yield dummy_name finally: del _INSTALLED_MODULES[dummy_name]