Skip to content

Commit

Permalink
add autofix for B033
Browse files Browse the repository at this point in the history
  • Loading branch information
diceroll123 committed Jan 14, 2024
1 parent b6ce4f5 commit d07dcbb
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 12 deletions.
4 changes: 2 additions & 2 deletions crates/ruff_linter/src/checkers/ast/analyze/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -980,9 +980,9 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) {
flake8_pie::rules::unnecessary_spread(checker, dict);
}
}
Expr::Set(ast::ExprSet { elts, range: _ }) => {
Expr::Set(ast::ExprSet { elts, range }) => {
if checker.enabled(Rule::DuplicateValue) {
flake8_bugbear::rules::duplicate_value(checker, elts);
flake8_bugbear::rules::duplicate_value(checker, elts, *range);
}
}
Expr::Yield(_) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use ruff_python_ast::Expr;
use ruff_python_ast::{Expr, ExprSet};
use rustc_hash::FxHashSet;

use ruff_diagnostics::{Diagnostic, Violation};
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::comparable::ComparableExpr;
use ruff_text_size::Ranged;
use ruff_text_size::{Ranged, TextRange};

use crate::checkers::ast::Checker;

Expand All @@ -30,28 +30,46 @@ pub struct DuplicateValue {
value: String,
}

impl Violation for DuplicateValue {
impl AlwaysFixableViolation for DuplicateValue {
#[derive_message_formats]
fn message(&self) -> String {
let DuplicateValue { value } = self;
format!("Sets should not contain duplicate item `{value}`")
}

fn fix_title(&self) -> String {
let DuplicateValue { value } = self;
format!("Remove duplicate item `{value}`")
}
}

/// B033
pub(crate) fn duplicate_value(checker: &mut Checker, elts: &Vec<Expr>) {
pub(crate) fn duplicate_value(checker: &mut Checker, elts: &[Expr], range: TextRange) {
let mut seen_values: FxHashSet<ComparableExpr> = FxHashSet::default();
for elt in elts {
for (index, elt) in elts.iter().enumerate() {
if elt.is_literal_expr() {
let comparable_value: ComparableExpr = elt.into();

if !seen_values.insert(comparable_value) {
checker.diagnostics.push(Diagnostic::new(
let mut diagnostic = Diagnostic::new(
DuplicateValue {
value: checker.generator().expr(elt),
},
elt.range(),
));
);

let mut elts_without_duplicate = elts.to_owned();
elts_without_duplicate.remove(index);

diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement(
checker.generator().expr(&Expr::Set(ExprSet {
elts: elts_without_duplicate,
range,
})),
range,
)));

checker.diagnostics.push(diagnostic);
}
};
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
---
source: crates/ruff_linter/src/rules/flake8_bugbear/mod.rs
---
B033.py:4:35: B033 Sets should not contain duplicate item `"value1"`
B033.py:4:35: B033 [*] Sets should not contain duplicate item `"value1"`
|
2 | # Errors.
3 | ###
4 | incorrect_set = {"value1", 23, 5, "value1"}
| ^^^^^^^^ B033
5 | incorrect_set = {1, 1}
|
= help: Remove duplicate item `"value1"`

B033.py:5:21: B033 Sets should not contain duplicate item `1`
Safe fix
1 1 | ###
2 2 | # Errors.
3 3 | ###
4 |-incorrect_set = {"value1", 23, 5, "value1"}
4 |+incorrect_set = {"value1", 23, 5}
5 5 | incorrect_set = {1, 1}
6 6 |
7 7 | ###

B033.py:5:21: B033 [*] Sets should not contain duplicate item `1`
|
3 | ###
4 | incorrect_set = {"value1", 23, 5, "value1"}
Expand All @@ -19,5 +30,16 @@ B033.py:5:21: B033 Sets should not contain duplicate item `1`
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}
5 |+incorrect_set = {1}
6 6 |
7 7 | ###
8 8 | # Non-errors.


0 comments on commit d07dcbb

Please sign in to comment.