mirror of https://github.com/astral-sh/ruff
Ignore list-copy recommendations for async `for` loops (#11250)
## Summary Removes these from `PERF402`, but adds them to `PERF401`, with a custom message to use an `async` comprehension. Closes https://github.com/astral-sh/ruff/issues/10787.
This commit is contained in:
parent
64700d296f
commit
3a7c01b365
|
|
@ -72,3 +72,18 @@ def f():
|
||||||
result = Foo()
|
result = Foo()
|
||||||
for i in items:
|
for i in items:
|
||||||
result.append(i) # Ok
|
result.append(i) # Ok
|
||||||
|
|
||||||
|
|
||||||
|
def f():
|
||||||
|
items = [1, 2, 3, 4]
|
||||||
|
result = []
|
||||||
|
async for i in items:
|
||||||
|
if i % 2:
|
||||||
|
result.append(i) # PERF401
|
||||||
|
|
||||||
|
|
||||||
|
def f():
|
||||||
|
items = [1, 2, 3, 4]
|
||||||
|
result = []
|
||||||
|
async for i in items:
|
||||||
|
result.append(i) # PERF401
|
||||||
|
|
|
||||||
|
|
@ -43,3 +43,10 @@ def f():
|
||||||
|
|
||||||
for path in ("foo", "bar"):
|
for path in ("foo", "bar"):
|
||||||
sys.path.append(path) # OK
|
sys.path.append(path) # OK
|
||||||
|
|
||||||
|
|
||||||
|
def f():
|
||||||
|
items = [1, 2, 3, 4]
|
||||||
|
result = []
|
||||||
|
async for i in items:
|
||||||
|
result.append(i) # PERF402
|
||||||
|
|
|
||||||
|
|
@ -1323,10 +1323,10 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) {
|
||||||
pylint::rules::dict_iter_missing_items(checker, target, iter);
|
pylint::rules::dict_iter_missing_items(checker, target, iter);
|
||||||
}
|
}
|
||||||
if checker.enabled(Rule::ManualListComprehension) {
|
if checker.enabled(Rule::ManualListComprehension) {
|
||||||
perflint::rules::manual_list_comprehension(checker, target, body);
|
perflint::rules::manual_list_comprehension(checker, for_stmt);
|
||||||
}
|
}
|
||||||
if checker.enabled(Rule::ManualListCopy) {
|
if checker.enabled(Rule::ManualListCopy) {
|
||||||
perflint::rules::manual_list_copy(checker, target, body);
|
perflint::rules::manual_list_copy(checker, for_stmt);
|
||||||
}
|
}
|
||||||
if checker.enabled(Rule::ManualDictComprehension) {
|
if checker.enabled(Rule::ManualDictComprehension) {
|
||||||
perflint::rules::manual_dict_comprehension(checker, target, body);
|
perflint::rules::manual_dict_comprehension(checker, target, body);
|
||||||
|
|
|
||||||
|
|
@ -44,22 +44,28 @@ use crate::checkers::ast::Checker;
|
||||||
/// filtered.extend(x for x in original if x % 2)
|
/// filtered.extend(x for x in original if x % 2)
|
||||||
/// ```
|
/// ```
|
||||||
#[violation]
|
#[violation]
|
||||||
pub struct ManualListComprehension;
|
pub struct ManualListComprehension {
|
||||||
|
is_async: bool,
|
||||||
|
}
|
||||||
|
|
||||||
impl Violation for ManualListComprehension {
|
impl Violation for ManualListComprehension {
|
||||||
#[derive_message_formats]
|
#[derive_message_formats]
|
||||||
fn message(&self) -> String {
|
fn message(&self) -> String {
|
||||||
format!("Use a list comprehension to create a transformed list")
|
let ManualListComprehension { is_async } = self;
|
||||||
|
match is_async {
|
||||||
|
false => format!("Use a list comprehension to create a transformed list"),
|
||||||
|
true => format!("Use an async list comprehension to create a transformed list"),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// PERF401
|
/// PERF401
|
||||||
pub(crate) fn manual_list_comprehension(checker: &mut Checker, target: &Expr, body: &[Stmt]) {
|
pub(crate) fn manual_list_comprehension(checker: &mut Checker, for_stmt: &ast::StmtFor) {
|
||||||
let Expr::Name(ast::ExprName { id, .. }) = target else {
|
let Expr::Name(ast::ExprName { id, .. }) = &*for_stmt.target else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let (stmt, if_test) = match body {
|
let (stmt, if_test) = match &*for_stmt.body {
|
||||||
// ```python
|
// ```python
|
||||||
// for x in y:
|
// for x in y:
|
||||||
// if z:
|
// if z:
|
||||||
|
|
@ -121,10 +127,13 @@ pub(crate) fn manual_list_comprehension(checker: &mut Checker, target: &Expr, bo
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignore direct list copies (e.g., `for x in y: filtered.append(x)`).
|
// Ignore direct list copies (e.g., `for x in y: filtered.append(x)`), unless it's async, which
|
||||||
if if_test.is_none() {
|
// `manual-list-copy` doesn't cover.
|
||||||
if arg.as_name_expr().is_some_and(|arg| arg.id == *id) {
|
if !for_stmt.is_async {
|
||||||
return;
|
if if_test.is_none() {
|
||||||
|
if arg.as_name_expr().is_some_and(|arg| arg.id == *id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -179,7 +188,10 @@ pub(crate) fn manual_list_comprehension(checker: &mut Checker, target: &Expr, bo
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
checker
|
checker.diagnostics.push(Diagnostic::new(
|
||||||
.diagnostics
|
ManualListComprehension {
|
||||||
.push(Diagnostic::new(ManualListComprehension, *range));
|
is_async: for_stmt.is_async,
|
||||||
|
},
|
||||||
|
*range,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,12 +45,16 @@ impl Violation for ManualListCopy {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// PERF402
|
/// PERF402
|
||||||
pub(crate) fn manual_list_copy(checker: &mut Checker, target: &Expr, body: &[Stmt]) {
|
pub(crate) fn manual_list_copy(checker: &mut Checker, for_stmt: &ast::StmtFor) {
|
||||||
let Expr::Name(ast::ExprName { id, .. }) = target else {
|
if for_stmt.is_async {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let Expr::Name(ast::ExprName { id, .. }) = &*for_stmt.target else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let [stmt] = body else {
|
let [stmt] = &*for_stmt.body else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,4 +17,18 @@ PERF401.py:13:9: PERF401 Use a list comprehension to create a transformed list
|
||||||
| ^^^^^^^^^^^^^^^^^^^^ PERF401
|
| ^^^^^^^^^^^^^^^^^^^^ PERF401
|
||||||
|
|
|
|
||||||
|
|
||||||
|
PERF401.py:82:13: PERF401 Use an async list comprehension to create a transformed list
|
||||||
|
|
|
||||||
|
80 | async for i in items:
|
||||||
|
81 | if i % 2:
|
||||||
|
82 | result.append(i) # PERF401
|
||||||
|
| ^^^^^^^^^^^^^^^^ PERF401
|
||||||
|
|
|
||||||
|
|
||||||
|
PERF401.py:89:9: PERF401 Use an async list comprehension to create a transformed list
|
||||||
|
|
|
||||||
|
87 | result = []
|
||||||
|
88 | async for i in items:
|
||||||
|
89 | result.append(i) # PERF401
|
||||||
|
| ^^^^^^^^^^^^^^^^ PERF401
|
||||||
|
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue