"""A shim module for deprecated imports """ # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. import importlib.abc import importlib.util import sys import types from importlib import import_module from .importstring import import_item class ShimWarning(Warning): """A warning to show when a module has moved, and a shim is in its place.""" class ShimImporter(importlib.abc.MetaPathFinder): """Import hook for a shim. This ensures that submodule imports return the real target module, not a clone that will confuse `is` and `isinstance` checks. """ def __init__(self, src, mirror): self.src = src self.mirror = mirror def _mirror_name(self, fullname): """get the name of the mirrored module""" return self.mirror + fullname[len(self.src) :] def find_spec(self, fullname, path, target=None): if fullname.startswith(self.src + "."): mirror_name = self._mirror_name(fullname) return importlib.util.find_spec(mirror_name) class ShimModule(types.ModuleType): def __init__(self, *args, **kwargs): self._mirror = kwargs.pop("mirror") src = kwargs.pop("src", None) if src: kwargs['name'] = src.rsplit('.', 1)[-1] super(ShimModule, self).__init__(*args, **kwargs) # add import hook for descendent modules if src: sys.meta_path.append( ShimImporter(src=src, mirror=self._mirror) ) @property def __path__(self): return [] @property def __spec__(self): """Don't produce __spec__ until requested""" return import_module(self._mirror).__spec__ def __dir__(self): return dir(import_module(self._mirror)) @property def __all__(self): """Ensure __all__ is always defined""" mod = import_module(self._mirror) try: return mod.__all__ except AttributeError: return [name for name in dir(mod) if not name.startswith('_')] def __getattr__(self, key): # Use the equivalent of import_item(name), see below name = "%s.%s" % (self._mirror, key) try: return import_item(name) except ImportError as e: raise AttributeError(key) from e def __repr__(self): # repr on a module can be called during error handling; make sure # it does not fail, even if the import fails try: return self.__getattr__("__repr__")() except AttributeError: return f""