fix: 为 Runtime 和 Loader 补充包式插件导入支持

This commit is contained in:
anderwer
2026-03-15 16:58:53 +08:00
parent e1b3cf6e9f
commit e8244ed49e
2 changed files with 22 additions and 4 deletions

View File

@@ -9,6 +9,7 @@
from collections import deque from collections import deque
from typing import Any, Dict, List, Optional, Set, Tuple from typing import Any, Dict, List, Optional, Set, Tuple
import contextlib
import importlib import importlib
import importlib.util import importlib.util
import json import json
@@ -239,7 +240,19 @@ class PluginLoader:
module = importlib.util.module_from_spec(spec) module = importlib.util.module_from_spec(spec)
sys.modules[module_name] = module sys.modules[module_name] = module
spec.loader.exec_module(module)
plugin_parent_dir = os.path.dirname(plugin_dir)
inserted_plugin_parent = False
if plugin_parent_dir and plugin_parent_dir not in sys.path:
sys.path.insert(0, plugin_parent_dir)
inserted_plugin_parent = True
try:
spec.loader.exec_module(module)
finally:
if inserted_plugin_parent:
with contextlib.suppress(ValueError):
sys.path.remove(plugin_parent_dir)
# 优先使用新版 create_plugin 工厂函数 # 优先使用新版 create_plugin 工厂函数
create_plugin = getattr(module, "create_plugin", None) create_plugin = getattr(module, "create_plugin", None)

View File

@@ -627,14 +627,19 @@ def _isolate_sys_path(plugin_dirs: List[str]) -> None:
allowed.add(p) allowed.add(p)
# 添加插件目录 # 添加插件目录
for d in plugin_dirs: plugin_dir_paths = [os.path.normpath(d) for d in plugin_dirs]
allowed.add(os.path.normpath(d)) for d in plugin_dir_paths:
allowed.add(d)
# 添加项目根目录(使得 src.plugin_runtime / src.common 可导入) # 添加项目根目录(使得 src.plugin_runtime / src.common 可导入)
runtime_root = os.path.normpath(os.path.join(os.path.dirname(__file__), "..", "..", "..")) runtime_root = os.path.normpath(os.path.join(os.path.dirname(__file__), "..", "..", ".."))
allowed.add(runtime_root) allowed.add(runtime_root)
sys.path[:] = [p for p in sys.path if p in allowed] preserved_paths = [p for p in sys.path if p in allowed]
for extra_path in [*plugin_dir_paths, runtime_root]:
if extra_path not in preserved_paths:
preserved_paths.append(extra_path)
sys.path[:] = preserved_paths
# 安装 import 钩子,阻止插件导入主程序核心模块 # 安装 import 钩子,阻止插件导入主程序核心模块
# 仅允许 src.plugin_runtime 和 src.common拒绝其他 src.* 子包 # 仅允许 src.plugin_runtime 和 src.common拒绝其他 src.* 子包