diff --git a/crates/ruff_linter/resources/test/fixtures/pylint/too_many_locals.py b/crates/ruff_linter/resources/test/fixtures/pylint/too_many_locals.py index ab1f61cf5be4f..40af4a3fb1bf9 100644 --- a/crates/ruff_linter/resources/test/fixtures/pylint/too_many_locals.py +++ b/crates/ruff_linter/resources/test/fixtures/pylint/too_many_locals.py @@ -1,5 +1,4 @@ -def func(): - # Ok +def func() -> None: # Ok # 15 is max default first = 1 second = 2 @@ -17,8 +16,7 @@ def func(): fourteenth = 14 fifteenth = 15 -def func(): - # PLR0914 +def func() -> None: # PLR0914 first = 1 second = 2 third = 3 diff --git a/crates/ruff_linter/src/checkers/ast/analyze/deferred_scopes.rs b/crates/ruff_linter/src/checkers/ast/analyze/deferred_scopes.rs index 1695db066a79b..c4597a495bdd3 100644 --- a/crates/ruff_linter/src/checkers/ast/analyze/deferred_scopes.rs +++ b/crates/ruff_linter/src/checkers/ast/analyze/deferred_scopes.rs @@ -1,9 +1,8 @@ -use std::ops::Add; - use ruff_diagnostics::Diagnostic; +use ruff_python_ast::identifier::Identifier; use ruff_python_semantic::analyze::visibility; use ruff_python_semantic::{Binding, BindingKind, ScopeKind}; -use ruff_text_size::{Ranged, TextRange, TextSize}; +use ruff_text_size::Ranged; use crate::checkers::ast::Checker; use crate::codes::Rule; @@ -342,29 +341,24 @@ pub(crate) fn deferred_scopes(checker: &mut Checker) { if checker.enabled(Rule::TooManyLocals) { // PLR0914 - let mut num_locals = 0; - let mut last_seen_range = TextRange::default(); - for (_name, binding_id) in scope.bindings() { - let binding = checker.semantic.binding(binding_id); - if matches!(binding.kind, BindingKind::Assignment) { - num_locals += 1; - - // use the beginning of the last seen assignment as the range - last_seen_range = TextRange::new( - binding.range().start(), - binding.range().start().add(TextSize::from(1)), - ); - } - } + let num_locals = scope + .binding_ids() + .filter(|&id| { + let binding = checker.semantic.binding(id); + matches!(binding.kind, BindingKind::Assignment) + }) + .count(); if num_locals > checker.settings.pylint.max_locals { - diagnostics.push(Diagnostic::new( - pylint::rules::TooManyLocals { - current_amount: num_locals, - max_amount: checker.settings.pylint.max_locals, - }, - last_seen_range, - )); + if let ScopeKind::Function(func) = scope.kind { + diagnostics.push(Diagnostic::new( + pylint::rules::TooManyLocals { + current_amount: num_locals, + max_amount: checker.settings.pylint.max_locals, + }, + func.identifier(), + )); + }; } } } diff --git a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__too_many_locals.snap b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__too_many_locals.snap index f9286ddb25280..100255a4c8b6c 100644 --- a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__too_many_locals.snap +++ b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__too_many_locals.snap @@ -1,13 +1,14 @@ --- source: crates/ruff_linter/src/rules/pylint/mod.rs --- -too_many_locals.py:36:5: PLR0914 Too many local variables: (16/15) +too_many_locals.py:19:5: PLR0914 Too many local variables: (16/15) | -34 | thirteenth = 13 -35 | fourteenth = 14 -36 | fifteenth = 15 - | ^ PLR0914 -37 | sixteenth = 16 +17 | fifteenth = 15 +18 | +19 | def func() -> None: # PLR0914 + | ^^^^ PLR0914 +20 | first = 1 +21 | second = 2 |