Skip to content

Commit

Permalink
Showing 3 changed files with 129 additions and 35 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Errors

for item in {1}:
print(f"I can count to {item}!")

for item in {"apples", "lemons", "water"}: # flags in-line set literals
print(f"I like {item}.")

31 changes: 24 additions & 7 deletions crates/ruff_linter/src/rules/pylint/rules/iteration_over_set.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use ast::ExprContext;
use ruff_python_ast::{self as ast, Expr};

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

use crate::checkers::ast::Checker;
use crate::{checkers::ast::Checker, registry::AsRule};

/// ## What it does
/// Checks for iterations over `set` literals.
@@ -30,11 +31,15 @@ use crate::checkers::ast::Checker;
#[violation]
pub struct IterationOverSet;

impl Violation for IterationOverSet {
impl AlwaysFixableViolation for IterationOverSet {
#[derive_message_formats]
fn message(&self) -> String {
format!("Use a sequence type instead of a `set` when iterating over values")
}

fn fix_title(&self) -> String {
format!("Use a sequence type instead of a `set` when iterating over values")
}
}

/// PLC0208
@@ -47,7 +52,19 @@ pub(crate) fn iteration_over_set(checker: &mut Checker, expr: &Expr) {
return;
}

checker
.diagnostics
.push(Diagnostic::new(IterationOverSet, expr.range()));
let mut diagnostic = Diagnostic::new(IterationOverSet, expr.range());

if checker.patch(diagnostic.kind.rule()) {
let tuple = checker.generator().expr(&Expr::Tuple(ast::ExprTuple {
elts: elts.clone(),
ctx: ExprContext::Store,
range: TextRange::default(),
}));
diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement(
format!("({tuple})"),
expr.range(),
)));
}

checker.diagnostics.push(diagnostic);
}
Original file line number Diff line number Diff line change
@@ -1,53 +1,127 @@
---
source: crates/ruff_linter/src/rules/pylint/mod.rs
---
iteration_over_set.py:3:13: PLC0208 Use a sequence type instead of a `set` when iterating over values
iteration_over_set.py:3:13: PLC0208 [*] Use a sequence type instead of a `set` when iterating over values
|
1 | # Errors
2 |
3 | for item in {"apples", "lemons", "water"}: # flags in-line set literals
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLC0208
4 | print(f"I like {item}.")
3 | for item in {1}:
| ^^^ PLC0208
4 | print(f"I can count to {item}!")
|
= help: Use a sequence type instead of a `set` when iterating over values

Fix
1 1 | # Errors
2 2 |
3 |-for item in {1}:
3 |+for item in (1,):
4 4 | print(f"I can count to {item}!")
5 5 |
6 6 | for item in {"apples", "lemons", "water"}: # flags in-line set literals

iteration_over_set.py:6:28: PLC0208 Use a sequence type instead of a `set` when iterating over values
iteration_over_set.py:6:13: PLC0208 [*] Use a sequence type instead of a `set` when iterating over values
|
4 | print(f"I like {item}.")
4 | print(f"I can count to {item}!")
5 |
6 | numbers_list = [i for i in {1, 2, 3}] # flags sets in list comprehensions
| ^^^^^^^^^ PLC0208
7 |
8 | numbers_set = {i for i in {1, 2, 3}} # flags sets in set comprehensions
6 | for item in {"apples", "lemons", "water"}: # flags in-line set literals
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLC0208
7 | print(f"I like {item}.")
|
= help: Use a sequence type instead of a `set` when iterating over values

iteration_over_set.py:8:27: PLC0208 Use a sequence type instead of a `set` when iterating over values
Fix
3 3 | for item in {1}:
4 4 | print(f"I can count to {item}!")
5 5 |
6 |-for item in {"apples", "lemons", "water"}: # flags in-line set literals
6 |+for item in ("apples", "lemons", "water"): # flags in-line set literals
7 7 | print(f"I like {item}.")
8 8 |
9 9 | numbers_list = [i for i in {1, 2, 3}] # flags sets in list comprehensions

iteration_over_set.py:9:28: PLC0208 [*] Use a sequence type instead of a `set` when iterating over values
|
7 | print(f"I like {item}.")
8 |
9 | numbers_list = [i for i in {1, 2, 3}] # flags sets in list comprehensions
| ^^^^^^^^^ PLC0208
10 |
11 | numbers_set = {i for i in {1, 2, 3}} # flags sets in set comprehensions
|
6 | numbers_list = [i for i in {1, 2, 3}] # flags sets in list comprehensions
7 |
8 | numbers_set = {i for i in {1, 2, 3}} # flags sets in set comprehensions
= help: Use a sequence type instead of a `set` when iterating over values

