From f69040f888db1e9e7a311ab6744a88f0c945d687 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Mon, 31 Jul 2023 23:47:58 -0400 Subject: [PATCH] Avoid PERF401 false positive on list access in loop --- crates/ruff/resources/test/fixtures/perflint/PERF401.py | 7 +++++++ .../src/rules/perflint/rules/manual_list_comprehension.rs | 8 ++++++++ crates/ruff/src/rules/perflint/rules/manual_list_copy.rs | 5 ++--- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/crates/ruff/resources/test/fixtures/perflint/PERF401.py b/crates/ruff/resources/test/fixtures/perflint/PERF401.py index 2c4434c8ed433c..f50cf49e066ec7 100644 --- a/crates/ruff/resources/test/fixtures/perflint/PERF401.py +++ b/crates/ruff/resources/test/fixtures/perflint/PERF401.py @@ -45,3 +45,10 @@ 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) 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 2881cd70bb1d8a..1f9f287edfcd96 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 051b508adab86b..902fb2138b42fe 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) }) {