Avoid parsing pyproject.toml files when settings are fixed (#1827)

Apart from being wasteful, this can also cause problems (see the linked
issue).

Resolves #1812.
This commit is contained in:
Charlie Marsh 2023-01-12 13:15:44 -05:00 committed by GitHub
parent 38f5e8f423
commit dcccfe2591
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 40 additions and 34 deletions

View File

@ -17,7 +17,7 @@ resources/test/project/examples/docs/docs/file.py:8:5: F841 Local variable `x` i
resources/test/project/project/file.py:1:8: F401 `os` imported but unused resources/test/project/project/file.py:1:8: F401 `os` imported but unused
resources/test/project/project/import_file.py:1:1: I001 Import block is un-sorted or un-formatted resources/test/project/project/import_file.py:1:1: I001 Import block is un-sorted or un-formatted
Found 7 error(s). Found 7 error(s).
6 potentially fixable with the --fix option. 7 potentially fixable with the --fix option.
``` ```
Running from the project directory itself should exhibit the same behavior: Running from the project directory itself should exhibit the same behavior:
@ -32,7 +32,7 @@ examples/docs/docs/file.py:8:5: F841 Local variable `x` is assigned to but never
project/file.py:1:8: F401 `os` imported but unused project/file.py:1:8: F401 `os` imported but unused
project/import_file.py:1:1: I001 Import block is un-sorted or un-formatted project/import_file.py:1:1: I001 Import block is un-sorted or un-formatted
Found 7 error(s). Found 7 error(s).
6 potentially fixable with the --fix option. 7 potentially fixable with the --fix option.
``` ```
Running from the sub-package directory should exhibit the same behavior, but omit the top-level Running from the sub-package directory should exhibit the same behavior, but omit the top-level
@ -43,7 +43,7 @@ files:
docs/file.py:1:1: I001 Import block is un-sorted or un-formatted docs/file.py:1:1: I001 Import block is un-sorted or un-formatted
docs/file.py:8:5: F841 Local variable `x` is assigned to but never used docs/file.py:8:5: F841 Local variable `x` is assigned to but never used
Found 2 error(s). Found 2 error(s).
1 potentially fixable with the --fix option. 2 potentially fixable with the --fix option.
``` ```
`--config` should force Ruff to use the specified `pyproject.toml` for all files, and resolve `--config` should force Ruff to use the specified `pyproject.toml` for all files, and resolve
@ -74,7 +74,7 @@ docs/docs/file.py:1:1: I001 Import block is un-sorted or un-formatted
docs/docs/file.py:8:5: F841 Local variable `x` is assigned to but never used docs/docs/file.py:8:5: F841 Local variable `x` is assigned to but never used
excluded/script.py:5:5: F841 Local variable `x` is assigned to but never used excluded/script.py:5:5: F841 Local variable `x` is assigned to but never used
Found 4 error(s). Found 4 error(s).
1 potentially fixable with the --fix option. 4 potentially fixable with the --fix option.
``` ```
Passing an excluded directory directly should report errors in the contained files: Passing an excluded directory directly should report errors in the contained files:

View File

@ -232,6 +232,7 @@ pub fn python_files_in_path(
// Search for `pyproject.toml` files in all parent directories. // Search for `pyproject.toml` files in all parent directories.
let mut resolver = Resolver::default(); let mut resolver = Resolver::default();
if matches!(pyproject_strategy, PyprojectDiscovery::Hierarchical(..)) {
for path in &paths { for path in &paths {
for ancestor in path.ancestors() { for ancestor in path.ancestors() {
if let Some(pyproject) = settings_toml(ancestor)? { if let Some(pyproject) = settings_toml(ancestor)? {
@ -241,6 +242,7 @@ pub fn python_files_in_path(
} }
} }
} }
}
// Check if the paths themselves are excluded. // Check if the paths themselves are excluded.
if file_strategy.force_exclude { if file_strategy.force_exclude {
@ -272,6 +274,7 @@ pub fn python_files_in_path(
Box::new(|result| { Box::new(|result| {
// Search for the `pyproject.toml` file in this directory, before we visit any // Search for the `pyproject.toml` file in this directory, before we visit any
// of its contents. // of its contents.
if matches!(pyproject_strategy, PyprojectDiscovery::Hierarchical(..)) {
if let Ok(entry) = &result { if let Ok(entry) = &result {
if entry if entry
.file_type() .file_type()
@ -299,6 +302,7 @@ pub fn python_files_in_path(
} }
} }
} }
}
// Respect our own exclusion behavior. // Respect our own exclusion behavior.
if let Ok(entry) = &result { if let Ok(entry) = &result {
@ -366,6 +370,7 @@ pub fn python_file_at_path(
// Search for `pyproject.toml` files in all parent directories. // Search for `pyproject.toml` files in all parent directories.
let mut resolver = Resolver::default(); let mut resolver = Resolver::default();
if matches!(pyproject_strategy, PyprojectDiscovery::Hierarchical(..)) {
for ancestor in path.ancestors() { for ancestor in path.ancestors() {
if let Some(pyproject) = settings_toml(ancestor)? { if let Some(pyproject) = settings_toml(ancestor)? {
let (root, settings) = let (root, settings) =
@ -373,6 +378,7 @@ pub fn python_file_at_path(
resolver.add(root, settings); resolver.add(root, settings);
} }
} }
}
// Check exclusions. // Check exclusions.
Ok(!is_file_excluded(&path, &resolver, pyproject_strategy)) Ok(!is_file_excluded(&path, &resolver, pyproject_strategy))