diff --git a/crates/ruff/resources/test/fixtures/perflint/PERF401.py b/crates/ruff/resources/test/fixtures/perflint/PERF401.py index 2c4434c8ed433..886e5b9ada1da 100644 --- a/crates/ruff/resources/test/fixtures/perflint/PERF401.py +++ b/crates/ruff/resources/test/fixtures/perflint/PERF401.py @@ -45,3 +45,18 @@ def f(): for i in items: if i not in result: result.append(i) # OK + + +def f(): + fibonacci = [0, 1] + for i in range(20): + fibonacci.append(sum(fibonacci[-2:])) # OK + print(fibonacci) + + +def f(): + foo = object() + foo.fibonacci = [0, 1] + for i in range(20): + foo.fibonacci.append(sum(foo.fibonacci[-2:])) # OK + print(foo.fibonacci) diff --git a/crates/ruff/src/rules/perflint/rules/manual_list_comprehension.rs b/crates/ruff/src/rules/perflint/rules/manual_list_comprehension.rs index 2881cd70bb1d8..1f9f287edfcd9 100644 --- a/crates/ruff/src/rules/perflint/rules/manual_list_comprehension.rs +++ b/crates/ruff/src/rules/perflint/rules/manual_list_comprehension.rs @@ -2,6 +2,7 @@ use ruff_python_ast::{self as ast, Expr, Stmt}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::comparable::ComparableExpr; use ruff_python_ast::helpers::any_over_expr; use crate::checkers::ast::Checker; @@ -129,6 +130,13 @@ pub(crate) fn manual_list_comprehension(checker: &mut Checker, target: &Expr, bo return; } + // Avoid, e.g., `for x in y: filtered.append(filtered[-1] * 2)`. + if any_over_expr(arg, &|expr| { + ComparableExpr::from(expr) == ComparableExpr::from(value) + }) { + return; + } + // Avoid if the value is used in the conditional test, e.g., // // ```python diff --git a/crates/ruff/src/rules/perflint/rules/manual_list_copy.rs b/crates/ruff/src/rules/perflint/rules/manual_list_copy.rs index 051b508adab86..902fb2138b42f 100644 --- a/crates/ruff/src/rules/perflint/rules/manual_list_copy.rs +++ b/crates/ruff/src/rules/perflint/rules/manual_list_copy.rs @@ -1,8 +1,7 @@ -use ruff_python_ast::{self as ast, Expr, Stmt}; - use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::helpers::any_over_expr; +use ruff_python_ast::{self as ast, Expr, Stmt}; use crate::checkers::ast::Checker; @@ -89,7 +88,7 @@ pub(crate) fn manual_list_copy(checker: &mut Checker, target: &Expr, body: &[Stm return; } - // Avoid, e.g., `for x in y: filtered[x].append(x * x)`. + // Avoid, e.g., `for x in y: filtered[x].append(x)`. if any_over_expr(value, &|expr| { expr.as_name_expr().map_or(false, |expr| expr.id == *id) }) {