Use set bracket replacement for iteration-over-set (#8001)

This commit is contained in:
Charlie Marsh 2023-10-17 00:12:05 -04:00 committed by GitHub
parent 73049df3ed
commit cb6d74c27b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 128 additions and 77 deletions

View file

@ -6,6 +6,14 @@ for item in {1}:
for item in {"apples", "lemons", "water"}: # flags in-line set literals
print(f"I like {item}.")
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}.")
numbers_list = [i for i in {1, 2, 3}] # flags sets in list comprehensions
numbers_set = {i for i in {1, 2, 3}} # flags sets in set comprehensions

View file

@ -1,9 +1,7 @@
use ast::ExprContext;
use ruff_python_ast::{self as ast, Expr};
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
use ruff_macros::{derive_message_formats, violation};
use ruff_text_size::{Ranged, TextRange};
use ruff_python_ast::{self as ast, Expr};
use ruff_text_size::Ranged;
use crate::checkers::ast::Checker;
@ -38,7 +36,7 @@ impl AlwaysFixableViolation for IterationOverSet {
}
fn fix_title(&self) -> String {
format!("Use a sequence type instead of a `set` when iterating over values")
format!("Convert to `tuple`")
}
}
@ -54,15 +52,14 @@ pub(crate) fn iteration_over_set(checker: &mut Checker, expr: &Expr) {
let mut diagnostic = Diagnostic::new(IterationOverSet, expr.range());
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(),
)));
let tuple = if let [elt] = elts.as_slice() {
let elt = checker.locator().slice(elt);
format!("({elt},)")
} else {
let set = checker.locator().slice(expr);
format!("({})", &set[1..set.len() - 1])
};
diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement(tuple, expr.range())));
checker.diagnostics.push(diagnostic);
}

View file

