From dcccfe2591eb2debb7e11f6fce4fc5359e48cc67 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Thu, 12 Jan 2023 13:15:44 -0500 Subject: [PATCH] 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. --- resources/test/project/README.md | 8 ++-- src/resolver.rs | 66 +++++++++++++++++--------------- 2 files changed, 40 insertions(+), 34 deletions(-) diff --git a/resources/test/project/README.md b/resources/test/project/README.md index d9a22fcd1a..f65db93466 100644 --- a/resources/test/project/README.md +++ b/resources/test/project/README.md @@ -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/import_file.py:1:1: I001 Import block is un-sorted or un-formatted 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: @@ -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/import_file.py:1:1: I001 Import block is un-sorted or un-formatted 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 @@ -43,7 +43,7 @@ files: 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 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 @@ -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 excluded/script.py:5:5: F841 Local variable `x` is assigned to but never used 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: diff --git a/src/resolver.rs b/src/resolver.rs index 686439ab67..0d47108dc4 100644 --- a/src/resolver.rs +++ b/src/resolver.rs @@ -232,12 +232,14 @@ pub fn python_files_in_path( // Search for `pyproject.toml` files in all parent directories. let mut resolver = Resolver::default(); - for path in &paths { - for ancestor in path.ancestors() { - if let Some(pyproject) = settings_toml(ancestor)? { - let (root, settings) = - resolve_scoped_settings(&pyproject, &Relativity::Parent, processor)?; - resolver.add(root, settings); + if matches!(pyproject_strategy, PyprojectDiscovery::Hierarchical(..)) { + for path in &paths { + for ancestor in path.ancestors() { + if let Some(pyproject) = settings_toml(ancestor)? { + let (root, settings) = + resolve_scoped_settings(&pyproject, &Relativity::Parent, processor)?; + resolver.add(root, settings); + } } } } @@ -272,29 +274,31 @@ pub fn python_files_in_path( Box::new(|result| { // Search for the `pyproject.toml` file in this directory, before we visit any // of its contents. - if let Ok(entry) = &result { - if entry - .file_type() - .map_or(false, |file_type| file_type.is_dir()) - { - match settings_toml(entry.path()) { - Ok(Some(pyproject)) => match resolve_scoped_settings( - &pyproject, - &Relativity::Parent, - processor, - ) { - Ok((root, settings)) => { - resolver.write().unwrap().add(root, settings); - } + if matches!(pyproject_strategy, PyprojectDiscovery::Hierarchical(..)) { + if let Ok(entry) = &result { + if entry + .file_type() + .map_or(false, |file_type| file_type.is_dir()) + { + match settings_toml(entry.path()) { + Ok(Some(pyproject)) => match resolve_scoped_settings( + &pyproject, + &Relativity::Parent, + processor, + ) { + Ok((root, settings)) => { + resolver.write().unwrap().add(root, settings); + } + Err(err) => { + *error.lock().unwrap() = Err(err); + return WalkState::Quit; + } + }, + Ok(None) => {} Err(err) => { *error.lock().unwrap() = Err(err); return WalkState::Quit; } - }, - Ok(None) => {} - Err(err) => { - *error.lock().unwrap() = Err(err); - return WalkState::Quit; } } } @@ -366,11 +370,13 @@ pub fn python_file_at_path( // Search for `pyproject.toml` files in all parent directories. let mut resolver = Resolver::default(); - for ancestor in path.ancestors() { - if let Some(pyproject) = settings_toml(ancestor)? { - let (root, settings) = - resolve_scoped_settings(&pyproject, &Relativity::Parent, processor)?; - resolver.add(root, settings); + if matches!(pyproject_strategy, PyprojectDiscovery::Hierarchical(..)) { + for ancestor in path.ancestors() { + if let Some(pyproject) = settings_toml(ancestor)? { + let (root, settings) = + resolve_scoped_settings(&pyproject, &Relativity::Parent, processor)?; + resolver.add(root, settings); + } } }