black没有插件机制,所有格式化逻辑硬编码,不支持自定义风格;所谓“插件”实为外部包装脚本或独立工具,需通过pre-commit等编排调用。

black 插件机制根本不存在
Black 没有插件系统,也不支持自定义风格。所谓“black 插件”是常见误解——它不提供 register_formatter、add_transform 或任何钩子函数。你无法通过 pip install 一个包就让 black 把 if x: y() 格式化成多行,或把括号对齐方式改成 Google 风格。
它的设计哲学就是「只有一种正确格式」,所有格式化逻辑硬编码在 lib2to3 改写器和 format_str 主流程里。想改风格?只能 fork 仓库、改源码、自己维护分支。
为什么 black 不开放 style API
Black 团队明确拒绝风格配置项,连 --line-length 都曾被质疑是否破坏一致性。他们认为:可配置项会带来碎片化、降低跨项目可读性、增加测试负担。这不是技术限制,而是立场选择。
所以你看到的「black 插件」项目,实际只有两类:
- 基于 black 的包装脚本(比如先用 black 格式化,再用 sed 替换引号)
- 完全独立的 formatter(如 flynt 或 pyupgrade),只是和 black 一起被调用
它们都不影响 black 自身输出,也不被 black 加载或识别。
立即学习“Python免费学习笔记(深入)”;
替代方案:用 pre-commit + 多工具链
真要实现「black 后再做风格微调」,得靠外部编排。常见组合是:pre-commit + 多个 hook:
-
black:负责基础结构(缩进、空行、操作符换行) -
isort:调整 import 排序(black 不管这个) -
pycln:自动删未使用 import(black 不处理语义) - 自定义脚本:比如用
ast解析后重写字符串字面量引号类型
注意:black 输出必须是最终输入给后续工具的源码——不能依赖它“留出接口”。例如,你想强制单引号,就得在 black 运行完立刻跑 unify 或自己写个 fix_quotes.py 脚本处理 .py 文件。
fork black 后修改的关键位置
如果非改不可,核心改动点很集中:
- 行宽控制:修改
DEFAULT_LINE_LENGTH常量(在src/black/__init__.py) - 引号偏好:搜
preferred_quote,定位到strings.py中的normalize_string_quotes - 括号换行策略:看
nodes.py里的maybe_split_elif和maybe_split_comma类方法 - 测试必须全过:
pytest tests/test_format.py—— black 对 AST 等价性极其敏感,小改动极易触发AssertionError: AST mismatch
每次 upstream 更新都得手动 merge 冲突,特别是 mode.py 和 linegen.py 这两块,重构频繁。别低估维护成本。
真正难的不是改某一行代码,而是守住「改完还能叫 black 吗」这条线——一旦加了开关、配了规则、允许用户选风格,你就已经不在 black 的世界里了。










