PPysolate SpineREAD THE CODE · UNDERSTAND THE SYSTEM
课程与章节
IMPLEMENTATION / 08

Python 工具实现

Guest 经固定 Go 桥调用 native Python worker。

本章目录

这个示例保留原有 Go 工具,额外展示一个由 native Python 实现的固定工具。两端都是 Python,但权限和执行位置不同。

一个命令

./demos/core.sh python

输入 [2, 4, 6, 8],native worker 计算 count=4、total=20,Guest 根据结果计算 mean=5。这里求和只是为了让桥接容易看懂;实际不值得为这么小的计算启动进程。

先打开两个 Python 文件

  • examples/python_provider.py:真正运行在 Wasm CPython 中的程序,调用 report_stats 并计算平均值。
  • providers/report.py:真正运行在宿主 native Python 中的实现,读取 stdin JSON,计算并向 stdout 输出 JSON。

这两个文件都可直接阅读。Guest 的工具名由 Host 注入,IDE 类型提示见 Python 编辑器说明。按定义跳转通常到 .pyi 接口声明,业务实现要打开上述 provider 文件。

Guest Python:report_stats(numbers=inputs["numbers"])
        |
        v
已有 C / Wasm ABI → Go Host reportStats
        |
        | 校验参数;固定工具、固定脚本
        v
exec.CommandContext(ctx, "python3", "providers/report.py")
        |
        | stdin: {"numbers":[2,4,6,8]}
        v
native Python:校验输入,求和
        |
        | stdout: {"count":4,"total":20}
        v
Go 解析结果 → Guest 计算 mean → result 返回

Go 桥接做了什么

cmd/python-provider/main.go 的 run 创建 Runner,manifest 只注册 report_stats,没有授予 early-read。

reportStats 接受 1–100 个有限数值,校验后启动固定 worker。没有 shell 命令拼接,Guest 参数不能选择可执行程序或脚本路径。python3 由 Host 的 PATH 解析,所以 Host 环境仍须可信。

每次调用创建一个进程,输入与输出通过 JSON 传递。子进程退出失败、输出不是合法 JSON、计数不匹配等错误回到 Guest,不伪造成功。worker 再独立验证输入,错误写 stderr,并返回非零退出码。

验证

go test ./cmd/python-provider -count=1
uvx pyright --project pyrightconfig.json

真实 Guest 测试覆盖成功路径、坏输入、worker 失败和 malformed JSON;另外直接启动 worker 验证其参数检查。类型检查只处理示例,不会执行工具。

边界与取舍

  • native worker 不在 Wasm Guest 内,拥有启动它的 Host 用户权限。固定路径和 JSON 不是操作系统沙箱。
  • 当前脚本是可信的本地演示代码,不应把这个桥接当作不可信 native 代码的隔离方案。stdin/stdout 收集也不是通用恶意 worker 资源防护。
  • CommandContext 提供本进程的取消行为,不等于任意子进程树都被收回,也不撤销已发生的外部效果。
  • 每次启动解释器有额外开销。本示例没有 worker pool,没有性能优势声明。
  • 不改 Spine 核心,不替换 PLM/prefix 的 Go 工具,也不自动授予提前执行许可。

面试时可以用一句话概括:Pysolate 的能力边界由 Host 控制,工具业务实现可以用 Python;Guest 不因工具采用 Python 实现而获得宿主执行权限。