@ -9,7 +9,7 @@ iteration_over_set.py:3:13: PLC0208 [*] Use a sequence type instead of a `set` w
| ^^^ PLC0208
4 | print(f"I can count to {item}!")
|
= help: Use a sequence type instead of a `set` when iterating over values
= help: Convert to `tuple`
Fix
1 1 | # Errors
@ -28,7 +28,7 @@ iteration_over_set.py:6:13: PLC0208 [*] Use a sequence type instead of a `set` w
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLC0208
7 | print(f"I like {item}.")
|
= help: Use a sequence type instead of a `set` when iterating over values
= help: Convert to `tuple`
Fix
3 3 | for item in {1}:
@ -38,90 +38,136 @@ iteration_over_set.py:6:13: PLC0208 [*] Use a sequence type instead of a `set` w
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
9 9 | for item in {1,}:
iteration_over_set.py:9:28: PLC0208 [*] Use a sequence type instead of a `set` when iterating over values
iteration_over_set.py:9:13: 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
9 | for item in {1,}:
| ^^^^ PLC0208
10 | print(f"I can count to {item}!")
|
= help: Use a sequence type instead of a `set` when iterating over values
= help: Convert to `tuple`
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 |
9 |-for item in {1,}:
9 |+for item in (1,):
10 10 | print(f"I can count to {item}!")
11 11 |
12 12 | for item in {
iteration_over_set.py:11:27: PLC0208 [*] Use a sequence type instead of a `set` when iterating over values
iteration_over_set.py:12:13: 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
12 |
13 | numbers_dict = {str(i): i for i in {1, 2, 3}} # flags sets in dict comprehensions
10 | print(f"I can count to {item}!")
11 |
12 | for item in {
| _____________^
13 | | "apples", "lemons", "water"
14 | | }: # flags in-line set literals
| |_^ PLC0208
15 | print(f"I like {item}.")
|
= help: Use a sequence type instead of a `set` when iterating over values
= help: Convert to `tuple`
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:13:36: PLC0208 [*] Use a sequence type instead of a `set` when iterating over values
|
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
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
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
9 9 | for item in {1,}:
10 10 | print(f"I can count to {item}!")
11 11 |
12 |-for item in {
12 |+for item in (
13 13 | "apples", "lemons", "water"
14 |-}: # flags in-line set literals
14 |+): # flags in-line set literals
15 15 | print(f"I like {item}.")
16 16 |
17 17 | numbers_list = [i for i in {1, 2, 3}] # flags sets in list comprehensions
iteration_over_set.py:15:27: PLC0208 [*] Use a sequence type instead of a `set` when iterating over values
iteration_over_set.py:17:28: PLC0208 [*] Use a sequence type instead of a `set` when iterating over values
|
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
15 | print(f"I like {item}.")
16 |
17 | # Non-errors
17 | numbers_list = [i for i in {1, 2, 3}] # flags sets in list comprehensions
| ^^^^^^^^^ PLC0208
18 |
19 | 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
= help: Convert to `tuple`
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
14 14 | }: # flags in-line set literals
15 15 | print(f"I like {item}.")
16 16 |
17 17 | # Non-errors
17 |-numbers_list = [i for i in {1, 2, 3}] # flags sets in list comprehensions
17 |+numbers_list = [i for i in (1, 2, 3)] # flags sets in list comprehensions
18 18 |
19 19 | numbers_set = {i for i in {1, 2, 3}} # flags sets in set comprehensions
20 20 |
iteration_over_set.py:19:27: PLC0208 [*] Use a sequence type instead of a `set` when iterating over values
|
17 | numbers_list = [i for i in {1, 2, 3}] # flags sets in list comprehensions
18 |
19 | numbers_set = {i for i in {1, 2, 3}} # flags sets in set comprehensions
| ^^^^^^^^^ PLC0208
20 |
21 | numbers_dict = {str(i): i for i in {1, 2, 3}} # flags sets in dict comprehensions
|
= help: Convert to `tuple`
Fix
16 16 |
17 17 | numbers_list = [i for i in {1, 2, 3}] # flags sets in list comprehensions
18 18 |
19 |-numbers_set = {i for i in {1, 2, 3}} # flags sets in set comprehensions
19 |+numbers_set = {i for i in (1, 2, 3)} # flags sets in set comprehensions
20 20 |
21 21 | numbers_dict = {str(i): i for i in {1, 2, 3}} # flags sets in dict comprehensions
22 22 |
iteration_over_set.py:21:36: PLC0208 [*] Use a sequence type instead of a `set` when iterating over values
|
19 | numbers_set = {i for i in {1, 2, 3}} # flags sets in set comprehensions
20 |
21 | numbers_dict = {str(i): i for i in {1, 2, 3}} # flags sets in dict comprehensions
| ^^^^^^^^^ PLC0208
22 |
23 | numbers_gen = (i for i in {1, 2, 3}) # flags sets in generator expressions
|
= help: Convert to `tuple`
Fix
18 18 |
19 19 | numbers_set = {i for i in {1, 2, 3}} # flags sets in set comprehensions
20 20 |
21 |-numbers_dict = {str(i): i for i in {1, 2, 3}} # flags sets in dict comprehensions
21 |+numbers_dict = {str(i): i for i in (1, 2, 3)} # flags sets in dict comprehensions
22 22 |
23 23 | numbers_gen = (i for i in {1, 2, 3}) # flags sets in generator expressions
24 24 |
iteration_over_set.py:23:27: PLC0208 [*] Use a sequence type instead of a `set` when iterating over values
|
21 | numbers_dict = {str(i): i for i in {1, 2, 3}} # flags sets in dict comprehensions
22 |
23 | numbers_gen = (i for i in {1, 2, 3}) # flags sets in generator expressions
| ^^^^^^^^^ PLC0208
24 |
25 | # Non-errors
|
= help: Convert to `tuple`
Fix
20 20 |
21 21 | numbers_dict = {str(i): i for i in {1, 2, 3}} # flags sets in dict comprehensions
22 22 |
23 |-numbers_gen = (i for i in {1, 2, 3}) # flags sets in generator expressions
23 |+numbers_gen = (i for i in (1, 2, 3)) # flags sets in generator expressions
24 24 |
25 25 | # Non-errors
26 26 |