diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_comprehensions/C401.py b/crates/ruff_linter/resources/test/fixtures/flake8_comprehensions/C401.py index fa1cdc0e51c3e..6f54b249a6a11 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_comprehensions/C401.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_comprehensions/C401.py @@ -1,20 +1,30 @@ -x = set(x for x in range(3)) -x = set(x for x in range(3)) -y = f"{set(a if a < 6 else 0 for a in range(3))}" -_ = "{}".format(set(a if a < 6 else 0 for a in range(3))) -print(f"Hello {set(a for a in range(3))} World") - +# Cannot conbime with C416. Should use set comprehension here. +even_nums = set(2 * x for x in range(3)) +odd_nums = set( + 2 * x + 1 for x in range(3) +) +small_nums = f"{set(a if a < 6 else 0 for a in range(3))}" def f(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") + + +# 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') }") -# The fix generated for this diagnostic is incorrect, as we add additional space -# around the set comprehension. -print(f"{ {set(a for a in 'abc')} }") + +# Not built-in set. +def set(*args, **kwargs): + return None + +set(2 * x for x in range(3)) +set(x for x in range(3)) diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_generator_set.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_generator_set.rs index b5fcc4b315080..0530922b757ef 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_generator_set.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_generator_set.rs @@ -1,6 +1,8 @@ use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix}; use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast as ast; +use ruff_python_ast::comparable::ComparableExpr; +use ruff_python_ast::ExprGenerator; use ruff_text_size::{Ranged, TextSize}; use crate::checkers::ast::Checker; @@ -10,37 +12,53 @@ use super::helpers; /// ## What it does /// Checks for unnecessary generators that can be rewritten as `set` -/// comprehensions. +/// comprehensions (or with `set` directly). /// /// ## Why is this bad? /// It is unnecessary to use `set` around a generator expression, since /// there are equivalent comprehensions for these types. Using a /// 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 /// ```python /// set(f(x) for x in foo) +/// set(x for x in foo) /// ``` /// /// Use instead: /// ```python /// {f(x) for x in foo} +/// set(foo) /// ``` /// /// ## Fix safety /// 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. #[violation] -pub struct UnnecessaryGeneratorSet; +pub struct UnnecessaryGeneratorSet { + short_circuit: bool, +} impl AlwaysFixableViolation for UnnecessaryGeneratorSet { #[derive_message_formats] 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 { - "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") { 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}`. - 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), - ); + let Some(ExprGenerator { + elt, generators, .. + }) = argument.as_generator_expr() + else { + return; + }; + + // Short-circuit: given `set(x for x in y)`, generate `set(y)` (in lieu of `{x for x in y}`). + if let [generator] = generators.as_slice() { + if generator.ifs.is_empty() && !generator.is_async { + if ComparableExpr::from(elt) == ComparableExpr::from(&generator.target) { + let mut diagnostic = Diagnostic::new( + UnnecessaryGeneratorSet { + short_circuit: true, + }, + call.range(), + ); + 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(), - ); + // 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]) - }); + Fix::unsafe_edits(call_start, [call_end]) + }); - checker.diagnostics.push(diagnostic); - } + checker.diagnostics.push(diagnostic); } diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/snapshots/ruff_linter__rules__flake8_comprehensions__tests__C401_C401.py.snap b/crates/ruff_linter/src/rules/flake8_comprehensions/snapshots/ruff_linter__rules__flake8_comprehensions__tests__C401_C401.py.snap index 85daacb403a35..fdde5715682af 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/snapshots/ruff_linter__rules__flake8_comprehensions__tests__C401_C401.py.snap +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/snapshots/ruff_linter__rules__flake8_comprehensions__tests__C401_C401.py.snap @@ -1,255 +1,249 @@ --- 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)) - | ^^^^^^^^^^^^^^^^^^^^^^^^ C401 -2 | x = set(x for x in range(3)) -3 | y = f"{set(a if a < 6 else 0 for a in range(3))}" +1 | # Cannot conbime with C416. Should use set comprehension here. +2 | even_nums = set(2 * x for x in range(3)) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C401 +3 | odd_nums = set( +4 | 2 * x + 1 for x in range(3) | = help: Rewrite as a `set` comprehension ℹ Unsafe fix -1 |-x = set(x for x in range(3)) - 1 |+x = {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 4 | _ = "{}".format(set(a if a < 6 else 0 for a in range(3))) - -C401.py:2:5: C401 [*] Unnecessary generator (rewrite as a `set` comprehension) +1 1 | # Cannot conbime with C416. Should use set comprehension here. +2 |-even_nums = set(2 * x for x in range(3)) + 2 |+even_nums = {2 * x for x in range(3)} +3 3 | odd_nums = set( +4 4 | 2 * x + 1 for x in range(3) +5 5 | ) + +C401.py:3:12: C401 [*] Unnecessary generator (rewrite as a `set` comprehension) | -1 | x = set(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))}" -4 | _ = "{}".format(set(a if a < 6 else 0 for a in range(3))) +1 | # Cannot conbime with C416. Should use set comprehension here. +2 | even_nums = set(2 * x for x in range(3)) +3 | odd_nums = set( + | ____________^ +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 ℹ Unsafe fix -1 1 | x = set(x for x in range(3)) -2 |-x = set(x for x in range(3)) - 2 |+x = {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 5 | print(f"Hello {set(a for a in range(3))} World") - -C401.py:3:8: C401 [*] Unnecessary generator (rewrite as a `set` comprehension) - | -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 | +1 1 | # Cannot conbime with C416. Should use set comprehension here. +2 2 | even_nums = set(2 * x for x in range(3)) +3 |-odd_nums = set( + 3 |+odd_nums = { +4 4 | 2 * x + 1 for x in range(3) +5 |-) + 5 |+} +6 6 | small_nums = f"{set(a if a < 6 else 0 for a in range(3))}" 7 7 | +8 8 | def f(x): -C401.py:5:16: C401 [*] Unnecessary generator (rewrite as a `set` comprehension) +C401.py:6:17: 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 +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 -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 | +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:12:16: C401 [*] Unnecessary generator (rewrite as a `set` comprehension) +C401.py:11:16: C401 [*] Unnecessary generator (rewrite as a `set` comprehension) | -12 | print(f'Hello {set(a for a in "abc")} World') - | ^^^^^^^^^^^^^^^^^^^^^ C401 -13 | print(f"Hello {set(a for a in 'abc')} World") -14 | print(f"Hello {set(f(a) for a in 'abc')} World") + 9 | return x +10 | +11 | 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 11 | -12 |-print(f'Hello {set(a for a in "abc")} World') - 12 |+print(f'Hello { {a for a in "abc"} } World') -13 13 | print(f"Hello {set(a for a in 'abc')} World") -14 14 | print(f"Hello {set(f(a) for a in 'abc')} World") -15 15 | print(f"{set(a for a in 'abc') - set(a for a in 'ab')}") +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:13:16: C401 [*] Unnecessary generator (rewrite as a `set` comprehension) +C401.py:12:17: C401 [*] Unnecessary generator (rewrite as a `set` comprehension) | -12 | print(f'Hello {set(a for a in "abc")} World') -13 | print(f"Hello {set(a for a in 'abc')} World") - | ^^^^^^^^^^^^^^^^^^^^^ C401 -14 | print(f"Hello {set(f(a) for a in 'abc')} World") -15 | print(f"{set(a for a in 'abc') - set(a for a in 'ab')}") +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 ℹ Unsafe fix +9 9 | return x 10 10 | -11 11 | -12 12 | print(f'Hello {set(a for a in "abc")} World') -13 |-print(f"Hello {set(a for a in 'abc')} World") - 13 |+print(f"Hello { {a for a in 'abc'} } World") -14 14 | print(f"Hello {set(f(a) for a in 'abc')} World") -15 15 | 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') }") - -C401.py:14:16: C401 [*] Unnecessary generator (rewrite as a `set` comprehension) - | -12 | print(f'Hello {set(a for a in "abc")} World') -13 | print(f"Hello {set(a for a in 'abc')} World") -14 | print(f"Hello {set(f(a) for a in 'abc')} World") +11 11 | print(f"Hello {set(f(a) for a in 'abc')} World") +12 |-print(f"Hello { set(f(a) for a in 'abc') } World") + 12 |+print(f"Hello { {f(a) for a in 'abc'} } World") +13 13 | +14 14 | +15 15 | # Short-circuit case, combine with C416 and should produce x = set(range(3)) + +C401.py:16:5: C401 [*] Unnecessary generator (rewrite using `set()` + | +15 | # Short-circuit case, combine with C416 and should produce x = set(range(3)) +16 | x = set(x for x in range(3)) + | ^^^^^^^^^^^^^^^^^^^^^^^^ C401 +17 | x = set( +18 | x for x in range(3) + | + = help: Rewrite using `set()` + +ℹ Unsafe fix +13 13 | +14 14 | +15 15 | # Short-circuit case, combine with C416 and should produce x = set(range(3)) +16 |-x = set(x for x in range(3)) + 16 |+x = set(range(3)) +17 17 | x = set( +18 18 | x for x in range(3) +19 19 | ) + +C401.py:17:5: C401 [*] Unnecessary generator (rewrite using `set()` + | +15 | # Short-circuit case, combine with C416 and should produce x = set(range(3)) +16 | x = set(x for x in range(3)) +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 -15 | 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') }") +21 | 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 -11 11 | -12 12 | print(f'Hello {set(a for a in "abc")} World') -13 13 | print(f"Hello {set(a for a in 'abc')} World") -14 |-print(f"Hello {set(f(a) for a in 'abc')} World") - 14 |+print(f"Hello { {f(a) for a in 'abc'} } World") -15 15 | 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') }") -17 17 | - -C401.py:15:10: C401 [*] Unnecessary generator (rewrite as a `set` comprehension) - | -13 | print(f"Hello {set(a for a in 'abc')} World") -14 | print(f"Hello {set(f(a) for a in 'abc')} World") -15 | print(f"{set(a for a in 'abc') - set(a for a in 'ab')}") +17 17 | x = set( +18 18 | x for x in range(3) +19 19 | ) +20 |-print(f"Hello {set(a for a in range(3))} World") + 20 |+print(f"Hello {set(range(3))} World") +21 21 | 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') }") +23 23 | + +C401.py:21:10: C401 [*] Unnecessary generator (rewrite using `set()` + | +19 | ) +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')}") | ^^^^^^^^^^^^^^^^^^^^^ 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 -12 12 | print(f'Hello {set(a for a in "abc")} World') -13 13 | print(f"Hello {set(a for a in 'abc')} World") -14 14 | print(f"Hello {set(f(a) for a in 'abc')} World") -15 |-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')}") -16 16 | print(f"{ set(a for a in 'abc') - set(a for a in 'ab') }") -17 17 | -18 18 | # The fix generated for this diagnostic is incorrect, as we add additional space - -C401.py:15:34: C401 [*] Unnecessary generator (rewrite as a `set` comprehension) - | -13 | print(f"Hello {set(a for a in 'abc')} World") -14 | print(f"Hello {set(f(a) for a in 'abc')} World") -15 | print(f"{set(a for a in 'abc') - set(a for a in 'ab')}") +18 18 | x for x in range(3) +19 19 | ) +20 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')}") + 21 |+print(f"{set('abc') - set(a for a in 'ab')}") +22 22 | print(f"{ set(a for a in 'abc') - set(a for a in 'ab') }") +23 23 | +24 24 | + +C401.py:21:34: C401 [*] Unnecessary generator (rewrite using `set()` + | +19 | ) +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')}") | ^^^^^^^^^^^^^^^^^^^^ 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 -12 12 | print(f'Hello {set(a for a in "abc")} World') -13 13 | print(f"Hello {set(a for a in 'abc')} World") -14 14 | print(f"Hello {set(f(a) for a in 'abc')} World") -15 |-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'} }") -16 16 | print(f"{ set(a for a in 'abc') - set(a for a in 'ab') }") -17 17 | -18 18 | # The fix generated for this diagnostic is incorrect, as we add additional space - -C401.py:16:11: C401 [*] Unnecessary generator (rewrite as a `set` comprehension) - | -14 | print(f"Hello {set(f(a) for a in 'abc')} World") -15 | 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') }") +18 18 | x for x in range(3) +19 19 | ) +20 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')}") + 21 |+print(f"{set(a for a in 'abc') - set('ab')}") +22 22 | print(f"{ set(a for a in 'abc') - set(a for a in 'ab') }") +23 23 | +24 24 | + +C401.py:22:11: C401 [*] Unnecessary generator (rewrite using `set()` + | +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')}") +22 | print(f"{ set(a for a in 'abc') - set(a for a in 'ab') }") | ^^^^^^^^^^^^^^^^^^^^^ 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 -13 13 | print(f"Hello {set(a for a in 'abc')} World") -14 14 | print(f"Hello {set(f(a) for a in 'abc')} World") -15 15 | 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') }") - 16 |+print(f"{ {a for a in 'abc'} - set(a for a in 'ab') }") -17 17 | -18 18 | # The fix generated for this diagnostic is incorrect, as we add additional space -19 19 | # around the set comprehension. - -C401.py:16:35: C401 [*] Unnecessary generator (rewrite as a `set` comprehension) - | -14 | print(f"Hello {set(f(a) for a in 'abc')} World") -15 | 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') }") +19 19 | ) +20 20 | print(f"Hello {set(a for a in range(3))} World") +21 21 | 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') }") + 22 |+print(f"{ set('abc') - set(a for a in 'ab') }") +23 23 | +24 24 | +25 25 | # Not built-in set. + +C401.py:22:35: C401 [*] Unnecessary generator (rewrite using `set()` + | +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')}") +22 | print(f"{ set(a for a in 'abc') - set(a for a in 'ab') }") | ^^^^^^^^^^^^^^^^^^^^ C401 -17 | -18 | # The fix generated for this diagnostic is incorrect, as we add additional space - | - = help: Rewrite as a `set` comprehension - -ℹ Unsafe fix -13 13 | print(f"Hello {set(a for a in 'abc')} World") -14 14 | print(f"Hello {set(f(a) for a in 'abc')} World") -15 15 | 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') }") - 16 |+print(f"{ set(a for a in 'abc') - {a for a in 'ab'} }") -17 17 | -18 18 | # The fix generated for this diagnostic is incorrect, as we add additional space -19 19 | # around the set comprehension. - -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 + = help: Rewrite using `set()` ℹ 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'} } }") - - +19 19 | ) +20 20 | print(f"Hello {set(a for a in range(3))} World") +21 21 | 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') }") + 22 |+print(f"{ set(a for a in 'abc') - set('ab') }") +23 23 | +24 24 | +25 25 | # Not built-in set.