From be6c938748ce99af81fd6d190d97f3ff54e7c1cd Mon Sep 17 00:00:00 2001 From: RF-Tar-Railt Date: Sun, 15 Dec 2024 22:02:45 +0800 Subject: [PATCH] :bug: fix plugin load --- arclet/entari/plugin/__init__.py | 16 ++++++----- arclet/entari/plugin/module.py | 46 ++++++++++++++++++-------------- 2 files changed, 35 insertions(+), 27 deletions(-) diff --git a/arclet/entari/plugin/__init__.py b/arclet/entari/plugin/__init__.py index fed5d0a..75ae653 100644 --- a/arclet/entari/plugin/__init__.py +++ b/arclet/entari/plugin/__init__.py @@ -57,10 +57,13 @@ def load_plugin( return plugin_service._apply[path](conf) try: mod = import_plugin(path, config=conf) + if not mod: + path1 = f"entari_plugin_{path}" + mod = import_plugin(path1, config=conf) if not mod: log.plugin.opt(colors=True).error(f"cannot found plugin {path!r}") return - log.plugin.opt(colors=True).success(f"loaded plugin {path!r}") + log.plugin.opt(colors=True).success(f"loaded plugin {mod.__name__!r}") if mod.__name__ in plugin_service._unloaded: if mod.__name__ in plugin_service._referents and plugin_service._referents[mod.__name__]: referents = plugin_service._referents[mod.__name__].copy() @@ -89,12 +92,11 @@ def load_plugin( def load_plugins(dir_: str | PathLike | Path): path = dir_ if isinstance(dir_, Path) else Path(dir_) - if path.is_dir(): - for p in path.iterdir(): - if p.suffix in (".py", "") and p.stem not in {"__init__", "__pycache__"}: - load_plugin(".".join(p.parts[:-1:1]) + "." + p.stem) - elif path.is_file(): - load_plugin(".".join(path.parts[:-1:1]) + "." + path.stem) + if not path.is_dir(): + raise NotADirectoryError(f"{path} is not a directory") + for p in path.iterdir(): + if p.suffix in (".py", "") and p.stem not in {"__init__", "__pycache__"}: + load_plugin(".".join(p.parts[:-1:1]) + "." + p.stem) def dispose(plugin: str): diff --git a/arclet/entari/plugin/module.py b/arclet/entari/plugin/module.py index d8fe983..8431ec8 100644 --- a/arclet/entari/plugin/module.py +++ b/arclet/entari/plugin/module.py @@ -257,7 +257,7 @@ def exec_module(self, module: ModuleType, config: Optional[dict[str, str]] = Non # leave plugin context delattr(module, "__cached__") delattr(module, "__plugin_service__") - sys.modules.pop(module.__name__, None) + # sys.modules.pop(module.__name__, None) _current_plugin.reset(token) # get plugin metadata @@ -313,30 +313,36 @@ def find_spec(name, package=None): fullname = resolve_name(name, package) if name.startswith(".") else name parent_name = fullname.rpartition(".")[0] if parent_name: - if parent_name in plugin_service.plugins: - parent = plugin_service.plugins[parent_name].module + parts = parent_name.split(".") + _current = parts[0] + if _current in plugin_service.plugins: + parent = plugin_service.plugins[_current].module + enter_plugin = True else: + parent = __import__(_current, fromlist=["__path__"]) enter_plugin = False - index = 0 - while (index := parent_name.find(".", index + 1)) != -1: - if parent_name[:index] in plugin_service.plugins: + _current += "." + for part in parts[1:]: + _current += part + if _current in plugin_service.plugins: + parent = plugin_service.plugins[_current].module + enter_plugin = True + _current += "." + continue + if _current in _ENSURE_IS_PLUGIN: + parent = import_plugin(_current) + if parent: enter_plugin = True - continue - if enter_plugin: - if import_plugin(parent_name[:index]): - continue - else: - enter_plugin = False - __import__(parent_name[:index], fromlist=["__path__"]) else: - __import__(parent_name[:index], fromlist=["__path__"]) - if parent_name in plugin_service.plugins: - parent = plugin_service.plugins[parent_name].module - elif enter_plugin: - if not (parent := import_plugin(parent_name)): - parent = __import__(parent_name, fromlist=["__path__"]) + parent = __import__(_current, fromlist=["__path__"]) + _current += "." + continue + if enter_plugin and (parent := import_plugin(_current)): + pass else: - parent = __import__(parent_name, fromlist=["__path__"]) + enter_plugin = False + parent = __import__(_current, fromlist=["__path__"]) + _current += "." try: parent_path = parent.__path__ except AttributeError as e: