diff --git a/src/plugin_runtime/runner/plugin_loader.py b/src/plugin_runtime/runner/plugin_loader.py index 97ab3284..9efe184d 100644 --- a/src/plugin_runtime/runner/plugin_loader.py +++ b/src/plugin_runtime/runner/plugin_loader.py @@ -9,6 +9,7 @@ from collections import deque from typing import Any, Dict, List, Optional, Set, Tuple +import contextlib import importlib import importlib.util import json @@ -239,7 +240,19 @@ class PluginLoader: module = importlib.util.module_from_spec(spec) 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 = getattr(module, "create_plugin", None) diff --git a/src/plugin_runtime/runner/runner_main.py b/src/plugin_runtime/runner/runner_main.py index 245a5487..dae1cfa1 100644 --- a/src/plugin_runtime/runner/runner_main.py +++ b/src/plugin_runtime/runner/runner_main.py @@ -627,14 +627,19 @@ def _isolate_sys_path(plugin_dirs: List[str]) -> None: allowed.add(p) # 添加插件目录 - for d in plugin_dirs: - allowed.add(os.path.normpath(d)) + plugin_dir_paths = [os.path.normpath(d) for d in plugin_dirs] + for d in plugin_dir_paths: + allowed.add(d) # 添加项目根目录(使得 src.plugin_runtime / src.common 可导入) runtime_root = os.path.normpath(os.path.join(os.path.dirname(__file__), "..", "..", "..")) 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 钩子,阻止插件导入主程序核心模块 # 仅允许 src.plugin_runtime 和 src.common,拒绝其他 src.* 子包