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: