ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Black 报 “INTERNAL ERROR: Black produced code that is not equivalent to the source“ 怎么排查

Black 报 “INTERNAL ERROR: Black produced code that is not equivalent to the source“ 怎么排查 Black 报 INTERNAL ERROR: Black produced code that is not equivalent to the source 怎么排查【免费下载链接】blackThe uncompromising Python code formatter项目地址: https://gitcode.com/GitHub_Trending/bl/black当你用 Black 格式化某个 Python 文件时如果终端出现下面这样的报错说明 Black 拒绝了这次格式化error: cannot format test.py: INTERNAL ERROR: Black produced code that is not equivalent to the source. Please report a bug on https://github.com/psf/black/issues. This diff might be helpful: /tmp/blk_kjdr1oog.log Oh no! 1 file would fail to reformat.这篇文章基于 Black 仓库中的文档和源码说明这条报错的来龙去脉、错误信息里各部分分别是什么以及按文档能走的排查与上报路径。这条报错是怎么产生的Black 默认运行在--safe模式下格式化之后它会把源码的 AST抽象语法树和格式化结果的 AST 逐行字符串化后对比要求二者语义等价。这个安全检查是 Black 的默认行为可以用--fast关闭、用--safe显式开启见 The basics ---fast/--safeBy default,Blackperforms an AST safety check after formatting your code. The--fastflag turns off this check and the--safeflag explicitly enables it.该检查的实现位于 src/black/init.py 的assert_equivalent函数它先解析源文件和格式化结果的 AST再把两者转成字符串比较。一旦不一致就会把「源 AST 与结果 AST 的 diff」写进一个临时文件然后抛出你看到的那条INTERNAL ERROR并附上 Black 版本与 Python 运行时信息_black_info()返回Black 版本 on Python (实现) 版本。需要注意AST 对比并不是「零容忍」。当前风格的说明文档 列出了三种被明确允许的 AST 差异这些情况不会触发本错误docstring 的前后空白清理与重新缩进del语句外层可选括号的处理解释器层面语义等价注释包括 Python 3.8 起属于 AST 的 type comments被移动位置。所以报出INTERNAL ERROR时差异已经超出了这些已知例外属于 Black 自己应当避免的内部问题。读懂报错信息里的三部分对照上面的示例输出错误消息包含三部分排查时按这个顺序看出问题的文件cannot format test.py指明是哪个文件没能通过安全检查。版本信息完整报错里带有Black 版本 on Python (实现) 版本由_black_info()生成见 src/black/init.py。这是复现和上报 bug 的关键环境信息记录你的 Black 版本和 Python 版本。诊断 diff 文件This diff might be helpful: /tmp/blk_kjdr1oog.log中的路径示例中的/tmp/blk_kjdr1oog.log是文档给出的示例结果你的路径每次不同指向源码 AST 与格式化结果 AST 的对比。查看这个文件能看出具体是哪一段代码在 AST 层面发生了变化。另外可以确认源文件没有被修改。FAQ「Is Black safe to use?」 明确写道安全检查发现问题时会抛出错误文件保持原样an error is raised and the file is left untouched。所以不需要回滚直接处理即可。用--check在 CI 中识别这类错误如果你在 CI 或脚本里跑 Black可以用--check让 Black 只检查不落盘此时内部错误会以退出码 123 体现见 The basics ---check退出码 0没有任何文件需要变更退出码 1有文件会被重新格式化退出码 123发生了内部错误即本文这类问题。文档中的示例输出注意其中的报错行即本文错误$ black test.py --check error: cannot format test.py: INTERNAL ERROR: Black produced code that is not equivalent to the source. Please report a bug on https://github.com/psf/black/issues. This diff might be helpful: /tmp/blk_kjdr1oog.log Oh no! 1 file would fail to reformat. $ echo $? 123也就是说脚本中用$?或等价的退出码判断拿到 123就能确定是内部错误而不是普通的「需要重排」可以据此在 CI 中单独告警。官方给出的处理路径这条错误消息本身就指明了 Black 认为正确的处理流程把该问题作为 bug 上报并附上那个 diff 文件。结合文档中已给出的事实上报时值得包含的内容是出问题的源文件内容或最小可复现代码报错中的 Black 版本与 Python 版本信息报错里给出的那个临时 diff 文件/tmp/blk_*.log形式内容是源 AST 与结果 AST 的差异。错误消息中的上报地址是 GitHub 项目 issue 入口见 docs/usage_and_configuration/the_basics.md 示例原文。可选项--fast跳过安全检查如果你只是想绕过这个检查继续拿到格式化结果文档记录的开关是--fast它关闭格式化后的 AST 安全检查。需要留意两点这个检查是 Black 的核心保障风格文档 明确表示它是一项重要特性且没有放松的计划所以--fast只是跳过验证并不表示差异无风险跳过检查后退出码 123 对应的这条内部错误不会在--check流程中因等价性失败出现是否适合在你的流程中使用需要自行权衡。小结排查动作清单确认源文件未被改动无需回滚FAQ 明确文件在报错时保持原样。记下报错中的 Black 版本、Python 版本并打开报错给出的/tmp/blk_*.logdiff 文件定位 AST 差异对应的代码段。在 CI 中用black --check配合退出码 123 监控这类内部错误。按错误消息指引把源文件、版本信息和 diff 文件作为 bug 报告附上。仅在需要继续拿到格式化结果时考虑--fast并理解它只是关闭安全验证。参考文档The basics、FAQ、当前风格的 AST 检查说明以及报错实现 src/black/init.py。【免费下载链接】blackThe uncompromising Python code formatter项目地址: https://gitcode.com/GitHub_Trending/bl/black创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进