[`flake8-comprehensions`] Handled special case for `C401` which also matches `C416` (#10596)

## Summary

<!-- What's the purpose of the change? What does it do, and why? -->

Similar to #10419, there was a case where there is a collision of C401
and C416 (as discussed in #10101).
Fixed this by implementing short-circuit for the comprehension of the
form `{x for x in foo}`.

## Test Plan

<!-- How was it tested? -->

Extended `C401.py` with the case where `set` is not builtin function,
and divided the case where the short-circuit should occur.
Removed the last testcase of `print(f"{ {set(a for a in 'abc')} }")`
test as this is invalid as a python code, but should I keep this?
This commit is contained in:
hikaru-kajita 2024-03-26 12:54:58 +09:00 committed by GitHub
parent 80b46889ed
commit a28776e3aa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 286 additions and 233 deletions

View File

@ -1,20 +1,30 @@
x = set(x for x in range(3)) # Cannot conbime with C416. Should use set comprehension here.
x = set(x for x in range(3)) even_nums = set(2 * x for x in range(3))
y = f"{set(a if a < 6 else 0 for a in range(3))}" odd_nums = set(
_ = "{}".format(set(a if a < 6 else 0 for a in range(3))) 2 * x + 1 for x in range(3)
print(f"Hello {set(a for a in range(3))} World") )
small_nums = f"{set(a if a < 6 else 0 for a in range(3))}"
def f(x): def f(x):
return x return x
print(f'Hello {set(a for a in "abc")} World')
print(f"Hello {set(a for a in 'abc')} World")
print(f"Hello {set(f(a) for a in 'abc')} World") print(f"Hello {set(f(a) for a in 'abc')} World")
print(f"Hello { set(f(a) for a in 'abc') } World")
# Short-circuit case, combine with C416 and should produce x = set(range(3))
x = set(x for x in range(3))
x = set(
x for x in range(3)
)
print(f"Hello {set(a for a in range(3))} World")
print(f"{set(a for a in 'abc') - set(a for a in 'ab')}") print(f"{set(a for a in 'abc') - set(a for a in 'ab')}")
print(f"{ set(a for a in 'abc') - set(a for a in 'ab') }") print(f"{ set(a for a in 'abc') - set(a for a in 'ab') }")
# The fix generated for this diagnostic is incorrect, as we add additional space
# around the set comprehension. # Not built-in set.
print(f"{ {set(a for a in 'abc')} }") def set(*args, **kwargs):
return None
set(2 * x for x in range(3))
set(x for x in range(3))

View File

@ -1,6 +1,8 @@
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
use ruff_macros::{derive_message_formats, violation}; use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast as ast; use ruff_python_ast as ast;
use ruff_python_ast::comparable::ComparableExpr;
use ruff_python_ast::ExprGenerator;
use ruff_text_size::{Ranged, TextSize}; use ruff_text_size::{Ranged, TextSize};
use crate::checkers::ast::Checker; use crate::checkers::ast::Checker;
@ -10,37 +12,53 @@ use super::helpers;
/// ## What it does /// ## What it does
/// Checks for unnecessary generators that can be rewritten as `set` /// Checks for unnecessary generators that can be rewritten as `set`
/// comprehensions. /// comprehensions (or with `set` directly).
/// ///
/// ## Why is this bad? /// ## Why is this bad?
/// It is unnecessary to use `set` around a generator expression, since /// It is unnecessary to use `set` around a generator expression, since
/// there are equivalent comprehensions for these types. Using a /// there are equivalent comprehensions for these types. Using a
/// comprehension is clearer and more idiomatic. /// comprehension is clearer and more idiomatic.
/// ///
/// Further, if the comprehension can be removed entirely, as in the case of
/// `set(x for x in foo)`, it's better to use `set(foo)` directly, since it's
/// even more direct.
///
/// ## Examples /// ## Examples
/// ```python /// ```python
/// set(f(x) for x in foo) /// set(f(x) for x in foo)
/// set(x for x in foo)
/// ``` /// ```
/// ///
/// Use instead: /// Use instead:
/// ```python /// ```python
/// {f(x) for x in foo} /// {f(x) for x in foo}
/// set(foo)
/// ``` /// ```
/// ///
/// ## Fix safety /// ## Fix safety
/// This rule's fix is marked as unsafe, as it may occasionally drop comments /// This rule's fix is marked as unsafe, as it may occasionally drop comments
/// when rewriting the call. In most cases, though, comments will be preserved. /// when rewriting the call. In most cases, though, comments will be preserved.
#[violation] #[violation]
pub struct UnnecessaryGeneratorSet; pub struct UnnecessaryGeneratorSet {
short_circuit: bool,
}
impl AlwaysFixableViolation for UnnecessaryGeneratorSet { impl AlwaysFixableViolation for UnnecessaryGeneratorSet {
#[derive_message_formats] #[derive_message_formats]
fn message(&self) -> String { fn message(&self) -> String {
format!("Unnecessary generator (rewrite as a `set` comprehension)") if self.short_circuit {
format!("Unnecessary generator (rewrite using `set()`")
} else {
format!("Unnecessary generator (rewrite as a `set` comprehension)")
}
} }
fn fix_title(&self) -> String { fn fix_title(&self) -> String {
"Rewrite as a `set` comprehension".to_string() if self.short_circuit {
"Rewrite using `set()`".to_string()
} else {
"Rewrite as a `set` comprehension".to_string()
}
} }
} }
@ -57,28 +75,59 @@ pub(crate) fn unnecessary_generator_set(checker: &mut Checker, call: &ast::ExprC
if !checker.semantic().is_builtin("set") { if !checker.semantic().is_builtin("set") {
return; return;
} }
if argument.is_generator_expr() {
let mut diagnostic = Diagnostic::new(UnnecessaryGeneratorSet, call.range());
// Convert `set(x for x in y)` to `{x for x in y}`. let Some(ExprGenerator {
diagnostic.set_fix({ elt, generators, ..
// Replace `set(` with `}`. }) = argument.as_generator_expr()
let call_start = Edit::replacement( else {
pad_start("{", call.range(), checker.locator(), checker.semantic()), return;
call.start(), };
call.arguments.start() + TextSize::from(1),
);
// Replace `)` with `}`. // Short-circuit: given `set(x for x in y)`, generate `set(y)` (in lieu of `{x for x in y}`).
let call_end = Edit::replacement( if let [generator] = generators.as_slice() {
pad_end("}", call.range(), checker.locator(), checker.semantic()), if generator.ifs.is_empty() && !generator.is_async {
call.arguments.end() - TextSize::from(1), if ComparableExpr::from(elt) == ComparableExpr::from(&generator.target) {
call.end(), let mut diagnostic = Diagnostic::new(
); UnnecessaryGeneratorSet {
short_circuit: true,
Fix::unsafe_edits(call_start, [call_end]) },
}); call.range(),
);
checker.diagnostics.push(diagnostic); let iterator = format!("set({})", checker.locator().slice(generator.iter.range()));
diagnostic.set_fix(Fix::unsafe_edit(Edit::range_replacement(
iterator,
call.range(),
)));
checker.diagnostics.push(diagnostic);
return;
}
}
} }
// Convert `set(f(x) for x in y)` to `{f(x) for x in y}`.
let mut diagnostic = Diagnostic::new(
UnnecessaryGeneratorSet {
short_circuit: false,
},
call.range(),
);
diagnostic.set_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(),
);
Fix::unsafe_edits(call_start, [call_end])
});
checker.diagnostics.push(diagnostic);
} }

