diff --git a/Cargo.lock b/Cargo.lock index 2618f79662..668a7613b3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "Inflector" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" + [[package]] name = "adler" version = "1.0.2" @@ -1023,6 +1029,19 @@ dependencies = [ "windows-sys 0.45.0", ] +[[package]] +name = "is-macro" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7d079e129b77477a49c5c4f1cfe9ce6c2c909ef52520693e8e811a714c7b20" +dependencies = [ + "Inflector", + "pmutil", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "is-terminal" version = "0.4.4" @@ -1971,6 +1990,7 @@ dependencies = [ "ignore", "imperative", "insta", + "is-macro", "itertools", "js-sys", "libcst", diff --git a/crates/ruff/Cargo.toml b/crates/ruff/Cargo.toml index e100007472..f83a04b658 100644 --- a/crates/ruff/Cargo.toml +++ b/crates/ruff/Cargo.toml @@ -33,6 +33,7 @@ glob = { version = "0.3.0" } globset = { version = "0.4.9" } ignore = { version = "0.4.18" } imperative = { version = "1.0.3" } +is-macro = { workspace = true } itertools = { workspace = true } libcst = { workspace = true } log = { version = "0.4.17" } diff --git a/crates/ruff/src/ast/types.rs b/crates/ruff/src/ast/types.rs index c3e11be0f3..dba8781e25 100644 --- a/crates/ruff/src/ast/types.rs +++ b/crates/ruff/src/ast/types.rs @@ -124,7 +124,7 @@ impl<'a> Scope<'a> { // StarImportation // FutureImportation -#[derive(Clone, Debug)] +#[derive(Clone, Debug, is_macro::Is)] pub enum BindingKind<'a> { Annotation, Argument, diff --git a/crates/ruff/src/checkers/ast.rs b/crates/ruff/src/checkers/ast.rs index 278c4f3970..4df49b76e8 100644 --- a/crates/ruff/src/checkers/ast.rs +++ b/crates/ruff/src/checkers/ast.rs @@ -229,9 +229,8 @@ impl<'a> Checker<'a> { /// Return `true` if `member` is bound as a builtin. pub fn is_builtin(&self, member: &str) -> bool { - self.find_binding(member).map_or(false, |binding| { - matches!(binding.kind, BindingKind::Builtin) - }) + self.find_binding(member) + .map_or(false, |binding| binding.kind.is_builtin()) } pub fn resolve_call_path<'b>(&'a self, value: &'b Expr) -> Option> @@ -1928,9 +1927,7 @@ where if self.scopes[GLOBAL_SCOPE_INDEX] .bindings .get(name) - .map_or(true, |index| { - matches!(self.bindings[*index].kind, BindingKind::Annotation) - }) + .map_or(true, |index| self.bindings[*index].kind.is_annotation()) { let index = self.bindings.len(); self.bindings.push(Binding { @@ -1992,9 +1989,7 @@ where if self.scopes[GLOBAL_SCOPE_INDEX] .bindings .get(name) - .map_or(true, |index| { - matches!(self.bindings[*index].kind, BindingKind::Annotation) - }) + .map_or(true, |index| self.bindings[*index].kind.is_annotation()) { let index = self.bindings.len(); self.bindings.push(Binding { @@ -4136,7 +4131,7 @@ impl<'a> Checker<'a> { let existing_binding_index = self.scopes[*scope_index].bindings.get(&name).unwrap(); let existing = &self.bindings[*existing_binding_index]; let in_current_scope = stack_index == 0; - if !matches!(existing.kind, BindingKind::Builtin) + if !existing.kind.is_builtin() && existing.source.as_ref().map_or(true, |left| { binding.source.as_ref().map_or(true, |right| { !branch_detection::different_forks( @@ -4156,7 +4151,7 @@ impl<'a> Checker<'a> { | BindingKind::StarImportation(..) | BindingKind::FutureImportation ); - if matches!(binding.kind, BindingKind::LoopVar) && existing_is_import { + if binding.kind.is_loop_var() && existing_is_import { if self.settings.rules.enabled(&Rule::ImportShadowedByLoopVar) { self.diagnostics.push(Diagnostic::new( pyflakes::rules::ImportShadowedByLoopVar { @@ -4170,7 +4165,7 @@ impl<'a> Checker<'a> { if !existing.used() && binding.redefines(existing) && (!self.settings.dummy_variable_rgx.is_match(name) || existing_is_import) - && !(matches!(existing.kind, BindingKind::FunctionDefinition) + && !(existing.kind.is_function_definition() && visibility::is_overload( self, cast::decorator_list(existing.source.as_ref().unwrap()), @@ -4205,36 +4200,29 @@ impl<'a> Checker<'a> { let scope = self.current_scope(); let binding = if let Some(index) = scope.bindings.get(&name) { - if matches!(self.bindings[*index].kind, BindingKind::Builtin) { - // Avoid overriding builtins. - binding - } else if matches!(self.bindings[*index].kind, BindingKind::Global) { - // If the original binding was a global, and the new binding conflicts within - // the current scope, then the new binding is also a global. - Binding { - runtime_usage: self.bindings[*index].runtime_usage, - synthetic_usage: self.bindings[*index].synthetic_usage, - typing_usage: self.bindings[*index].typing_usage, - kind: BindingKind::Global, - ..binding + let existing = &self.bindings[*index]; + match &existing.kind { + BindingKind::Builtin => { + // Avoid overriding builtins. + binding } - } else if matches!(self.bindings[*index].kind, BindingKind::Nonlocal) { - // If the original binding was a nonlocal, and the new binding conflicts within - // the current scope, then the new binding is also a nonlocal. - Binding { - runtime_usage: self.bindings[*index].runtime_usage, - synthetic_usage: self.bindings[*index].synthetic_usage, - typing_usage: self.bindings[*index].typing_usage, - kind: BindingKind::Nonlocal, - ..binding + kind @ (BindingKind::Global | BindingKind::Nonlocal) => { + // If the original binding was a global or nonlocal, and the new binding conflicts within + // the current scope, then the new binding is also as the same. + Binding { + runtime_usage: existing.runtime_usage, + synthetic_usage: existing.synthetic_usage, + typing_usage: existing.typing_usage, + kind: kind.clone(), + ..binding + } } - } else { - Binding { - runtime_usage: self.bindings[*index].runtime_usage, - synthetic_usage: self.bindings[*index].synthetic_usage, - typing_usage: self.bindings[*index].typing_usage, + _ => Binding { + runtime_usage: existing.runtime_usage, + synthetic_usage: existing.synthetic_usage, + typing_usage: existing.typing_usage, ..binding - } + }, } } else { binding @@ -4243,7 +4231,7 @@ impl<'a> Checker<'a> { // Don't treat annotations as assignments if there is an existing value // in scope. let scope = &mut self.scopes[*(self.scope_stack.last().expect("No current scope found"))]; - if !(matches!(binding.kind, BindingKind::Annotation) && scope.bindings.contains_key(name)) { + if !(binding.kind.is_annotation() && scope.bindings.contains_key(name)) { if let Some(rebound_index) = scope.bindings.insert(name, binding_index) { scope .rebounds @@ -4282,7 +4270,7 @@ impl<'a> Checker<'a> { let context = self.execution_context(); self.bindings[*index].mark_used(scope_id, Range::from_located(expr), context); - if matches!(self.bindings[*index].kind, BindingKind::Annotation) + if self.bindings[*index].kind.is_annotation() && !self.in_deferred_string_type_definition && !self.in_deferred_type_definition { @@ -4430,9 +4418,7 @@ impl<'a> Checker<'a> { .current_scope() .bindings .get(id) - .map_or(false, |index| { - matches!(self.bindings[*index].kind, BindingKind::Global) - }) + .map_or(false, |index| self.bindings[*index].kind.is_global()) { pep8_naming::rules::non_lowercase_variable_in_function(self, expr, parent, id); } @@ -4935,7 +4921,7 @@ impl<'a> Checker<'a> { { for (name, index) in &scope.bindings { let binding = &self.bindings[*index]; - if matches!(binding.kind, BindingKind::Global) { + if binding.kind.is_global() { if let Some(stmt) = &binding.source { if matches!(stmt.node, StmtKind::Global { .. }) { diagnostics.push(Diagnostic::new( diff --git a/crates/ruff/src/directives.rs b/crates/ruff/src/directives.rs index 891f79a6be..ad3ab6ec11 100644 --- a/crates/ruff/src/directives.rs +++ b/crates/ruff/src/directives.rs @@ -6,7 +6,6 @@ use rustpython_parser::ast::Location; use rustpython_parser::lexer::LexResult; use rustpython_parser::Tok; -use crate::registry::LintSource; use crate::settings::Settings; bitflags! { @@ -21,7 +20,7 @@ impl Flags { if settings .rules .iter_enabled() - .any(|rule_code| matches!(rule_code.lint_source(), LintSource::Imports)) + .any(|rule_code| rule_code.lint_source().is_imports()) { Self::NOQA | Self::ISORT } else { diff --git a/crates/ruff/src/linter.rs b/crates/ruff/src/linter.rs index ad71f8e4de..f98b4a5b28 100644 --- a/crates/ruff/src/linter.rs +++ b/crates/ruff/src/linter.rs @@ -20,7 +20,7 @@ use crate::directives::Directives; use crate::doc_lines::{doc_lines_from_ast, doc_lines_from_tokens}; use crate::message::{Message, Source}; use crate::noqa::{add_noqa, rule_is_ignored}; -use crate::registry::{Diagnostic, LintSource, Rule}; +use crate::registry::{Diagnostic, Rule}; use crate::rules::pycodestyle; use crate::settings::{flags, Settings}; use crate::source_code::{Indexer, Locator, Stylist}; @@ -81,7 +81,7 @@ pub fn check_path( if settings .rules .iter_enabled() - .any(|rule_code| matches!(rule_code.lint_source(), LintSource::Tokens)) + .any(|rule_code| rule_code.lint_source().is_tokens()) { diagnostics.extend(check_tokens(locator, &tokens, settings, autofix)); } @@ -90,7 +90,7 @@ pub fn check_path( if settings .rules .iter_enabled() - .any(|rule_code| matches!(rule_code.lint_source(), LintSource::Filesystem)) + .any(|rule_code| rule_code.lint_source().is_filesystem()) { diagnostics.extend(check_file_path(path, package, settings)); } @@ -99,7 +99,7 @@ pub fn check_path( if settings .rules .iter_enabled() - .any(|rule_code| matches!(rule_code.lint_source(), LintSource::LogicalLines)) + .any(|rule_code| rule_code.lint_source().is_logical_lines()) { diagnostics.extend(check_logical_lines(&tokens, locator, stylist, settings)); } @@ -108,12 +108,12 @@ pub fn check_path( let use_ast = settings .rules .iter_enabled() - .any(|rule_code| matches!(rule_code.lint_source(), LintSource::Ast)); + .any(|rule_code| rule_code.lint_source().is_ast()); let use_imports = !directives.isort.skip_file && settings .rules .iter_enabled() - .any(|rule_code| matches!(rule_code.lint_source(), LintSource::Imports)); + .any(|rule_code| rule_code.lint_source().is_imports()); if use_ast || use_imports || use_doc_lines { match ruff_rustpython::parse_program_tokens(tokens, &path.to_string_lossy()) { Ok(python_ast) => { @@ -177,7 +177,7 @@ pub fn check_path( if settings .rules .iter_enabled() - .any(|rule_code| matches!(rule_code.lint_source(), LintSource::PhysicalLines)) + .any(|rule_code| rule_code.lint_source().is_physical_lines()) { diagnostics.extend(check_physical_lines( path, @@ -203,7 +203,7 @@ pub fn check_path( || settings .rules .iter_enabled() - .any(|rule_code| matches!(rule_code.lint_source(), LintSource::NoQa)) + .any(|rule_code| rule_code.lint_source().is_noqa()) { check_noqa( &mut diagnostics, diff --git a/crates/ruff/src/registry.rs b/crates/ruff/src/registry.rs index 3ab1c1cced..ebdca77595 100644 --- a/crates/ruff/src/registry.rs +++ b/crates/ruff/src/registry.rs @@ -759,6 +759,7 @@ impl Linter { } } +#[derive(is_macro::Is)] pub enum LintSource { Ast, Io, @@ -766,7 +767,7 @@ pub enum LintSource { LogicalLines, Tokens, Imports, - NoQa, + Noqa, Filesystem, } @@ -775,7 +776,7 @@ impl Rule { /// physical lines). pub const fn lint_source(&self) -> &'static LintSource { match self { - Rule::UnusedNOQA => &LintSource::NoQa, + Rule::UnusedNOQA => &LintSource::Noqa, Rule::BlanketNOQA | Rule::BlanketTypeIgnore | Rule::DocLineTooLong diff --git a/crates/ruff/src/resolver.rs b/crates/ruff/src/resolver.rs index 2cba43043a..59154920a4 100644 --- a/crates/ruff/src/resolver.rs +++ b/crates/ruff/src/resolver.rs @@ -19,7 +19,7 @@ use crate::settings::{pyproject, AllSettings, Settings}; /// The strategy used to discover the relevant `pyproject.toml` file for each /// Python file. -#[derive(Debug)] +#[derive(Debug, is_macro::Is)] pub enum PyprojectDiscovery { /// Use a fixed `pyproject.toml` file for all Python files (i.e., one /// provided on the command-line). @@ -30,7 +30,7 @@ pub enum PyprojectDiscovery { } impl PyprojectDiscovery { - fn top_level_settings(&self) -> &AllSettings { + pub fn top_level_settings(&self) -> &AllSettings { match self { PyprojectDiscovery::Fixed(settings) => settings, PyprojectDiscovery::Hierarchical(settings) => settings, @@ -82,13 +82,7 @@ impl Resolver { .settings .iter() .rev() - .find_map(|(root, settings)| { - if path.starts_with(root) { - Some(settings) - } else { - None - } - }) + .find_map(|(root, settings)| path.starts_with(root).then_some(settings)) .unwrap_or(default), } } @@ -228,7 +222,7 @@ pub fn python_files_in_path( // Search for `pyproject.toml` files in all parent directories. let mut resolver = Resolver::default(); let mut seen = FxHashSet::default(); - if matches!(pyproject_strategy, PyprojectDiscovery::Hierarchical(..)) { + if pyproject_strategy.is_hierarchical() { for path in &paths { for ancestor in path.ancestors() { if seen.insert(ancestor) { @@ -277,7 +271,7 @@ 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 matches!(pyproject_strategy, PyprojectDiscovery::Hierarchical(..)) { + if pyproject_strategy.is_hierarchical() { if let Ok(entry) = &result { if entry .file_type() @@ -372,7 +366,7 @@ pub fn python_file_at_path( // Search for `pyproject.toml` files in all parent directories. let mut resolver = Resolver::default(); - if matches!(pyproject_strategy, PyprojectDiscovery::Hierarchical(..)) { + if pyproject_strategy.is_hierarchical() { for ancestor in path.ancestors() { if let Some(pyproject) = settings_toml(ancestor)? { let (root, settings) = diff --git a/crates/ruff/src/rules/flake8_bugbear/rules/unused_loop_control_variable.rs b/crates/ruff/src/rules/flake8_bugbear/rules/unused_loop_control_variable.rs index efaa29b419..3b301b4186 100644 --- a/crates/ruff/src/rules/flake8_bugbear/rules/unused_loop_control_variable.rs +++ b/crates/ruff/src/rules/flake8_bugbear/rules/unused_loop_control_variable.rs @@ -23,7 +23,7 @@ use rustc_hash::FxHashMap; use rustpython_parser::ast::{Expr, ExprKind, Stmt}; use serde::{Deserialize, Serialize}; -use crate::ast::types::{BindingKind, Range, RefEquality}; +use crate::ast::types::{Range, RefEquality}; use crate::ast::visitor::Visitor; use crate::ast::{helpers, visitor}; use crate::checkers::ast::Checker; @@ -185,7 +185,7 @@ pub fn unused_loop_control_variable( .and_then(|source| (source == &RefEquality(stmt)).then_some(binding)) }); if let Some(binding) = binding { - if matches!(binding.kind, BindingKind::LoopVar) { + if binding.kind.is_loop_var() { if !binding.used() { diagnostic.amend(Fix::replacement( rename, diff --git a/crates/ruff/src/rules/flake8_self/rules/private_member_access.rs b/crates/ruff/src/rules/flake8_self/rules/private_member_access.rs index 8f2a7d546a..e4dca40545 100644 --- a/crates/ruff/src/rules/flake8_self/rules/private_member_access.rs +++ b/crates/ruff/src/rules/flake8_self/rules/private_member_access.rs @@ -3,7 +3,7 @@ use rustpython_parser::ast::{Expr, ExprKind}; use ruff_macros::{define_violation, derive_message_formats}; use crate::ast::helpers::collect_call_path; -use crate::ast::types::{BindingKind, Range, ScopeKind}; +use crate::ast::types::{Range, ScopeKind}; use crate::checkers::ast::Checker; use crate::registry::Diagnostic; use crate::violation::Violation; @@ -101,7 +101,7 @@ pub fn private_member_access(checker: &mut Checker, expr: &Expr) { .map_or(false, |binding| { // TODO(charlie): Could the name ever be bound to a _different_ // class here? - matches!(binding.kind, BindingKind::ClassDefinition) + binding.kind.is_class_definition() }) } else { false diff --git a/crates/ruff/src/rules/flake8_unused_arguments/rules.rs b/crates/ruff/src/rules/flake8_unused_arguments/rules.rs index 4be2da38ca..721f332868 100644 --- a/crates/ruff/src/rules/flake8_unused_arguments/rules.rs +++ b/crates/ruff/src/rules/flake8_unused_arguments/rules.rs @@ -9,7 +9,7 @@ use super::helpers; use super::types::Argumentable; use crate::ast::function_type; use crate::ast::function_type::FunctionType; -use crate::ast::types::{Binding, BindingKind, FunctionDef, Lambda, Scope, ScopeKind}; +use crate::ast::types::{Binding, FunctionDef, Lambda, Scope, ScopeKind}; use crate::checkers::ast::Checker; use crate::registry::Diagnostic; use crate::violation::Violation; @@ -89,8 +89,7 @@ fn function( dummy_variable_rgx: &Regex, ignore_variadic_names: bool, ) -> Vec { - let mut diagnostics: Vec = vec![]; - for arg in args + let args = args .posonlyargs .iter() .chain(args.args.iter()) @@ -104,24 +103,8 @@ fn function( iter::once::>(args.kwarg.as_deref()) .flatten() .skip(usize::from(ignore_variadic_names)), - ) - { - if let Some(binding) = values - .get(&arg.node.arg.as_str()) - .map(|index| &bindings[*index]) - { - if !binding.used() - && matches!(binding.kind, BindingKind::Argument) - && !dummy_variable_rgx.is_match(arg.node.arg.as_str()) - { - diagnostics.push(Diagnostic::new( - argumentable.check_for(arg.node.arg.to_string()), - binding.range, - )); - } - } - } - diagnostics + ); + call(argumentable, args, values, bindings, dummy_variable_rgx) } /// Check a method for unused arguments. @@ -133,8 +116,7 @@ fn method( dummy_variable_rgx: &Regex, ignore_variadic_names: bool, ) -> Vec { - let mut diagnostics: Vec = vec![]; - for arg in args + let args = args .posonlyargs .iter() .chain(args.args.iter()) @@ -149,14 +131,25 @@ fn method( iter::once::>(args.kwarg.as_deref()) .flatten() .skip(usize::from(ignore_variadic_names)), - ) - { + ); + call(argumentable, args, values, bindings, dummy_variable_rgx) +} + +fn call<'a>( + argumentable: &Argumentable, + args: impl Iterator, + values: &FxHashMap<&str, usize>, + bindings: &[Binding], + dummy_variable_rgx: &Regex, +) -> Vec { + let mut diagnostics: Vec = vec![]; + for arg in args { if let Some(binding) = values .get(&arg.node.arg.as_str()) .map(|index| &bindings[*index]) { if !binding.used() - && matches!(binding.kind, BindingKind::Argument) + && binding.kind.is_argument() && !dummy_variable_rgx.is_match(arg.node.arg.as_str()) { diagnostics.push(Diagnostic::new( diff --git a/crates/ruff/src/rules/pyflakes/rules/unused_annotation.rs b/crates/ruff/src/rules/pyflakes/rules/unused_annotation.rs index f39093bb3c..acd4b5d5cb 100644 --- a/crates/ruff/src/rules/pyflakes/rules/unused_annotation.rs +++ b/crates/ruff/src/rules/pyflakes/rules/unused_annotation.rs @@ -1,6 +1,5 @@ use ruff_macros::{define_violation, derive_message_formats}; -use crate::ast::types::BindingKind; use crate::checkers::ast::Checker; use crate::registry::Diagnostic; use crate::violation::Violation; @@ -27,7 +26,7 @@ pub fn unused_annotation(checker: &mut Checker, scope: usize) { .map(|(name, index)| (name, &checker.bindings[*index])) { if !binding.used() - && matches!(binding.kind, BindingKind::Annotation) + && binding.kind.is_annotation() && !checker.settings.dummy_variable_rgx.is_match(name) { checker.diagnostics.push(Diagnostic::new( diff --git a/crates/ruff/src/rules/pyflakes/rules/unused_variable.rs b/crates/ruff/src/rules/pyflakes/rules/unused_variable.rs index 532f97d0f9..d4368e9295 100644 --- a/crates/ruff/src/rules/pyflakes/rules/unused_variable.rs +++ b/crates/ruff/src/rules/pyflakes/rules/unused_variable.rs @@ -5,7 +5,7 @@ use rustpython_parser::ast::{ExprKind, Located, Stmt, StmtKind}; use rustpython_parser::{lexer, Mode, Tok}; use crate::ast::helpers::contains_effect; -use crate::ast::types::{BindingKind, Range, RefEquality, ScopeKind}; +use crate::ast::types::{Range, RefEquality, ScopeKind}; use crate::autofix::helpers::delete_stmt; use crate::checkers::ast::Checker; use crate::fix::Fix; @@ -330,7 +330,7 @@ pub fn unused_variable(checker: &mut Checker, scope: usize) { .map(|(name, index)| (name, &checker.bindings[*index])) { if !binding.used() - && matches!(binding.kind, BindingKind::Assignment) + && binding.kind.is_assignment() && !checker.settings.dummy_variable_rgx.is_match(name) && name != &"__tracebackhide__" && name != &"__traceback_info__" diff --git a/crates/ruff_cli/src/commands/run.rs b/crates/ruff_cli/src/commands/run.rs index c717c9f2a9..f2f2a7c37c 100644 --- a/crates/ruff_cli/src/commands/run.rs +++ b/crates/ruff_cli/src/commands/run.rs @@ -41,23 +41,22 @@ pub fn run( // Initialize the cache. if cache.into() { + fn init_cache(path: &std::path::Path) { + if let Err(e) = cache::init(path) { + error!( + "Failed to initialize cache at {}: {e:?}", + path.to_string_lossy() + ); + } + } + match &pyproject_strategy { PyprojectDiscovery::Fixed(settings) => { - if let Err(e) = cache::init(&settings.cli.cache_dir) { - error!( - "Failed to initialize cache at {}: {e:?}", - settings.cli.cache_dir.to_string_lossy() - ); - } + init_cache(&settings.cli.cache_dir); } PyprojectDiscovery::Hierarchical(default) => { for settings in std::iter::once(default).chain(resolver.iter()) { - if let Err(e) = cache::init(&settings.cli.cache_dir) { - error!( - "Failed to initialize cache at {}: {e:?}", - settings.cli.cache_dir.to_string_lossy() - ); - } + init_cache(&settings.cli.cache_dir); } } } diff --git a/crates/ruff_cli/src/commands/run_stdin.rs b/crates/ruff_cli/src/commands/run_stdin.rs index 554634c8ed..298901c644 100644 --- a/crates/ruff_cli/src/commands/run_stdin.rs +++ b/crates/ruff_cli/src/commands/run_stdin.rs @@ -28,10 +28,7 @@ pub fn run_stdin( return Ok(Diagnostics::default()); } } - let settings = match pyproject_strategy { - PyprojectDiscovery::Fixed(settings) => settings, - PyprojectDiscovery::Hierarchical(settings) => settings, - }; + let settings = pyproject_strategy.top_level_settings(); let package_root = filename .and_then(Path::parent) .and_then(|path| packaging::detect_package_root(path, &settings.lib.namespace_packages)); diff --git a/crates/ruff_cli/src/main.rs b/crates/ruff_cli/src/main.rs index da3c82b2e2..25b49c4cd8 100644 --- a/crates/ruff_cli/src/main.rs +++ b/crates/ruff_cli/src/main.rs @@ -9,7 +9,6 @@ use colored::Colorize; use notify::{recommended_watcher, RecursiveMode, Watcher}; use ::ruff::logging::{set_up_logging, LogLevel}; -use ::ruff::resolver::PyprojectDiscovery; use ::ruff::settings::types::SerializationFormat; use ::ruff::settings::CliSettings; use ::ruff::{fix, fs, warn_user_once}; @@ -151,10 +150,7 @@ fn check(args: CheckArgs, log_level: LogLevel) -> Result { show_fixes, update_check, .. - } = match &pyproject_strategy { - PyprojectDiscovery::Fixed(settings) => settings.cli.clone(), - PyprojectDiscovery::Hierarchical(settings) => settings.cli.clone(), - }; + } = pyproject_strategy.top_level_settings().cli.clone(); // Autofix rules are as follows: // - If `--fix` or `--fix-only` is set, always apply fixes to the filesystem (or