LazyLoader module borrowed from Tensorflow https://github.com/tensorflow/tensorflow/blob/v2.2.0/tensorflow/python/util/lazy_loader.py. This class adds "module caching". This will throw an exception if module cannot be imported. Lazily import a module, mainly to avoid pulling in large d
| 74 | |
| 75 | |
| 76 | class LazyLoader(types.ModuleType): |
| 77 | """LazyLoader module borrowed from Tensorflow https://github.com/tensorflow/tensorflow/blob/v2.2.0/tensorflow/python/util/lazy_loader.py. |
| 78 | |
| 79 | This class adds "module caching". |
| 80 | This will throw an exception if module cannot be imported. |
| 81 | |
| 82 | Lazily import a module, mainly to avoid pulling in large dependencies. |
| 83 | `contrib`, and `ffmpeg` are examples of modules that are large and not always |
| 84 | needed, and this allows them to only be loaded when they are used. |
| 85 | """ |
| 86 | |
| 87 | def __init__( |
| 88 | self, |
| 89 | local_name: str, |
| 90 | parent_module_globals: dict[str, t.Any], |
| 91 | name: str, |
| 92 | warning: str | None = None, |
| 93 | exc_msg: str | None = None, |
| 94 | exc: type[Exception] = ImportError, |
| 95 | ): |
| 96 | """Create a lazy loaded module. |
| 97 | |
| 98 | Args: |
| 99 | local_name (str): The name of the module in the parent's globals. |
| 100 | parent_module_globals (dict[str, t.Any]): The parent's globals. |
| 101 | name (str): The name of the module to be imported. |
| 102 | warning (str, optional): A warning to be emitted when the module is loaded. Defaults to None. |
| 103 | exc_msg (str, optional): An exception message to be raised when the module is loaded. Defaults to None. |
| 104 | exc (type[Exception], optional): The exception to be raised when the module is loaded. Defaults to ImportError. |
| 105 | |
| 106 | Returns: |
| 107 | LazyLoader: A lazy loaded module. |
| 108 | """ |
| 109 | self._local_name = local_name |
| 110 | self._parent_module_globals = parent_module_globals |
| 111 | self._warning = warning |
| 112 | self._exc_msg = exc_msg |
| 113 | self._exc = exc |
| 114 | self._module: types.ModuleType | None = None |
| 115 | |
| 116 | super().__init__(str(name)) |
| 117 | |
| 118 | def _load(self) -> types.ModuleType: |
| 119 | """Load the module and insert it into the parent's globals.""" |
| 120 | # Import the target module and insert it into the parent's namespace |
| 121 | try: |
| 122 | module = importlib.import_module(self.__name__) |
| 123 | self._parent_module_globals[self._local_name] = module |
| 124 | # The additional add to sys.modules ensures library is actually loaded. |
| 125 | sys.modules[self._local_name] = module |
| 126 | except ModuleNotFoundError as err: |
| 127 | raise self._exc(f"{self._exc_msg} (reason: {err})") from None |
| 128 | |
| 129 | # Emit a warning if one was specified |
| 130 | if self._warning: |
| 131 | logger.warning(self._warning) |
| 132 | # Make sure to only warn once. |
| 133 | self._warning = None |
no outgoing calls