Black 不尊重 pyproject.toml 中的扩展排除

Sal*_*aja 6 python visual-studio-code python-black pyproject.toml

在 VSCode 中,使用 Python 3.9 和 black==22.6.0,我的项目结构如下:

--- root
------src
---------module0.py
---------module1.py
------tests
---------test_folder0
------------test_file0.py
------------test_file1.py
---------test_folder1
---------etc.
Run Code Online (Sandbox Code Playgroud)

pyproject.toml无法获得extend-exlude实际排除我的测试文件的部分。我已经尝试了多种不同的方法,包括整个测试文件夹以及 test_whatever.py 文件,但似乎没有任何效果,即使我的各种尝试已经过https://regex101.com/的验证。最简单的例子:

[tool.black]
line-length = 200
target-version = ['py39']
include = '\.pyi?$'
extend-exclude = '''.*test_.*'''
Run Code Online (Sandbox Code Playgroud)

要么我的正则表达式错误(或者黑色需要一些修改),要么 VSCode 忽略我的项目配置或 idk。

小智 13

Maintainer of Black here :wave:

OK, so I actually missed a few points in my comments. To address the main question, this is 100% expected behaviour. Your regex is fine.

The thing is that when you ask VSCode to format your file on save, it calls Black passing the filepath to your current file (you just saved) directly. If you open the "Output" tab in the bottom panel and then save a Python file, you'll notice something like this:

./venv/bin/python -m black --safe --diff --quiet ./tests/data/nothing-changed.py
Run Code Online (Sandbox Code Playgroud)

--include, --exclude, and --extend-exclude only affect files and directories that are discovered by Black itself. You might be wondering, huh, Black can look for files to format? Yes, it does when you run black . or give Black any other directory. The flipside of this is that these options do nothing to files given as an argument to Black.

If you want to keep Format on Save enabled, your only recourse is to use --force-exclude which is similar to --extend-exclude but it's always enforced. You can either configure --force-exclude in pyproject.toml or via VSCode's Black arguments setting (preferably for the current workspace only).

The difference between putting it in pyproject.toml and configuring VSCode to pass extra options to Black is well, when it's applied. If it's in pyproject.toml it will always be enforced, even when you're not using VSCode and instead are using a bash shell or whatever. This can be useful if you're using pre-commit (which passes files to Black directly just like VSCode) or similar, but can be annoying otherwise.

(如果您确实选择通过 强制排除项目范围内的文件,则可以通过管道输入或在 CLI 上pyproject.toml临时清除来格式化强制排除的文件,例如--force-excludeblack --force-exclude='' file_you_want_to_format_even_though_it_is_force_excluded.py)