From b574c93109bf1f08416b2bce77a0b0c6053cdc73 Mon Sep 17 00:00:00 2001 From: Steve C Date: Sat, 13 Jan 2024 23:58:24 -0500 Subject: [PATCH] tweak logic --- .../test/fixtures/flake8_bugbear/B033.py | 2 +- .../flake8_bugbear/rules/duplicate_value.rs | 56 ++++++++++++------- ...__flake8_bugbear__tests__B033_B033.py.snap | 31 ++++++++-- 3 files changed, 64 insertions(+), 25 deletions(-) diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_bugbear/B033.py b/crates/ruff_linter/resources/test/fixtures/flake8_bugbear/B033.py index 61f2dd355ba5c2..f94a62bee6a380 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_bugbear/B033.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_bugbear/B033.py @@ -2,7 +2,7 @@ # Errors. ### incorrect_set = {"value1", 23, 5, "value1"} -incorrect_set = {1, 1} +incorrect_set = {1, 1, 2, 1} ### # Non-errors. diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/rules/duplicate_value.rs b/crates/ruff_linter/src/rules/flake8_bugbear/rules/duplicate_value.rs index f5f90a511d62d3..b21f258cfb8147 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/rules/duplicate_value.rs +++ b/crates/ruff_linter/src/rules/flake8_bugbear/rules/duplicate_value.rs @@ -46,31 +46,49 @@ impl AlwaysFixableViolation for DuplicateValue { /// B033 pub(crate) fn duplicate_value(checker: &mut Checker, elts: &[Expr], range: TextRange) { let mut seen_values: FxHashSet = FxHashSet::default(); + let mut duplicate_indices: Vec = Vec::new(); + let mut unique_indices: Vec = Vec::new(); + for (index, elt) in elts.iter().enumerate() { if elt.is_literal_expr() { let comparable_value: ComparableExpr = elt.into(); - if !seen_values.insert(comparable_value) { - let mut diagnostic = Diagnostic::new( - DuplicateValue { - value: checker.generator().expr(elt), - }, - elt.range(), - ); + if seen_values.insert(comparable_value) { + unique_indices.push(index); + } else { + duplicate_indices.push(index); + } + } else { + unique_indices.push(index); + } + } - let mut elts_without_duplicate = elts.to_owned(); - elts_without_duplicate.remove(index); + if duplicate_indices.is_empty() { + return; + } - diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( - checker.generator().expr(&Expr::Set(ExprSet { - elts: elts_without_duplicate, - range, - })), - range, - ))); + let fix = Fix::safe_edit(Edit::range_replacement( + checker.generator().expr(&Expr::Set(ExprSet { + elts: unique_indices + .into_iter() + .map(|index| elts[index].clone()) + .collect(), + range: TextRange::default(), + })), + range, + )); - checker.diagnostics.push(diagnostic); - } - }; + for index in duplicate_indices { + let elt = &elts[index]; + let mut diagnostic = Diagnostic::new( + DuplicateValue { + value: checker.generator().expr(elt), + }, + elt.range(), + ); + + diagnostic.set_fix(fix.clone()); + + checker.diagnostics.push(diagnostic); } } diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B033_B033.py.snap b/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B033_B033.py.snap index 25e429be25fbd3..ecce5cf7cdc3d4 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B033_B033.py.snap +++ b/crates/ruff_linter/src/rules/flake8_bugbear/snapshots/ruff_linter__rules__flake8_bugbear__tests__B033_B033.py.snap @@ -7,7 +7,7 @@ B033.py:4:35: B033 [*] Sets should not contain duplicate item `"value1"` 3 | ### 4 | incorrect_set = {"value1", 23, 5, "value1"} | ^^^^^^^^ B033 -5 | incorrect_set = {1, 1} +5 | incorrect_set = {1, 1, 2, 1} | = help: Remove duplicate item `"value1"` @@ -17,7 +17,7 @@ B033.py:4:35: B033 [*] Sets should not contain duplicate item `"value1"` 3 3 | ### 4 |-incorrect_set = {"value1", 23, 5, "value1"} 4 |+incorrect_set = {"value1", 23, 5} -5 5 | incorrect_set = {1, 1} +5 5 | incorrect_set = {1, 1, 2, 1} 6 6 | 7 7 | ### @@ -25,7 +25,7 @@ B033.py:5:21: B033 [*] Sets should not contain duplicate item `1` | 3 | ### 4 | incorrect_set = {"value1", 23, 5, "value1"} -5 | incorrect_set = {1, 1} +5 | incorrect_set = {1, 1, 2, 1} | ^ B033 6 | 7 | ### @@ -36,8 +36,29 @@ B033.py:5:21: B033 [*] Sets should not contain duplicate item `1` 2 2 | # Errors. 3 3 | ### 4 4 | incorrect_set = {"value1", 23, 5, "value1"} -5 |-incorrect_set = {1, 1} - 5 |+incorrect_set = {1} +5 |-incorrect_set = {1, 1, 2, 1} + 5 |+incorrect_set = {1, 2} +6 6 | +7 7 | ### +8 8 | # Non-errors. + +B033.py:5:27: B033 [*] Sets should not contain duplicate item `1` + | +3 | ### +4 | incorrect_set = {"value1", 23, 5, "value1"} +5 | incorrect_set = {1, 1, 2, 1} + | ^ B033 +6 | +7 | ### + | + = help: Remove duplicate item `1` + +ℹ Safe fix +2 2 | # Errors. +3 3 | ### +4 4 | incorrect_set = {"value1", 23, 5, "value1"} +5 |-incorrect_set = {1, 1, 2, 1} + 5 |+incorrect_set = {1, 2} 6 6 | 7 7 | ### 8 8 | # Non-errors.