diff --git a/crates/ruff_linter/resources/test/fixtures/pylint/unnecessary_list_index_lookup.py b/crates/ruff_linter/resources/test/fixtures/pylint/unnecessary_list_index_lookup.py index 8911c8bd26..43fe696447 100644 --- a/crates/ruff_linter/resources/test/fixtures/pylint/unnecessary_list_index_lookup.py +++ b/crates/ruff_linter/resources/test/fixtures/pylint/unnecessary_list_index_lookup.py @@ -62,3 +62,17 @@ def value_intentionally_unused(): print(letters[index]) # OK blah = letters[index] # OK letters[index] = "d" # OK + + +def start(): + # OK + for index, list_item in enumerate(some_list, start=1): + print(some_list[index]) + + # PLR1736 + for index, list_item in enumerate(some_list, start=0): + print(some_list[index]) + + # PLR1736 + for index, list_item in enumerate(some_list): + print(some_list[index]) diff --git a/crates/ruff_linter/src/rules/pylint/rules/unnecessary_list_index_lookup.rs b/crates/ruff_linter/src/rules/pylint/rules/unnecessary_list_index_lookup.rs index 1203378999..21540b1655 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/unnecessary_list_index_lookup.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/unnecessary_list_index_lookup.rs @@ -1,7 +1,7 @@ use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::visitor::Visitor; -use ruff_python_ast::{self as ast, Expr, StmtFor}; +use ruff_python_ast::{self as ast, Expr, Int, Number, StmtFor}; use ruff_python_semantic::SemanticModel; use ruff_text_size::Ranged; @@ -151,6 +151,19 @@ fn enumerate_items<'a>( return None; }; + // If the `enumerate` call has a non-zero `start`, don't omit. + if !arguments.find_argument("start", 1).map_or(true, |expr| { + matches!( + expr, + Expr::NumberLiteral(ast::ExprNumberLiteral { + value: Number::Int(Int::ZERO), + .. + }) + ) + }) { + return None; + } + // Check that the function is the `enumerate` builtin. if !semantic.match_builtin_expr(func, "enumerate") { return None; diff --git a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR1736_unnecessary_list_index_lookup.py.snap b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR1736_unnecessary_list_index_lookup.py.snap index a212e600b2..afdb950361 100644 --- a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR1736_unnecessary_list_index_lookup.py.snap +++ b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__PLR1736_unnecessary_list_index_lookup.py.snap @@ -181,3 +181,40 @@ unnecessary_list_index_lookup.py:19:16: PLR1736 [*] List index lookup in `enumer 20 20 | 21 21 | 22 22 | def dont_fix_these(): + +unnecessary_list_index_lookup.py:74:15: PLR1736 [*] List index lookup in `enumerate()` loop + | +72 | # PLR1736 +73 | for index, list_item in enumerate(some_list, start=0): +74 | print(some_list[index]) + | ^^^^^^^^^^^^^^^^ PLR1736 +75 | +76 | # PLR1736 + | + = help: Use the loop variable directly + +ℹ Safe fix +71 71 | +72 72 | # PLR1736 +73 73 | for index, list_item in enumerate(some_list, start=0): +74 |- print(some_list[index]) + 74 |+ print(list_item) +75 75 | +76 76 | # PLR1736 +77 77 | for index, list_item in enumerate(some_list): + +unnecessary_list_index_lookup.py:78:15: PLR1736 [*] List index lookup in `enumerate()` loop + | +76 | # PLR1736 +77 | for index, list_item in enumerate(some_list): +78 | print(some_list[index]) + | ^^^^^^^^^^^^^^^^ PLR1736 + | + = help: Use the loop variable directly + +ℹ Safe fix +75 75 | +76 76 | # PLR1736 +77 77 | for index, list_item in enumerate(some_list): +78 |- print(some_list[index]) + 78 |+ print(list_item)