Source code for openwfs.devices

import importlib
import sys
from types import ModuleType


class _MockModule(ModuleType):
    """A mock object that replaces a missing module, or a function / class from that module.

    This class makes it possible to run openwfs without all optional dependencies installed.
    If `safe_import` tries to load a package that is not installed, it creates a `MockModule`
    as placeholder for that package. The openwfs subpackage that tried to load this package
    will then load normally (also so that readthedocs can parse the docstrings).
    Only when a function from the missing package is called, an error is raised (see `__call__`)."""

    def __init__(self, module_name: str, extra_name: str):
        super().__init__(module_name)
        self.module_name = module_name
        self.extra_name = extra_name
        self.message = f"""Module {self.module_name} is not installed.
            To install, use:
                pip install openwfs[{self.extra_name}]
            or
                pip install openwfs[all]
            """

    def __getattr__(self, name):
        """Mimicks accessing a submodule, function or class in the module.

        This just returns another MockModule object. Only when this object is called (e.g. `glfw.init()`),
        an error is raised.
        """
        if name.startswith("_"):
            return super().__getattr__(name)
        else:
            return _MockModule(self.module_name, self.extra_name)

    def __call__(self, *args, **kwargs):
        raise ModuleNotFoundError(self.message)


[docs] def is_loaded(module) -> bool: """Helper function to check if a module is a real loaded module or a mock module.""" return not isinstance(module, _MockModule)
[docs] def safe_import(module_name: str, extra_name: str): """Tries to import a module. If the import files (usually because the module is not installed), this function registers a mock module so that importing can still continue without giving an error. This is essential for loading openwfs if optional dependencies are missing. This is also important for `readthedocs`, where not all dependenceis can be installed.""" try: importlib.import_module(module_name) except (ModuleNotFoundError, AttributeError): sys.modules[module_name] = _MockModule(module_name, extra_name)
safe_import("harvesters", "genicam") safe_import("harvesters.core", "genicam") safe_import("nidaqmx", "nidaq") safe_import("nidaqmx.system", "nidaq") safe_import("nidaqmx.constants", "nidaq") safe_import("nidaqmx.stream_writers", "nidaq") safe_import("OpenGL", "opengl") safe_import("OpenGL.GL", "opengl") safe_import("glfw", "opengl") safe_import("zaber_motion", "zaber") safe_import("serial", "zaber") safe_import("serial.tools", "zaber") from .camera import Camera from .galvo_scanner import ScanningMicroscope, Axis from .nidaq_gain import Gain from . import slm from .slm import SLM from .zaber_stage import ZaberXYStage, ZaberLinearStage