-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Description
Describe the bug
When using stdin
+ --stdin-filename
, black will always set it's project root to the directory it auto-finds. The docs imply that you can override this by using --config
:
By default Black looks for pyproject.toml containing a [tool.black] section starting from the common base directory of all files and directories passed on the command line. If it’s not there, it looks in parent directories. It stops looking when it finds the file, or a .git directory, or a .hg directory, or the root of the file system, whichever comes first.
...
You can also explicitly specify the path to a particular file that you want with --config. In this situation Black will not look for any other file.
However, in practice, specifying --config
seems to make no difference, and it always uses the auto-found directory.
This is problematic when working with .git submodules, as there does not seem to be an easy way to enable formatting for the top-level repository (which you control), and disable it for the subrepos / submodules (which you do NOT control), without making edits in the repos you do not control.
To Reproduce
Our test directory structure will look like:
black-stdin-test/
|- pyproject.toml
|- submodule/
| |- .git/
| |- testfile.py
To create this, and run black, execute this .sh script:
#!/bin/bash
mkdir -p black-stdin-test
cd black-stdin-test
mkdir -p submodule/.git
echo "foo=7" > submodule/testfile.py
echo '[tool.black]
verbose = true
force-exclude = "submodule"
' > pyproject.toml
echo "================================"
echo "This will format the file, when it should be excluded"
echo "================================"
echo cat ${PWD}/submodule/testfile.py '|' black --stdin-filename ${PWD}/submodule/testfile.py --config ${PWD}/pyproject.toml - '>' /dev/null
cat ${PWD}/submodule/testfile.py | black --stdin-filename ${PWD}/submodule/testfile.py --config ${PWD}/pyproject.toml - > /dev/null
echo
echo
echo "================================"
echo "This won't format the file, as expected"
echo "================================"
echo black .
black .
This will give this output:
================================
This will format the file, when it should be excluded
================================
cat /black-stdin-test/submodule/testfile.py | black --stdin-filename /black-stdin-test/submodule/testfile.py --config /black-stdin-test/pyproject.toml - > /dev/null
Identified `/black-stdin-test/submodule` as project root containing a .git directory.
Using configuration in '/black-stdin-test/pyproject.toml'.
verbose: True
force_exclude: submodule
Found input source: "__BLACK_STDIN_FILENAME__/black-stdin-test/submodule/testfile.py"
reformatted /black-stdin-test/submodule/testfile.py
All done! ✨ 🍰 ✨
1 file reformatted.
================================
This won't format the file, as expected
================================
black .
Identified `/black-stdin-test` as project root containing a pyproject.toml.
Using configuration from project root.
verbose: True
force_exclude: submodule
Found input source directory: "/black-stdin-test"
/black-stdin-test/submodule ignored: matches the --force-exclude regular expression
No Python files are present to be formatted. Nothing to do 😴
Expected behavior
Given the docs quoted above, I would expect the --config
flag to set the project root, and allow excluding of the submodule
directory.
If the current behavior is intended, then at minimum I think the docs should be clarified... and ideally there should be a way to either explicitly set the project root. (Ideally, within a pyproject.toml
, you could set an option to always mark it's parent folder as the project root, so the exclude paths it contains would always be relative to "itself").
Environment
- Black's version: black, 24.2.1.dev1+gd1d4fc5 (running from latest dev branch)
- OS and Python version: Linux (Ubuntu 20.04)/Python 3.10.9