Fix
6 6 | for item in {"apples", "lemons", "water"}: # flags in-line set literals
7 7 | print(f"I like {item}.")
8 8 |
9 |-numbers_list = [i for i in {1, 2, 3}] # flags sets in list comprehensions
9 |+numbers_list = [i for i in (1, 2, 3)] # flags sets in list comprehensions
10 10 |
11 11 | numbers_set = {i for i in {1, 2, 3}} # flags sets in set comprehensions
12 12 |

iteration_over_set.py:11:27: PLC0208 [*] Use a sequence type instead of a `set` when iterating over values
|
9 | numbers_list = [i for i in {1, 2, 3}] # flags sets in list comprehensions
10 |
11 | numbers_set = {i for i in {1, 2, 3}} # flags sets in set comprehensions
| ^^^^^^^^^ PLC0208
9 |
10 | numbers_dict = {str(i): i for i in {1, 2, 3}} # flags sets in dict comprehensions
12 |
13 | numbers_dict = {str(i): i for i in {1, 2, 3}} # flags sets in dict comprehensions
|
= help: Use a sequence type instead of a `set` when iterating over values

Fix
8 8 |
9 9 | numbers_list = [i for i in {1, 2, 3}] # flags sets in list comprehensions
10 10 |
11 |-numbers_set = {i for i in {1, 2, 3}} # flags sets in set comprehensions
11 |+numbers_set = {i for i in (1, 2, 3)} # flags sets in set comprehensions
12 12 |
13 13 | numbers_dict = {str(i): i for i in {1, 2, 3}} # flags sets in dict comprehensions
14 14 |

iteration_over_set.py:10:36: PLC0208 Use a sequence type instead of a `set` when iterating over values
iteration_over_set.py:13:36: PLC0208 [*] Use a sequence type instead of a `set` when iterating over values
|
8 | numbers_set = {i for i in {1, 2, 3}} # flags sets in set comprehensions
9 |
10 | numbers_dict = {str(i): i for i in {1, 2, 3}} # flags sets in dict comprehensions
11 | numbers_set = {i for i in {1, 2, 3}} # flags sets in set comprehensions
12 |
13 | numbers_dict = {str(i): i for i in {1, 2, 3}} # flags sets in dict comprehensions
| ^^^^^^^^^ PLC0208
11 |
12 | numbers_gen = (i for i in {1, 2, 3}) # flags sets in generator expressions
14 |
15 | numbers_gen = (i for i in {1, 2, 3}) # flags sets in generator expressions
|
= help: Use a sequence type instead of a `set` when iterating over values

iteration_over_set.py:12:27: PLC0208 Use a sequence type instead of a `set` when iterating over values
Fix
10 10 |
11 11 | numbers_set = {i for i in {1, 2, 3}} # flags sets in set comprehensions
12 12 |
13 |-numbers_dict = {str(i): i for i in {1, 2, 3}} # flags sets in dict comprehensions
13 |+numbers_dict = {str(i): i for i in (1, 2, 3)} # flags sets in dict comprehensions
14 14 |
15 15 | numbers_gen = (i for i in {1, 2, 3}) # flags sets in generator expressions
16 16 |

iteration_over_set.py:15:27: PLC0208 [*] Use a sequence type instead of a `set` when iterating over values
|
10 | numbers_dict = {str(i): i for i in {1, 2, 3}} # flags sets in dict comprehensions
11 |
12 | numbers_gen = (i for i in {1, 2, 3}) # flags sets in generator expressions
13 | numbers_dict = {str(i): i for i in {1, 2, 3}} # flags sets in dict comprehensions
14 |
15 | numbers_gen = (i for i in {1, 2, 3}) # flags sets in generator expressions
| ^^^^^^^^^ PLC0208
13 |
14 | # Non-errors
16 |
17 | # Non-errors
|
= help: Use a sequence type instead of a `set` when iterating over values

Fix
12 12 |
13 13 | numbers_dict = {str(i): i for i in {1, 2, 3}} # flags sets in dict comprehensions
14 14 |
15 |-numbers_gen = (i for i in {1, 2, 3}) # flags sets in generator expressions
15 |+numbers_gen = (i for i in (1, 2, 3)) # flags sets in generator expressions
16 16 |
17 17 | # Non-errors
18 18 |


0 comments on commit 5986ff7

Please sign in to comment.