Merge pull request #1553 from Anderwer/fix/plugin-runtime-package-imports

fix: 为 Runtime 和 Loader 补充包式插件导入支持
This commit is contained in:
墨梓柒
2026-03-15 22:00:19 +08:00
committed by GitHub
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.* 子包