Skip to content

Commit

Permalink
Improve performance by skipping unnecessary normalisation (#3751)
Browse files Browse the repository at this point in the history
This speeds up black by about 40% when the cache is full
  • Loading branch information
hauntsaninja committed Jul 9, 2023
1 parent f3b50e4 commit 2593af2
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Expand Up @@ -55,6 +55,7 @@

<!-- Changes that improve Black's performance. -->

- Speed up _Black_ significantly when the cache is full (#3751)
- Avoid importing `IPython` in a case where we wouldn't need it (#3748)

### Output
Expand Down
23 changes: 17 additions & 6 deletions src/black/files.py
Expand Up @@ -276,15 +276,24 @@ def normalize_path_maybe_ignore(
return root_relative_path


def path_is_ignored(
path: Path, gitignore_dict: Dict[Path, PathSpec], report: Report
def _path_is_ignored(
root_relative_path: str,
root: Path,
gitignore_dict: Dict[Path, PathSpec],
report: Report,
) -> bool:
path = root / root_relative_path
# Note that this logic is sensitive to the ordering of gitignore_dict. Callers must
# ensure that gitignore_dict is ordered from least specific to most specific.
for gitignore_path, pattern in gitignore_dict.items():
relative_path = normalize_path_maybe_ignore(path, gitignore_path, report)
if relative_path is None:
try:
relative_path = path.relative_to(gitignore_path).as_posix()
except ValueError:
break
if pattern.match_file(relative_path):
report.path_ignored(path, "matches a .gitignore file content")
report.path_ignored(
path.relative_to(root), "matches a .gitignore file content"
)
return True
return False

Expand Down Expand Up @@ -326,7 +335,9 @@ def gen_python_files(
continue

# First ignore files matching .gitignore, if passed
if gitignore_dict and path_is_ignored(child, gitignore_dict, report):
if gitignore_dict and _path_is_ignored(
normalized_path, root, gitignore_dict, report
):
continue

# Then ignore with `--exclude` `--extend-exclude` and `--force-exclude` options.
Expand Down
4 changes: 3 additions & 1 deletion tests/test_black.py
Expand Up @@ -508,6 +508,8 @@ def _mocked_calls() -> bool:
"pathlib.Path.cwd", return_value=working_directory
), patch("pathlib.Path.is_dir", side_effect=mock_n_calls([True])):
ctx = FakeContext()
# Note that the root folder (project_root) isn't the folder
# named "root" (aka working_directory)
ctx.obj["root"] = project_root
report = MagicMock(verbose=True)
black.get_sources(
Expand All @@ -527,7 +529,7 @@ def _mocked_calls() -> bool:
for _, mock_args, _ in report.path_ignored.mock_calls
), "A symbolic link was reported."
report.path_ignored.assert_called_once_with(
Path("child", "b.py"), "matches a .gitignore file content"
Path("root", "child", "b.py"), "matches a .gitignore file content"
)

def test_report_verbose(self) -> None:
Expand Down

0 comments on commit 2593af2

Please sign in to comment.