Ignore `reimplemented-builtin` if in `async` context (#5101)

## Summary

Checks if `checker` is in an `async` context. If yes, return early.

Fixes #5098.

## Test Plan

`cargo test`
This commit is contained in:
Tom Kuson 2023-06-14 23:00:30 +01:00 committed by GitHub
parent 848f184b8c
commit 08cd140ea6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 50 additions and 0 deletions

View File

@ -171,3 +171,17 @@ def f():
if x.isdigit():
return True
return False
async def f():
# OK
for x in iterable:
if await check(x):
return True
return False
async def f():
# SIM110
for x in iterable:
if check(x):
return True
return False

View File

@ -5,6 +5,7 @@ use rustpython_parser::ast::{
use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::helpers::any_over_expr;
use ruff_python_ast::source_code::Generator;
use crate::checkers::ast::Checker;
@ -224,6 +225,11 @@ fn return_stmt(id: &str, test: &Expr, target: &Expr, iter: &Expr, generator: Gen
generator.stmt(&node3.into())
}
/// Return `true` if the `Expr` contains an `await` expression.
fn contains_await(expr: &Expr) -> bool {
any_over_expr(expr, &|expr| matches!(expr, Expr::Await(_)))
}
/// SIM110, SIM111
pub(crate) fn convert_for_loop_to_any_all(
checker: &mut Checker,
@ -236,6 +242,13 @@ pub(crate) fn convert_for_loop_to_any_all(
if let Some(loop_info) = return_values_for_else(stmt)
.or_else(|| sibling.and_then(|sibling| return_values_for_siblings(stmt, sibling)))
{
// Check if loop_info.target, loop_info.iter, or loop_info.test contains `await`.
if contains_await(loop_info.target)
|| contains_await(loop_info.iter)
|| contains_await(loop_info.test)
{
return;
}
if loop_info.return_value && !loop_info.next_return_value {
if checker.enabled(Rule::ReimplementedBuiltin) {
let contents = return_stmt(

View File

@ -294,4 +294,27 @@ SIM110.py:162:5: SIM110 [*] Use `return any(x.isdigit() for x in "012ß9💣2
167 164 |
168 165 | def f():
SIM110.py:184:5: SIM110 [*] Use `return any(check(x) for x in iterable)` instead of `for` loop
|
182 | async def f():
183 | # SIM110
184 | for x in iterable:
| _____^
185 | | if check(x):
186 | | return True
187 | | return False
| |________________^ SIM110
|
= help: Replace with `return any(check(x) for x in iterable)`
Suggested fix
181 181 |
182 182 | async def f():
183 183 | # SIM110
184 |- for x in iterable:
185 |- if check(x):
186 |- return True
187 |- return False
184 |+ return any(check(x) for x in iterable)