最具妥协性的代码格式化工具。
项目描述
最具妥协性的代码格式化工具
“任何你喜欢的颜色。”
Black 是最具妥协性的 Python 代码格式化工具。通过使用它,你同意放弃对手动格式化的细节控制。作为回报,Black 会给你速度、确定性和摆脱 pycodestyle
对格式化的唠叨。你可以节省时间和精神能量,用于更重要的任务。
无论你阅读哪个项目,Blackened 代码看起来都一样。格式化在一段时间后变得透明,你可以专注于内容。
Black 通过产生尽可能小的差异来使代码审查更快。
现在就试用 Black 操场。观看 PyCon 2019 演讲 了解更多信息。
目录: 安装和用法 | 代码风格 | 实用主义 | pyproject.toml | 编辑器集成 | blackd | 版本控制集成 | 忽略未修改的文件 | 已使用 | 客户评价 | 展示你的风格 | 贡献 | 变更日志 | 作者
安装和用法
安装
Black 可以通过运行 pip install black
来安装。它需要 Python 3.6.0+ 来运行,但也可以用它格式化 Python 2 代码。
用法
要立即开始使用,使用合理的默认值
black {source_file_or_directory}
命令行选项
Black 不提供很多选项。您可以通过运行 black --help
来列出它们
black [OPTIONS] [SRC]...
Options:
-c, --code TEXT Format the code passed in as a string.
-l, --line-length INTEGER How many characters per line to allow.
[default: 88]
-t, --target-version [py27|py33|py34|py35|py36|py37|py38]
Python versions that should be supported by
Black's output. [default: per-file auto-
detection]
--py36 Allow using Python 3.6-only syntax on all
input files. This will put trailing commas
in function signatures and calls also after
*args and **kwargs. Deprecated; use
--target-version instead. [default: per-file
auto-detection]
--pyi Format all input files like typing stubs
regardless of file extension (useful when
piping source on standard input).
-S, --skip-string-normalization
Don't normalize string quotes or prefixes.
--check Don't write the files back, just return the
status. Return code 0 means nothing would
change. Return code 1 means some files
would be reformatted. Return code 123 means
there was an internal error.
--diff Don't write the files back, just output a
diff for each file on stdout.
--fast / --safe If --fast given, skip temporary sanity
checks. [default: --safe]
--include TEXT A regular expression that matches files and
directories that should be included on
recursive searches. An empty value means
all files are included regardless of the
name. Use forward slashes for directories
on all platforms (Windows, too). Exclusions
are calculated first, inclusions later.
[default: \.pyi?$]
--exclude TEXT A regular expression that matches files and
directories that should be excluded on
recursive searches. An empty value means no
paths are excluded. Use forward slashes for
directories on all platforms (Windows, too).
Exclusions are calculated first, inclusions
later. [default: /(\.eggs|\.git|\.hg|\.mypy
_cache|\.nox|\.tox|\.venv|_build|buck-
out|build|dist)/]
-q, --quiet Don't emit non-error messages to stderr.
Errors are still emitted, silence those with
2>/dev/null.
-v, --verbose Also emit messages to stderr about files
that were not changed or were ignored due to
--exclude=.
--version Show the version and exit.
--config PATH Read configuration from PATH.
-h, --help Show this message and exit.
Black 是一个行为良好的 Unix 风格的命令行工具
- 如果没有传递源代码,则它不会做任何事情;
- 如果使用
-
作为文件名,则从标准输入读取并写入标准输出; - 它只将消息输出到标准错误;
- 除非发生内部错误(或使用了
--check
),否则退出代码为 0。
注意:这是一个测试版产品
Black 已经被许多项目成功使用,从小型到大型。它还拥有一个不错的测试套件。然而,它仍然非常新。事情可能还会有一段时间不稳定。这通过“Beta”分类器以及版本号中的“b”来明确指出。这意味着,在格式化器变得稳定之前,您应该预计将来可能会有一些格式化更改。尽管如此,没有计划进行重大的风格更改,主要是对错误报告的反应。
此外,作为一种临时安全措施,Black 将检查重格式化后的代码是否仍然生成与原始代码等效的有效 AST。这会减慢其速度。如果您感到自信,请使用 --fast
。
Black 代码风格
Black 在原地重格式化整个文件。它不可配置。它不考虑以前的格式。它不会重格式化以 # fmt: off
开头并以 # fmt: on
结尾的块。 # fmt: on/off
必须位于相同的缩进级别。它还识别 YAPF 的具有相同效果的块注释,作为对跨代码的礼貌。
Black 如何包装行
Black 忽略以前的格式,并将均匀的水平和垂直空白应用于您的代码。水平空白规则可以总结为:做任何能让 pycodestyle
满意的事情。由 Black 使用的编码风格可以看作是 PEP 8 的一个严格子集。
至于垂直空白,Black 尝试将每个完整的表达式或简单语句渲染到一行。如果这适合分配的行长度,那就太好了。
# in:
j = [1,
2,
3
]
# out:
j = [1, 2, 3]
如果不适合,Black 将查看第一个外匹配括号的第一个内容,并将其放在单独的缩进行中。
# in:
ImportantClass.important_method(exc, limit, lookup_lines, capture_locals, extra_argument)
# out:
ImportantClass.important_method(
exc, limit, lookup_lines, capture_locals, extra_argument
)
如果仍然不符合要求,它将使用相同的规则进一步分解内部表达式,每次缩进匹配的括号。如果匹配括号对的内容是逗号分隔的(如参数列表、字典字面量等),则Black将首先尝试将它们放在与匹配括号相同的行上。如果这样不行,它将把它们全部放在单独的行上。
# in:
def very_important_function(template: str, *variables, file: os.PathLike, engine: str, header: bool = True, debug: bool = False):
"""Applies `variables` to the `template` and writes to `file`."""
with open(file, 'w') as f:
...
# out:
def very_important_function(
template: str,
*variables,
file: os.PathLike,
engine: str,
header: bool = True,
debug: bool = False,
):
"""Applies `variables` to the `template` and writes to `file`."""
with open(file, "w") as f:
...
你可能已经注意到,关闭括号总是缩进的,并且总是添加一个尾随逗号。这种格式产生的diff更小;当你添加或删除一个元素时,总是只有一行。此外,关闭括号缩进提供了一个清晰的分隔符,用于分隔两个具有相同缩进级别的不同代码部分(如上面示例中的参数列表和文档字符串)。
如果数据结构字面量(元组、列表、集合、字典)或“from”导入的行无法适应分配的长度,它将始终拆分为每行一个元素。这减少了diff,并使代码的阅读者能够找到引入特定条目的提交。这也使Black与以下配置兼容isort。
兼容的`.isort.cfg`
[settings]
multi_line_output=3
include_trailing_comma=True
force_grid_wrap=0
use_parentheses=True
line_length=88
等效的命令行是
$ isort --multi-line=3 --trailing-comma --force-grid-wrap=0 --use-parentheses --line-width=88 [ file.py ]
行长度
你可能已经注意到默认的行长度很奇怪。Black默认为每行88个字符,这恰好比80多10%。这个数字被发现比坚持80(最受欢迎的)或甚至79(由标准库使用)产生更短的文件。一般来说,90左右看起来是明智的选择。
如果你按行数付费,你可以使用更低的数字传递--line-length
。Black将尝试尊重这一点。然而,有时它无法在不违反其他规则的情况下做到这一点。在这些罕见的情况下,自动格式化的代码将超过你的分配限制。
你也可以增加它,但请记住,视力障碍人士发现处理超过100个字符的行长度更困难。它还会对典型屏幕分辨率的并排diff审查产生不利影响。长行还使在文档或讲演幻灯片中整齐地呈现代码更困难。
如果你使用Flake8,可以将max-line-length
增加到88并忘记它。或者,使用Bugbear的B950警告代替E501,并将最大行长度保持在80,这可能是你已经在使用的。你可以这样做
[flake8]
max-line-length = 80
...
select = C,E,F,W,B,B950
ignore = E203, E501, W503
你将发现Black自己的.flake8配置文件配置如下。有关禁用W503和E203的原因的解释可以在本文档的更后面找到。如果你对B950背后的推理感兴趣,请参阅Bugbear的文档。简要地说,“就像高速公路限速一样,我们不会因为超过了几公里/小时而打扰你”。
如果你正在寻找一个最小化、兼容Black的flake8配置
[flake8]
max-line-length = 88
extend-ignore = E203
空行
Black避免不必要的垂直空白。这符合PEP 8的精神,PEP 8说函数内的垂直空白应仅少量使用。
Black将在函数内允许单个空行,以及在模块级别上由原始编辑器留下的单个和双空行,除非它们在括号表达式中。由于此类表达式总是被重新格式化以适应最小空间,因此此类空白会丢失。
它还会在函数定义前后插入适当的间距。在内部函数前后为一行,在模块级函数和类前后为两行。Black不会在函数/类定义和紧跟在给定函数/类前面的独立注释之间放置空行。
Black 将强制在类级别的文档字符串和第一个后续字段或方法之间使用单空行。这符合 PEP 257。
Black 不会在函数文档字符串后插入空行,除非由于内部函数紧接着开始而需要该空行。
尾随逗号
Black 将为用逗号分隔的表达式添加尾随逗号,其中每个元素都在其自己的行上。这包括函数签名。
如果表达式适合一行,则移除不必要的尾随逗号。这使得您的行超出指定的行长度限制的可能性降低1%。此外,在这种情况下,如果您在调用中添加了另一个参数,您很可能仍然会将其放入同一行。这不会使差异变得更大。
移除尾随逗号的一个例外是只有一个元素的元组表达式。在这种情况下,Black 不会触摸单个尾随逗号,因为这会意外地改变底层的数据类型。请注意,这也是当在索引时使用逗号时的情况。这是一个伪装成元组的元组:numpy_array[3, ]
。
添加尾随逗号的一个例外是包含 *
、*args
或 **kwargs
的函数签名。在这种情况下,只有在 Python 3.6 上才安全地使用尾随逗号。如果您的文件已经是 3.6+,Black 将会在这种情况下使用尾随逗号。如果您想知道它是如何知道的,它会查找 f-strings 和具有星号的函数签名中现有的尾随逗号的使用。换句话说,如果您想在这种情况下使用尾随逗号,而 Black 没有识别到它是安全的,请手动添加它,Black 将保留它。
字符串
Black 倾向于使用双引号("
和 """
),而不是单引号('
和 '''
)。只要它不会导致比之前更多的反斜杠转义,它将用后者替换前者。
Black 还将字符串前缀标准化,使其始终为小写。除此之外,如果您的代码已经是 Python 3.6+ 或使用了 unicode_literals
未来的导入,Black 将从字符串前缀中删除 u
,因为在这些场景中它是无意义的。
标准化为单一引号形式的主要原因是美学。在所有地方使用一种引号可以减少读者的干扰。它还将使 Black 的未来版本能够合并最终在同一行结束的连续字符串字面量(有关详细信息,请参阅 #26)。
为什么选择双引号?它们预见了英文文本中的撇号。它们与 PEP 257 中描述的文档字符串标准相匹配。双引号中的空字符串(""
)不可能与一个双引号混淆,无论使用的字体和语法高亮显示如何。除此之外,字符串的双引号与 C 语言保持一致,而 Python 与 C 语言有很多交互。
在像美国英语这样的键盘布局中,输入单引号比输入双引号要容易一些。后者需要使用 Shift 键。我的建议是继续使用您打字更快的内容,让 Black 处理转换。
如果您正在将 Black 应用于具有现有字符串约定(如流行的 "数据使用单引号,人类可读字符串使用双引号")的大型项目,您可以在命令行上传递 --skip-string-normalization
。这旨在作为采用辅助工具,避免在新项目中使用此选项。
数字字面量
Black 将大多数数字字面量标准化,以小写字母表示语法部分,以大写字母表示数字本身:0xAB
而不是 0XAB
,以及 1e10
而不是 1E10
。Python 2的长字面量以 2L
的形式表示,而不是 2l
,以避免 l
和 1
之间的混淆。
换行符与二元运算符
Black 在将代码块拆分为多行时,会在二元运算符之前换行。这是为了让 Black 符合最近更改的 PEP 8 风格指南,该指南强调这种方法可以改善可读性。
此行为可能会在像Flake8这样的风格指南执行工具中引发 W503 line break before binary operator
警告。由于 W503
不符合PEP 8规范,您应该告诉Flake8忽略这些警告。
切片
PEP 8 建议将切片中的 :
视为具有最低优先级的二元运算符,并在两侧留出相同数量的空格,除非省略参数(例如,ham[1 + 1 :]
)。它还指出,对于扩展切片,两个 :
运算符都必须有相同数量的空格,除非省略参数(ham[1 + 1 ::]
)。Black 一致地强制执行这些规则。
此行为可能会在像Flake8这样的风格指南执行工具中引发 E203 whitespace before ':'
警告。由于 E203
不符合PEP 8规范,您应该告诉Flake8忽略这些警告。
括号
Python语法中某些括号是可选的。任何表达式都可以包裹在一对括号中,形成一个原子。有一些有趣的情况
if (...)
while (...)
for (...) in (...)
assert (...), (...)
from X import (...)
- 类似以下赋值
target = (...)
target: type = (...)
some, *un, packing = (...)
augmented += (...)
在这些情况下,如果整个语句适合一行,或者内部表达式没有其他分隔符可以进一步拆分,则可以删除括号。如果只有一个分隔符,并且表达式以括号开始或结束,则括号也可以成功省略,因为现有的括号对无论如何都会整齐地组织表达式。否则,将添加括号。
请注意,Black 不会添加或删除任何额外的嵌套括号,这些括号可能对清晰度或进一步的代码组织有用。例如,这些括号不会被删除
return not (this or that)
decision = (maybe.this() and values > 0) or (maybe.that() and values < 0)
调用链
一些流行的API,如ORM,使用调用链。这种API样式被称为 流畅接口。 Black 通过将调用或索引操作后面的点视为一个非常低优先级的分隔符来格式化这些接口。更容易通过示例来展示这种行为。看看这个例子
def example(session):
result = (
session.query(models.Customer.id)
.filter(
models.Customer.account_id == account_id,
models.Customer.email == email_address,
)
.order_by(models.Customer.id.asc())
.all()
)
类型存根文件
PEP 484描述了Python中类型提示的语法。类型提示的用例之一是为无法直接包含类型注解的模块提供类型注解(它们可能用C编写,或为第三方,或它们的实现可能过于动态,等等)。
为了解决这个问题,可以使用具有 .pyi
扩展名的 stub 文件 来描述外部模块的类型信息。这些stub文件省略了它们所描述的类和函数的实现,而是只包含文件的结构(列出全局变量、函数和类及其成员)。这些文件的推荐代码风格比PEP 8更简洁
- 推荐将
...
放在类/函数签名同一行上; - 避免在连续的模块级函数、名称或方法之间以及单个类内的字段之间使用垂直空白;
- 在顶级类定义之间使用单个空行,或者如果类非常小,则不需要空行。
Black 强制执行上述规则。还有一些关于格式化 .pyi
文件的额外指南,目前尚未强制执行,但可能在格式化器的未来版本中实施。
- 所有函数体应该是空的(使用
...
代替正文); - 不要使用文档字符串;
- 优先使用
...
而不是pass
; - 对于具有默认值的参数,使用
...
代替实际默认值; - 避免在类型注解中使用字符串字面量,stub文件支持原生的向前引用(类似于Python 3.7代码中的
from __future__ import annotations
); - 即使对于针对旧版本Python的stub,也使用变量注解而不是类型注释;
- 对于默认为
None
的参数,明确使用Optional[]
; - 使用
float
而不是Union[int, float]
。
实用主义
Black 的早期版本在某些方面是绝对主义者。它遵循其初始作者的风格。在当时,这是可以接受的,因为它使实现变得简单,而且用户并不多。没有报告很多边缘情况。作为一个成熟的工具,Black 对其通常持有的规则做一些例外。本节记录了这些例外是什么以及为什么是这样。
神奇的尾随逗号
Black 通常不考虑现有的格式。
然而,在某些情况下,你可能在代码中放入了一个短集合或函数调用,但你预计它将来会增长。
例如
TRANSLATIONS = {
"en_us": "English (US)",
"pl_pl": "polski",
}
Black 的早期版本曾经无情地将这些合并为一行(它适合!)。现在,你可以通过自己放置尾随逗号来传达你不想这样做。当你这样做时,Black 将知道始终将你的集合展开为一行一个项目。
如何停止这样做?只需删除那个尾随逗号,如果适合的话,Black 将将你的集合合并为一行。
r"strings" 和 R"strings"
Black 规范化了字符串引号以及字符串前缀,使它们变为小写。这个规则的例外是 r-字符串。事实证明,非常流行的 MagicPython 语法高亮器,默认由 GitHub 和 Visual Studio Code 等使用,区分 r-字符串和 R-字符串。前者被语法高亮为正则表达式,而后者被视为真正的原始字符串,没有任何特殊含义。
pyproject.toml
Black 能够从 pyproject.toml
文件中读取其命令行选项的项目特定默认值。这对于指定项目的自定义 --include
和 --exclude
模式特别有用。
技巧:如果你在问自己“我需要配置什么?”答案是“不需要”。Black 是关于合理默认值。
什么是 pyproject.toml
文件?
PEP 518 定义了 pyproject.toml
作为存储 Python 项目构建系统要求的配置文件。借助像 Poetry 或 Flit 这样的工具,它可以完全替代 setup.py
和 setup.cfg
文件的需求。
Black 在哪里寻找文件
默认情况下,Black 从命令行传递的所有文件和目录的公共基本目录开始寻找 pyproject.toml
。如果找不到,它将在父目录中查找。它会在找到文件、.git
目录、.hg
目录或文件系统的根目录时停止查找,哪个先找到就停止。
如果您正在格式化标准输入,Black 将从当前工作目录开始寻找配置。
您也可以使用 --config
显式指定您想要特定文件的路径。在这种情况下,Black 将不会寻找任何其他文件。
如果您使用 --verbose
运行,如果找到了文件并使用了它,您将看到一条蓝色消息。
请注意,blackd
不会使用 pyproject.toml
配置。
配置格式
正如文件扩展名所暗示的,pyproject.toml
是一个 TOML 文件。它包含针对不同工具的单独部分。Black 使用 [tool.black]
部分。选项键与命令行上选项的长名称相同。
请注意,您必须在 TOML 中使用单引号字符串来指定正则表达式。它等同于 Python 中的 r-strings。多行字符串被 Black 视为详细正则表达式。使用 [ ]
来表示一个重要的空格字符。
示例 `pyproject.toml`
[tool.black]
line-length = 88
target-version = ['py37']
include = '\.pyi?$'
exclude = '''
(
/(
\.eggs # exclude a few common directories in the
| \.git # root of the project
| \.hg
| \.mypy_cache
| \.tox
| \.venv
| _build
| buck-out
| build
| dist
)/
| foo.py # also separately exclude a file named foo.py in
# the root of the project
)
'''
查找层次结构
命令行选项有默认值,您可以在 --help
中看到。一个 pyproject.toml
可以覆盖这些默认值。最后,命令行上用户提供的选项将覆盖这两者。
Black 在整个运行过程中只会使用一个 pyproject.toml
文件。它不会寻找多个文件,也不会从文件层次结构的不同级别组合配置。
编辑器集成
Emacs
使用 proofit404/blacken 或 Elpy。
PyCharm/IntelliJ IDEA
- 安装
black
。
$ pip install black
- 找到您的
black
安装文件夹。
在 macOS / Linux / BSD 上
$ which black
/usr/local/bin/black # possible location
在 Windows 上
$ where black
%LocalAppData%\Programs\Python\Python36-32\Scripts\black.exe # possible location
- 在 PyCharm/IntelliJ IDEA 中打开外部工具
在 macOS 上
PyCharm -> 首选项 -> 工具 -> 外部工具
在 Windows / Linux / BSD 上
文件 -> 设置 -> 工具 -> 外部工具
-
点击 + 图标添加一个新外部工具,并使用以下值
- 名称:Black
- 描述:Black 是无妥协的 Python 代码格式化工具。
- 程序:<安装位置从步骤 2>
- 参数:
"$FilePath$"
-
通过选择
工具 -> 外部工具 -> black
格式化当前打开的文件。- 或者,您可以设置一个快捷键,通过导航到
首选项或设置 -> 键盘映射 -> 外部工具 -> 外部工具 - Black
。
- 或者,您可以设置一个快捷键,通过导航到
-
可选地,在每次文件保存时运行 Black
- 确保您已安装 文件监视器 插件。
- 转到
首选项或设置 -> 工具 -> 文件监视器
并点击+
添加新的监视器- 名称:Black
- 文件类型:Python
- 作用域:项目文件
- 程序:<安装位置从步骤 2>
- 参数:
$FilePath$
- 刷新输出路径:
$FilePath$
- 工作目录:
$ProjectFileDir$
- 取消选中 "自动保存编辑的文件以触发监视器"
Wing IDE
Wing 通过 OS 命令工具支持 Black,具体说明请参阅 Wing 文档中的 pep8 格式化。详细步骤如下:
- 安装
black
。
$ pip install black
- 请确保它可以从命令行运行,例如:
$ black --help
- 在 Wing IDE 中,激活 操作系统命令 面板,并将命令 black 定义为在当前选定的文件上执行 black。
- 使用“工具” -> “操作系统命令”菜单选择项。
- 在 操作系统命令 -> “新建:命令行..” 中点击 +。
- 标题:black
- 命令行:black %s
- I/O 编码:使用默认
- 键盘绑定:F1
- 执行时提升操作系统命令
- 执行前自动保存文件
- 行模式
- 在编辑器中选择一个文件,然后按 F1 键,或按步骤 3 中选择的任何键绑定,以重新格式化文件。
Vim
命令和快捷键
:Black
格式化整个文件(不支持范围);:BlackUpgrade
升级虚拟环境中的 Black;:BlackVersion
获取虚拟环境中 Black 的当前版本。
配置
g:black_fast
(默认值为0
)g:black_linelength
(默认值为88
)g:black_skip_string_normalization
(默认值为0
)g:black_virtualenv
(默认值为~/.vim/black
或~/.local/share/nvim/black
)
使用 vim-plug
Plug 'psf/black'
或使用 Vundle
Plugin 'psf/black'
或者您可以从 plugin/black.vim 复制插件。
mkdir -p ~/.vim/pack/python/start/black/plugin
curl https://raw.githubusercontent.com/psf/black/master/plugin/black.vim -o ~/.vim/pack/python/start/black/plugin/black.vim
如果需要任何更改才能与 Vim 8 的内置 packadd
、Pathogen 等兼容,请告诉我。
此插件 需要用 Python 3.6+ 支持构建的 Vim 7.0+。它需要 Python 3.6 来在 Vim 进程内运行 Black,这比调用外部命令要快得多。
首次运行时,插件会使用正确的 Python 版本创建自己的虚拟环境并自动安装 Black。您可以通过调用 :BlackUpgrade
并重新启动 Vim 来稍后升级它。
如果您需要做任何特殊的事情才能使您的虚拟环境正常工作并安装 Black(例如,您想运行 master 版本),请手动创建虚拟环境并将 g:black_virtualenv
指向它。插件将使用它。
要保存时运行 Black,请将以下行添加到 .vimrc
或 init.vim
autocmd BufWritePre *.py execute ':Black'
要按按键运行 Black(例如下面的 F9),请添加以下内容
nnoremap <F9> :Black<CR>
如何获取带 Python 3.6 的 Vim? 在 Ubuntu 17.10 上,Vim 默认附带 Python 3.6。在 macOS 上使用 Homebrew 运行:brew install vim
。从源代码构建 Vim 时,使用:./configure --enable-python3interp=yes
。网上有许多关于如何做到这一点的指南。
Visual Studio Code
SublimeText 3
使用 sublack 插件。
Jupyter Notebook Magic
使用 blackcellmagic。
Python 语言服务器
如果您的编辑器支持 语言服务器协议(Atom、Sublime Text、Visual Studio Code 等),您可以使用 Python 语言服务器 与 pyls-black 插件。
Atom/Nuclide
使用 python-black。
Kakoune
将以下钩子添加到您的 kakrc 中,然后使用 :format
运行 black。
hook global WinSetOption filetype=python %{
set-option window formatcmd 'black -q -'
}
Thonny
其他编辑器
其他编辑器可能需要外部贡献。
欢迎补丁! ✨ 🍰 ✨
任何可以使用其stdio模式通过Black管道代码的工具(只需-
作为文件名即可,详情请见此处)。格式化的代码将被返回到标准输出(除非传递了--check
)。尽管Black仍会在标准错误输出中显示消息,但这不应影响您的使用。
这可以与PyCharm或IntelliJ的文件监视器一起使用。
blackd
blackd
是一个小的HTTP服务器,它通过简单协议公开Black的功能。使用它的主要好处是避免每次格式化文件时启动新的Black进程的开销。
用法
blackd
并非默认与Black一起打包,因为它有额外的依赖。您需要执行pip install black[d]
来安装它。
您可以通过运行blackd
在默认端口上启动服务器,只绑定到本地接口。您将看到一行显示服务器版本、它正在监听的主机和端口。然后blackd
将在标准输出中打印一个访问日志,类似于大多数网络服务器,并合并任何由无效格式化请求引起的异常跟踪。
blackd
提供的选项比Black更少。您可以通过运行blackd --help
来查看它们。
Usage: blackd [OPTIONS]
Options:
--bind-host TEXT Address to bind the server to.
--bind-port INTEGER Port to listen on
--version Show the version and exit.
-h, --help Show this message and exit.
目前还没有官方的blackd
客户端工具!您可以使用curl
来测试blackd
是否工作。
blackd --bind-port 9090 & # or let blackd choose a port
curl -s -XPOST "localhost:9090" -d "print('valid')"
协议
blackd
只接受位于/
路径的POST
请求。请求正文应包含要格式化的Python源代码,根据请求头中的Content-Type
字段的charset
字段进行编码。如果没有指定charset
,则blackd
假定UTF-8
。
有一些HTTP头控制源代码的格式化方式。这些与Black的命令行标志相对应。有一个例外:X-Protocol-Version
,如果存在,其值应为1
,否则请求将被拒绝,返回HTTP 501
(未实现)。
控制代码格式化的头包括
X-Line-Length
:对应于--line-length
命令行标志。X-Skip-String-Normalization
:对应于--skip-string-normalization
命令行标志。如果存在且其值不是空字符串,则不会执行字符串标准化。X-Fast-Or-Safe
:如果设置为fast
,则blackd
将像Black在传递了--fast
命令行标志时一样操作。X-Python-Variant
:如果设置为pyi
,则blackd
将像Black在传递了--pyi
命令行标志时一样操作。否则,其值必须对应于Python版本或由逗号分隔的Python版本集,可以可选地带有前缀py
。例如,要请求与Python 3.5和3.6兼容的代码,将头设置为py3.5,py3.6
。X-Diff
:对应于--diff
命令行标志。如果存在,将输出格式化的diff。
如果这些头中的任何一个设置为无效值,则blackd
返回一个HTTP 400
错误响应,并在消息体中提到有问题的头的名称。
除了上述内容外,blackd
还可以产生以下响应代码
HTTP 204
:如果输入已经格式良好。响应正文为空。HTTP 200
:如果输入需要格式化。响应正文包含格式化的Python代码,并且Content-Type
头已相应设置。HTTP 400
:如果输入包含语法错误。错误详情在响应体中返回。HTTP 500
:如果在尝试格式化输入时发生任何错误。响应体包含错误文本表示。
响应头包括一个包含Black版本的X-Black-Version
头。
版本控制集成
使用 pre-commit。一旦安装完成,将其添加到您仓库中的 .pre-commit-config.yaml
repos:
- repo: https://github.com/psf/black
rev: stable
hooks:
- id: black
language_version: python3.6
然后运行 pre-commit install
,您就可以使用了。
在钩子中避免使用 args
。相反,将必要的配置存储在 pyproject.toml
中,这样 Black 的编辑器和命令行使用在您的项目中都能保持一致性。请参阅 Black 自身的 pyproject.toml 示例。
如果您已经使用 Python 3.7,请相应地切换 language_version
。最后,stable
是一个指向 PyPI 上最新版本的标签。如果您想运行 master,这也是一个选项。
忽略未修改的文件
Black 会记住它已经格式化的文件,除非使用 --diff
标志或通过标准输入传递代码。这些信息按用户存储。文件的精确位置取决于 Black 版本和运行 Black 的系统。该文件是非便携式的。在常见操作系统上的标准位置是
- Windows:
C:\\Users\<username>\AppData\Local\black\black\Cache\<version>\cache.<line-length>.<file-mode>.pickle
- macOS:
/Users/<username>/Library/Caches/black/<version>/cache.<line-length>.<file-mode>.pickle
- Linux:
/home/<username>/.cache/black/<version>/cache.<line-length>.<file-mode>.pickle
file-mode
是一个 int 标志,它确定文件是否仅作为 3.6+ 格式化,以及是否省略了字符串归一化。
要覆盖 macOS 或 Linux 上这些文件的位置,将环境变量 XDG_CACHE_HOME
设置为您首选的位置。例如,如果您想将缓存放在运行 Black 的目录中,设置 XDG_CACHE_HOME=.cache
。然后 Black 将将上述文件写入到 .cache/black/<version>/
。
使用 Black
以下知名开源项目信任 Black 来强制执行一致的代码风格:pytest、tox、Pyramid、Django Channels、Hypothesis、attrs、SQLAlchemy、Poetry、PyPA 应用程序(Warehouse、Pipenv、virtualenv)、pandas、Pillow、所有 Datadog Agent 集成、Home Assistant。
我们遗漏了谁吗?告诉我们。
客户评价
Dusty Phillips,作家
Black 有自己的观点,所以您不需要。
Hynek Schlawack,attrs
的创建者、Twisted 和 CPython 的核心开发者
我想要的圣诞礼物是一个不会糟糕的自动格式化工具!
Carl Meyer,Django 核心开发者
至少名字不错。
Kenneth Reitz,requests
和 pipenv
的创建者
这大大提高了我们代码的格式化。非常感谢!
展示您的风格
在项目的 README.md 中使用徽章
[](https://github.com/psf/black)
在 README.rst 中使用徽章
.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
:target: https://github.com/psf/black
许可协议
MIT
为 Black 贡献
就灵感而言,Black 和 gofmt 一样可配置。这是故意的。
欢迎提交错误报告和修复!然而,在您提出新功能或配置选项之前,请自问一下您为什么需要它。如果它能够更好地与其他工作流集成、修复不一致性、提高效率等——那就去做吧!另一方面,如果您的回答是“因为我不喜欢某种格式”,那么您还没有准备好接受 Black。这类更改不太可能被接受。您仍然可以尝试,但要做好失望的准备。
更多详情请参阅CONTRIBUTING。
变更日志
日志变得相当长。它已经移至自己的文件。
参见CHANGES。
作者
由Łukasz Langa整合。
由Carol Willing、Carl Meyer、Jelle Zijlstra、Mika Naylor、Zsolt Dollenstein和Cooper Lees维护。
多亏了以下人士的贡献
- Abdur-Rahmaan Janhangeer
- Adam Johnson
- Alexander Huynh
- Andrew Thorp
- Andrey
- Andy Freeland
- Anthony Sottile
- Arjaan Buijk
- Artem Malyshev
- Asger Hautop Drewsen
- Augie Fackler
- Aviskar KC
- Benjamin Woodruff
- Brandt Bucher
- Charles Reid
- Christian Heimes
- Chuck Wooters
- Cooper Ry Lees
- Daniel Hahler
- Daniel M. Capella
- Daniele Esposti
- dylanjblack
- Eli Treuherz
- Florent Thiery
- hauntsaninja
- Hugo van Kemenade
- Ivan Katanić
- Jason Fried
- jgirardet
- Joe Antonakakis
- Jon Dufresne
- Jonas Obrist
- Josh Bode
- Juan Luis Cano Rodríguez
- Katie McLaughlin
- Lawrence Chan
- Linus Groh
- Luka Sterbic
- Mariatta
- Matt VanEseltine
- Michael Flaxman
- Michael J. Sullivan
- Michael McClimon
- Miguel Gaiowski
- Mike
- Min ho Kim
- Miroslav Shubernetskiy
- Neraste
- Ofek Lev
- Osaetin Daniel
- Pablo Galindo
- Peter Bengtsson
- pmacosta
- Rishikesh Jha
- Stavros Korokithakis
- Stephen Rosen
- Sunil Kapil
- Thom Lu
- Tom Christie
- Tzu-ping Chung
- Utsav Shah
- vezeli
- Vishwas B Sharma
- Yngve Høiseth
- Yurii Karabas
变更日志
19.10b0
-
增加了对PEP 572赋值表达式的支持(#711)
-
增加了对PEP 570位置参数的支持(#943)
-
增加了对异步生成器的支持(#593)
-
增加了通过在内部放置显式的尾逗号来预先分割集合的支持(#826)
-
增加了
black -c
作为从命令行传递代码的方式(#761) -
--safe现在可以与Python 2代码一起工作(#840)
-
修复了针对Python 2特定代码的语法选择(#765)
-
修复了函数定义和调用站点中尾逗号的特征检测(#763)
-
# fmt: off
/# fmt: on
注释对在相同代码块中多次放置现在表现正确(#1005) -
Black不再在具有61个以上核心的Windows机器上崩溃(#838)
-
Black不再在以反斜杠开头的前置注释上崩溃(#767)
-
Black不再在
from
...import
块中的注释上崩溃(#829) -
Black不再在某些平台配置的Python 3.7上崩溃(#494)
-
Black不再在from-imports中的注释上失败(#671)
-
Black不再在文件以反斜杠开头时失败(#922)
-
Black不再将常规注释与类型注释合并(#1027)
-
Black不再分割包含类型注释的长行(#997)
-
删除了
yield
表达式周围的不必要括号(#834) -
在解包赋值时增加了长元组的括号(#832)
-
当它们由一元运算符前缀时,增加了复杂幂的括号(#646)
-
修复了导致Black以目标行长为1格式化某些代码的bug(#762)
-
Black不再在字符串边界上的f-string子表达式中引入引号(#863)
-
如果Black在单个表达式中放置括号,则将注释移动到包装表达式而不是括号之后(#872)
-
blackd
现在在响应头中返回Black的版本(#1013) -
当提供
X-Diff
头时,blackd
现在可以输出源代码的格式化差异(#969)
19.3b0
-
新选项
--target-version
用于控制哪些Python版本应该针对Black格式化的代码(#618) -
已弃用
--py36
(请使用--target-version=py36
代替)(#724) -
Black不再将数值字面量规范化为包含
_
分隔符(#696) -
长
del
语句现在被分成多行(#698) -
类型注释在函数签名中不再被破坏
-
提高了格式化深层嵌套数据结构的性能(#509)
-
Black现在可以在Windows上并行格式化多个文件(#632)
-
Black现在以原子方式创建缓存文件,这允许它在并行管道(如
xargs -P8
)中使用(#673) -
Black现在正确地缩进在以前用制表符格式化的文件的注释(#262)
-
blackd
现在支持CORS(#622)
18.9b0
-
数值字面量现在由Black格式化(#452,#461,#464,#469)
-
在Python 3.6+代码中,数值字面量现在规范化为包含
_
分隔符 -
添加了
--skip-numeric-underscore-normalization
以禁用上述行为并保留输入中的数值下划线 -
在数值字面量中的
_
被识别为Python 3.6+ -
数值字面量中的大多数字母现在都小写(例如,在
1e10
,0x01
) -
十六进制数字始终大写(例如,
0xBADC0DE
)
-
-
添加了
blackd
,有关更多信息,请参阅其文档(#349) -
相邻的字符串字面量现在正确地分割成多行(#463)
-
现在为不适合一行的一行单行导入添加了尾随逗号(#250)
-
当
--check
对文件成功时,现在填充缓存,这加快了正确格式化且未修改的连续文件检查的速度(#448) -
现在删除了文件开头的空白(#399)
-
修复了pweave和Spyder IDE特殊注释的破坏性格式化(#532)
-
修复了解包大元组的格式化不稳定问题(#267)
-
修复了带有重命名的
__future__
导入的解析问题(#389) -
修复了直接在
yield
和其他节点之前# fmt: off
的作用域问题(#385) -
修复了具有默认参数的lambda表达式的格式化问题(#468)
-
修复了
async for
语句:Black不再将它们拆分成单独的行(#372) -
注意:Vim插件停止将
,=
注册为默认和弦,因为事实证明这是一个糟糕的主意(#415)
18.6b4
- 热修复:不要在多个注释直接在
# fmt: off
之前时冻结(#371)
18.6b3
-
类型存根文件(
.pyi
)现在在常量之后添加了空白行(#340) -
# fmt: off
和# fmt: on
现在更加可靠-
它们现在也适用于括号对内
-
它们现在可以正确地跨越函数/类边界
-
它们现在在缩进块以空行或错位注释开始时也可以工作
-
-
使Click在无效环境中不会失败;请注意,Click是正确的,但在处理Python源代码时,我们访问非ASCII文件路径的可能性很低(#277)
-
修复了包含内部插值表达式中引号的f-string的不当格式化问题(#322)
-
修复了在文件中找到长列表字面量时的不必要减速
-
修复了具有非常多个兄弟的AST节点上的不必要减速
-
修复了字符串规范化期间掠夺反斜杠的问题
-
修复了由于符号链接指向项目目录外部导致的崩溃(#338)
18.6b2
-
添加了
--config
(#65) -
添加了与
--help
等效的-h
(#316) -
修复了在
-S
被使用时文件缓存未正确修改的问题 -
修复了字符串解包中的额外空间问题(#305)
-
修复了空的三重引号字符串的格式化问题(#313)
-
修复了在无注释的行上计算注释位置时的不必要降速
18.6b1
-
热修复:不要在stdout输出面向人类的信息(#299)
-
热修复:不要在非零返回码时输出蛋糕表情(#300)
18.6b0
-
添加了
--include
和--exclude
(#270) -
添加了
--skip-string-normalization
(#118) -
添加了
--verbose
(#283) -
在
--diff
中输出的标题现在实际上符合统一差异规范 -
修复了长简单赋值被不必要的括号包裹的问题(#273)
-
修复了包含多行字符串的行中的不必要的括号问题(#232)
-
修复了如果使用旧版本的Click,则stdin处理不正确的问题(#276)
-
Black现在在原地格式化文件时保留行结束符(#258)
18.5b1
-
添加了
--pyi
(#249) -
添加了
--py36
(#249) -
Python语法pickle缓存与格式化缓存一起存储,使得Black可以在site-packages不可写的环境中工作(#192)
-
Black现在强制执行类级文档字符串(和/或字段)以及第一个方法的PEP 257空行
-
修复了在省略行拆分的大表达式尾部的注释中被省略的注释中产生无效代码的问题(#237)
-
修复了在
# fmt: off
部分中删除可选括号的问题(#224) -
修复了在非常长的导入中,星号被错误地包裹在可选括号中产生的无效代码问题(#234)
-
修复了在省略行拆分的大表达式尾部注释中移动内联注释导致的不稳定的格式化问题(#238)
-
修复了如果没有类文档字符串或字段,则类声明和第一个方法之间有多余的空行的问题(#219)
-
修复了函数签名和内部函数或内部类之间的多余空行问题(#196)
18.5b0
-
调用链现在按照流畅接口风格进行格式化(#67)
-
数据结构字面量(元组、列表、字典和集合)现在也总是像导入一样展开,当它们不适合单行时(#152)
-
切片现在按照PEP 8进行格式化(#178)
-
现在也自动管理赋值和返回语句右侧的括号(#140)
-
数学运算符现在使用它们各自的优先级来界定多行表达式(#148)
-
在以括号开始或结束且仅包含单个运算符的表达式中省略了可选括号(#177)
-
在类定义中现在移除了空括号(#145、#180)
-
字符串前缀现在统一为小写,Python 3.6+代码和Python 2.7+代码中移除了
u
(#188、#198、#199) -
类型存根文件(
.pyi
)现在以与PEP 484一致的样式进行格式化(#207、#210) -
现在增量地报告重格式化多个文件时的进度
-
修复了在缩进后关闭括号后不必要的将尾随括号(内容带有括号)拆分为自己的行的问题(#119)
-
修复了在导入中有时留下无效的尾随逗号的问题(#185)
-
修复了使用多个可删除括号对时的非确定性格式化问题(#183)
-
修复了在长赋值中不必要地将多行字符串包裹在可选括号中的问题(#215)
-
修复了当只有单个名称时,不拆分长from导入的问题
-
修复了通过检查解包函数调用来固定的 Python 3.6+ 文件发现。这解决了在函数签名中使用星号和函数调用中使用星号时,尾随逗号引起的非确定格式化问题,但前者会被重新格式化到单行。
-
修复了处理可选圆括号时崩溃的问题 (#193)
-
修复了“is”,“is not”,“in”和“not in”在拆分时没有被考虑为操作符
-
修复了遇到死链接时的崩溃
18.4a4
- 不要在
--check
时填充缓存 (#175)
18.4a3
-
添加了一个“缓存”;磁盘上未更改的已重新格式化的文件将不会再次重新格式化 (#109)
-
--check
和--diff
不再互斥 (#149) -
泛化星号表达式处理,包括双星号;这解决了乘法使表达式“不安全”的问题,因为尾随逗号 (#132)
-
Black不再强制在控制流语句后放置空行 (#90)
-
Black现在导入的分割方式类似于isort的“模式3 + 尾随逗号” (#127)
-
修复了独立注释关闭块时的注释缩进 (#16, #32)
-
修复了独立注释如果紧接在类、def或装饰器之前时接收额外的空行 (#56, #154)
-
修复了
--diff
没有显示整个路径 (#130) -
修复了函数调用中星号和双星号后面的复杂表达式解析 (#2)
-
修复了lambda参数中的逗号上的无效拆分 (#133)
-
修复了三目运算符缺少拆分的情况 (#141)
18.4a2
-
修复了解析未对齐的独立注释 (#99, #112)
-
修复了字典字面量内部字典拆包的位置 (#111)
-
Vim插件现在也适用于Windows
-
修复了遇到字符串中不必要的转义引号时的不稳定格式化 (#120)
18.4a1
-
添加了
--quiet
(#78) -
添加了自动括号管理 (#4)
-
添加了pre-commit集成 (#103, #104)
-
修复了
--check
多个文件时的报告 (#101, #102) -
修复了从原始字符串中移除反斜杠转义符 (#100, #105)
18.4a0
-
添加了
--diff
(#87) -
在所有分隔符之前添加换行符(除非是逗号等),以更好地符合PEP 8 (#73)
-
将字符串字面量标准化为几乎到处使用双引号 (#75)
-
修复了解析嵌套括号表达式中的独立注释;Black将不再产生超长行或将所有独立注释放置在表达式的末尾 (#22)
-
修复了18.3a4回归:在空行带有尾随空格时不会崩溃 (#80)
-
修复了18.3a4回归:使用
# yapf: disable
作为尾随注释会导致Black不输出文件的其余部分 (#95) -
当按下CTRL+C进行多文件格式化时,Black不再因为asyncio相关的异常而失控
-
模块级别只允许最多两个空行,并且函数内部只允许单行空行 (#74)
18.3a4
-
# fmt: off
和# fmt: on
已实现 (#5) -
自动检测格式化文件中已弃用的Python 2形式的print语句和exec语句 (#49)
-
在类型化函数参数的默认值中使用适当的空格处理复杂表达式 (#60)
-
仅当使用--check时返回退出代码1 (#50)
-
不要从方括号索引中删除单个尾随逗号 (#59)
-
如果上一个因子叶不是数学运算符,则不要省略空格 (#55)
-
如果它是第一个参数,则省略kwarg拆包中的额外空格 (#46)
-
省略Sphinx自动属性注释中的额外空格 (#68)
18.3a3
-
不要删除方括号表达式之外的单行空行 (#19)
-
添加了将格式化从stdin管道传输到stdin的能力 (#25)
-
恢复了使用 legacy 语法使用
async
作为名称格式化代码的能力 (#20, #42) -
更有效地处理numpy样式的数组索引 (#33,再次)
18.3a2
-
改变了二进制运算符的位置,使其出现在行首而不是行尾,遵循了PEP 8最近的一次变更 (#21)
-
在分割时忽略空括号对。这避免了非常奇怪的格式化 (#34, #35)
-
如果调用只有一个参数,则删除尾随逗号
-
如果顶层函数之间有注释,不要在上方函数之后放置四个空行
-
修复了带有导入的新行格式不稳定的问题
-
修复了如果它是简单语句,则将后置脚本独立注释折叠到最后一句话的问题 (#18, #28)
-
修复了numpy风格数组索引中的缺失空格 (#33)
-
修复了基于星号的算术表达式后的多余空格 (#31)
18.3a1
-
添加了
--check
-
仅在这样做安全的情况下,在函数签名和调用中放置尾随逗号。如果文件是Python 3.6+,则始终安全,否则只有在签名或调用中未使用
*args
或**kwargs
的情况下才安全。 (#8) -
修复了相对导入中点的不正确间距 (#6, #13)
-
修复了for循环中展开变量后逗号分割的不正确问题 (#23)
-
修复了括号表达式中的多余空格 (#7)
-
修复了在默认参数中括号后和空格中的多余空格 (#14, #17)
-
修复了当操作数是复杂表达式时的算术运算符后的多余空格 (#15)
18.3a0
-
首次发布版本,2018年🍰快乐日!
-
alpha质量
-
按日期版本化(见:https://calver.org/)
项目详情
black-but-with-tabs-instead-of-spaces-19.11.tar.gz的散列
算法 | 散列摘要 | |
---|---|---|
SHA256 | 01b00ac677000874b86c6f22efc965ab2cc16645a27b86b01bac2fed68a5a12e |
|
MD5 | cb6a55013b636059841cea8c6fafb152 |
|
BLAKE2b-256 | 677b0b508d621ea1d9112aeab305d20c2d26bc9d579b6865daa05098a54f2d49 |
black_but_with_tabs_instead_of_spaces-19.11-py36-none-any.whl的散列
算法 | 散列摘要 | |
---|---|---|
SHA256 | bd5dd0842cef0a2c6714bd7381c8ead9106f68c64c64c706679a6a7fabb7ba48 |
|
MD5 | bc04c6d1e1edd62edebd11589761e970 |
|
BLAKE2b-256 | fc42f10fc031bc6df2fe374ebb1fce5482f2b2dcb333590afd2fe8850c56bda3 |