From d71d42658298e9ec766be04adb29eebf3554d134 2021-11-16 23:43:14 From: Nikita Kniazev Date: 2021-11-16 23:43:14 Subject: [PATCH] ShimImporter: implement modern interface --- diff --git a/IPython/utils/shimmodule.py b/IPython/utils/shimmodule.py index cc05503..ec243a0 100644 --- a/IPython/utils/shimmodule.py +++ b/IPython/utils/shimmodule.py @@ -3,6 +3,8 @@ # 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 @@ -13,41 +15,26 @@ 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(object): + +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_module(self, fullname, path=None): - """Return self if we should be used to import the module.""" - if fullname.startswith(self.src + '.'): - mirror_name = self._mirror_name(fullname) - try: - mod = import_item(mirror_name) - except ImportError: - return - else: - if not isinstance(mod, types.ModuleType): - # not a module - return None - return self + return self.mirror + fullname[len(self.src) :] - def load_module(self, fullname): - """Import the mirrored module, and insert it into sys.modules""" - mirror_name = self._mirror_name(fullname) - mod = import_item(mirror_name) - sys.modules[fullname] = mod - return mod + 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): diff --git a/IPython/utils/tests/test_shimmodule.py b/IPython/utils/tests/test_shimmodule.py index 814e482..30f2ffa 100644 --- a/IPython/utils/tests/test_shimmodule.py +++ b/IPython/utils/tests/test_shimmodule.py @@ -8,3 +8,7 @@ def test_shim_warning(): sys.modules.pop('IPython.config', None) with pytest.warns(ShimWarning): import IPython.config + + import traitlets.config + + assert IPython.config.Config is traitlets.config.Config