RustPython 标准库同步检查清单:基于 scripts/checklist_template.md 的 CPython Lib 对齐追踪机制
RustPython 标准库同步检查清单基于 scripts/checklist_template.md 的 CPython Lib 对齐追踪机制【免费下载链接】RustPythonA Python Interpreter written in Rust项目地址: https://gitcode.com/GitHub_Trending/ru/RustPythonRustPython 作为用 Rust 实现的 Python 解释器其Lib/目录中的纯 Python 标准库直接复用并同步自 CPython。scripts/checklist_template.md正是这一同步工程的作战地图——它是一份 Jinja2 模板由scripts/generate_checklist.py驱动自动生成一份逐库、逐测试的对齐进度清单含复选框与关联 PR 编号用于追踪哪些标准库模块已从 CPython 迁移、哪些尚未添加、哪些配套测试仍然缺失。读完本文你将理解这套清单的生成原理、四个分类板块的含义、判定已完成/未完成的源码级逻辑以及 RustPython 维护者围绕它搭建的整套update_lib工具链。一、清单要解决什么问题RustPython 与 CPython 的 Lib 同步RustPython 的架构中解释器核心crates/vm用 Rust 实现而大量标准库则以纯 Python 形式存放在仓库根目录的 Lib/ 下例如Lib/json/、Lib/email/、Lib/asyncio/、Lib/pathlib/等这些文件绝大多数直接源自 CPython 的Lib/目录。这种设计带来了一个持续的工程问题CPython 的Lib/随版本不断演进RustPython 需要回答三个问题——哪些模块已经拷贝过来了哪些模块在 RustPython 中尚不存在un-added每个已同步模块对应的 CPython 测试test_*.py是否也同步了过来、并且没有与上游产生 diffchecklist_template.md就是为回答这三个问题而设计的输出模板。它本身不含具体数据而是通过 Jinja2 宏与循环把generate_checklist.py计算出的数据渲染成一份人类可读、机器可解析的 Markdown 进度清单。二、模板结构逐行解析四个板块与一个宏scripts/checklist_template.md全文仅 21 行结构非常精炼。其骨架如下{% macro display_line(i) %}- {% if i.completed True %}[x] {% elif i.completed False %}[ ] {% endif %}{{ i.name }}{% if i.pr ! None %} {{ i.pr }}{% endif %}{% endmacro %} # List of libraries {% for lib in update_libs %}{{ display_line(lib) }} {% endfor %} # List of un-added libraries These libraries are not added yet. Pure python one will be possible while others are not. {% for lib in add_libs %}{{ display_line(lib) }} {% endfor %} # List of tests without python libraries {% for lib in update_tests %}{{ display_line(lib) }} {% endfor %} # List of un-added tests without python libraries {% for lib in add_tests %}{{ display_line(lib) }} {% endfor %}2.1 核心宏display_line清单行的渲染规则模板开头的display_line(i)宏定义了每一行清单条目的渲染规则它接收一个数据对象i输出形如- [x] json #1234的 Markdown 行。逐段拆解其逻辑-Markdown 无序列表前缀{% if i.completed True %}[x] {% elif i.completed False %}[ ] {% endif %}依据completed字段三态输出——True输出勾选[x]False输出未勾选[ ]注意completed为None对应已由 PR 完成但本地产物尚未同步的场景时两个分支都不命中不输出任何复选框这正好对应源码中Output.completed为Optional[bool]的设计详见 scripts/generate_checklist.py{{ i.name }}模块或测试的名称如json、test_abc源码中Output.name是str{% if i.pr ! None %} {{ i.pr }}{% endif %}若关联了 PR 编号如#5736追加输出便于维护者回溯到具体合并请求。2.2 四个数据板块的含义模板通过 Jinja2 循环遍历四组列表分别渲染四个板块板块标题遍历变量含义典型条目# List of librariesupdate_libsCPythonLib/下已存在于 RustPython的模块/文件- [x] json、- [ ] abc# List of un-added librariesadd_libsCPythonLib/下尚未添加到 RustPython 的模块- [ ] tomllib# List of tests without python librariesupdate_testsCPythonLib/test/下已存在于 RustPython的测试文件- [ ] test_ast# List of un-added tests without python librariesadd_testsCPythonLib/test/下尚未添加的测试文件- [ ] test_zipfile注意 un-added 板块上方还有一句说明These libraries are not added yet. Pure python one will be possible while others are not.——即未添加的库中纯 Python 实现的模块未来可以移植而依赖 C 扩展的模块则暂时不可行。这一判断对应了 RustPython 生态的现实约束Rust 侧只有用纯 Python 或 Rust 原生重写的能力无法直接链接 CPython 的 C 扩展。三、数据从哪来generate_checklist.py 的完整数据流模板本身只是壳真正的计算逻辑全部在 scripts/generate_checklist.py 中。整条流水线可以分为五个阶段。3.1 命令行参数脚本使用argparse定义了两个参数--cpython必填pathlib.Path指向 CPython 源码根目录的路径用于读取其Lib/与Lib/test/作为比对基准--notes可选pathlib.Path指向备注文件即仓库中的 scripts/notes.txt用于把模块与相关说明、关联 issue 关联起来。启动后脚本还会做路径校验--cpython必须存在且为目录若不是绝对路径则用.resolve()转为绝对路径见 scripts/generate_checklist.py而 RustPython 侧的Lib/则通过pathlib.Path(__file__).parent.parent / Lib定位——即与脚本所在目录scripts/平级的仓库根目录下的Lib/这保证了脚本无论从何处执行都能找到正确的本地库目录。3.2 已更新库的状态来源GitHub issue #5736脚本通过两个 GitHub REST API 调用获取哪些库已被 PR 更新过get_updated_libs()拉取issue #5736的正文scripts/generate_checklist.pyissue 正文中每行形如- libname #PR编号的列表被解析为dict[str, LibUpdate]check_pr(pr_id)对每个 PR 编号调用/pulls/{id}接口检查merged_at字段是否为None从而判断该 PR 是否已合并scripts/generate_checklist.py。LibUpdate是一个仅含两个字段的 dataclasspr关联 PR 编号可空与done是否已合并默认True。issue 正文行的解析规则是去掉-前缀后按空格切分每行最多两个 token模块名 可选 PR 号多余则触发断言失败见 scripts/generate_checklist.py。3.3 Lib 与 test 的枚举规则脚本遍历 CPython 的Lib/与Lib/test/两个目录遵循严格的过滤规则顶层目录与*.py文件都会被计入libs列表但显式忽略__pycache__和test常量ignored_objs见 scripts/generate_checklist.py对Lib/test/下的条目仅收录名称以test_开头、且不是已有对应库的测试即test_foo.py的foo不在libs中时才会进入tests列表——这正是模板中 tests without python libraries没有对应 Python 库的测试这一标题的由来。例如test_ast.py对应库ast已存在就不会被算作无库测试。3.4 完成度判定difflib 统一 diff 作为是否同步的硬标准对每个模块/测试脚本用difflib.unified_diff逐行比较 RustPython 与 CPython 的对应文件若 diff 行数大于 0 或读取出现UnicodeDecodeError即判定为未完成见check_diffscripts/generate_checklist.py。两条核心判定函数check_lib_completion(rustpython_path, cpython_path)一个库只有在它自己的文件与 CPython 完全一致、且它对应的test_库名.py也完整同步时才算完成scripts/generate_checklist.py——库与其测试是捆绑验收的check_test_completion测试文件必须同时存在于两侧且 diff 为空才算完成scripts/generate_checklist.py。此外还有一个优先级逻辑如果 issue #5736 中记录了某库已由已合并 PR 完成completedTrue且pr非空则该条目即使本地尚未同步也会被归入update_libs而不是add_libsscripts/generate_checklist.py保证 PR 完成与本地落盘之间的窗口期不会造成清单误判。3.5 备注notes机制与模板渲染--notes指定的备注文件如 scripts/notes.txt格式为每行模块名 备注内容//开头的行为注释行。脚本将其解析为dict[str, list[str]]并在渲染时通过handle_notes把对应备注附着到条目上scripts/generate_checklist.py未被任何模块消费的备注会在结束时以Unattached Note警告形式输出scripts/generate_checklist.py防止备注悬空。最后脚本用jinja2.Environment(loaderFileSystemLoader(.))加载当前目录下的checklist_template.md把四个列表update_libs、add_libs、update_tests、add_tests渲染进模板并打印到标准输出scripts/generate_checklist.py。四、notes.txt维护者沉淀的同步知识库scripts/notes.txt 是清单生成时默认使用的备注文件其中沉淀了大量无法用代码表达的同步经验格式为模块名 备注。典型条目包括关联 PR / issue如ctypes #5572、importlib #4565、warnings #4013需要额外拷贝的附属文件如re Dont forget sre files提示re模块还要带上sre_compile.py、sre_constants.py、sre_parse.py、site Dont forget _sitebuiltins.py、pydoc pydoc_data替代实现文件如abc _collections_abc.py、datetime _pydatetime.py、io _pyio.py——这些是 RustPython 用纯 Python 重写的 CPython C 实现模块阻塞性说明如os Blocker: Some tests requires async comprehension关联测试文件如pickle test/pickletester.py supports test_pickle.py。值得注意的是文件末尾用// test分节//行在解析时会被跳过见 scripts/generate_checklist.py其后test_*前缀的条目对应测试类备注如test_gc #4158、test_mmap #3847这些备注最终会挂到测试板块的对应条目上。五、配套工具链update_lib 从看清单到动手同步清单回答缺什么而 scripts/update_lib/ 工具包回答怎么补。这是一个以python scripts/update_lib command形式调用的多子命令 CLI入口见 scripts/update_lib/main.py与清单模板构成完整的同步工作流子命令用途示例quick推荐的一键流程打补丁 自动标记失败python scripts/update_lib quick cpython/Lib/test/test_foo.pycopy-lib从 CPython 拷贝库文件/目录先删除本地旧文件python scripts/update_lib copy-lib cpython/Lib/dataclasses.pymigrate从 CPython 迁移测试文件保留 RustPython 的标记python scripts/update_lib migrate cpython/Lib/test/test_foo.pypatches补丁管理在文件间提取/应用补丁python scripts/update_lib patches --from Lib/test/foo.py --to cpython/Lib/test/foo.pyauto-mark运行测试并自动给失败项打expectedFailurepython scripts/update_lib auto-mark Lib/test/test_foo.pydeps展示模块依赖信息python scripts/update_lib depstodo展示按优先级排序的待更新模块/测试列表python scripts/update_lib todo --limit 20其中todo命令与清单模板的理念一脉相承它依据DEPENDENCIES关系计算依赖评分——无纯 Python 依赖的模块得分-1有依赖的按未更新的依赖数量计分排序优先级依次为被依赖数越多越靠前、原生依赖越少越靠前见 scripts/update_lib/cmd_todo.py测试则按对应库是否已就绪分为 0库已就绪可立即更新、1无对应库、2需先等库三档scripts/update_lib/cmd_todo.py。输出格式与模板保持一致的- [x]/- [ ]复选框风格并附带依赖数、被依赖数、最近更新时间与 diff 行数等元信息。todo输出还包含两个额外板块Untracked Files存在于 CPython 但本地Lib/缺失的非模块文件如数据文件与Original Files本地Lib/中存在但 CPython 没有的 RustPython 原创文件如_dummy_thread.py进一步补全了清单模板的四板块覆盖范围。六、互补机制whats_left.py 与 not_impl.py 的覆盖度审计除了逐库同步清单仓库还提供了另一层API 级覆盖度审计scripts/whats_left.py 会在 CPython 3.14 下运行遍历 CPython 的 builtins 方法、标准库模块生成一份包含expected_methods、cpymods、libdir的数据文件extra_tests/not_impl.py再用 RustPython 自身cargo run --release执行该文件对比双方整个模块缺失 →not_implemented模块存在但导入失败 →failed_to_import模块属性缺失 →missing_items函数签名不匹配 →mismatched_items需--signature参数展示__doc__不一致 →mismatched_doc_items需--doc参数展示。最终输出按# modules、# builtin items、# stdlib items分组打印并附带# summary统计见 scripts/whats_left.py。如果说checklist_template.md追踪的是文件级同步whats_left.py追踪的就是API 级对齐两者从不同粒度共同支撑 RustPython 标准库的兼容性评估。七、实战如何阅读与使用这份清单7.1 生成清单在仓库根目录执行需先准备一份 CPython 源码并安装requests、jinja2依赖python scripts/generate_checklist.py --cpython /path/to/cpython --notes scripts/notes.txt脚本依赖 GitHub API 读取 issue #5736 与 PR 合并状态网络不可用时相关状态会回退为本地 diff 判定。7.2 解读输出生成结果的四个板块对应模板的四段List of libraries[x]表示该库文件及对应测试与 CPython 完全一致[ ]表示仍存在 diff 或测试缺失行尾的#编号是对应的已合并 PRList of un-added librariesCPython 有而 RustPython 没有的模块纯 Python 的可期移植依赖 C 扩展的短期内不可行List of tests without python libraries已同步的、没有对应库的独立测试List of un-added tests without python libraries尚未同步的独立测试。7.3 从清单到行动对照清单找到[ ]条目后即可进入update_lib工作流先todo看优先级 →copy-lib拉取缺失文件 →quick打补丁 自动标记失败项→ 用patches管理对 CPython 文件的 RustPython 定制修改完成后重新运行generate_checklist.py验证该条目是否变为[x]。整个过程与 scripts/checklist_template.md 定义的四板块状态机一一对应构成 RustPython 标准库同步工程的完整闭环。【免费下载链接】RustPythonA Python Interpreter written in Rust项目地址: https://gitcode.com/GitHub_Trending/ru/RustPython创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联
返回资讯列表 →