On windows the path `FoObAR` is the same as `foobar`, so the output
of `black` on a windows machine could output the path to `.gitignore`
with an upper or lower-case drive letter.
Fixes#4268
Previously we would allow whitespace changes in all strings, now
only in docstrings.
Co-authored-by: Shantanu <12621235+hauntsaninja@users.noreply.github.com>
This relates to #4015, #4161 and the behaviour of os.getcwd()
Black is a big user of pathlib and as such loves doing `.resolve()`,
since for a long time it was the only good way of getting an absolute
path in pathlib. However, this has two problems:
The first minor problem is performance, e.g. in #3751 I (safely) got rid
of a bunch of `.resolve()` which made Black 40% faster on cached runs.
The second more important problem is that always resolving symlinks
results in unintuitive exclusion behaviour. For instance, a gitignored
symlink should never alter formatting of your actual code. This kind of
thing was reported by users a few times.
In #3846, I improved the exclusion rule logic for symlinks in
`gen_python_files` and everything was good.
But `gen_python_files` isn't enough, there's also `get_sources`, which
handles user specified paths directly (instead of files Black
discovers). So in #4015, I made a very similar change to #3846 for
`get_sources`, and this is where some problems began.
The core issue was the line:
```
root_relative_path = path.absolute().relative_to(root).as_posix()
```
The first issue is that despite root being computed from user inputs, we
call `.resolve()` while computing it (likely unecessarily). Which means
that `path` may not actually be relative to `root`. So I started off
this PR trying to fix that, when I ran into the second issue. Which is
that `os.getcwd()` (as called by `os.path.abspath` or `Path.absolute` or
`Path.cwd`) also often resolves symlinks!
```
>>> import os
>>> os.environ.get("PWD")
'/Users/shantanu/dev/black/symlink/bug'
>>> os.getcwd()
'/Users/shantanu/dev/black/actual/bug'
```
This also meant that the breakage often would not show up when input
relative paths.
This doesn't affect `gen_python_files` / #3846 because things are always
absolute and known to be relative to `root`.
Anyway, it looks like #4161 fixed the crash by just swallowing the error
and ignoring the file. Instead, we should just try to compute the actual
relative path. I think this PR should be quite safe, but we could also
consider reverting some of the previous changes; the associated issues
weren't too popular.
At the same time, I think there's still behaviour that can be improved
and I kind of want to make larger changes, but maybe I'll save that for
if we do something like #3952
Hopefully fixes#4205, fixes#4209, actual fix for #4077
This PR does not change any behaviour.
There have been 1-2 issues about symlinks recently. Both over and under
resolving can cause problems. This makes a case where we resolve more
explicit and prevent a resolved path from leaking out via the return.
A follow up to #4024 but for `if` guards in `case` statements. I noticed this
when #4024 was made stable, and noticed I had some code that had extra parens
around the `if` guard.
Fixes#2863
This is pretty desirable in a monorepo situation where you have
configuration in the root since it will mean you don't have to
reconfigure every project.
The good news for backward compatibility is that `find_project_root`
continues to stop at any git or hg root, so in all cases repo root
coincides with a pyproject.toml missing tool.black, we'll continue to
have the project root as before and end up using default config
(i.e. we're unlikely to randomly start using the user config).
The other thing we need to be a little careful about is that changing
find_project_root logic affects what `exclude` is relative to. Since we
only change in cases where there is no config, this only applies where
users were using `exclude` via command line arg (and had pyproject.toml
missing tool.black in a dir that was not repo root).
Finally, for the few who could be affected, the fix is to put an empty
`[tool.black]` in pyproject.toml
In #4096 I added a list of current preview/unstable features to the docs. I think
this is important for publicizing what's in our preview style. This PR adds an
automated test to ensure the list stays up to date in the future.
- Ensure total file length stays under 96
- Hash the path only if it's too long
- Proceed normally (with a warning) if the cache can't be read
Fixes#4172