[flake8-comprehensions] bugfix for C413 autofix (#2804)

This commit is contained in:
Simon Brugman 2023-02-12 16:56:07 +01:00 committed by GitHub
parent f8ac6d7bf0
commit 2dccb7611a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 156 additions and 5 deletions

View file

@ -4,7 +4,9 @@ list(sorted(x))
reversed(sorted(x))
reversed(sorted(x, key=lambda e: e))
reversed(sorted(x, reverse=True))
reversed(sorted(x, key=lambda e: e, reverse=True))
reversed(sorted(x, reverse=True, key=lambda e: e))
reversed(sorted(x, reverse=False))
def reversed(*args, **kwargs):
return None

View file

@ -743,6 +743,7 @@ pub fn fix_unnecessary_call_around_sorted(
if outer_name.value == "list" {
body.value = Expression::Call(inner_call.clone());
} else {
// If the `reverse` argument is used
let args = if inner_call.args.iter().any(|arg| {
matches!(
arg.keyword,
@ -752,7 +753,46 @@ pub fn fix_unnecessary_call_around_sorted(
})
)
}) {
inner_call.args.clone()
// Negate the `reverse` argument
inner_call
.args
.clone()
.into_iter()
.map(|mut arg| {
if matches!(
arg.keyword,
Some(Name {
value: "reverse",
..
})
) {
if let Expression::Name(ref val) = arg.value {
if val.value == "True" {
// TODO: even better would be to drop the argument, as False is the default
arg.value = Expression::Name(Box::new(Name {
value: "False",
lpar: vec![],
rpar: vec![],
}));
arg
} else if val.value == "False" {
arg.value = Expression::Name(Box::new(Name {
value: "True",
lpar: vec![],
rpar: vec![],
}));
arg
} else {
arg
}
} else {
arg
}
} else {
arg
}
})
.collect_vec()
} else {
let mut args = inner_call.args.clone();
args.push(Arg {

View file

@ -10,6 +10,29 @@ use crate::rules::flake8_comprehensions::fixes;
use crate::violation::AlwaysAutofixableViolation;
define_violation!(
/// ## What it does
/// Checks for unnecessary `list` or `reversed` calls around `sorted`
/// calls.
///
/// ## Why is this bad?
/// It is unnecessary to use `list` around `sorted`, as the latter already
/// returns a list.
///
/// It is also unnecessary to use `reversed` around `sorted`, as the latter
/// has a `reverse` argument that can be used in lieu of an additional
/// `reversed` call.
///
/// In both cases, it's clearer to avoid the redundant call.
///
/// ## Examples
/// ```python
/// reversed(sorted(iterable))
/// ```
///
/// Use instead:
/// ```python
/// sorted(iterable, reverse=True)
/// ```
pub struct UnnecessaryCallAroundSorted {
pub func: String,
}

View file

@ -1,5 +1,5 @@
---
source: src/rules/flake8_comprehensions/mod.rs
source: crates/ruff/src/rules/flake8_comprehensions/mod.rs
expression: diagnostics
---
- kind:
@ -70,7 +70,7 @@ expression: diagnostics
column: 33
fix:
content:
- "sorted(x, reverse=True)"
- "sorted(x, reverse=False)"
location:
row: 6
column: 0
@ -78,4 +78,61 @@ expression: diagnostics
row: 6
column: 33
parent: ~
- kind:
UnnecessaryCallAroundSorted:
func: reversed
location:
row: 7
column: 0
end_location:
row: 7
column: 50
fix:
content:
- "sorted(x, key=lambda e: e, reverse=False)"
location:
row: 7
column: 0
end_location:
row: 7
column: 50
parent: ~
- kind:
UnnecessaryCallAroundSorted:
func: reversed
location:
row: 8
column: 0
end_location:
row: 8
column: 50
fix:
content:
- "sorted(x, reverse=False, key=lambda e: e)"
location:
row: 8
column: 0
end_location:
row: 8
column: 50
parent: ~
- kind:
UnnecessaryCallAroundSorted:
func: reversed
location:
row: 9
column: 0
end_location:
row: 9
column: 34
fix:
content:
- "sorted(x, reverse=True)"
location:
row: 9
column: 0
end_location:
row: 9
column: 34
parent: ~