Handled dict and set inside f-string (#4249) (#4563)

This commit is contained in:
Davide Canton 2023-06-09 06:53:13 +02:00 committed by GitHub
parent 2bb32ee943
commit 63fdcea29e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
25 changed files with 1380 additions and 207 deletions

View file

@ -1,13 +1,20 @@
x = set(x for x in range(3)) x = set(x for x in range(3))
x = set( x = set(x for x in range(3))
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)))
y = f'{set(a if a < 6 else 0 for a in range(3))}' print(f"Hello {set(a for a in range(3))} World")
_ = '{}'.format(set(a if a < 6 else 0 for a in range(3)))
print(f'Hello {set(a for a in range(3))} World')
def set(*args, **kwargs):
return None
set(x for x 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"{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')} }")

View file

@ -5,3 +5,14 @@ dict(
dict(((x, x) for x in range(3)), z=3) dict(((x, x) for x in range(3)), z=3)
y = f'{dict((x, x) for x in range(3))}' y = f'{dict((x, x) for x in range(3))}'
print(f'Hello {dict((x, x) for x in range(3))} World') print(f'Hello {dict((x, x) for x in range(3))} World')
print(f"Hello {dict((x, x) for x in 'abc')} World")
print(f'Hello {dict((x, x) for x in "abc")} World')
print(f'Hello {dict((x,x) for x in "abc")} World')
f'{dict((x, x) for x in range(3)) | dict((x, x) for x in range(3))}'
f'{ dict((x, x) for x in range(3)) | dict((x, x) for x in range(3)) }'
def f(x):
return x
print(f'Hello {dict((x,f(x)) for x in "abc")} World')

View file

@ -2,3 +2,14 @@ s = set([x for x in range(3)])
s = set( s = set(
[x for x in range(3)] [x for x in range(3)]
) )
s = f"{set([x for x in 'ab'])}"
s = f'{set([x for x in "ab"])}'
def f(x):
return x
s = f"{set([f(x) for x in 'ab'])}"
s = f"{ set([x for x in 'ab']) | set([x for x in 'ab']) }"
s = f"{set([x for x in 'ab']) | set([x for x in 'ab'])}"

View file

@ -1,2 +1,13 @@
dict([(i, i) for i in range(3)]) dict([(i, i) for i in range(3)])
dict([(i, i) for i in range(3)], z=4) dict([(i, i) for i in range(3)], z=4)
def f(x):
return x
f'{dict([(s,s) for s in "ab"])}'
f"{dict([(s,s) for s in 'ab'])}"
f"{dict([(s, s) for s in 'ab'])}"
f"{dict([(s,f(s)) for s in 'ab'])}"
f'{dict([(s,s) for s in "ab"]) | dict([(s,s) for s in "ab"])}'
f'{ dict([(s,s) for s in "ab"]) | dict([(s,s) for s in "ab"]) }'

View file

@ -16,3 +16,11 @@ set(
set( set(
[1,] [1,]
) )
f"{set([1,2,3])}"
f"{set(['a', 'b'])}"
f'{set(["a", "b"])}'
f"{set(['a', 'b']) - set(['a'])}"
f"{ set(['a', 'b']) - set(['a']) }"
f"a {set(['a', 'b']) - set(['a'])} b"
f"a { set(['a', 'b']) - set(['a']) } b"

View file

@ -10,3 +10,13 @@ def list():
a = list() a = list()
f"{dict(x='y')}"
f'{dict(x="y")}'
f"{dict()}"
f"a {dict()} b"
f"{dict(x='y') | dict(y='z')}"
f"{ dict(x='y') | dict(y='z') }"
f"a {dict(x='y') | dict(y='z')} b"
f"a { dict(x='y') | dict(y='z') } b"

View file

@ -136,36 +136,36 @@ impl<'a> Checker<'a> {
/// Create a [`Generator`] to generate source code based on the current AST state. /// Create a [`Generator`] to generate source code based on the current AST state.
pub(crate) fn generator(&self) -> Generator { pub(crate) fn generator(&self) -> Generator {
fn quote_style(
model: &SemanticModel,
locator: &Locator,
indexer: &Indexer,
) -> Option<Quote> {
if !model.in_f_string() {
return None;
}
// Find the quote character used to start the containing f-string.
let expr = model.expr()?;
let string_range = indexer.f_string_range(expr.start())?;
let trailing_quote = trailing_quote(locator.slice(string_range))?;
// Invert the quote character, if it's a single quote.
match *trailing_quote {
"'" => Some(Quote::Double),
"\"" => Some(Quote::Single),
_ => None,
}
}
Generator::new( Generator::new(
self.stylist.indentation(), self.stylist.indentation(),
quote_style(&self.semantic_model, self.locator, self.indexer) self.f_string_quote_style().unwrap_or(self.stylist.quote()),
.unwrap_or(self.stylist.quote()),
self.stylist.line_ending(), self.stylist.line_ending(),
) )
} }
/// Returns the appropriate quoting for f-string by reversing the one used outside of
/// the f-string.
///
/// If the current expression in the context is not an f-string, returns ``None``.
pub(crate) fn f_string_quote_style(&self) -> Option<Quote> {
let model = &self.semantic_model;
if !model.in_f_string() {
return None;
}
// Find the quote character used to start the containing f-string.
let expr = model.expr()?;
let string_range = self.indexer.f_string_range(expr.start())?;
let trailing_quote = trailing_quote(self.locator.slice(string_range))?;
// Invert the quote character, if it's a single quote.
match *trailing_quote {
"'" => Some(Quote::Double),
"\"" => Some(Quote::Single),
_ => None,
}
}
/// Returns the [`IsolationLevel`] for fixes in the current context. /// Returns the [`IsolationLevel`] for fixes in the current context.
/// ///
/// The primary use-case for fix isolation is to ensure that we don't delete all statements /// The primary use-case for fix isolation is to ensure that we don't delete all statements
@ -2729,22 +2729,12 @@ where
} }
if self.enabled(Rule::UnnecessaryGeneratorSet) { if self.enabled(Rule::UnnecessaryGeneratorSet) {
flake8_comprehensions::rules::unnecessary_generator_set( flake8_comprehensions::rules::unnecessary_generator_set(
self, self, expr, func, args, keywords,
expr,
self.semantic_model.expr_parent(),
func,
args,
keywords,
); );
} }
if self.enabled(Rule::UnnecessaryGeneratorDict) { if self.enabled(Rule::UnnecessaryGeneratorDict) {
flake8_comprehensions::rules::unnecessary_generator_dict( flake8_comprehensions::rules::unnecessary_generator_dict(
self, self, expr, func, args, keywords,
expr,
self.semantic_model.expr_parent(),
func,
args,
keywords,
); );
} }
if self.enabled(Rule::UnnecessaryListComprehensionSet) { if self.enabled(Rule::UnnecessaryListComprehensionSet) {

View file

@ -7,15 +7,19 @@ use libcst_native::{
RightParen, RightSquareBracket, Set, SetComp, SimpleString, SimpleWhitespace, RightParen, RightSquareBracket, Set, SetComp, SimpleString, SimpleWhitespace,
TrailingWhitespace, Tuple, TrailingWhitespace, Tuple,
}; };
use ruff_text_size::TextRange;
use rustpython_parser::ast::Ranged; use rustpython_parser::ast::Ranged;
use crate::autofix::codemods::CodegenStylist;
use ruff_diagnostics::{Edit, Fix}; use ruff_diagnostics::{Edit, Fix};
use ruff_python_ast::source_code::{Locator, Stylist}; use ruff_python_ast::source_code::{Locator, Stylist};
use crate::cst::matchers::{ use crate::autofix::codemods::CodegenStylist;
match_arg, match_call, match_call_mut, match_expression, match_generator_exp, match_lambda, use crate::{
match_list_comp, match_name, match_tuple, checkers::ast::Checker,
cst::matchers::{
match_arg, match_call, match_call_mut, match_expression, match_generator_exp, match_lambda,
match_list_comp, match_name, match_tuple,
},
}; };
/// (C400) Convert `list(x for x in y)` to `[x for x in y]`. /// (C400) Convert `list(x for x in y)` to `[x for x in y]`.
@ -53,11 +57,12 @@ pub(crate) fn fix_unnecessary_generator_list(
/// (C401) Convert `set(x for x in y)` to `{x for x in y}`. /// (C401) Convert `set(x for x in y)` to `{x for x in y}`.
pub(crate) fn fix_unnecessary_generator_set( pub(crate) fn fix_unnecessary_generator_set(
locator: &Locator, checker: &Checker,
stylist: &Stylist,
expr: &rustpython_parser::ast::Expr, expr: &rustpython_parser::ast::Expr,
parent: Option<&rustpython_parser::ast::Expr>,
) -> Result<Edit> { ) -> Result<Edit> {
let locator = checker.locator;
let stylist = checker.stylist;
// Expr(Call(GeneratorExp)))) -> Expr(SetComp))) // Expr(Call(GeneratorExp)))) -> Expr(SetComp)))
let module_text = locator.slice(expr.range()); let module_text = locator.slice(expr.range());
let mut tree = match_expression(module_text)?; let mut tree = match_expression(module_text)?;
@ -79,25 +84,23 @@ pub(crate) fn fix_unnecessary_generator_set(
rpar: generator_exp.rpar.clone(), rpar: generator_exp.rpar.clone(),
})); }));
let mut content = tree.codegen_stylist(stylist); let content = tree.codegen_stylist(stylist);
// If the expression is embedded in an f-string, surround it with spaces to avoid Ok(Edit::range_replacement(
// syntax errors. pad_expression(content, expr.range(), checker),
if let Some(rustpython_parser::ast::Expr::FormattedValue(_)) = parent { expr.range(),
content = format!(" {content} "); ))
}
Ok(Edit::range_replacement(content, expr.range()))
} }
/// (C402) Convert `dict((x, x) for x in range(3))` to `{x: x for x in /// (C402) Convert `dict((x, x) for x in range(3))` to `{x: x for x in
/// range(3)}`. /// range(3)}`.
pub(crate) fn fix_unnecessary_generator_dict( pub(crate) fn fix_unnecessary_generator_dict(
locator: &Locator, checker: &Checker,
stylist: &Stylist,
expr: &rustpython_parser::ast::Expr, expr: &rustpython_parser::ast::Expr,
parent: Option<&rustpython_parser::ast::Expr>,
) -> Result<Edit> { ) -> Result<Edit> {
let locator = checker.locator;
let stylist = checker.stylist;
let module_text = locator.slice(expr.range()); let module_text = locator.slice(expr.range());
let mut tree = match_expression(module_text)?; let mut tree = match_expression(module_text)?;
let call = match_call_mut(&mut tree)?; let call = match_call_mut(&mut tree)?;
@ -126,23 +129,19 @@ pub(crate) fn fix_unnecessary_generator_dict(
whitespace_after_colon: ParenthesizableWhitespace::SimpleWhitespace(SimpleWhitespace(" ")), whitespace_after_colon: ParenthesizableWhitespace::SimpleWhitespace(SimpleWhitespace(" ")),
})); }));
let mut content = tree.codegen_stylist(stylist); Ok(Edit::range_replacement(
pad_expression(tree.codegen_stylist(stylist), expr.range(), checker),
// If the expression is embedded in an f-string, surround it with spaces to avoid expr.range(),
// syntax errors. ))
if let Some(rustpython_parser::ast::Expr::FormattedValue(_)) = parent {
content = format!(" {content} ");
}
Ok(Edit::range_replacement(content, expr.range()))
} }
/// (C403) Convert `set([x for x in y])` to `{x for x in y}`. /// (C403) Convert `set([x for x in y])` to `{x for x in y}`.
pub(crate) fn fix_unnecessary_list_comprehension_set( pub(crate) fn fix_unnecessary_list_comprehension_set(
locator: &Locator, checker: &Checker,
stylist: &Stylist,
expr: &rustpython_parser::ast::Expr, expr: &rustpython_parser::ast::Expr,
) -> Result<Edit> { ) -> Result<Edit> {
let locator = checker.locator;
let stylist = checker.stylist;
// Expr(Call(ListComp)))) -> // Expr(Call(ListComp)))) ->
// Expr(SetComp))) // Expr(SetComp)))
let module_text = locator.slice(expr.range()); let module_text = locator.slice(expr.range());
@ -166,7 +165,7 @@ pub(crate) fn fix_unnecessary_list_comprehension_set(
})); }));
Ok(Edit::range_replacement( Ok(Edit::range_replacement(
tree.codegen_stylist(stylist), pad_expression(tree.codegen_stylist(stylist), expr.range(), checker),
expr.range(), expr.range(),
)) ))
} }
@ -174,10 +173,12 @@ pub(crate) fn fix_unnecessary_list_comprehension_set(
/// (C404) Convert `dict([(i, i) for i in range(3)])` to `{i: i for i in /// (C404) Convert `dict([(i, i) for i in range(3)])` to `{i: i for i in
/// range(3)}`. /// range(3)}`.
pub(crate) fn fix_unnecessary_list_comprehension_dict( pub(crate) fn fix_unnecessary_list_comprehension_dict(
locator: &Locator, checker: &Checker,
stylist: &Stylist,
expr: &rustpython_parser::ast::Expr, expr: &rustpython_parser::ast::Expr,
) -> Result<Edit> { ) -> Result<Edit> {
let locator = checker.locator;
let stylist = checker.stylist;
let module_text = locator.slice(expr.range()); let module_text = locator.slice(expr.range());
let mut tree = match_expression(module_text)?; let mut tree = match_expression(module_text)?;
let call = match_call_mut(&mut tree)?; let call = match_call_mut(&mut tree)?;
@ -188,16 +189,15 @@ pub(crate) fn fix_unnecessary_list_comprehension_dict(
let tuple = match_tuple(&list_comp.elt)?; let tuple = match_tuple(&list_comp.elt)?;
let [Element::Simple { let [Element::Simple {
value: key, value: key, ..
comma: Some(comma),
}, Element::Simple { value, .. }] = &tuple.elements[..] else { bail!("Expected tuple with two elements"); }; }, Element::Simple { value, .. }] = &tuple.elements[..] else { bail!("Expected tuple with two elements"); };
tree = Expression::DictComp(Box::new(DictComp { tree = Expression::DictComp(Box::new(DictComp {
key: Box::new(key.clone()), key: Box::new(key.clone()),
value: Box::new(value.clone()), value: Box::new(value.clone()),
for_in: list_comp.for_in.clone(), for_in: list_comp.for_in.clone(),
whitespace_before_colon: comma.whitespace_before.clone(), whitespace_before_colon: ParenthesizableWhitespace::default(),
whitespace_after_colon: comma.whitespace_after.clone(), whitespace_after_colon: ParenthesizableWhitespace::SimpleWhitespace(SimpleWhitespace(" ")),
lbrace: LeftCurlyBrace { lbrace: LeftCurlyBrace {
whitespace_after: call.whitespace_before_args.clone(), whitespace_after: call.whitespace_before_args.clone(),
}, },
@ -209,7 +209,7 @@ pub(crate) fn fix_unnecessary_list_comprehension_dict(
})); }));
Ok(Edit::range_replacement( Ok(Edit::range_replacement(
tree.codegen_stylist(stylist), pad_expression(tree.codegen_stylist(stylist), expr.range(), checker),
expr.range(), expr.range(),
)) ))
} }
@ -259,10 +259,12 @@ fn drop_trailing_comma<'a>(
/// (C405) Convert `set((1, 2))` to `{1, 2}`. /// (C405) Convert `set((1, 2))` to `{1, 2}`.
pub(crate) fn fix_unnecessary_literal_set( pub(crate) fn fix_unnecessary_literal_set(
locator: &Locator, checker: &Checker,
stylist: &Stylist,
expr: &rustpython_parser::ast::Expr, expr: &rustpython_parser::ast::Expr,
) -> Result<Edit> { ) -> Result<Edit> {
let locator = checker.locator;
let stylist = checker.stylist;
// Expr(Call(List|Tuple)))) -> Expr(Set))) // Expr(Call(List|Tuple)))) -> Expr(Set)))
let module_text = locator.slice(expr.range()); let module_text = locator.slice(expr.range());
let mut tree = match_expression(module_text)?; let mut tree = match_expression(module_text)?;
@ -294,17 +296,19 @@ pub(crate) fn fix_unnecessary_literal_set(
} }
Ok(Edit::range_replacement( Ok(Edit::range_replacement(
tree.codegen_stylist(stylist), pad_expression(tree.codegen_stylist(stylist), expr.range(), checker),
expr.range(), expr.range(),
)) ))
} }
/// (C406) Convert `dict([(1, 2)])` to `{1: 2}`. /// (C406) Convert `dict([(1, 2)])` to `{1: 2}`.
pub(crate) fn fix_unnecessary_literal_dict( pub(crate) fn fix_unnecessary_literal_dict(
locator: &Locator, checker: &Checker,
stylist: &Stylist,
expr: &rustpython_parser::ast::Expr, expr: &rustpython_parser::ast::Expr,
) -> Result<Edit> { ) -> Result<Edit> {
let locator = checker.locator;
let stylist = checker.stylist;
// Expr(Call(List|Tuple)))) -> Expr(Dict))) // Expr(Call(List|Tuple)))) -> Expr(Dict)))
let module_text = locator.slice(expr.range()); let module_text = locator.slice(expr.range());
let mut tree = match_expression(module_text)?; let mut tree = match_expression(module_text)?;
@ -358,36 +362,50 @@ pub(crate) fn fix_unnecessary_literal_dict(
})); }));
Ok(Edit::range_replacement( Ok(Edit::range_replacement(
tree.codegen_stylist(stylist), pad_expression(tree.codegen_stylist(stylist), expr.range(), checker),
expr.range(), expr.range(),
)) ))
} }
/// (C408) /// (C408)
pub(crate) fn fix_unnecessary_collection_call( pub(crate) fn fix_unnecessary_collection_call(
locator: &Locator, checker: &Checker,
stylist: &Stylist,
expr: &rustpython_parser::ast::Expr, expr: &rustpython_parser::ast::Expr,
) -> Result<Edit> { ) -> Result<Edit> {
enum Collection {
Tuple,
List,
Dict,
}
let locator = checker.locator;
let stylist = checker.stylist;
// Expr(Call("list" | "tuple" | "dict")))) -> Expr(List|Tuple|Dict) // Expr(Call("list" | "tuple" | "dict")))) -> Expr(List|Tuple|Dict)
let module_text = locator.slice(expr.range()); let module_text = locator.slice(expr.range());
let mut tree = match_expression(module_text)?; let mut tree = match_expression(module_text)?;
let call = match_call_mut(&mut tree)?; let call = match_call(&tree)?;
let name = match_name(&call.func)?; let name = match_name(&call.func)?;
let collection = match name.value {
"tuple" => Collection::Tuple,
"list" => Collection::List,
"dict" => Collection::Dict,
_ => bail!("Expected 'tuple', 'list', or 'dict'"),
};
// Arena allocator used to create formatted strings of sufficient lifetime, // Arena allocator used to create formatted strings of sufficient lifetime,
// below. // below.
let mut arena: Vec<String> = vec![]; let mut arena: Vec<String> = vec![];
match name.value { match collection {
"tuple" => { Collection::Tuple => {
tree = Expression::Tuple(Box::new(Tuple { tree = Expression::Tuple(Box::new(Tuple {
elements: vec![], elements: vec![],
lpar: vec![LeftParen::default()], lpar: vec![LeftParen::default()],
rpar: vec![RightParen::default()], rpar: vec![RightParen::default()],
})); }));
} }
"list" => { Collection::List => {
tree = Expression::List(Box::new(List { tree = Expression::List(Box::new(List {
elements: vec![], elements: vec![],
lbracket: LeftSquareBracket::default(), lbracket: LeftSquareBracket::default(),
@ -396,7 +414,7 @@ pub(crate) fn fix_unnecessary_collection_call(
rpar: vec![], rpar: vec![],
})); }));
} }
"dict" => { Collection::Dict => {
if call.args.is_empty() { if call.args.is_empty() {
tree = Expression::Dict(Box::new(Dict { tree = Expression::Dict(Box::new(Dict {
elements: vec![], elements: vec![],
@ -406,16 +424,18 @@ pub(crate) fn fix_unnecessary_collection_call(
rpar: vec![], rpar: vec![],
})); }));
} else { } else {
let quote = checker.f_string_quote_style().unwrap_or(stylist.quote());
// Quote each argument. // Quote each argument.
for arg in &call.args { for arg in &call.args {
let quoted = format!( let quoted = format!(
"{}{}{}", "{}{}{}",
stylist.quote(), quote,
arg.keyword arg.keyword
.as_ref() .as_ref()
.expect("Expected dictionary argument to be kwarg") .expect("Expected dictionary argument to be kwarg")
.value, .value,
stylist.quote(), quote,
); );
arena.push(quoted); arena.push(quoted);
} }
@ -457,17 +477,56 @@ pub(crate) fn fix_unnecessary_collection_call(
})); }));
} }
} }
_ => {
bail!("Expected function name to be one of: 'tuple', 'list', 'dict'");
}
}; };
Ok(Edit::range_replacement( Ok(Edit::range_replacement(
tree.codegen_stylist(stylist), if matches!(collection, Collection::Dict) {
pad_expression(tree.codegen_stylist(stylist), expr.range(), checker)
} else {
tree.codegen_stylist(stylist)
},
expr.range(), expr.range(),
)) ))
} }
/// Re-formats the given expression for use within a formatted string.
///
/// For example, when converting a `dict` call to a dictionary literal within
/// a formatted string, we might naively generate the following code:
///
/// ```python
/// f"{{'a': 1, 'b': 2}}"
/// ```
///
/// However, this is a syntax error under the f-string grammar. As such,
/// this method will pad the start and end of an expression as needed to
/// avoid producing invalid syntax.
fn pad_expression(content: String, range: TextRange, checker: &Checker) -> String {
if !checker.semantic_model().in_f_string() {
return content;
}
// If the expression is immediately preceded by an opening brace, then
// we need to add a space before the expression.
let prefix = checker.locator.up_to(range.start());
let left_pad = matches!(prefix.chars().rev().next(), Some('{'));
// If the expression is immediately preceded by an opening brace, then
// we need to add a space before the expression.
let suffix = checker.locator.after(range.end());
let right_pad = matches!(suffix.chars().next(), Some('}'));
if left_pad && right_pad {
format!(" {content} ")
} else if left_pad {
format!(" {content}")
} else if right_pad {
format!("{content} ")
} else {
content
}
}
/// (C409) Convert `tuple([1, 2])` to `tuple(1, 2)` /// (C409) Convert `tuple([1, 2])` to `tuple(1, 2)`
pub(crate) fn fix_unnecessary_literal_within_tuple_call( pub(crate) fn fix_unnecessary_literal_within_tuple_call(
locator: &Locator, locator: &Locator,

View file

@ -90,9 +90,7 @@ pub(crate) fn unnecessary_collection_call(
); );
if checker.patch(diagnostic.kind.rule()) { if checker.patch(diagnostic.kind.rule()) {
#[allow(deprecated)] #[allow(deprecated)]
diagnostic.try_set_fix_from_edit(|| { diagnostic.try_set_fix_from_edit(|| fixes::fix_unnecessary_collection_call(checker, expr));
fixes::fix_unnecessary_collection_call(checker.locator, checker.stylist, expr)
});
} }
checker.diagnostics.push(diagnostic); checker.diagnostics.push(diagnostic);
} }

View file

@ -45,7 +45,6 @@ impl AlwaysAutofixableViolation for UnnecessaryGeneratorDict {
pub(crate) fn unnecessary_generator_dict( pub(crate) fn unnecessary_generator_dict(
checker: &mut Checker, checker: &mut Checker,
expr: &Expr, expr: &Expr,
parent: Option<&Expr>,
func: &Expr, func: &Expr,
args: &[Expr], args: &[Expr],
keywords: &[Keyword], keywords: &[Keyword],
@ -60,12 +59,7 @@ pub(crate) fn unnecessary_generator_dict(
if checker.patch(diagnostic.kind.rule()) { if checker.patch(diagnostic.kind.rule()) {
#[allow(deprecated)] #[allow(deprecated)]
diagnostic.try_set_fix_from_edit(|| { diagnostic.try_set_fix_from_edit(|| {
fixes::fix_unnecessary_generator_dict( fixes::fix_unnecessary_generator_dict(checker, expr)
checker.locator,
checker.stylist,
expr,
parent,
)
}); });
} }
checker.diagnostics.push(diagnostic); checker.diagnostics.push(diagnostic);

View file

@ -45,7 +45,6 @@ impl AlwaysAutofixableViolation for UnnecessaryGeneratorSet {
pub(crate) fn unnecessary_generator_set( pub(crate) fn unnecessary_generator_set(
checker: &mut Checker, checker: &mut Checker,
expr: &Expr, expr: &Expr,
parent: Option<&Expr>,
func: &Expr, func: &Expr,
args: &[Expr], args: &[Expr],
keywords: &[Keyword], keywords: &[Keyword],
@ -60,9 +59,8 @@ pub(crate) fn unnecessary_generator_set(
let mut diagnostic = Diagnostic::new(UnnecessaryGeneratorSet, expr.range()); let mut diagnostic = Diagnostic::new(UnnecessaryGeneratorSet, expr.range());
if checker.patch(diagnostic.kind.rule()) { if checker.patch(diagnostic.kind.rule()) {
#[allow(deprecated)] #[allow(deprecated)]
diagnostic.try_set_fix_from_edit(|| { diagnostic
fixes::fix_unnecessary_generator_set(checker.locator, checker.stylist, expr, parent) .try_set_fix_from_edit(|| fixes::fix_unnecessary_generator_set(checker, expr));
});
} }
checker.diagnostics.push(diagnostic); checker.diagnostics.push(diagnostic);
} }

View file

@ -66,7 +66,7 @@ pub(crate) fn unnecessary_list_comprehension_dict(
if checker.patch(diagnostic.kind.rule()) { if checker.patch(diagnostic.kind.rule()) {
#[allow(deprecated)] #[allow(deprecated)]
diagnostic.try_set_fix_from_edit(|| { diagnostic.try_set_fix_from_edit(|| {
fixes::fix_unnecessary_list_comprehension_dict(checker.locator, checker.stylist, expr) fixes::fix_unnecessary_list_comprehension_dict(checker, expr)
}); });
} }
checker.diagnostics.push(diagnostic); checker.diagnostics.push(diagnostic);

View file

@ -58,11 +58,7 @@ pub(crate) fn unnecessary_list_comprehension_set(
if checker.patch(diagnostic.kind.rule()) { if checker.patch(diagnostic.kind.rule()) {
#[allow(deprecated)] #[allow(deprecated)]
diagnostic.try_set_fix_from_edit(|| { diagnostic.try_set_fix_from_edit(|| {
fixes::fix_unnecessary_list_comprehension_set( fixes::fix_unnecessary_list_comprehension_set(checker, expr)
checker.locator,
checker.stylist,
expr,
)
}); });
} }
checker.diagnostics.push(diagnostic); checker.diagnostics.push(diagnostic);

View file

@ -80,9 +80,7 @@ pub(crate) fn unnecessary_literal_dict(
); );
if checker.patch(diagnostic.kind.rule()) { if checker.patch(diagnostic.kind.rule()) {
#[allow(deprecated)] #[allow(deprecated)]
diagnostic.try_set_fix_from_edit(|| { diagnostic.try_set_fix_from_edit(|| fixes::fix_unnecessary_literal_dict(checker, expr));
fixes::fix_unnecessary_literal_dict(checker.locator, checker.stylist, expr)
});
} }
checker.diagnostics.push(diagnostic); checker.diagnostics.push(diagnostic);
} }

View file

@ -74,9 +74,7 @@ pub(crate) fn unnecessary_literal_set(
); );
if checker.patch(diagnostic.kind.rule()) { if checker.patch(diagnostic.kind.rule()) {
#[allow(deprecated)] #[allow(deprecated)]
diagnostic.try_set_fix_from_edit(|| { diagnostic.try_set_fix_from_edit(|| fixes::fix_unnecessary_literal_set(checker, expr));
fixes::fix_unnecessary_literal_set(checker.locator, checker.stylist, expr)
});
} }
checker.diagnostics.push(diagnostic); checker.diagnostics.push(diagnostic);
} }

View file

@ -5,102 +5,251 @@ C401.py:1:5: C401 [*] Unnecessary generator (rewrite as a `set` comprehension)
| |
1 | x = set(x for x in range(3)) 1 | x = set(x for x in range(3))
| ^^^^^^^^^^^^^^^^^^^^^^^^ C401 | ^^^^^^^^^^^^^^^^^^^^^^^^ C401
2 | x = set( 2 | x = set(x for x in range(3))
3 | x for x in range(3) 3 | y = 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
Suggested fix Suggested fix
1 |-x = set(x for x in range(3)) 1 |-x = set(x for x in range(3))
1 |+x = {x for x in range(3)} 1 |+x = {x for x in range(3)}
2 2 | x = set( 2 2 | x = set(x for x in range(3))
3 3 | x for x in range(3) 3 3 | y = f"{set(a if a < 6 else 0 for a in range(3))}"
4 4 | ) 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) C401.py:2:5: C401 [*] Unnecessary generator (rewrite as a `set` comprehension)
| |
2 | x = set(x for x in range(3)) 2 | x = set(x for x in range(3))
3 | x = set( 3 | x = set(x for x in range(3))
| _____^ | ^^^^^^^^^^^^^^^^^^^^^^^^ C401
4 | | x for x in range(3) 4 | y = f"{set(a if a < 6 else 0 for a in range(3))}"
5 | | ) 5 | _ = "{}".format(set(a if a < 6 else 0 for a in range(3)))
| |_^ C401
6 | y = f'{set(a if a < 6 else 0 for a in range(3))}'
7 | _ = '{}'.format(set(a if a < 6 else 0 for a in range(3)))
| |
= help: Rewrite as a `set` comprehension = help: Rewrite as a `set` comprehension
Suggested fix Suggested fix
1 1 | x = set(x for x in range(3)) 1 1 | x = set(x for x in range(3))
2 |-x = set( 2 |-x = set(x for x in range(3))
2 |+x = { 2 |+x = {x for x in range(3)}
3 3 | x for x in range(3) 3 3 | y = f"{set(a if a < 6 else 0 for a in range(3))}"
4 |-) 4 4 | _ = "{}".format(set(a if a < 6 else 0 for a in range(3)))
4 |+} 5 5 | print(f"Hello {set(a for a in range(3))} World")
5 5 | y = f'{set(a if a < 6 else 0 for a in range(3))}'
6 6 | _ = '{}'.format(set(a if a < 6 else 0 for a in range(3)))
7 7 | print(f'Hello {set(a for a in range(3))} World')
C401.py:5:8: C401 [*] Unnecessary generator (rewrite as a `set` comprehension) C401.py:3:8: C401 [*] Unnecessary generator (rewrite as a `set` comprehension)
| |
5 | x for x in range(3) 3 | x = set(x for x in range(3))
6 | ) 4 | x = set(x for x in range(3))
7 | y = f'{set(a if a < 6 else 0 for a in range(3))}' 5 | y = f"{set(a if a < 6 else 0 for a in range(3))}"
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C401 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C401
8 | _ = '{}'.format(set(a if a < 6 else 0 for a in range(3))) 6 | _ = "{}".format(set(a if a < 6 else 0 for a in range(3)))
9 | print(f'Hello {set(a for a in range(3))} World') 7 | print(f"Hello {set(a for a in range(3))} World")
| |
= help: Rewrite as a `set` comprehension = help: Rewrite as a `set` comprehension
Suggested fix Suggested fix
2 2 | x = set( 1 1 | x = set(x for x in range(3))
3 3 | x for x in range(3) 2 2 | x = set(x for x in range(3))
4 4 | ) 3 |-y = f"{set(a if a < 6 else 0 for a in range(3))}"
5 |-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)} }"
5 |+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)))
6 6 | _ = '{}'.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")
7 7 | print(f'Hello {set(a for a in range(3))} World') 6 6 |
8 8 |
C401.py:6:17: C401 [*] Unnecessary generator (rewrite as a `set` comprehension) C401.py:4:17: C401 [*] Unnecessary generator (rewrite as a `set` comprehension)
| |
6 | ) 4 | x = set(x for x in range(3))
7 | y = f'{set(a if a < 6 else 0 for a in range(3))}' 5 | y = f"{set(a if a < 6 else 0 for a in range(3))}"
8 | _ = '{}'.format(set(a if a < 6 else 0 for a in range(3))) 6 | _ = "{}".format(set(a if a < 6 else 0 for a in range(3)))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C401 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C401
9 | print(f'Hello {set(a for a in range(3))} World') 7 | print(f"Hello {set(a for a in range(3))} World")
| |
= help: Rewrite as a `set` comprehension = help: Rewrite as a `set` comprehension
Suggested fix Suggested fix
3 3 | x for x in range(3) 1 1 | x = set(x for x in range(3))
4 4 | ) 2 2 | x = set(x for x in range(3))
5 5 | y = f'{set(a if a < 6 else 0 for a in range(3))}' 3 3 | y = f"{set(a if a < 6 else 0 for a in range(3))}"
6 |-_ = '{}'.format(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)))
6 |+_ = '{}'.format({a if a < 6 else 0 for a in range(3)}) 4 |+_ = "{}".format({a if a < 6 else 0 for a in range(3)})
7 7 | print(f'Hello {set(a for a in range(3))} World') 5 5 | print(f"Hello {set(a for a in range(3))} World")
8 8 | 6 6 |
9 9 | def set(*args, **kwargs): 7 7 |
C401.py:7:16: C401 [*] Unnecessary generator (rewrite as a `set` comprehension) C401.py:5:16: C401 [*] Unnecessary generator (rewrite as a `set` comprehension)
|
5 | y = f"{set(a if a < 6 else 0 for a in range(3))}"
6 | _ = "{}".format(set(a if a < 6 else 0 for a in range(3)))
7 | print(f"Hello {set(a for a in range(3))} World")
| ^^^^^^^^^^^^^^^^^^^^^^^^ C401
|
= help: Rewrite as a `set` comprehension
Suggested 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 |
8 8 | def f(x):
C401.py:12:16: C401 [*] Unnecessary generator (rewrite as a `set` comprehension)
| |
7 | y = f'{set(a if a < 6 else 0 for a in range(3))}' 12 | print(f'Hello {set(a for a in "abc")} World')
8 | _ = '{}'.format(set(a if a < 6 else 0 for a in range(3))) | ^^^^^^^^^^^^^^^^^^^^^ C401
9 | print(f'Hello {set(a for a in range(3))} 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")
10 |
11 | def set(*args, **kwargs):
| |
= help: Rewrite as a `set` comprehension = help: Rewrite as a `set` comprehension
Suggested fix Suggested fix
4 4 | ) 9 9 | return x
5 5 | y = f'{set(a if a < 6 else 0 for a in range(3))}' 10 10 |
6 6 | _ = '{}'.format(set(a if a < 6 else 0 for a in range(3))) 11 11 |
7 |-print(f'Hello {set(a for a in range(3))} World') 12 |-print(f'Hello {set(a for a in "abc")} World')
7 |+print(f'Hello { {a for a in range(3)} } World') 12 |+print(f'Hello { {a for a in "abc"} } World')
8 8 | 13 13 | print(f"Hello {set(a for a in 'abc')} World")
9 9 | def set(*args, **kwargs): 14 14 | print(f"Hello {set(f(a) for a in 'abc')} World")
10 10 | return None 15 15 | print(f"{set(a for a in 'abc') - set(a for a in 'ab')}")
C401.py:13:16: C401 [*] Unnecessary generator (rewrite as a `set` comprehension)
|
13 | print(f'Hello {set(a for a in "abc")} World')
14 | print(f"Hello {set(a for a in 'abc')} World")
| ^^^^^^^^^^^^^^^^^^^^^ C401
15 | print(f"Hello {set(f(a) for a in 'abc')} World")
16 | print(f"{set(a for a in 'abc') - set(a for a in 'ab')}")
|
= help: Rewrite as a `set` comprehension
Suggested fix
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)
|
14 | print(f'Hello {set(a for a in "abc")} World')
15 | print(f"Hello {set(a for a in 'abc')} World")
16 | print(f"Hello {set(f(a) for a in 'abc')} World")
| ^^^^^^^^^^^^^^^^^^^^^^^^ C401
17 | print(f"{set(a for a in 'abc') - set(a for a in 'ab')}")
18 | print(f"{ set(a for a in 'abc') - set(a for a in 'ab') }")
|
= help: Rewrite as a `set` comprehension
Suggested 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)
|
15 | print(f"Hello {set(a for a in 'abc')} World")
16 | print(f"Hello {set(f(a) for a in 'abc')} World")
17 | print(f"{set(a for a in 'abc') - set(a for a in 'ab')}")
| ^^^^^^^^^^^^^^^^^^^^^ C401
18 | print(f"{ set(a for a in 'abc') - set(a for a in 'ab') }")
|
= help: Rewrite as a `set` comprehension
Suggested 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)
|
15 | print(f"Hello {set(a for a in 'abc')} World")
16 | print(f"Hello {set(f(a) for a in 'abc')} World")
17 | print(f"{set(a for a in 'abc') - set(a for a in 'ab')}")
| ^^^^^^^^^^^^^^^^^^^^ C401
18 | print(f"{ set(a for a in 'abc') - set(a for a in 'ab') }")
|
= help: Rewrite as a `set` comprehension
Suggested 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)
|
16 | print(f"Hello {set(f(a) for a in 'abc')} World")
17 | print(f"{set(a for a in 'abc') - set(a for a in 'ab')}")
18 | print(f"{ set(a for a in 'abc') - set(a for a in 'ab') }")
| ^^^^^^^^^^^^^^^^^^^^^ C401
19 |
20 | # The fix generated for this diagnostic is incorrect, as we add additional space
|
= help: Rewrite as a `set` comprehension
Suggested 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)
|
16 | print(f"Hello {set(f(a) for a in 'abc')} World")
17 | print(f"{set(a for a in 'abc') - set(a for a in 'ab')}")
18 | print(f"{ set(a for a in 'abc') - set(a for a in 'ab') }")
| ^^^^^^^^^^^^^^^^^^^^ C401
19 |
20 | # The fix generated for this diagnostic is incorrect, as we add additional space
|
= help: Rewrite as a `set` comprehension
Suggested 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)
|
20 | # The fix generated for this diagnostic is incorrect, as we add additional space
21 | # around the set comprehension.
22 | print(f"{ {set(a for a in 'abc')} }")
| ^^^^^^^^^^^^^^^^^^^^^ C401
|
= help: Rewrite as a `set` comprehension
Suggested 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'} } }")

View file

@ -42,14 +42,15 @@ C402.py:2:1: C402 [*] Unnecessary generator (rewrite as a `dict` comprehension)
7 7 | print(f'Hello {dict((x, x) for x in range(3))} World') 7 7 | print(f'Hello {dict((x, x) for x in range(3))} World')
C402.py:6:8: C402 [*] Unnecessary generator (rewrite as a `dict` comprehension) C402.py:6:8: C402 [*] Unnecessary generator (rewrite as a `dict` comprehension)
| |
6 | ) 6 | )
7 | dict(((x, x) for x in range(3)), z=3) 7 | dict(((x, x) for x in range(3)), z=3)
8 | y = f'{dict((x, x) for x in range(3))}' 8 | y = f'{dict((x, x) for x in range(3))}'
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C402 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C402
9 | print(f'Hello {dict((x, x) for x in range(3))} World') 9 | print(f'Hello {dict((x, x) for x in range(3))} World')
| 10 | print(f"Hello {dict((x, x) for x in 'abc')} World")
= help: Rewrite as a `dict` comprehension |
= help: Rewrite as a `dict` comprehension
Suggested fix Suggested fix
3 3 | (x, x) for x in range(3) 3 3 | (x, x) for x in range(3)
@ -58,15 +59,19 @@ C402.py:6:8: C402 [*] Unnecessary generator (rewrite as a `dict` comprehension)
6 |-y = f'{dict((x, x) for x in range(3))}' 6 |-y = f'{dict((x, x) for x in range(3))}'
6 |+y = f'{ {x: x for x in range(3)} }' 6 |+y = f'{ {x: x for x in range(3)} }'
7 7 | print(f'Hello {dict((x, x) for x in range(3))} World') 7 7 | print(f'Hello {dict((x, x) for x in range(3))} World')
8 8 | print(f"Hello {dict((x, x) for x in 'abc')} World")
9 9 | print(f'Hello {dict((x, x) for x in "abc")} World')
C402.py:7:16: C402 [*] Unnecessary generator (rewrite as a `dict` comprehension) C402.py:7:16: C402 [*] Unnecessary generator (rewrite as a `dict` comprehension)
| |
7 | dict(((x, x) for x in range(3)), z=3) 7 | dict(((x, x) for x in range(3)), z=3)
8 | y = f'{dict((x, x) for x in range(3))}' 8 | y = f'{dict((x, x) for x in range(3))}'
9 | print(f'Hello {dict((x, x) for x in range(3))} World') 9 | print(f'Hello {dict((x, x) for x in range(3))} World')
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C402 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C402
| 10 | print(f"Hello {dict((x, x) for x in 'abc')} World")
= help: Rewrite as a `dict` comprehension 11 | print(f'Hello {dict((x, x) for x in "abc")} World')
|
= help: Rewrite as a `dict` comprehension
Suggested fix Suggested fix
4 4 | ) 4 4 | )
@ -74,5 +79,166 @@ C402.py:7:16: C402 [*] Unnecessary generator (rewrite as a `dict` comprehension)
6 6 | y = f'{dict((x, x) for x in range(3))}' 6 6 | y = f'{dict((x, x) for x in range(3))}'
7 |-print(f'Hello {dict((x, x) for x in range(3))} World') 7 |-print(f'Hello {dict((x, x) for x in range(3))} World')
7 |+print(f'Hello { {x: x for x in range(3)} } World') 7 |+print(f'Hello { {x: x for x in range(3)} } World')
8 8 | print(f"Hello {dict((x, x) for x in 'abc')} World")
9 9 | print(f'Hello {dict((x, x) for x in "abc")} World')
10 10 | print(f'Hello {dict((x,x) for x in "abc")} World')
C402.py:8:16: C402 [*] Unnecessary generator (rewrite as a `dict` comprehension)
|
8 | y = f'{dict((x, x) for x in range(3))}'
9 | print(f'Hello {dict((x, x) for x in range(3))} World')
10 | print(f"Hello {dict((x, x) for x in 'abc')} World")
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ C402
11 | print(f'Hello {dict((x, x) for x in "abc")} World')
12 | print(f'Hello {dict((x,x) for x in "abc")} World')
|
= help: Rewrite as a `dict` comprehension
Suggested fix
5 5 | dict(((x, x) for x in range(3)), z=3)
6 6 | y = f'{dict((x, x) for x in range(3))}'
7 7 | print(f'Hello {dict((x, x) for x in range(3))} World')
8 |-print(f"Hello {dict((x, x) for x in 'abc')} World")
8 |+print(f"Hello { {x: x for x in 'abc'} } World")
9 9 | print(f'Hello {dict((x, x) for x in "abc")} World')
10 10 | print(f'Hello {dict((x,x) for x in "abc")} World')
11 11 |
C402.py:9:16: C402 [*] Unnecessary generator (rewrite as a `dict` comprehension)
|
9 | print(f'Hello {dict((x, x) for x in range(3))} World')
10 | print(f"Hello {dict((x, x) for x in 'abc')} World")
11 | print(f'Hello {dict((x, x) for x in "abc")} World')
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ C402
12 | print(f'Hello {dict((x,x) for x in "abc")} World')
|
= help: Rewrite as a `dict` comprehension
Suggested fix
6 6 | y = f'{dict((x, x) for x in range(3))}'
7 7 | print(f'Hello {dict((x, x) for x in range(3))} World')
8 8 | print(f"Hello {dict((x, x) for x in 'abc')} World")
9 |-print(f'Hello {dict((x, x) for x in "abc")} World')
9 |+print(f'Hello { {x: x for x in "abc"} } World')
10 10 | print(f'Hello {dict((x,x) for x in "abc")} World')
11 11 |
12 12 | f'{dict((x, x) for x in range(3)) | dict((x, x) for x in range(3))}'
C402.py:10:16: C402 [*] Unnecessary generator (rewrite as a `dict` comprehension)
|
10 | print(f"Hello {dict((x, x) for x in 'abc')} World")
11 | print(f'Hello {dict((x, x) for x in "abc")} World')
12 | print(f'Hello {dict((x,x) for x in "abc")} World')
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ C402
13 |
14 | f'{dict((x, x) for x in range(3)) | dict((x, x) for x in range(3))}'
|
= help: Rewrite as a `dict` comprehension
Suggested fix
7 7 | print(f'Hello {dict((x, x) for x in range(3))} World')
8 8 | print(f"Hello {dict((x, x) for x in 'abc')} World")
9 9 | print(f'Hello {dict((x, x) for x in "abc")} World')
10 |-print(f'Hello {dict((x,x) for x in "abc")} World')
10 |+print(f'Hello { {x: x for x in "abc"} } World')
11 11 |
12 12 | f'{dict((x, x) for x in range(3)) | dict((x, x) for x in range(3))}'
13 13 | f'{ dict((x, x) for x in range(3)) | dict((x, x) for x in range(3)) }'
C402.py:12:4: C402 [*] Unnecessary generator (rewrite as a `dict` comprehension)
|
12 | print(f'Hello {dict((x,x) for x in "abc")} World')
13 |
14 | f'{dict((x, x) for x in range(3)) | dict((x, x) for x in range(3))}'
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C402
15 | f'{ dict((x, x) for x in range(3)) | dict((x, x) for x in range(3)) }'
|
= help: Rewrite as a `dict` comprehension
Suggested fix
9 9 | print(f'Hello {dict((x, x) for x in "abc")} World')
10 10 | print(f'Hello {dict((x,x) for x in "abc")} World')
11 11 |
12 |-f'{dict((x, x) for x in range(3)) | dict((x, x) for x in range(3))}'
12 |+f'{ {x: x for x in range(3)} | dict((x, x) for x in range(3))}'
13 13 | f'{ dict((x, x) for x in range(3)) | dict((x, x) for x in range(3)) }'
14 14 |
15 15 | def f(x):
C402.py:12:37: C402 [*] Unnecessary generator (rewrite as a `dict` comprehension)
|
12 | print(f'Hello {dict((x,x) for x in "abc")} World')
13 |
14 | f'{dict((x, x) for x in range(3)) | dict((x, x) for x in range(3))}'
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C402
15 | f'{ dict((x, x) for x in range(3)) | dict((x, x) for x in range(3)) }'
|
= help: Rewrite as a `dict` comprehension
Suggested fix
9 9 | print(f'Hello {dict((x, x) for x in "abc")} World')
10 10 | print(f'Hello {dict((x,x) for x in "abc")} World')
11 11 |
12 |-f'{dict((x, x) for x in range(3)) | dict((x, x) for x in range(3))}'
12 |+f'{dict((x, x) for x in range(3)) | {x: x for x in range(3)} }'
13 13 | f'{ dict((x, x) for x in range(3)) | dict((x, x) for x in range(3)) }'
14 14 |
15 15 | def f(x):
C402.py:13:5: C402 [*] Unnecessary generator (rewrite as a `dict` comprehension)
|
13 | f'{dict((x, x) for x in range(3)) | dict((x, x) for x in range(3))}'
14 | f'{ dict((x, x) for x in range(3)) | dict((x, x) for x in range(3)) }'
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C402
15 |
16 | def f(x):
|
= help: Rewrite as a `dict` comprehension
Suggested fix
10 10 | print(f'Hello {dict((x,x) for x in "abc")} World')
11 11 |
12 12 | f'{dict((x, x) for x in range(3)) | dict((x, x) for x in range(3))}'
13 |-f'{ dict((x, x) for x in range(3)) | dict((x, x) for x in range(3)) }'
13 |+f'{ {x: x for x in range(3)} | dict((x, x) for x in range(3)) }'
14 14 |
15 15 | def f(x):
16 16 | return x
C402.py:13:38: C402 [*] Unnecessary generator (rewrite as a `dict` comprehension)
|
13 | f'{dict((x, x) for x in range(3)) | dict((x, x) for x in range(3))}'
14 | f'{ dict((x, x) for x in range(3)) | dict((x, x) for x in range(3)) }'
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C402
15 |
16 | def f(x):
|
= help: Rewrite as a `dict` comprehension
Suggested fix
10 10 | print(f'Hello {dict((x,x) for x in "abc")} World')
11 11 |
12 12 | f'{dict((x, x) for x in range(3)) | dict((x, x) for x in range(3))}'
13 |-f'{ dict((x, x) for x in range(3)) | dict((x, x) for x in range(3)) }'
13 |+f'{ dict((x, x) for x in range(3)) | {x: x for x in range(3)} }'
14 14 |
15 15 | def f(x):
16 16 | return x
C402.py:18:16: C402 [*] Unnecessary generator (rewrite as a `dict` comprehension)
|
18 | return x
19 |
20 | print(f'Hello {dict((x,f(x)) for x in "abc")} World')
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C402
|
= help: Rewrite as a `dict` comprehension
Suggested fix
15 15 | def f(x):
16 16 | return x
17 17 |
18 |-print(f'Hello {dict((x,f(x)) for x in "abc")} World')
18 |+print(f'Hello { {x: f(x) for x in "abc"} } World')

View file

@ -25,6 +25,8 @@ C403.py:2:5: C403 [*] Unnecessary `list` comprehension (rewrite as a `set` compr
4 | | [x for x in range(3)] 4 | | [x for x in range(3)]
5 | | ) 5 | | )
| |_^ C403 | |_^ C403
6 |
7 | s = f"{set([x for x in 'ab'])}"
| |
= help: Rewrite as a `set` comprehension = help: Rewrite as a `set` comprehension
@ -36,5 +38,135 @@ C403.py:2:5: C403 [*] Unnecessary `list` comprehension (rewrite as a `set` compr
2 |+s = { 2 |+s = {
3 |+ x for x in range(3) 3 |+ x for x in range(3)
4 |+} 4 |+}
5 5 |
6 6 | s = f"{set([x for x in 'ab'])}"
7 7 | s = f'{set([x for x in "ab"])}'
C403.py:6:8: C403 [*] Unnecessary `list` comprehension (rewrite as a `set` comprehension)
|
6 | )
7 |
8 | s = f"{set([x for x in 'ab'])}"
| ^^^^^^^^^^^^^^^^^^^^^^ C403
9 | s = f'{set([x for x in "ab"])}'
|
= help: Rewrite as a `set` comprehension
Suggested fix
3 3 | [x for x in range(3)]
4 4 | )
5 5 |
6 |-s = f"{set([x for x in 'ab'])}"
6 |+s = f"{ {x for x in 'ab'} }"
7 7 | s = f'{set([x for x in "ab"])}'
8 8 |
9 9 | def f(x):
C403.py:7:8: C403 [*] Unnecessary `list` comprehension (rewrite as a `set` comprehension)
|
7 | s = f"{set([x for x in 'ab'])}"
8 | s = f'{set([x for x in "ab"])}'
| ^^^^^^^^^^^^^^^^^^^^^^ C403
9 |
10 | def f(x):
|
= help: Rewrite as a `set` comprehension
Suggested fix
4 4 | )
5 5 |
6 6 | s = f"{set([x for x in 'ab'])}"
7 |-s = f'{set([x for x in "ab"])}'
7 |+s = f'{ {x for x in "ab"} }'
8 8 |
9 9 | def f(x):
10 10 | return x
C403.py:12:8: C403 [*] Unnecessary `list` comprehension (rewrite as a `set` comprehension)
|
12 | return x
13 |
14 | s = f"{set([f(x) for x in 'ab'])}"
| ^^^^^^^^^^^^^^^^^^^^^^^^^ C403
15 |
16 | s = f"{ set([x for x in 'ab']) | set([x for x in 'ab']) }"
|
= help: Rewrite as a `set` comprehension
Suggested fix
9 9 | def f(x):
10 10 | return x
11 11 |
12 |-s = f"{set([f(x) for x in 'ab'])}"
12 |+s = f"{ {f(x) for x in 'ab'} }"
13 13 |
14 14 | s = f"{ set([x for x in 'ab']) | set([x for x in 'ab']) }"
15 15 | s = f"{set([x for x in 'ab']) | set([x for x in 'ab'])}"
C403.py:14:9: C403 [*] Unnecessary `list` comprehension (rewrite as a `set` comprehension)
|
14 | s = f"{set([f(x) for x in 'ab'])}"
15 |
16 | s = f"{ set([x for x in 'ab']) | set([x for x in 'ab']) }"
| ^^^^^^^^^^^^^^^^^^^^^^ C403
17 | s = f"{set([x for x in 'ab']) | set([x for x in 'ab'])}"
|
= help: Rewrite as a `set` comprehension
Suggested fix
11 11 |
12 12 | s = f"{set([f(x) for x in 'ab'])}"
13 13 |
14 |-s = f"{ set([x for x in 'ab']) | set([x for x in 'ab']) }"
14 |+s = f"{ {x for x in 'ab'} | set([x for x in 'ab']) }"
15 15 | s = f"{set([x for x in 'ab']) | set([x for x in 'ab'])}"
C403.py:14:34: C403 [*] Unnecessary `list` comprehension (rewrite as a `set` comprehension)
|
14 | s = f"{set([f(x) for x in 'ab'])}"
15 |
16 | s = f"{ set([x for x in 'ab']) | set([x for x in 'ab']) }"
| ^^^^^^^^^^^^^^^^^^^^^^ C403
17 | s = f"{set([x for x in 'ab']) | set([x for x in 'ab'])}"
|
= help: Rewrite as a `set` comprehension
Suggested fix
11 11 |
12 12 | s = f"{set([f(x) for x in 'ab'])}"
13 13 |
14 |-s = f"{ set([x for x in 'ab']) | set([x for x in 'ab']) }"
14 |+s = f"{ set([x for x in 'ab']) | {x for x in 'ab'} }"
15 15 | s = f"{set([x for x in 'ab']) | set([x for x in 'ab'])}"
C403.py:15:8: C403 [*] Unnecessary `list` comprehension (rewrite as a `set` comprehension)
|
15 | s = f"{ set([x for x in 'ab']) | set([x for x in 'ab']) }"
16 | s = f"{set([x for x in 'ab']) | set([x for x in 'ab'])}"
| ^^^^^^^^^^^^^^^^^^^^^^ C403
|
= help: Rewrite as a `set` comprehension
Suggested fix
12 12 | s = f"{set([f(x) for x in 'ab'])}"
13 13 |
14 14 | s = f"{ set([x for x in 'ab']) | set([x for x in 'ab']) }"
15 |-s = f"{set([x for x in 'ab']) | set([x for x in 'ab'])}"
15 |+s = f"{ {x for x in 'ab'} | set([x for x in 'ab'])}"
C403.py:15:33: C403 [*] Unnecessary `list` comprehension (rewrite as a `set` comprehension)
|
15 | s = f"{ set([x for x in 'ab']) | set([x for x in 'ab']) }"
16 | s = f"{set([x for x in 'ab']) | set([x for x in 'ab'])}"
| ^^^^^^^^^^^^^^^^^^^^^^ C403
|
= help: Rewrite as a `set` comprehension
Suggested fix
12 12 | s = f"{set([f(x) for x in 'ab'])}"
13 13 |
14 14 | s = f"{ set([x for x in 'ab']) | set([x for x in 'ab']) }"
15 |-s = f"{set([x for x in 'ab']) | set([x for x in 'ab'])}"
15 |+s = f"{set([x for x in 'ab']) | {x for x in 'ab'} }"

View file

@ -13,5 +13,155 @@ C404.py:1:1: C404 [*] Unnecessary `list` comprehension (rewrite as a `dict` comp
1 |-dict([(i, i) for i in range(3)]) 1 |-dict([(i, i) for i in range(3)])
1 |+{i: i for i in range(3)} 1 |+{i: i for i in range(3)}
2 2 | dict([(i, i) for i in range(3)], z=4) 2 2 | dict([(i, i) for i in range(3)], z=4)
3 3 |
4 4 | def f(x):
C404.py:7:4: C404 [*] Unnecessary `list` comprehension (rewrite as a `dict` comprehension)
|
7 | return x
8 |
9 | f'{dict([(s,s) for s in "ab"])}'
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ C404
10 | f"{dict([(s,s) for s in 'ab'])}"
11 | f"{dict([(s, s) for s in 'ab'])}"
|
= help: Rewrite as a `dict` comprehension
Suggested fix
4 4 | def f(x):
5 5 | return x
6 6 |
7 |-f'{dict([(s,s) for s in "ab"])}'
7 |+f'{ {s: s for s in "ab"} }'
8 8 | f"{dict([(s,s) for s in 'ab'])}"
9 9 | f"{dict([(s, s) for s in 'ab'])}"
10 10 | f"{dict([(s,f(s)) for s in 'ab'])}"
C404.py:8:4: C404 [*] Unnecessary `list` comprehension (rewrite as a `dict` comprehension)
|
8 | f'{dict([(s,s) for s in "ab"])}'
9 | f"{dict([(s,s) for s in 'ab'])}"
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ C404
10 | f"{dict([(s, s) for s in 'ab'])}"
11 | f"{dict([(s,f(s)) for s in 'ab'])}"
|
= help: Rewrite as a `dict` comprehension
Suggested fix
5 5 | return x
6 6 |
7 7 | f'{dict([(s,s) for s in "ab"])}'
8 |-f"{dict([(s,s) for s in 'ab'])}"
8 |+f"{ {s: s for s in 'ab'} }"
9 9 | f"{dict([(s, s) for s in 'ab'])}"
10 10 | f"{dict([(s,f(s)) for s in 'ab'])}"
11 11 |
C404.py:9:4: C404 [*] Unnecessary `list` comprehension (rewrite as a `dict` comprehension)
|
9 | f'{dict([(s,s) for s in "ab"])}'
10 | f"{dict([(s,s) for s in 'ab'])}"
11 | f"{dict([(s, s) for s in 'ab'])}"
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C404
12 | f"{dict([(s,f(s)) for s in 'ab'])}"
|
= help: Rewrite as a `dict` comprehension
Suggested fix
6 6 |
7 7 | f'{dict([(s,s) for s in "ab"])}'
8 8 | f"{dict([(s,s) for s in 'ab'])}"
9 |-f"{dict([(s, s) for s in 'ab'])}"
9 |+f"{ {s: s for s in 'ab'} }"
10 10 | f"{dict([(s,f(s)) for s in 'ab'])}"
11 11 |
12 12 | f'{dict([(s,s) for s in "ab"]) | dict([(s,s) for s in "ab"])}'
C404.py:10:4: C404 [*] Unnecessary `list` comprehension (rewrite as a `dict` comprehension)
|
10 | f"{dict([(s,s) for s in 'ab'])}"
11 | f"{dict([(s, s) for s in 'ab'])}"
12 | f"{dict([(s,f(s)) for s in 'ab'])}"
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C404
13 |
14 | f'{dict([(s,s) for s in "ab"]) | dict([(s,s) for s in "ab"])}'
|
= help: Rewrite as a `dict` comprehension
Suggested fix
7 7 | f'{dict([(s,s) for s in "ab"])}'
8 8 | f"{dict([(s,s) for s in 'ab'])}"
9 9 | f"{dict([(s, s) for s in 'ab'])}"
10 |-f"{dict([(s,f(s)) for s in 'ab'])}"
10 |+f"{ {s: f(s) for s in 'ab'} }"
11 11 |
12 12 | f'{dict([(s,s) for s in "ab"]) | dict([(s,s) for s in "ab"])}'
13 13 | f'{ dict([(s,s) for s in "ab"]) | dict([(s,s) for s in "ab"]) }'
C404.py:12:4: C404 [*] Unnecessary `list` comprehension (rewrite as a `dict` comprehension)
|
12 | f"{dict([(s,f(s)) for s in 'ab'])}"
13 |
14 | f'{dict([(s,s) for s in "ab"]) | dict([(s,s) for s in "ab"])}'
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ C404
15 | f'{ dict([(s,s) for s in "ab"]) | dict([(s,s) for s in "ab"]) }'
|
= help: Rewrite as a `dict` comprehension
Suggested fix
9 9 | f"{dict([(s, s) for s in 'ab'])}"
10 10 | f"{dict([(s,f(s)) for s in 'ab'])}"
11 11 |
12 |-f'{dict([(s,s) for s in "ab"]) | dict([(s,s) for s in "ab"])}'
12 |+f'{ {s: s for s in "ab"} | dict([(s,s) for s in "ab"])}'
13 13 | f'{ dict([(s,s) for s in "ab"]) | dict([(s,s) for s in "ab"]) }'
C404.py:12:34: C404 [*] Unnecessary `list` comprehension (rewrite as a `dict` comprehension)
|
12 | f"{dict([(s,f(s)) for s in 'ab'])}"
13 |
14 | f'{dict([(s,s) for s in "ab"]) | dict([(s,s) for s in "ab"])}'
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ C404
15 | f'{ dict([(s,s) for s in "ab"]) | dict([(s,s) for s in "ab"]) }'
|
= help: Rewrite as a `dict` comprehension
Suggested fix
9 9 | f"{dict([(s, s) for s in 'ab'])}"
10 10 | f"{dict([(s,f(s)) for s in 'ab'])}"
11 11 |
12 |-f'{dict([(s,s) for s in "ab"]) | dict([(s,s) for s in "ab"])}'
12 |+f'{dict([(s,s) for s in "ab"]) | {s: s for s in "ab"} }'
13 13 | f'{ dict([(s,s) for s in "ab"]) | dict([(s,s) for s in "ab"]) }'
C404.py:13:5: C404 [*] Unnecessary `list` comprehension (rewrite as a `dict` comprehension)
|
13 | f'{dict([(s,s) for s in "ab"]) | dict([(s,s) for s in "ab"])}'
14 | f'{ dict([(s,s) for s in "ab"]) | dict([(s,s) for s in "ab"]) }'
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ C404
|
= help: Rewrite as a `dict` comprehension
Suggested fix
10 10 | f"{dict([(s,f(s)) for s in 'ab'])}"
11 11 |
12 12 | f'{dict([(s,s) for s in "ab"]) | dict([(s,s) for s in "ab"])}'
13 |-f'{ dict([(s,s) for s in "ab"]) | dict([(s,s) for s in "ab"]) }'
13 |+f'{ {s: s for s in "ab"} | dict([(s,s) for s in "ab"]) }'
C404.py:13:35: C404 [*] Unnecessary `list` comprehension (rewrite as a `dict` comprehension)
|
13 | f'{dict([(s,s) for s in "ab"]) | dict([(s,s) for s in "ab"])}'
14 | f'{ dict([(s,s) for s in "ab"]) | dict([(s,s) for s in "ab"]) }'
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ C404
|
= help: Rewrite as a `dict` comprehension
Suggested fix
10 10 | f"{dict([(s,f(s)) for s in 'ab'])}"
11 11 |
12 12 | f'{dict([(s,s) for s in "ab"]) | dict([(s,s) for s in "ab"])}'
13 |-f'{ dict([(s,s) for s in "ab"]) | dict([(s,s) for s in "ab"]) }'
13 |+f'{ dict([(s,s) for s in "ab"]) | {s: s for s in "ab"} }'

View file

@ -183,6 +183,8 @@ C405.py:16:1: C405 [*] Unnecessary `list` literal (rewrite as a `set` literal)
19 | | [1,] 19 | | [1,]
20 | | ) 20 | | )
| |_^ C405 | |_^ C405
21 | f"{set([1,2,3])}"
22 | f"{set(['a', 'b'])}"
| |
= help: Rewrite as a `set` literal = help: Rewrite as a `set` literal
@ -194,5 +196,218 @@ C405.py:16:1: C405 [*] Unnecessary `list` literal (rewrite as a `set` literal)
17 |- [1,] 17 |- [1,]
18 |-) 18 |-)
16 |+{1,} 16 |+{1,}
19 17 | f"{set([1,2,3])}"
20 18 | f"{set(['a', 'b'])}"
21 19 | f'{set(["a", "b"])}'
C405.py:19:4: C405 [*] Unnecessary `list` literal (rewrite as a `set` literal)
|
19 | [1,]
20 | )
21 | f"{set([1,2,3])}"
| ^^^^^^^^^^^^ C405
22 | f"{set(['a', 'b'])}"
23 | f'{set(["a", "b"])}'
|
= help: Rewrite as a `set` literal
Suggested fix
16 16 | set(
17 17 | [1,]
18 18 | )
19 |-f"{set([1,2,3])}"
19 |+f"{ {1,2,3} }"
20 20 | f"{set(['a', 'b'])}"
21 21 | f'{set(["a", "b"])}'
22 22 |
C405.py:20:4: C405 [*] Unnecessary `list` literal (rewrite as a `set` literal)
|
20 | )
21 | f"{set([1,2,3])}"
22 | f"{set(['a', 'b'])}"
| ^^^^^^^^^^^^^^^ C405
23 | f'{set(["a", "b"])}'
|
= help: Rewrite as a `set` literal
Suggested fix
17 17 | [1,]
18 18 | )
19 19 | f"{set([1,2,3])}"
20 |-f"{set(['a', 'b'])}"
20 |+f"{ {'a', 'b'} }"
21 21 | f'{set(["a", "b"])}'
22 22 |
23 23 | f"{set(['a', 'b']) - set(['a'])}"
C405.py:21:4: C405 [*] Unnecessary `list` literal (rewrite as a `set` literal)
|
21 | f"{set([1,2,3])}"
22 | f"{set(['a', 'b'])}"
23 | f'{set(["a", "b"])}'
| ^^^^^^^^^^^^^^^ C405
24 |
25 | f"{set(['a', 'b']) - set(['a'])}"
|
= help: Rewrite as a `set` literal
Suggested fix
18 18 | )
19 19 | f"{set([1,2,3])}"
20 20 | f"{set(['a', 'b'])}"
21 |-f'{set(["a", "b"])}'
21 |+f'{ {"a", "b"} }'
22 22 |
23 23 | f"{set(['a', 'b']) - set(['a'])}"
24 24 | f"{ set(['a', 'b']) - set(['a']) }"
C405.py:23:4: C405 [*] Unnecessary `list` literal (rewrite as a `set` literal)
|
23 | f'{set(["a", "b"])}'
24 |
25 | f"{set(['a', 'b']) - set(['a'])}"
| ^^^^^^^^^^^^^^^ C405
26 | f"{ set(['a', 'b']) - set(['a']) }"
27 | f"a {set(['a', 'b']) - set(['a'])} b"
|
= help: Rewrite as a `set` literal
Suggested fix
20 20 | f"{set(['a', 'b'])}"
21 21 | f'{set(["a", "b"])}'
22 22 |
23 |-f"{set(['a', 'b']) - set(['a'])}"
23 |+f"{ {'a', 'b'} - set(['a'])}"
24 24 | f"{ set(['a', 'b']) - set(['a']) }"
25 25 | f"a {set(['a', 'b']) - set(['a'])} b"
26 26 | f"a { set(['a', 'b']) - set(['a']) } b"
C405.py:23:22: C405 [*] Unnecessary `list` literal (rewrite as a `set` literal)
|
23 | f'{set(["a", "b"])}'
24 |
25 | f"{set(['a', 'b']) - set(['a'])}"
| ^^^^^^^^^^ C405
26 | f"{ set(['a', 'b']) - set(['a']) }"
27 | f"a {set(['a', 'b']) - set(['a'])} b"
|
= help: Rewrite as a `set` literal
Suggested fix
20 20 | f"{set(['a', 'b'])}"
21 21 | f'{set(["a", "b"])}'
22 22 |
23 |-f"{set(['a', 'b']) - set(['a'])}"
23 |+f"{set(['a', 'b']) - {'a'} }"
24 24 | f"{ set(['a', 'b']) - set(['a']) }"
25 25 | f"a {set(['a', 'b']) - set(['a'])} b"
26 26 | f"a { set(['a', 'b']) - set(['a']) } b"
C405.py:24:5: C405 [*] Unnecessary `list` literal (rewrite as a `set` literal)
|
24 | f"{set(['a', 'b']) - set(['a'])}"
25 | f"{ set(['a', 'b']) - set(['a']) }"
| ^^^^^^^^^^^^^^^ C405
26 | f"a {set(['a', 'b']) - set(['a'])} b"
27 | f"a { set(['a', 'b']) - set(['a']) } b"
|
= help: Rewrite as a `set` literal
Suggested fix
21 21 | f'{set(["a", "b"])}'
22 22 |
23 23 | f"{set(['a', 'b']) - set(['a'])}"
24 |-f"{ set(['a', 'b']) - set(['a']) }"
24 |+f"{ {'a', 'b'} - set(['a']) }"
25 25 | f"a {set(['a', 'b']) - set(['a'])} b"
26 26 | f"a { set(['a', 'b']) - set(['a']) } b"
C405.py:24:23: C405 [*] Unnecessary `list` literal (rewrite as a `set` literal)
|
24 | f"{set(['a', 'b']) - set(['a'])}"
25 | f"{ set(['a', 'b']) - set(['a']) }"
| ^^^^^^^^^^ C405
26 | f"a {set(['a', 'b']) - set(['a'])} b"
27 | f"a { set(['a', 'b']) - set(['a']) } b"
|
= help: Rewrite as a `set` literal
Suggested fix
21 21 | f'{set(["a", "b"])}'
22 22 |
23 23 | f"{set(['a', 'b']) - set(['a'])}"
24 |-f"{ set(['a', 'b']) - set(['a']) }"
24 |+f"{ set(['a', 'b']) - {'a'} }"
25 25 | f"a {set(['a', 'b']) - set(['a'])} b"
26 26 | f"a { set(['a', 'b']) - set(['a']) } b"
C405.py:25:6: C405 [*] Unnecessary `list` literal (rewrite as a `set` literal)
|
25 | f"{set(['a', 'b']) - set(['a'])}"
26 | f"{ set(['a', 'b']) - set(['a']) }"
27 | f"a {set(['a', 'b']) - set(['a'])} b"
| ^^^^^^^^^^^^^^^ C405
28 | f"a { set(['a', 'b']) - set(['a']) } b"
|
= help: Rewrite as a `set` literal
Suggested fix
22 22 |
23 23 | f"{set(['a', 'b']) - set(['a'])}"
24 24 | f"{ set(['a', 'b']) - set(['a']) }"
25 |-f"a {set(['a', 'b']) - set(['a'])} b"
25 |+f"a { {'a', 'b'} - set(['a'])} b"
26 26 | f"a { set(['a', 'b']) - set(['a']) } b"
C405.py:25:24: C405 [*] Unnecessary `list` literal (rewrite as a `set` literal)
|
25 | f"{set(['a', 'b']) - set(['a'])}"
26 | f"{ set(['a', 'b']) - set(['a']) }"
27 | f"a {set(['a', 'b']) - set(['a'])} b"
| ^^^^^^^^^^ C405
28 | f"a { set(['a', 'b']) - set(['a']) } b"
|
= help: Rewrite as a `set` literal
Suggested fix
22 22 |
23 23 | f"{set(['a', 'b']) - set(['a'])}"
24 24 | f"{ set(['a', 'b']) - set(['a']) }"
25 |-f"a {set(['a', 'b']) - set(['a'])} b"
25 |+f"a {set(['a', 'b']) - {'a'} } b"
26 26 | f"a { set(['a', 'b']) - set(['a']) } b"
C405.py:26:7: C405 [*] Unnecessary `list` literal (rewrite as a `set` literal)
|
26 | f"{ set(['a', 'b']) - set(['a']) }"
27 | f"a {set(['a', 'b']) - set(['a'])} b"
28 | f"a { set(['a', 'b']) - set(['a']) } b"
| ^^^^^^^^^^^^^^^ C405
|
= help: Rewrite as a `set` literal
Suggested fix
23 23 | f"{set(['a', 'b']) - set(['a'])}"
24 24 | f"{ set(['a', 'b']) - set(['a']) }"
25 25 | f"a {set(['a', 'b']) - set(['a'])} b"
26 |-f"a { set(['a', 'b']) - set(['a']) } b"
26 |+f"a { {'a', 'b'} - set(['a']) } b"
C405.py:26:25: C405 [*] Unnecessary `list` literal (rewrite as a `set` literal)
|
26 | f"{ set(['a', 'b']) - set(['a']) }"
27 | f"a {set(['a', 'b']) - set(['a'])} b"
28 | f"a { set(['a', 'b']) - set(['a']) } b"
| ^^^^^^^^^^ C405
|
= help: Rewrite as a `set` literal
Suggested fix
23 23 | f"{set(['a', 'b']) - set(['a'])}"
24 24 | f"{ set(['a', 'b']) - set(['a']) }"
25 25 | f"a {set(['a', 'b']) - set(['a'])} b"
26 |-f"a { set(['a', 'b']) - set(['a']) } b"
26 |+f"a { set(['a', 'b']) - {'a'} } b"

View file

@ -75,4 +75,234 @@ C408.py:4:6: C408 [*] Unnecessary `dict` call (rewrite as a literal)
6 6 | 6 6 |
7 7 | 7 7 |
C408.py:14:4: C408 [*] Unnecessary `dict` call (rewrite as a literal)
|
14 | a = list()
15 |
16 | f"{dict(x='y')}"
| ^^^^^^^^^^^ C408
17 | f'{dict(x="y")}'
18 | f"{dict()}"
|
= help: Rewrite as a literal
Suggested fix
11 11 |
12 12 | a = list()
13 13 |
14 |-f"{dict(x='y')}"
14 |+f"{ {'x': 'y'} }"
15 15 | f'{dict(x="y")}'
16 16 | f"{dict()}"
17 17 | f"a {dict()} b"
C408.py:15:4: C408 [*] Unnecessary `dict` call (rewrite as a literal)
|
15 | f"{dict(x='y')}"
16 | f'{dict(x="y")}'
| ^^^^^^^^^^^ C408
17 | f"{dict()}"
18 | f"a {dict()} b"
|
= help: Rewrite as a literal
Suggested fix
12 12 | a = list()
13 13 |
14 14 | f"{dict(x='y')}"
15 |-f'{dict(x="y")}'
15 |+f'{ {"x": "y"} }'
16 16 | f"{dict()}"
17 17 | f"a {dict()} b"
18 18 |
C408.py:16:4: C408 [*] Unnecessary `dict` call (rewrite as a literal)
|
16 | f"{dict(x='y')}"
17 | f'{dict(x="y")}'
18 | f"{dict()}"
| ^^^^^^ C408
19 | f"a {dict()} b"
|
= help: Rewrite as a literal
Suggested fix
13 13 |
14 14 | f"{dict(x='y')}"
15 15 | f'{dict(x="y")}'
16 |-f"{dict()}"
16 |+f"{ {} }"
17 17 | f"a {dict()} b"
18 18 |
19 19 | f"{dict(x='y') | dict(y='z')}"
C408.py:17:6: C408 [*] Unnecessary `dict` call (rewrite as a literal)
|
17 | f'{dict(x="y")}'
18 | f"{dict()}"
19 | f"a {dict()} b"
| ^^^^^^ C408
20 |
21 | f"{dict(x='y') | dict(y='z')}"
|
= help: Rewrite as a literal
Suggested fix
14 14 | f"{dict(x='y')}"
15 15 | f'{dict(x="y")}'
16 16 | f"{dict()}"
17 |-f"a {dict()} b"
17 |+f"a { {} } b"
18 18 |
19 19 | f"{dict(x='y') | dict(y='z')}"
20 20 | f"{ dict(x='y') | dict(y='z') }"
C408.py:19:4: C408 [*] Unnecessary `dict` call (rewrite as a literal)
|
19 | f"a {dict()} b"
20 |
21 | f"{dict(x='y') | dict(y='z')}"
| ^^^^^^^^^^^ C408
22 | f"{ dict(x='y') | dict(y='z') }"
23 | f"a {dict(x='y') | dict(y='z')} b"
|
= help: Rewrite as a literal
Suggested fix
16 16 | f"{dict()}"
17 17 | f"a {dict()} b"
18 18 |
19 |-f"{dict(x='y') | dict(y='z')}"
19 |+f"{ {'x': 'y'} | dict(y='z')}"
20 20 | f"{ dict(x='y') | dict(y='z') }"
21 21 | f"a {dict(x='y') | dict(y='z')} b"
22 22 | f"a { dict(x='y') | dict(y='z') } b"
C408.py:19:18: C408 [*] Unnecessary `dict` call (rewrite as a literal)
|
19 | f"a {dict()} b"
20 |
21 | f"{dict(x='y') | dict(y='z')}"
| ^^^^^^^^^^^ C408
22 | f"{ dict(x='y') | dict(y='z') }"
23 | f"a {dict(x='y') | dict(y='z')} b"
|
= help: Rewrite as a literal
Suggested fix
16 16 | f"{dict()}"
17 17 | f"a {dict()} b"
18 18 |
19 |-f"{dict(x='y') | dict(y='z')}"
19 |+f"{dict(x='y') | {'y': 'z'} }"
20 20 | f"{ dict(x='y') | dict(y='z') }"
21 21 | f"a {dict(x='y') | dict(y='z')} b"
22 22 | f"a { dict(x='y') | dict(y='z') } b"
C408.py:20:5: C408 [*] Unnecessary `dict` call (rewrite as a literal)
|
20 | f"{dict(x='y') | dict(y='z')}"
21 | f"{ dict(x='y') | dict(y='z') }"
| ^^^^^^^^^^^ C408
22 | f"a {dict(x='y') | dict(y='z')} b"
23 | f"a { dict(x='y') | dict(y='z') } b"
|
= help: Rewrite as a literal
Suggested fix
17 17 | f"a {dict()} b"
18 18 |
19 19 | f"{dict(x='y') | dict(y='z')}"
20 |-f"{ dict(x='y') | dict(y='z') }"
20 |+f"{ {'x': 'y'} | dict(y='z') }"
21 21 | f"a {dict(x='y') | dict(y='z')} b"
22 22 | f"a { dict(x='y') | dict(y='z') } b"
C408.py:20:19: C408 [*] Unnecessary `dict` call (rewrite as a literal)
|
20 | f"{dict(x='y') | dict(y='z')}"
21 | f"{ dict(x='y') | dict(y='z') }"
| ^^^^^^^^^^^ C408
22 | f"a {dict(x='y') | dict(y='z')} b"
23 | f"a { dict(x='y') | dict(y='z') } b"
|
= help: Rewrite as a literal
Suggested fix
17 17 | f"a {dict()} b"
18 18 |
19 19 | f"{dict(x='y') | dict(y='z')}"
20 |-f"{ dict(x='y') | dict(y='z') }"
20 |+f"{ dict(x='y') | {'y': 'z'} }"
21 21 | f"a {dict(x='y') | dict(y='z')} b"
22 22 | f"a { dict(x='y') | dict(y='z') } b"
C408.py:21:6: C408 [*] Unnecessary `dict` call (rewrite as a literal)
|
21 | f"{dict(x='y') | dict(y='z')}"
22 | f"{ dict(x='y') | dict(y='z') }"
23 | f"a {dict(x='y') | dict(y='z')} b"
| ^^^^^^^^^^^ C408
24 | f"a { dict(x='y') | dict(y='z') } b"
|
= help: Rewrite as a literal
Suggested fix
18 18 |
19 19 | f"{dict(x='y') | dict(y='z')}"
20 20 | f"{ dict(x='y') | dict(y='z') }"
21 |-f"a {dict(x='y') | dict(y='z')} b"
21 |+f"a { {'x': 'y'} | dict(y='z')} b"
22 22 | f"a { dict(x='y') | dict(y='z') } b"
C408.py:21:20: C408 [*] Unnecessary `dict` call (rewrite as a literal)
|
21 | f"{dict(x='y') | dict(y='z')}"
22 | f"{ dict(x='y') | dict(y='z') }"
23 | f"a {dict(x='y') | dict(y='z')} b"
| ^^^^^^^^^^^ C408
24 | f"a { dict(x='y') | dict(y='z') } b"
|
= help: Rewrite as a literal
Suggested fix
18 18 |
19 19 | f"{dict(x='y') | dict(y='z')}"
20 20 | f"{ dict(x='y') | dict(y='z') }"
21 |-f"a {dict(x='y') | dict(y='z')} b"
21 |+f"a {dict(x='y') | {'y': 'z'} } b"
22 22 | f"a { dict(x='y') | dict(y='z') } b"
C408.py:22:7: C408 [*] Unnecessary `dict` call (rewrite as a literal)
|
22 | f"{ dict(x='y') | dict(y='z') }"
23 | f"a {dict(x='y') | dict(y='z')} b"
24 | f"a { dict(x='y') | dict(y='z') } b"
| ^^^^^^^^^^^ C408
|
= help: Rewrite as a literal
Suggested fix
19 19 | f"{dict(x='y') | dict(y='z')}"
20 20 | f"{ dict(x='y') | dict(y='z') }"
21 21 | f"a {dict(x='y') | dict(y='z')} b"
22 |-f"a { dict(x='y') | dict(y='z') } b"
22 |+f"a { {'x': 'y'} | dict(y='z') } b"
C408.py:22:21: C408 [*] Unnecessary `dict` call (rewrite as a literal)
|
22 | f"{ dict(x='y') | dict(y='z') }"
23 | f"a {dict(x='y') | dict(y='z')} b"
24 | f"a { dict(x='y') | dict(y='z') } b"
| ^^^^^^^^^^^ C408
|
= help: Rewrite as a literal
Suggested fix
19 19 | f"{dict(x='y') | dict(y='z')}"
20 20 | f"{ dict(x='y') | dict(y='z') }"
21 21 | f"a {dict(x='y') | dict(y='z')} b"
22 |-f"a { dict(x='y') | dict(y='z') } b"
22 |+f"a { dict(x='y') | {'y': 'z'} } b"

View file

@ -55,4 +55,45 @@ C408.py:3:6: C408 [*] Unnecessary `dict` call (rewrite as a literal)
5 5 | d3 = dict(**d2) 5 5 | d3 = dict(**d2)
6 6 | 6 6 |
C408.py:16:4: C408 [*] Unnecessary `dict` call (rewrite as a literal)
|
16 | f"{dict(x='y')}"
17 | f'{dict(x="y")}'
18 | f"{dict()}"
| ^^^^^^ C408
19 | f"a {dict()} b"
|
= help: Rewrite as a literal
Suggested fix
13 13 |
14 14 | f"{dict(x='y')}"
15 15 | f'{dict(x="y")}'
16 |-f"{dict()}"
16 |+f"{ {} }"
17 17 | f"a {dict()} b"
18 18 |
19 19 | f"{dict(x='y') | dict(y='z')}"
C408.py:17:6: C408 [*] Unnecessary `dict` call (rewrite as a literal)
|
17 | f'{dict(x="y")}'
18 | f"{dict()}"
19 | f"a {dict()} b"
| ^^^^^^ C408
20 |
21 | f"{dict(x='y') | dict(y='z')}"
|
= help: Rewrite as a literal
Suggested fix
14 14 | f"{dict(x='y')}"
15 15 | f'{dict(x="y")}'
16 16 | f"{dict()}"
17 |-f"a {dict()} b"
17 |+f"a { {} } b"
18 18 |
19 19 | f"{dict(x='y') | dict(y='z')}"
20 20 | f"{ dict(x='y') | dict(y='z') }"

View file

@ -783,6 +783,7 @@ impl<'a> SemanticModel<'a> {
/// Return `true` if the context is in an f-string. /// Return `true` if the context is in an f-string.
pub const fn in_f_string(&self) -> bool { pub const fn in_f_string(&self) -> bool {
self.flags.contains(SemanticModelFlags::F_STRING) self.flags.contains(SemanticModelFlags::F_STRING)
|| self.flags.contains(SemanticModelFlags::NESTED_F_STRING)
} }
/// Return `true` if the context is in a nested f-string. /// Return `true` if the context is in a nested f-string.

0
fuzz/init-fuzzer.sh Executable file → Normal file
View file

0
fuzz/reinit-fuzzer.sh Executable file → Normal file
View file