From 8868ae2205742702df9c11bd65cc3186b25f538f Mon Sep 17 00:00:00 2001 From: Vincent A Date: Sun, 4 Apr 2021 22:11:19 +0200 Subject: [PATCH] weboob compat: override sys.meta_path to prevent package loaded twice Use case: the core does "import woob.x" but some app does "import weboob.x". This loaded modules twice and prevented isinstance() from cooperating. This trick loads modules only once. --- weboob/__init__.py | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/weboob/__init__.py b/weboob/__init__.py index 81a25e1aaa..49f2ba9430 100644 --- a/weboob/__init__.py +++ b/weboob/__init__.py @@ -17,11 +17,43 @@ # You should have received a copy of the GNU Lesser General Public License # along with woob. If not, see . +import sys +from importlib.abc import MetaPathFinder, Loader +import importlib + import woob -__path__ = woob.__path__ __title__ = woob.__title__ __version__ = woob.__version__ __author__ = woob.__author__ __copyright__ = woob.__copyright__ + + +# Use case: the core does "import woob.x" but some app does "import weboob.x". +# If we merely set __path__, python will generate different modules +# though they have the same path. So the references will be different, +# isinstance(woob.X(), weboob.X) will fail, etc. +# Instead, we must return the same module to prevent Python from generating +# another one. +# Trick found at https://stackoverflow.com/a/56872393 + +class AliasLoader(Loader): + def module_repr(self, module): + return repr(module) + + def load_module(self, fullname): + new_name = fullname.replace("weboob", "woob") + module = importlib.import_module(new_name) + sys.modules[fullname] = module + return module + + +class AliasImporter(MetaPathFinder): + def find_module(self, fullname, path=None): + root_name, _, __ = fullname.partition(".") + if root_name == "weboob": + return AliasLoader() + + +sys.meta_path.append(AliasImporter()) -- GitLab