Source code for crappy._global

# coding:utf-8

from typing import Optional, NoReturn, Any
from importlib import import_module
import webbrowser
from pkg_resources import resource_string, resource_filename
from numpy import frombuffer, uint8


# Quick access to documentation
[docs] def docs(): """Opens the online documentation of Crappy. It opens the latest version, and of course requires an internet access. .. versionadded:: 1.5.5 .. versionchanged:: 2.0.0 renamed from *doc* to *docs* """ webbrowser.open('https://crappy.readthedocs.io/en/latest/')
[docs] class OptionalModule: """Placeholder for optional dependencies that are not installed. Will display a message and raise an error when trying to use them. .. versionadded:: 1.4.0 """
[docs] def __init__(self, module_name: str, message: Optional[str] = None, lazy_import: bool = False) -> None: """Sets the arguments. Args: module_name: The name of the module s a :obj:`str`, preferably the one invoked with `pip install`. message: Optionally, the message to display in case the module is missing (as a :obj:`str`). If not provided, a generic message will be displayed. lazy_import: If :obj:`True`, the module won't be imported directly even if it is installed. Instead, it will be imported only when necessary. Allows reducing the import time, especially on Window. .. versionadded:: 2.0.0 """ self._name = module_name # Setting a default message if none was provided if message is not None: self._msg = message else: self._msg = f"The module {self._name} is necessary to use this " \ f"functionality. Please install it and try again !" self._lazy = lazy_import self._module = None
[docs] def __getattr__(self, attr: str) -> Any: """Method normally raising an exception indicating that the module is missing. In case the ``lazy_import`` argument was set to :obj:`True`, still tries to get the desired attribute and raises the exception only if the module is missing. """ # The module has to be imported only when called because it's too heavy if self._lazy: raise_ = False # Trying to import the module if self._module is None: try: self._module = import_module(self._name) except (ImportError, ModuleNotFoundError): raise_ = True # The module could be imported, returning the desired attribute if not raise_: return getattr(self._module, attr) # The module could not be imported raise RuntimeError(f"Missing module: {self._name}\n{self._msg}")
[docs] def __call__(self, *_, **__) -> NoReturn: """Method raising an exception indicating that the module is missing.""" raise RuntimeError(f"Missing module: {self._name}\n{self._msg}")
# Data aliases class resources: """This class defines aliases for quick access to the resources in the `tool/data/` folder. These aliases are then used in the examples provided on the GitHub repository, but could also be used in custom user scripts. .. versionadded:: 1.5.3 """ try: # Defining aliases to the images themselves from cv2 import imdecode speckle = imdecode(frombuffer(resource_string('crappy', 'tool/data/speckle.png'), uint8), flags=0) ve_markers = imdecode(frombuffer( resource_string('crappy', 'tool/data/ve_markers.tif'), uint8), flags=0) pad = imdecode(frombuffer(resource_string('crappy', 'tool/data/pad.png'), uint8), flags=0) # In case the module opencv-python is missing except (ModuleNotFoundError, ImportError): speckle = OptionalModule('opencv-python') ve_markers = OptionalModule('opencv-python') pad = OptionalModule('opencv-python') # Also getting the paths to the images paths = {'pad': resource_filename('crappy', 'tool/data/pad.png'), 'speckle': resource_filename('crappy', 'tool/data/speckle.png'), 've_markers': resource_filename('crappy', 'tool/data/ve_markers.tif')}
[docs] class LinkDataError(ValueError): """Exception raised when trying to send a wrong data type through a :class:`~crappy.links.Link`."""
[docs] class StartTimeout(TimeoutError): """Exception raised when the start event takes too long to be set."""
[docs] class PrepareError(IOError): """Error raised in a :class:`~crappy.blocks.Block` when waiting for all Blocks to be ready but another Block fails to prepare."""
class CameraConfigError(RuntimeError): """Error raised by a :class:`~crappy.tool.camera_config.CameraConfig` window when encountering an exception."""
[docs] class CameraPrepareError(RuntimeError): """Error raised by a :class:`~crappy.blocks.Camera` when one of its children processes crashes while preparing."""
[docs] class CameraRuntimeError(RuntimeError): """Error raised by a :class:`~crappy.blocks.Camera` when one of its children processes crashes while running."""
[docs] class T0NotSetError(ValueError): """Exception raised when requesting the t0 value when it is not set."""
[docs] class DefinitionError(NameError): """Exception raised when trying to define an object with the same name as an already-defined one.""" def __init__(self, msg: str) -> None: """Sets the msg attribute. Args: msg: The message to display along with the exception. """ super().__init__() self._msg = msg def __str__(self) -> str: return self._msg
[docs] class GeneratorStop(Exception): """Exception raised when a :class:`~crappy.blocks.Generator` Block reaches the end of its :class:`~crappy.blocks.generator_path.Path`."""
[docs] class ReaderStop(Exception): """Exception raised when a :class:`~crappy.camera.FileReader` Camera has exhausted all the images to read."""
[docs] class CrappyFail(Exception): """Exception raised when an unexpected Exception is caught in Crappy. Also raised when all the Blocks do not terminate gracefully.""" def __init__(self) -> None: """Only defined here to set the message to display when raised.""" super().__init__("This Exception means that an error occurred while " "running Crappy. Check the Traceback in the terminal for " "more information")