ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Black 更新日志全景解析:CalVer 版本体系、CHANGES.md 结构与稳定性政策的协同机制

Black 更新日志全景解析:CalVer 版本体系、CHANGES.md 结构与稳定性政策的协同机制 Black 更新日志全景解析:CalVer 版本体系、CHANGES.md 结构与稳定性政策的协同机制【免费下载链接】blackThe uncompromising Python code formatter项目地址: https://gitcode.com/GitHub_Trending/bl/blackBlack(PSF 旗下毫不妥协的 Python 代码格式化器)的版本演进全部沉淀在仓库根目录的 CHANGES.md 中,而 docs/change_log.md 则是将其渲染为官方文档站Change Log页面的入口。本文以这份变更日志为主体,结合仓库中的发布脚本、贡献文档与稳定性政策文档,讲清楚 Black 的版本号如何生成、变更日志各小节如何组织与核对、以及如何基于稳定性政策正确解读每一条条目——读完后你将能独立完成:在升级 Black 前定位相关行为变化、判断某项样式改动属于稳定风格还是预览风格、并按项目规范编写合格的 changelog 条目。docs/change_log.md:一个指向 CHANGES.md 的文档入口docs/change_log.md 本身只有 3 行,全部内容是一个 Sphinx MyST 的 include 指令:{include} ../CHANGES.md 这意味着文档站的 Change Log 页面并不维护独立内容,而是直接内嵌仓库根目录的 CHANGES.md(当前约 2500 行)。这一设计带来两点重要含义:单一事实来源:changelog 只有一处可写位置。任何文档里说的版本变化与 CHANGES.md 不一致的情况,都以 CHANGES.md 为准;链接锚点规范:正因为该文件会被渲染进文档站,条目标题才统一采用## Version X.Y.Z的形式(26.5.0 的 Documentation 小节记录了这个决定,即在 changelog 中使用 Version X.Y.Z 标题以便在 ReadTheDocs 上获得稳定的永久链接锚点),读者可以通过文档站的稳定锚点直接定位某个版本。CHANGES.md 的骨架:Unreleased 模板与版本小节打开 CHANGES.md 可以看到固定的两层结构。顶层:## Unreleased与## Version YY.M.N文件开头(第 3 行)是## Unreleased区块,其下带有一段 HTML 模板注释,提示 PR 作者:Please include the PR number in the changelog entry, not the issue number即条目必须引用 PR 编号而非 issue 编号。每条变更以 PR 编号收尾,例如当前 Unreleased 中的:Add support for NO_COLOR environment variable to disable ANSI output (#5129)--line-ranges no longer inserts an empty line after a docstring when the range covers only the docstring itself (#5312)Unreleased之下是逐版本向下的历史记录,从最近的## Version 26.5.1(约第 215 行)一直追溯到 2018 年的## Version 18.3a0。发布流程文档 docs/contributing/release_process.md 说明了这条时间线的维护方式:发布 GitHub Release 后,post release工作流会打开一个new-changelogPR,把空白的Unreleased模板重新加回 changelog(该 PR 故意不自动合并,以便出问题时重新切发布),并通过update-stable任务把stable分支强推到最新 tag。每个版本下的标准小节从 Unreleased 模板和既有版本条目可以归纳出 Black 的标准小节集合:小节含义### Highlights本版本最重要的、破坏性最大的变化(模板注释提示把特别重大或破坏性的变化放这里)### Stable style影响 Black 稳定代码样式的改动### Preview style影响--preview预览样式的改动### Configuration配置方式的变化(pyproject.toml、命令行、缓存等)### Parser解析器或版本自动检测的变化### Performance性能改进(近年条目显著增多,Unreleased 中即有二十余条)### Output终端输出与错误消息变化### _Blackd_服务端组件 blackd 的改动(如 25.11.0 中实现了 BlackDClient 客户端)### IntegrationsDocker、GitHub Actions、pre-commit、编辑器集成### Documentation文档与政策的重大变化个别版本还会出现临时小节,例如 24.10.0 的### Caching。空小节在切版时会被scripts/release.py自动清除。一个典型的Highlights 叙事示例来自 25.12.0:Black no longer supports running with Python 3.9 (#4842)这类运行环境变化被放在 Highlights 而非普通小节,因为它直接决定用户能否安装运行,阅读 changelog 时应优先扫读每个版本的 Highlights。版本号规范:CalVer 与 YY.M.N发布文档 docs/contributing/release_process.md 明确:Black 遵循 CalVer(日历版本)标准,格式为YY.M.N:YY/M是发布年份与月份,N是该月内的第几次发布;除非当月已有发布,否则N应为0;例如2026 年 1 月的第一次发布 →26.1.0;scripts/release.py会计算这个版本号并打印到 stdout 供复制。从 CHANGES.md 的时间线可以直观验证这套体系:早期为18.3a0、18.9b0(带预发布后缀),2020 起出现20.8b0,2021 起改为21.12b0这类 beta 后缀,而近期版本(23.7.0 之后)基本是不带后缀的正式号。此外,项目根目录的 action.yml、Dockerfile 等发布产物都随该版本号一起更新;25.11.0 的 Packaging 小节就记录了一次修正发布可执行文件中版本号错误的热修复(26.5.1 同样修正了发布可执行文件的版本号),可见版本号被广泛嵌入交付物,出错时会单独切 patch 版。稳定性政策:读懂 Stable style 与 Preview style 分节的关键changelog 之所以要把Stable style与Preview style严格分开,背后是 Black 的稳定性政策(见 docs/the_black_code_style/index.md):若代码已用 Black 格式化过,那么在同一个日历年内的其他版本、使用相同选项再格式化时,输出保持不变。文档中给出的例子是:项目在 2026 年可以安全使用black ~ 26.0;每个日历年的第一个版本可以包含格式化变化,且应尽量最小化,以纳入新 Python 语法带来的改进;--preview与--unstable两个标志不受该政策约束,输出无稳定保证。这条政策与 changelog 的运作是联动的:Stable style 小节 政策保护范围。其中既包含 bug 修复(如修复# fmt: off块前注释被误删),也包含年度风格切换(见下节);Preview style 小节 试验田。--preview的变化不会破坏同一年内的稳定输出承诺;CI 强制执行:贡献文档 docs/contributing/gauging_changes.md 描述了 diff-shades CI——对每个 PR,除了preview-new-changes(用 preview 风格跑一批开源项目并给出 diff 摘要)外,还有assert-no-changes任务,以稳定风格运行,一旦发现格式化输出变化就会让 CI 失败,从而确保同一年内代码不会被反反复复重新格式化。这正是稳定性政策在工程上的落地点。年度风格切换在 changelog 中的样子日历年的第一个版本会把上一年的 preview 特性转正为新的稳定风格,在 changelog 中表现为 Highlights 里的大段列举。从 CHANGES.md 可以读到三次完整实例:23.1.0 — 2023 稳定风格:纳入前一年 preview 的十余项变化(空行处理、冗余括号移除、隐式字符串拼接输出等),并首次从pyproject.toml自动推断受支持的 Python 版本;24.1.0 — 2024 稳定风格:列举了约二十项转正条目(如if-else表达式加括号、长赋值优先在右侧断行、模块 docstring 后强制换行),同时在 Preview style 小节引入了新的--unstable风格与--enable-unstable-feature标志,把已知有问题的特性从 preview 中隔离出去;25.1.0 — 2025 稳定风格:转正列表包含Unicode 转义十六进制统一小写、一致地为带类型参数添加尾随逗号、case 块 if 守卫中的冗余括号处理等,并列出当年新增、此前从未发布的两项(移除独占列表项的括号、泛型函数定义的更优雅折行)。对读者的实用含义:如果项目锁定black ~ 25.0,则 25.x 各版本间样式保证不变;而当 26.1.0 发布时,应重新检查一次 25.1.0 之后的 Preview/Highlights 记录,判断年度切换对本仓库 diff 的影响。版本时间线:从 18.9b0 到 26.5.1 的关键节点不必逐条阅读 2500 行,按里程碑扫描 CHANGES.md 就能把握 Black 的能力演进。以下节点均可在文件中直接定位核对:版本关键变化小节18.9b0早期形态:magic trailing comma、docstring 重缩进、彩色 diff、black-primer回归工具早期条目19.10b0PEP 572 海象运算符、PEP 570 位置-only 参数、black -c命令行格式化—20.8b0显式尾随逗号重新实现、--force-exclude、# fmt: off修复、基于 Hypothesis 的属性模糊测试—23.1.02023 稳定风格;从pyproject.toml推断 target 版本Highlights23.7.0移除 Python 3.7 运行时支持(仍支持格式化 3.7 代码);BLACK_NUM_WORKERS环境变量;新增 PEP 695 语法支持Highlights / Configuration / Parser23.11.0新增--line-ranges命令,只格式化指定行范围Highlights24.1.02024 稳定风格;引入--unstable与--enable-unstable-feature;移除长期弃用的--experimental-string-processingHighlights / Configuration24.3.0修复 Black 首个 CVE(CVE-2024-21503):docstring 中大量前导制表符导致的灾难性性能问题;同时强化 AST 安全检查Highlights / Performance24.4.1支持 Python 3.12 的 PEP 701 f-string 新语法;支持 PEP 696 类型参数默认值Highlights / Parser24.10.0官方测试 Python 3.13 并提供 mypyc 编译 wheel;明确拒绝 Python 3.12.5(上游内存安全问题),要求 3.12.6 或 3.12.4Highlights25.11.0支持 Python 3.14 基础语法与 PEP 750 t-string;--no-cache配置项;blackd 客户端实现Highlights / Configuration25.12.0不再支持 Python 3.9 运行Highlights26.5.0支持 Python 3.15(含 PEP 798 推导式解包、PEP 810 懒加载导入);解析失败返回 HTTP 400 而非 500(blackd)Highlights26.5.1 / Unreleased修复 t-string docstring 误判、# fmt: on前空行保留、NO_COLOR支持、大量针对# fmt: skip/大括号扫描路径的性能优化各小节几个值得注意的模式:安全与兼容性条目集中在 Highlights:如 24.3.0 的 CVE、24.10.0 对 Python 3.12.5 的禁用提示(因上游内存问题会导致 Black 的 AST 安全检查失败,文档建议改用 3.12.6 或 3.12.4)。如果你的部署环境涉及这些 Python 版本,应先于样式条目处理这类信息;Unreleased 中的 Performance 小节反映了当前开发重心:近二十条几乎全部是不再重新扫描整棵树/整行/整个子节点类算法优化(如max_delimiter_priority_in_atom、is_line_short_enough、append_leaves中避免全量重扫),并标注了各自的 PR 编号;条目粒度:每条都是行为 场景示例 PR 编号的三元组,例如 24.2.0 Configuration 中pyproject.toml缺少tool.black节时不再作为项目根依据……monorepo 用户若需保持旧行为,在旧pyproject.toml中添加空的[tool.black]即可——这类带迁移建议的条目对升级决策最有价值。从 changelog 反查仓库:发布流程如何自动维护这份日志changelog 的可信度很大程度来自发布自动化。docs/contributing/release_process.md 给出的完整流程如下,均可对照仓库文件验证:确定版本号:CalVerYY.M.N,由python3 scripts/release.py计算并输出(脚本仅在 Python 3.12 上测试);核对小节归属:确认自上次发布以来的 changelog 条目没有放错小节,文档建议运行git diff origin/stable CHANGES.md与stable分支比对——stable分支正是发布后由update-stable工作流强推到最新 tag 的;提交发布 PR:python3 scripts/release.py会自动完成大部分工作:把## Unreleased标题替换为版本号、删除空小节、更新 docs/integrations/source_version_control.md 与 docs/usage_and_configuration/the_basics.md 中对最新版本的引用;失败时可手工编辑,模板可由脚本直接复制;等 CI 全绿后创建 GitHub Release:tag 目标为main,标题即版本号,描述粘贴该版本的原始 changelog Markdown;发布后:post release工作流中new-changelog重新挂回 Unreleased 模板,update-stable对齐 stable 分支;发布节奏:目标是每 1~2 个月发一次 main 上的一切;除非有严重回归,每月至多一次;理想情况下不跳过 1 月发布,因为按稳定性政策新年第一个版本可改稳定风格,把样式变化收敛在 1 月能保持可预期。此外,diff-shades 的 CI 集成(docs/contributing/gauging_changes.md)在 PR 上自动对比两个 Black 修订版对一批开源项目的格式化差异:PR 触发时基线为PR 基分支最新提交,目标为合入 main 后的 PR 提交;对 main 的推送则以PyPI 最新版为基线。其 HTML/JSON 工件与 PR 评论摘要构成了 changelog 之外、可量化核对某 PR 到底改了什么格式的第二证据链。实战:如何高效使用这份更新日志升级前评估:先读目标版本 Highlights 中的运行环境条款(如 25.12.0 移除 Python 3.9 运行支持、24.10.0 拒绝 3.12.5),再对照 Stable style 判断是否涉及年度风格切换(23.1.0/24.1.0/25.1.0 模式),必要时用black --check --diff在分支上验证;定位行为回归:每条条目都带 PR 编号,从修复 场景 编号的写法可以直接反查对应实现与测试。例如 Unreleased 中保留# fmt: on前紧邻的空行 (#5300)、t-string 不再被当作 docstring (#5287)这类条目,说明当前开发重点在# fmt: skip/off/on指令与 Python 3.14 新语法(t-string,PEP 750)的边界情况;核对配置类变化:Configuration 小节记录了可直接迁移的行为,如 Unreleased 中BLACK_NUM_WORKERS非法值现在报 usage error 而非崩溃、空缓存文件按其他畸形缓存处理等,对 CI 与容器环境(缓存只读/缺失场景)尤为相关;遵循规范写条目:贡献时引用 PR 号而非 issue 号、把条目放进正确小节、重大破坏性变化写入 Highlights,并按 docs/contributing/release_process.md 与 docs/contributing/gauging_changes.md 的流程提交。小结Black 的 CHANGES.md 不只是一份流水账,而是 CalVer 版本规范、稳定/预览双风格、年度稳定性政策与 diff-shades CI 共同作用下的产物:Stable style小节受同年内输出不变的政策与assert-no-changesCI 约束,Preview style小节承载试验特性并在每年 1 月的版本中批量转正为新的稳定风格,Highlights 则汇总了环境支持与安全事故(CVE)等必须优先阅读的信息。掌握这套结构后,无论是锁定black ~ 26.0评估年度风格切换的影响,还是按模板规范撰写一条合格的 changelog 条目,都有了明确的依据与路径。【免费下载链接】blackThe uncompromising Python code formatter项目地址: https://gitcode.com/GitHub_Trending/bl/black创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表