From e8244ed49e4dafbec4929169729d2b8db5c81ce8 Mon Sep 17 00:00:00 2001 From: anderwer Date: Sun, 15 Mar 2026 16:58:53 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=B8=BA=20Runtime=20=E5=92=8C=20Loader?= =?UTF-8?q?=20=E8=A1=A5=E5=85=85=E5=8C=85=E5=BC=8F=E6=8F=92=E4=BB=B6?= =?UTF-8?q?=E5=AF=BC=E5=85=A5=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugin_runtime/runner/plugin_loader.py | 15 ++++++++++++++- src/plugin_runtime/runner/runner_main.py | 11 ++++++++--- 2 files changed, 22 insertions(+), 4 deletions(-) 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.* 子包