View File

@ -1,255 +1,249 @@
--- ---
source: crates/ruff_linter/src/rules/flake8_comprehensions/mod.rs source: crates/ruff_linter/src/rules/flake8_comprehensions/mod.rs
--- ---
C401.py:1:5: C401 [*] Unnecessary generator (rewrite as a `set` comprehension) C401.py:2:13: C401 [*] Unnecessary generator (rewrite as a `set` comprehension)
| |
1 | x = set(x for x in range(3)) 1 | # Cannot conbime with C416. Should use set comprehension here.
| ^^^^^^^^^^^^^^^^^^^^^^^^ C401 2 | even_nums = set(2 * x for x in range(3))
2 | x = set(x for x in range(3)) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C401
3 | y = f"{set(a if a < 6 else 0 for a in range(3))}" 3 | odd_nums = set(
4 | 2 * x + 1 for x in range(3)
| |
= help: Rewrite as a `set` comprehension = help: Rewrite as a `set` comprehension
Unsafe fix Unsafe fix
1 |-x = set(x for x in range(3)) 1 1 | # Cannot conbime with C416. Should use set comprehension here.
1 |+x = {x for x in range(3)} 2 |-even_nums = set(2 * x for x in range(3))
2 2 | x = set(x for x in range(3)) 2 |+even_nums = {2 * x for x in range(3)}
3 3 | y = f"{set(a if a < 6 else 0 for a in range(3))}" 3 3 | odd_nums = set(
4 4 | _ = "{}".format(set(a if a < 6 else 0 for a in range(3))) 4 4 | 2 * x + 1 for x in range(3)
5 5 | )
C401.py:2:5: C401 [*] Unnecessary generator (rewrite as a `set` comprehension) C401.py:3:12: C401 [*] Unnecessary generator (rewrite as a `set` comprehension)
| |
1 | x = set(x for x in range(3)) 1 | # Cannot conbime with C416. Should use set comprehension here.
2 | x = set(x for x in range(3)) 2 | even_nums = set(2 * x for x in range(3))
| ^^^^^^^^^^^^^^^^^^^^^^^^ C401 3 | odd_nums = set(
3 | y = f"{set(a if a < 6 else 0 for a in range(3))}" | ____________^
4 | _ = "{}".format(set(a if a < 6 else 0 for a in range(3))) 4 | | 2 * x + 1 for x in range(3)
5 | | )
| |_^ C401
6 | small_nums = f"{set(a if a < 6 else 0 for a in range(3))}"
| |
= help: Rewrite as a `set` comprehension = help: Rewrite as a `set` comprehension
Unsafe fix Unsafe fix
1 1 | x = set(x for x in range(3)) 1 1 | # Cannot conbime with C416. Should use set comprehension here.
2 |-x = set(x for x in range(3)) 2 2 | even_nums = set(2 * x for x in range(3))
2 |+x = {x for x in range(3)} 3 |-odd_nums = set(
3 3 | y = f"{set(a if a < 6 else 0 for a in range(3))}" 3 |+odd_nums = {
4 4 | _ = "{}".format(set(a if a < 6 else 0 for a in range(3))) 4 4 | 2 * x + 1 for x in range(3)
5 5 | print(f"Hello {set(a for a in range(3))} World") 5 |-)
5 |+}
C401.py:3:8: C401 [*] Unnecessary generator (rewrite as a `set` comprehension) 6 6 | small_nums = f"{set(a if a < 6 else 0 for a in range(3))}"
|
1 | x = set(x for x in range(3))
2 | x = set(x for x in range(3))
3 | y = f"{set(a if a < 6 else 0 for a in range(3))}"
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C401
4 | _ = "{}".format(set(a if a < 6 else 0 for a in range(3)))
5 | print(f"Hello {set(a for a in range(3))} World")
|
= help: Rewrite as a `set` comprehension
Unsafe fix
1 1 | x = set(x for x in range(3))
2 2 | x = set(x for x in range(3))
3 |-y = f"{set(a if a < 6 else 0 for a in range(3))}"
3 |+y = f"{ {a if a < 6 else 0 for a in range(3)} }"
4 4 | _ = "{}".format(set(a if a < 6 else 0 for a in range(3)))
5 5 | print(f"Hello {set(a for a in range(3))} World")
6 6 |
C401.py:4:17: C401 [*] Unnecessary generator (rewrite as a `set` comprehension)
|
2 | x = set(x for x in range(3))
3 | y = f"{set(a if a < 6 else 0 for a in range(3))}"
4 | _ = "{}".format(set(a if a < 6 else 0 for a in range(3)))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C401
5 | print(f"Hello {set(a for a in range(3))} World")
|
= help: Rewrite as a `set` comprehension
Unsafe fix
1 1 | x = set(x for x in range(3))
2 2 | x = set(x for x in range(3))
3 3 | y = f"{set(a if a < 6 else 0 for a in range(3))}"
4 |-_ = "{}".format(set(a if a < 6 else 0 for a in range(3)))
4 |+_ = "{}".format({a if a < 6 else 0 for a in range(3)})
5 5 | print(f"Hello {set(a for a in range(3))} World")
6 6 |
7 7 |
C401.py:5:16: C401 [*] Unnecessary generator (rewrite as a `set` comprehension)
|
3 | y = f"{set(a if a < 6 else 0 for a in range(3))}"
4 | _ = "{}".format(set(a if a < 6 else 0 for a in range(3)))
5 | print(f"Hello {set(a for a in range(3))} World")
| ^^^^^^^^^^^^^^^^^^^^^^^^ C401
|
= help: Rewrite as a `set` comprehension
Unsafe fix
2 2 | x = set(x for x in range(3))
3 3 | y = f"{set(a if a < 6 else 0 for a in range(3))}"
4 4 | _ = "{}".format(set(a if a < 6 else 0 for a in range(3)))
5 |-print(f"Hello {set(a for a in range(3))} World")
5 |+print(f"Hello { {a for a in range(3)} } World")
6 6 |
7 7 | 7 7 |
8 8 | def f(x): 8 8 | def f(x):
C401.py:12:16: C401 [*] Unnecessary generator (rewrite as a `set` comprehension) C401.py:6:17: C401 [*] Unnecessary generator (rewrite as a `set` comprehension)
|
4 | 2 * x + 1 for x in range(3)
5 | )
6 | small_nums = f"{set(a if a < 6 else 0 for a in range(3))}"
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C401
7 |
8 | def f(x):
|
= help: Rewrite as a `set` comprehension
Unsafe fix
3 3 | odd_nums = set(
4 4 | 2 * x + 1 for x in range(3)
5 5 | )
6 |-small_nums = f"{set(a if a < 6 else 0 for a in range(3))}"
6 |+small_nums = f"{ {a if a < 6 else 0 for a in range(3)} }"
7 7 |
8 8 | def f(x):
9 9 | return x
C401.py:11:16: C401 [*] Unnecessary generator (rewrite as a `set` comprehension)
| |
12 | print(f'Hello {set(a for a in "abc")} World') 9 | return x
| ^^^^^^^^^^^^^^^^^^^^^ C401 10 |
13 | print(f"Hello {set(a for a in 'abc')} World") 11 | print(f"Hello {set(f(a) for a in 'abc')} World")
14 | print(f"Hello {set(f(a) for a in 'abc')} World") | ^^^^^^^^^^^^^^^^^^^^^^^^ C401
12 | print(f"Hello { set(f(a) for a in 'abc') } World")
|
= help: Rewrite as a `set` comprehension
Unsafe fix
8 8 | def f(x):
9 9 | return x
10 10 |
11 |-print(f"Hello {set(f(a) for a in 'abc')} World")
11 |+print(f"Hello { {f(a) for a in 'abc'} } World")
12 12 | print(f"Hello { set(f(a) for a in 'abc') } World")
13 13 |
14 14 |
C401.py:12:17: C401 [*] Unnecessary generator (rewrite as a `set` comprehension)
|
11 | print(f"Hello {set(f(a) for a in 'abc')} World")
12 | print(f"Hello { set(f(a) for a in 'abc') } World")
| ^^^^^^^^^^^^^^^^^^^^^^^^ C401
| |
= help: Rewrite as a `set` comprehension = help: Rewrite as a `set` comprehension
Unsafe fix Unsafe fix
9 9 | return x 9 9 | return x
10 10 | 10 10 |
11 11 | 11 11 | print(f"Hello {set(f(a) for a in 'abc')} World")
12 |-print(f'Hello {set(a for a in "abc")} World') 12 |-print(f"Hello { set(f(a) for a in 'abc') } World")
12 |+print(f'Hello { {a for a in "abc"} } World') 12 |+print(f"Hello { {f(a) for a in 'abc'} } World")
13 13 | print(f"Hello {set(a for a in 'abc')} World") 13 13 |
14 14 | print(f"Hello {set(f(a) for a in 'abc')} World") 14 14 |
15 15 | print(f"{set(a for a in 'abc') - set(a for a in 'ab')}") 15 15 | # Short-circuit case, combine with C416 and should produce x = set(range(3))
C401.py:13:16: C401 [*] Unnecessary generator (rewrite as a `set` comprehension) C401.py:16:5: C401 [*] Unnecessary generator (rewrite using `set()`
| |
12 | print(f'Hello {set(a for a in "abc")} World') 15 | # Short-circuit case, combine with C416 and should produce x = set(range(3))
13 | print(f"Hello {set(a for a in 'abc')} World") 16 | x = set(x for x in range(3))
| ^^^^^^^^^^^^^^^^^^^^^ C401 | ^^^^^^^^^^^^^^^^^^^^^^^^ C401
14 | print(f"Hello {set(f(a) for a in 'abc')} World") 17 | x = set(
15 | print(f"{set(a for a in 'abc') - set(a for a in 'ab')}") 18 | x for x in range(3)
| |
= help: Rewrite as a `set` comprehension = help: Rewrite using `set()`
Unsafe fix Unsafe fix
10 10 | 13 13 |
11 11 | 14 14 |
12 12 | print(f'Hello {set(a for a in "abc")} World') 15 15 | # Short-circuit case, combine with C416 and should produce x = set(range(3))
13 |-print(f"Hello {set(a for a in 'abc')} World") 16 |-x = set(x for x in range(3))
13 |+print(f"Hello { {a for a in 'abc'} } World") 16 |+x = set(range(3))
14 14 | print(f"Hello {set(f(a) for a in 'abc')} World") 17 17 | x = set(
15 15 | print(f"{set(a for a in 'abc') - set(a for a in 'ab')}") 18 18 | x for x in range(3)
16 16 | print(f"{ set(a for a in 'abc') - set(a for a in 'ab') }") 19 19 | )
C401.py:14:16: C401 [*] Unnecessary generator (rewrite as a `set` comprehension) C401.py:17:5: C401 [*] Unnecessary generator (rewrite using `set()`
| |
12 | print(f'Hello {set(a for a in "abc")} World') 15 | # Short-circuit case, combine with C416 and should produce x = set(range(3))
13 | print(f"Hello {set(a for a in 'abc')} World") 16 | x = set(x for x in range(3))
14 | print(f"Hello {set(f(a) for a in 'abc')} World") 17 | x = set(
| _____^
18 | | x for x in range(3)
19 | | )
| |_^ C401
20 | print(f"Hello {set(a for a in range(3))} World")
21 | print(f"{set(a for a in 'abc') - set(a for a in 'ab')}")
|
= help: Rewrite using `set()`
Unsafe fix
14 14 |
15 15 | # Short-circuit case, combine with C416 and should produce x = set(range(3))
16 16 | x = set(x for x in range(3))
17 |-x = set(
18 |- x for x in range(3)
19 |-)
17 |+x = set(range(3))
20 18 | print(f"Hello {set(a for a in range(3))} World")
21 19 | print(f"{set(a for a in 'abc') - set(a for a in 'ab')}")
22 20 | print(f"{ set(a for a in 'abc') - set(a for a in 'ab') }")
C401.py:20:16: C401 [*] Unnecessary generator (rewrite using `set()`
|
18 | x for x in range(3)
19 | )
20 | print(f"Hello {set(a for a in range(3))} World")
| ^^^^^^^^^^^^^^^^^^^^^^^^ C401 | ^^^^^^^^^^^^^^^^^^^^^^^^ C401
15 | print(f"{set(a for a in 'abc') - set(a for a in 'ab')}") 21 | print(f"{set(a for a in 'abc') - set(a for a in 'ab')}")
16 | print(f"{ set(a for a in 'abc') - set(a for a in 'ab') }") 22 | print(f"{ set(a for a in 'abc') - set(a for a in 'ab') }")
| |
= help: Rewrite as a `set` comprehension = help: Rewrite using `set()`
Unsafe fix Unsafe fix
11 11 | 17 17 | x = set(
12 12 | print(f'Hello {set(a for a in "abc")} World') 18 18 | x for x in range(3)
13 13 | print(f"Hello {set(a for a in 'abc')} World") 19 19 | )
14 |-print(f"Hello {set(f(a) for a in 'abc')} World") 20 |-print(f"Hello {set(a for a in range(3))} World")
14 |+print(f"Hello { {f(a) for a in 'abc'} } World") 20 |+print(f"Hello {set(range(3))} World")
15 15 | print(f"{set(a for a in 'abc') - set(a for a in 'ab')}") 21 21 | print(f"{set(a for a in 'abc') - set(a for a in 'ab')}")
16 16 | print(f"{ set(a for a in 'abc') - set(a for a in 'ab') }") 22 22 | print(f"{ set(a for a in 'abc') - set(a for a in 'ab') }")
17 17 | 23 23 |
C401.py:15:10: C401 [*] Unnecessary generator (rewrite as a `set` comprehension) C401.py:21:10: C401 [*] Unnecessary generator (rewrite using `set()`
| |
13 | print(f"Hello {set(a for a in 'abc')} World") 19 | )
14 | print(f"Hello {set(f(a) for a in 'abc')} World") 20 | print(f"Hello {set(a for a in range(3))} World")
15 | print(f"{set(a for a in 'abc') - set(a for a in 'ab')}") 21 | print(f"{set(a for a in 'abc') - set(a for a in 'ab')}")
| ^^^^^^^^^^^^^^^^^^^^^ C401 | ^^^^^^^^^^^^^^^^^^^^^ C401
16 | print(f"{ set(a for a in 'abc') - set(a for a in 'ab') }") 22 | print(f"{ set(a for a in 'abc') - set(a for a in 'ab') }")
| |
= help: Rewrite as a `set` comprehension = help: Rewrite using `set()`
Unsafe fix Unsafe fix
12 12 | print(f'Hello {set(a for a in "abc")} World') 18 18 | x for x in range(3)
13 13 | print(f"Hello {set(a for a in 'abc')} World") 19 19 | )
14 14 | print(f"Hello {set(f(a) for a in 'abc')} World") 20 20 | print(f"Hello {set(a for a in range(3))} World")
15 |-print(f"{set(a for a in 'abc') - set(a for a in 'ab')}") 21 |-print(f"{set(a for a in 'abc') - set(a for a in 'ab')}")
15 |+print(f"{ {a for a in 'abc'} - set(a for a in 'ab')}") 21 |+print(f"{set('abc') - set(a for a in 'ab')}")
16 16 | print(f"{ set(a for a in 'abc') - set(a for a in 'ab') }") 22 22 | print(f"{ set(a for a in 'abc') - set(a for a in 'ab') }")
17 17 | 23 23 |
18 18 | # The fix generated for this diagnostic is incorrect, as we add additional space 24 24 |
C401.py:15:34: C401 [*] Unnecessary generator (rewrite as a `set` comprehension) C401.py:21:34: C401 [*] Unnecessary generator (rewrite using `set()`
| |
13 | print(f"Hello {set(a for a in 'abc')} World") 19 | )
14 | print(f"Hello {set(f(a) for a in 'abc')} World") 20 | print(f"Hello {set(a for a in range(3))} World")
15 | print(f"{set(a for a in 'abc') - set(a for a in 'ab')}") 21 | print(f"{set(a for a in 'abc') - set(a for a in 'ab')}")
| ^^^^^^^^^^^^^^^^^^^^ C401 | ^^^^^^^^^^^^^^^^^^^^ C401
16 | print(f"{ set(a for a in 'abc') - set(a for a in 'ab') }") 22 | print(f"{ set(a for a in 'abc') - set(a for a in 'ab') }")
| |
= help: Rewrite as a `set` comprehension = help: Rewrite using `set()`
Unsafe fix Unsafe fix
12 12 | print(f'Hello {set(a for a in "abc")} World') 18 18 | x for x in range(3)
13 13 | print(f"Hello {set(a for a in 'abc')} World") 19 19 | )
14 14 | print(f"Hello {set(f(a) for a in 'abc')} World") 20 20 | print(f"Hello {set(a for a in range(3))} World")
15 |-print(f"{set(a for a in 'abc') - set(a for a in 'ab')}") 21 |-print(f"{set(a for a in 'abc') - set(a for a in 'ab')}")
15 |+print(f"{set(a for a in 'abc') - {a for a in 'ab'} }") 21 |+print(f"{set(a for a in 'abc') - set('ab')}")
16 16 | print(f"{ set(a for a in 'abc') - set(a for a in 'ab') }") 22 22 | print(f"{ set(a for a in 'abc') - set(a for a in 'ab') }")
17 17 | 23 23 |
18 18 | # The fix generated for this diagnostic is incorrect, as we add additional space 24 24 |
C401.py:16:11: C401 [*] Unnecessary generator (rewrite as a `set` comprehension) C401.py:22:11: C401 [*] Unnecessary generator (rewrite using `set()`
| |
14 | print(f"Hello {set(f(a) for a in 'abc')} World") 20 | print(f"Hello {set(a for a in range(3))} World")
15 | print(f"{set(a for a in 'abc') - set(a for a in 'ab')}") 21 | print(f"{set(a for a in 'abc') - set(a for a in 'ab')}")
16 | print(f"{ set(a for a in 'abc') - set(a for a in 'ab') }") 22 | print(f"{ set(a for a in 'abc') - set(a for a in 'ab') }")
| ^^^^^^^^^^^^^^^^^^^^^ C401 | ^^^^^^^^^^^^^^^^^^^^^ C401
17 |
18 | # The fix generated for this diagnostic is incorrect, as we add additional space
| |
= help: Rewrite as a `set` comprehension = help: Rewrite using `set()`
Unsafe fix Unsafe fix
13 13 | print(f"Hello {set(a for a in 'abc')} World") 19 19 | )
14 14 | print(f"Hello {set(f(a) for a in 'abc')} World") 20 20 | print(f"Hello {set(a for a in range(3))} World")
15 15 | print(f"{set(a for a in 'abc') - set(a for a in 'ab')}") 21 21 | print(f"{set(a for a in 'abc') - set(a for a in 'ab')}")
16 |-print(f"{ set(a for a in 'abc') - set(a for a in 'ab') }") 22 |-print(f"{ set(a for a in 'abc') - set(a for a in 'ab') }")
16 |+print(f"{ {a for a in 'abc'} - set(a for a in 'ab') }") 22 |+print(f"{ set('abc') - set(a for a in 'ab') }")
17 17 | 23 23 |
18 18 | # The fix generated for this diagnostic is incorrect, as we add additional space 24 24 |
19 19 | # around the set comprehension. 25 25 | # Not built-in set.
C401.py:16:35: C401 [*] Unnecessary generator (rewrite as a `set` comprehension) C401.py:22:35: C401 [*] Unnecessary generator (rewrite using `set()`
| |
14 | print(f"Hello {set(f(a) for a in 'abc')} World") 20 | print(f"Hello {set(a for a in range(3))} World")
15 | print(f"{set(a for a in 'abc') - set(a for a in 'ab')}") 21 | print(f"{set(a for a in 'abc') - set(a for a in 'ab')}")
16 | print(f"{ set(a for a in 'abc') - set(a for a in 'ab') }") 22 | print(f"{ set(a for a in 'abc') - set(a for a in 'ab') }")
| ^^^^^^^^^^^^^^^^^^^^ C401 | ^^^^^^^^^^^^^^^^^^^^ C401
17 |
18 | # The fix generated for this diagnostic is incorrect, as we add additional space
| |
= help: Rewrite as a `set` comprehension = help: Rewrite using `set()`
Unsafe fix Unsafe fix
13 13 | print(f"Hello {set(a for a in 'abc')} World") 19 19 | )
14 14 | print(f"Hello {set(f(a) for a in 'abc')} World") 20 20 | print(f"Hello {set(a for a in range(3))} World")
15 15 | print(f"{set(a for a in 'abc') - set(a for a in 'ab')}") 21 21 | print(f"{set(a for a in 'abc') - set(a for a in 'ab')}")
16 |-print(f"{ set(a for a in 'abc') - set(a for a in 'ab') }") 22 |-print(f"{ set(a for a in 'abc') - set(a for a in 'ab') }")
16 |+print(f"{ set(a for a in 'abc') - {a for a in 'ab'} }") 22 |+print(f"{ set(a for a in 'abc') - set('ab') }")
17 17 | 23 23 |
18 18 | # The fix generated for this diagnostic is incorrect, as we add additional space 24 24 |
19 19 | # around the set comprehension. 25 25 | # Not built-in set.
C401.py:20:12: C401 [*] Unnecessary generator (rewrite as a `set` comprehension)
|
18 | # The fix generated for this diagnostic is incorrect, as we add additional space
19 | # around the set comprehension.
20 | print(f"{ {set(a for a in 'abc')} }")
| ^^^^^^^^^^^^^^^^^^^^^ C401
|
= help: Rewrite as a `set` comprehension
Unsafe fix
17 17 |
18 18 | # The fix generated for this diagnostic is incorrect, as we add additional space
19 19 | # around the set comprehension.
20 |-print(f"{ {set(a for a in 'abc')} }")
20 |+print(f"{ { {a for a in 'abc'} } }")