mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-04 10:48:32 +00:00
[flake8-comprehensions
] Handle extraneous parentheses around list comprehension (C403
) (#15877)
## Summary Given the following code: ```python set(([x for x in range(5)])) ``` the current implementation of C403 results in ```python {(x for x in range(5))} ``` which is a set containing a generator rather than the result of the generator. This change removes the extraneous parentheses so that the resulting code is: ```python {x for x in range(5)} ``` ## Test Plan `cargo nextest run` and `cargo insta test`
This commit is contained in:
parent
62075afe4f
commit
dc5e922221
3 changed files with 122 additions and 27 deletions
|
@ -21,3 +21,14 @@ s = set( # comment
|
|||
s = set([ # comment
|
||||
x for x in range(3)
|
||||
])
|
||||
|
||||
s = set(([x for x in range(3)]))
|
||||
|
||||
s = set(((([x for x in range(3)]))))
|
||||
|
||||
s = set( # outer set comment
|
||||
( # inner paren comment - not preserved
|
||||
((
|
||||
[ # comprehension comment
|
||||
x for x in range(3)]
|
||||
))))
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
|
||||
use ruff_macros::{derive_message_formats, ViolationMetadata};
|
||||
use ruff_python_ast as ast;
|
||||
use ruff_python_ast::parenthesize::parenthesized_range;
|
||||
use ruff_text_size::{Ranged, TextSize};
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
|
@ -55,32 +56,39 @@ pub(crate) fn unnecessary_list_comprehension_set(checker: &mut Checker, call: &a
|
|||
if !checker.semantic().has_builtin_binding("set") {
|
||||
return;
|
||||
}
|
||||
if argument.is_list_comp_expr() {
|
||||
let diagnostic = Diagnostic::new(UnnecessaryListComprehensionSet, call.range());
|
||||
let fix = {
|
||||
// Replace `set(` with `{`.
|
||||
let call_start = Edit::replacement(
|
||||
pad_start("{", call.range(), checker.locator(), checker.semantic()),
|
||||
call.start(),
|
||||
call.arguments.start() + TextSize::from(1),
|
||||
);
|
||||
|
||||
// Replace `)` with `}`.
|
||||
let call_end = Edit::replacement(
|
||||
pad_end("}", call.range(), checker.locator(), checker.semantic()),
|
||||
call.arguments.end() - TextSize::from(1),
|
||||
call.end(),
|
||||
);
|
||||
|
||||
// Delete the open bracket (`[`).
|
||||
let argument_start =
|
||||
Edit::deletion(argument.start(), argument.start() + TextSize::from(1));
|
||||
|
||||
// Delete the close bracket (`]`).
|
||||
let argument_end = Edit::deletion(argument.end() - TextSize::from(1), argument.end());
|
||||
|
||||
Fix::unsafe_edits(call_start, [argument_start, argument_end, call_end])
|
||||
};
|
||||
checker.diagnostics.push(diagnostic.with_fix(fix));
|
||||
if !argument.is_list_comp_expr() {
|
||||
return;
|
||||
}
|
||||
let diagnostic = Diagnostic::new(UnnecessaryListComprehensionSet, call.range());
|
||||
let one = TextSize::from(1);
|
||||
|
||||
// Replace `set(` with `{`.
|
||||
let call_start = Edit::replacement(
|
||||
pad_start("{", call.range(), checker.locator(), checker.semantic()),
|
||||
call.start(),
|
||||
call.arguments.start() + one,
|
||||
);
|
||||
|
||||
// Replace `)` with `}`.
|
||||
let call_end = Edit::replacement(
|
||||
pad_end("}", call.range(), checker.locator(), checker.semantic()),
|
||||
call.arguments.end() - one,
|
||||
call.end(),
|
||||
);
|
||||
|
||||
// If the list comprehension is parenthesized, remove the parentheses in addition to
|
||||
// removing the brackets.
|
||||
let replacement_range = parenthesized_range(
|
||||
argument.into(),
|
||||
(&call.arguments).into(),
|
||||
checker.comment_ranges(),
|
||||
checker.locator().contents(),
|
||||
)
|
||||
.unwrap_or_else(|| argument.range());
|
||||
|
||||
let span = argument.range().add_start(one).sub_end(one);
|
||||
let replacement =
|
||||
Edit::range_replacement(checker.source()[span].to_string(), replacement_range);
|
||||
let fix = Fix::unsafe_edits(call_start, [call_end, replacement]);
|
||||
checker.diagnostics.push(diagnostic.with_fix(fix));
|
||||
}
|
||||
|
|
|
@ -220,6 +220,8 @@ C403.py:21:5: C403 [*] Unnecessary list comprehension (rewrite as a set comprehe
|
|||
22 | | x for x in range(3)
|
||||
23 | | ])
|
||||
| |__^ C403
|
||||
24 |
|
||||
25 | s = set(([x for x in range(3)]))
|
||||
|
|
||||
= help: Rewrite as a set comprehension
|
||||
|
||||
|
@ -232,3 +234,77 @@ C403.py:21:5: C403 [*] Unnecessary list comprehension (rewrite as a set comprehe
|
|||
22 22 | x for x in range(3)
|
||||
23 |-])
|
||||
23 |+}
|
||||
24 24 |
|
||||
25 25 | s = set(([x for x in range(3)]))
|
||||
26 26 |
|
||||
|
||||
C403.py:25:5: C403 [*] Unnecessary list comprehension (rewrite as a set comprehension)
|
||||
|
|
||||
23 | ])
|
||||
24 |
|
||||
25 | s = set(([x for x in range(3)]))
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C403
|
||||
26 |
|
||||
27 | s = set(((([x for x in range(3)]))))
|
||||
|
|
||||
= help: Rewrite as a set comprehension
|
||||
|
||||
ℹ Unsafe fix
|
||||
22 22 | x for x in range(3)
|
||||
23 23 | ])
|
||||
24 24 |
|
||||
25 |-s = set(([x for x in range(3)]))
|
||||
25 |+s = {x for x in range(3)}
|
||||
26 26 |
|
||||
27 27 | s = set(((([x for x in range(3)]))))
|
||||
28 28 |
|
||||
|
||||
C403.py:27:5: C403 [*] Unnecessary list comprehension (rewrite as a set comprehension)
|
||||
|
|
||||
25 | s = set(([x for x in range(3)]))
|
||||
26 |
|
||||
27 | s = set(((([x for x in range(3)]))))
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C403
|
||||
28 |
|
||||
29 | s = set( # outer set comment
|
||||
|
|
||||
= help: Rewrite as a set comprehension
|
||||
|
||||
ℹ Unsafe fix
|
||||
24 24 |
|
||||
25 25 | s = set(([x for x in range(3)]))
|
||||
26 26 |
|
||||
27 |-s = set(((([x for x in range(3)]))))
|
||||
27 |+s = {x for x in range(3)}
|
||||
28 28 |
|
||||
29 29 | s = set( # outer set comment
|
||||
30 30 | ( # inner paren comment - not preserved
|
||||
|
||||
C403.py:29:5: C403 [*] Unnecessary list comprehension (rewrite as a set comprehension)
|
||||
|
|
||||
27 | s = set(((([x for x in range(3)]))))
|
||||
28 |
|
||||
29 | s = set( # outer set comment
|
||||
| _____^
|
||||
30 | | ( # inner paren comment - not preserved
|
||||
31 | | ((
|
||||
32 | | [ # comprehension comment
|
||||
33 | | x for x in range(3)]
|
||||
34 | | ))))
|
||||
| |_____^ C403
|
||||
|
|
||||
= help: Rewrite as a set comprehension
|
||||
|
||||
ℹ Unsafe fix
|
||||
26 26 |
|
||||
27 27 | s = set(((([x for x in range(3)]))))
|
||||
28 28 |
|
||||
29 |-s = set( # outer set comment
|
||||
30 |-( # inner paren comment - not preserved
|
||||
31 |-((
|
||||
32 |-[ # comprehension comment
|
||||
33 |- x for x in range(3)]
|
||||
34 |- ))))
|
||||
29 |+s = { # outer set comment
|
||||
30 |+ # comprehension comment
|
||||
31 |+ x for x in range(3)}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue