mirror of https://github.com/astral-sh/ruff
FURB142: Parenthesize generator arg in fixer to preserve scoping
- Fixes #21098. - When rewriting set.add(...) calls inside for-loops into set.update(...), wrap an unparenthesized generator-expression argument in parentheses to avoid altering scope and causing NameError. - Adds targeted logic in for_loop_set_mutations to detect Expr::Generator with parenthesized == false and parenthesize its source text.
This commit is contained in:
parent
17c7b3cde1
commit
376ebd63e4
|
|
@ -111,13 +111,24 @@ pub(crate) fn for_loop_set_mutations(checker: &Checker, for_stmt: &StmtFor) {
|
||||||
parenthesize_loop_iter_if_necessary(for_stmt, checker, IterLocation::Call),
|
parenthesize_loop_iter_if_necessary(for_stmt, checker, IterLocation::Call),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
(for_target, arg) => format!(
|
(for_target, arg) => {
|
||||||
"{}.{batch_method_name}({} for {} in {})",
|
// Parenthesize an unparenthesized generator expression argument to preserve semantics,
|
||||||
set.id,
|
// e.g. `s.add(c for c in x)` -> `s.update((c for c in x) for x in ...)`.
|
||||||
locator.slice(arg),
|
let arg_text = match arg {
|
||||||
locator.slice(for_target),
|
Expr::Generator(generator) if !generator.parenthesized => {
|
||||||
parenthesize_loop_iter_if_necessary(for_stmt, checker, IterLocation::Comprehension),
|
format!("({})", locator.slice(arg))
|
||||||
),
|
}
|
||||||
|
_ => locator.slice(arg).to_string(),
|
||||||
|
};
|
||||||
|
|
||||||
|
format!(
|
||||||
|
"{}.{batch_method_name}({} for {} in {})",
|
||||||
|
set.id,
|
||||||
|
arg_text,
|
||||||
|
locator.slice(for_target),
|
||||||
|
parenthesize_loop_iter_if_necessary(for_stmt, checker, IterLocation::Comprehension),
|
||||||
|
)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let applicability = if checker.comment_ranges().intersects(for_stmt.range) {
|
let applicability = if checker.comment_ranges().intersects(for_stmt.range) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue