在 macOS 上使用 ApplecontainerCLI 运行 RustPython 测试:完整实战指南
【免费下载链接】RustPythonA Python Interpreter written in Rust项目地址: https://gitcode.com/GitHub_Trending/ru/RustPython
本指南围绕 RustPython 仓库中
.agents/skills/apple-container/SKILL.md这一技能文档展开,讲解如何在 macOS 上使用 Apple 官方containerCLI(而非 Docker / Podman)启动 Linux 容器、挂载工作区、执行 RustPython 的-m test测试套件,并正确解读与汇报测试结果。读完本文,你将掌握一套可复用的容器化测试工作流,能够在 macOS 与 Linux 之间对比测试结果、定位平台相关差异,同时避免测试容器的误停误删。
背景:为什么用 ApplecontainerCLI 跑 RustPython 测试
RustPython 是用 Rust 实现的 Python 解释器,其代码库同时维护着从 CPython 移植来的 Lib/ 标准库,以及位于 crates/vm 的 Rust 虚拟机实现。开发者在 macOS 上日常开发时,很多行为(如文件 I/O、信号处理、编码细节)与 Linux 存在差异,需要借助 Linux 环境做交叉验证。
在 macOS 上运行 Linux 容器通常的直觉选择是 Docker 或 Podman,但本技能文档明确约定:NEVER use Docker, Podman, or any other container runtime. Only use thecontainercommand.(严禁使用 Docker、Podman 或任何其他容器运行时,只能使用container命令)。这是 Apple 官方随 Xcode 提供的容器 CLI(/usr/bin/container),基于 macOS 自带的 Virtualization.framework 实现轻量级 Linux 虚拟机与容器管理,无需额外安装 Docker 守护进程,也不依赖 Docker Desktop 的许可模式。
该技能的定位场景非常聚焦:当用户要求在 macOS 上运行或对比 Linux 测试结果时,Agent 用它把 RustPython 测试套件搬进 Linux 容器执行,从而区分“RustPython 自身缺陷”与“macOS 平台差异”。
前置条件与参数约定
参数:要执行的测试命令
SKILL.md 将“Test command to run”(要运行的测试命令)作为唯一参数,并给出三个示例:
test_iotest_codecs -vtest_io -v -m "test_errors"
这些参数正是 RustPython 的 regrtest 测试框架(python -m test)的入参。其含义如下:
test_io:只运行test_io这一个测试模块,等价于cargo run --release -- -m test test_io;-v:verbose 模式,逐条打印每个测试用例的执行结果;-m "test_errors":-m/--match选项,用 glob 模式过滤测试方法与用例,这里表示只匹配名为test_errors的用例。
参数解析逻辑可以在 Lib/test/libregrtest/cmdline.py 中找到:-v/--verbose被注册为action='count'(可叠加),-m/--match通过自定义的FilterAction把模式累积进match_tests列表,-u/--use用于启用特殊资源(如-uall,-gui),-j/--multiprocess控制并行进程数。
前置条件
运行本工作流前需确认两个前提,否则命令会直接失败:
containerCLI 已安装:通过 Homebrew 安装,命令为brew install container(Apple 官方容器工具,随新版本 Xcode 附带,Homebrew 也提供独立安装方式);- 开发镜像
rustpython-dev已构建:这是预先打好的镜像,内部应包含 Rust 工具链与 RustPython 的构建产物,SKILL.md 假设它已存在(构建细节不在本文范围)。
工作流详解
第一步:检查测试容器是否已在运行
container list 2>/dev/null | grep rustpython-testcontainer list列出当前所有容器,2>/dev/null屏蔽可能出现的噪声输出(如权限提示),再用grep rustpython-test过滤出本次工作流约定使用的容器名rustpython-test。如果容器已在运行,直接跳到第三步执行测试即可,避免重复创建同名容器导致冲突。
第二步:启动容器(若未运行)
container run -d --name rustpython-test -m 8G -c 4 \ --mount type=bind,source="$(pwd)",target=/workspace \ -w /workspace rustpython-dev sleep infinity逐项拆解这条命令:
| 参数 | 含义 |
|---|---|
-d | detached 模式,后台运行容器,终端不被占用 |
--name rustpython-test | 固定容器名,供后续exec/list/rm引用 |
-m 8G | 内存上限 8 GiB,测试套件(尤其test_io、test_codecs这类大模块)对内存有一定需求 |
-c 4 | 分配 4 个 CPU 核心,与-j并行测试可配合使用 |
--mount type=bind,source="$(pwd)",target=/workspace | bind mount 关键点:把当前工作目录(即 RustPython 仓库根目录)挂载到容器内的/workspace |
-w /workspace | 设置容器内工作目录为/workspace |
rustpython-dev | 使用的镜像名 |
sleep infinity | 容器主进程,让容器保持存活等待后续exec命令 |
bind mount 是本工作流最重要的设计:SKILL.md 在 Notes 中明确说明 “The workspace is bind-mounted, so local code changes are immediately available in the container”(工作区是 bind 挂载的,本地代码改动会立即在容器中生效)。这意味着你在宿主机修改的 Rust 源码或Lib/下的 Python 标准库文件,容器内立刻可见,无需重新拷贝镜像;只有 Rust 代码改动需要重新编译(见下方“代码变更后重建”小节)。
第三步:在容器内执行测试命令
container exec rustpython-test cargo run --release -- -m test <test-args><test-args>即参数部分定义的测试命令,例如:
# 运行整个 test_io 模块 container exec rustpython-test cargo run --release -- -m test test_io # 以 verbose 模式运行 test_codecs container exec rustpython-test cargo run --release -- -m test test_codecs -v # 只运行 test_io 中的 test_errors 用例 container exec rustpython-test cargo run --release -- -m test test_io -v -m "test_errors"这条命令背后的调用链值得展开:cargo run --release编译并运行 RustPython 的主程序(入口见 src/main.rs,它通过InterpreterBuilder::new()构建解释器并调用rustpython::run(config));-m test让解释器以模块方式加载 Lib/test/main.py,后者调用test.libregrtest.main.main(_add_python_opts=True)进入 regrtest 测试框架;main()的入口实现在 Lib/test/libregrtest/main.py(Regrtest类,“Execute a test suite”),它会解析命令行选项、按需查找test_*.py文件(findtests.py)、并通过 worker 进程执行测试。
仓库的 AGENTS.md 也印证了这一点,并给出性能建议:snippets 类测试用 debug 模式(cargo run,编译更快);-m test的 unittest 套件用 release 模式(cargo run --release,运行性能更好)。例如:
cargo run --release -- -m test test_unicode # 测试 test_unicode.py cargo run --release -- -m test test_unicode -k test_unicode_escape # 精确到某个函数对应的测试模块确实存在于仓库中,如 Lib/test/test_io.py 与 Lib/test/test_codecs.py。
第四步:汇报结果
测试跑完后,SKILL.md 要求按以下要点汇报:
- 展示通过/失败汇总:包括 expected failures(预期失败,即 CPython 中标记为已知失败或用例,RustPython 复现相同行为)与 unexpected successes(意外成功,即原本预期失败却通过了,通常意味着某个功能刚被实现);
- 突出与 macOS 结果的对比:如果已有 macOS 本机测试结果,重点标出“新增失败”(new failures),即 Linux 容器中失败但在 macOS 上通过的用例——这类差异往往是平台相关行为,而非解释器通用缺陷;
- 不要停止或删除容器:测试结束后容器保持运行状态,供后续多次测试复用。
Notes:容器管理的三条经验
SKILL.md 末尾的 Notes 提供了三条经过实践沉淀的操作约定:
1. 任意容器内命令都用exec包裹
container exec rustpython-test sh -c "..."需要查看文件、安装工具或调试时,统一用container exec rustpython-test sh -c "..."形式执行任意命令,避免绕过容器直接操作。
2. 代码变更后重建
container exec rustpython-test sh -c "cargo build --release"由于 bind mount 只同步源码,Rust 二进制变更必须重新编译才能在容器内生效。改完 Rust 代码后,先在容器内执行 release 构建,再跑测试。
3. 按需停止容器
container rm -f rustpython-test只有用户明确要求时才执行container rm -f rustpython-test强制删除容器。默认策略是保留容器以复用已编译产物——重新构建rustpython-dev镜像和增量编译都很耗时,保留容器能显著缩短后续迭代周期。
完整工作流速查
把四个步骤串联起来,一次完整的 Linux 测试流程如下:
# 1. 检查容器是否在运行 container list 2>/dev/null | grep rustpython-test # 2. 未运行时启动(已运行则跳过) container run -d --name rustpython-test -m 8G -c 4 \ --mount type=bind,source="$(pwd)",target=/workspace \ -w /workspace rustpython-dev sleep infinity # 3. 执行测试 container exec rustpython-test cargo run --release -- -m test test_io -v # 4. 汇报:汇总 pass/fail、expected failures、unexpected successes, # 对比 macOS 结果突出新增失败,容器保持运行 # 重建(仅 Rust 代码变更后需要) container exec rustpython-test sh -c "cargo build --release" # 清理(仅用户明确要求时) container rm -f rustpython-test与 RustPython 常规测试体系的关系
这套容器工作流并非独立于项目,而是 RustPython 多层级测试体系在 macOS 上的 Linux 补位。仓库的整体测试栈包括:
- Rust 层测试:
cargo test --workspace,覆盖 crates/vm 等 Rust crate 的单元测试(AGENTS.md 要求改动后至少运行cargo test --workspace --exclude rustpython_wasm --exclude rustpython-venvlauncher --exclude rustpython-capi); - Python snippets 测试:
extra_tests/snippets/下的脚本,用cargo run -- extra_tests/snippets/builtin_bytes.py或cd extra_tests && pytest -v运行(AGENTS.md); - CPython 移植测试套件:即本文主角,
cargo run --release -- -m test <module>驱动的Lib/test/regrtest 体系,测试文件直接沿用 CPython 的test_*.py命名(如 Lib/test/test_io.py、Lib/test/test_codecs.py),由 Lib/test/libregrtest 这套 runner 调度。
Applecontainer工作流把第三层测试搬到了 Linux 语义环境下执行,让开发者在不离开 macOS 的前提下获得可靠的 Linux 对照基线。整个技能的核心价值可以概括为三点:用 bind mount 实现源码即时同步、用固定容器名与sleep infinity保持可复用会话、用“测试后不删容器”的约定保护昂贵的编译产物。
【免费下载链接】RustPythonA Python Interpreter written in Rust项目地址: https://gitcode.com/GitHub_Trending/ru/RustPython
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考