mirror of https://github.com/astral-sh/ruff
Implement C414 (#406)
This commit is contained in:
parent
6ffe02ee05
commit
0072dfd81e
|
|
@ -215,7 +215,7 @@ ruff also implements some of the most popular Flake8 plugins natively, including
|
||||||
- [`flake8-builtins`](https://pypi.org/project/flake8-builtins/)
|
- [`flake8-builtins`](https://pypi.org/project/flake8-builtins/)
|
||||||
- [`flake8-super`](https://pypi.org/project/flake8-super/)
|
- [`flake8-super`](https://pypi.org/project/flake8-super/)
|
||||||
- [`flake8-print`](https://pypi.org/project/flake8-print/)
|
- [`flake8-print`](https://pypi.org/project/flake8-print/)
|
||||||
- [`flake8-comprehensions`](https://pypi.org/project/flake8-comprehensions/) (11/16)
|
- [`flake8-comprehensions`](https://pypi.org/project/flake8-comprehensions/) (12/16)
|
||||||
- [`flake8-bugbear`](https://pypi.org/project/flake8-bugbear/) (3/32)
|
- [`flake8-bugbear`](https://pypi.org/project/flake8-bugbear/) (3/32)
|
||||||
- [`flake8-docstrings`](https://pypi.org/project/flake8-docstrings/) (25/48)
|
- [`flake8-docstrings`](https://pypi.org/project/flake8-docstrings/) (25/48)
|
||||||
- [`pyupgrade`](https://pypi.org/project/pyupgrade/) (8/34)
|
- [`pyupgrade`](https://pypi.org/project/pyupgrade/) (8/34)
|
||||||
|
|
@ -293,6 +293,7 @@ The 🛠 emoji indicates that a rule is automatically fixable by the `--fix` com
|
||||||
| C408 | UnnecessaryCollectionCall | Unnecessary <dict/list/tuple> call - rewrite as a literal | | |
|
| C408 | UnnecessaryCollectionCall | Unnecessary <dict/list/tuple> call - rewrite as a literal | | |
|
||||||
| C409 | UnnecessaryLiteralWithinTupleCall | Unnecessary <list/tuple> literal passed to tuple() - remove the outer call to tuple() | | |
|
| C409 | UnnecessaryLiteralWithinTupleCall | Unnecessary <list/tuple> literal passed to tuple() - remove the outer call to tuple() | | |
|
||||||
| C410 | UnnecessaryLiteralWithinListCall | Unnecessary <list/tuple> literal passed to list() - rewrite as a list literal | | |
|
| C410 | UnnecessaryLiteralWithinListCall | Unnecessary <list/tuple> literal passed to list() - rewrite as a list literal | | |
|
||||||
|
| C414 | UnnecessaryDoubleCastOrProcess | Unnecessary <list/reversed/set/sorted/tuple> call within <list/set/sorted/tuple>(). | | |
|
||||||
| C415 | UnnecessarySubscriptReversal | Unnecessary subscript reversal of iterable within <reversed/set/sorted>() | | |
|
| C415 | UnnecessarySubscriptReversal | Unnecessary subscript reversal of iterable within <reversed/set/sorted>() | | |
|
||||||
| T201 | PrintFound | `print` found | | 🛠 |
|
| T201 | PrintFound | `print` found | | 🛠 |
|
||||||
| T203 | PPrintFound | `pprint` found | | 🛠 |
|
| T203 | PPrintFound | `pprint` found | | 🛠 |
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
x = [1, 2, 3]
|
||||||
|
list(list(x))
|
||||||
|
list(tuple(x))
|
||||||
|
tuple(list(x))
|
||||||
|
tuple(tuple(x))
|
||||||
|
set(set(x))
|
||||||
|
set(list(x))
|
||||||
|
set(tuple(x))
|
||||||
|
set(sorted(x))
|
||||||
|
set(reversed(x))
|
||||||
|
sorted(list(x))
|
||||||
|
sorted(tuple(x))
|
||||||
|
sorted(sorted(x))
|
||||||
|
sorted(reversed(x))
|
||||||
|
|
@ -1004,6 +1004,68 @@ pub fn unnecessary_literal_within_list_call(
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn unnecessary_double_cast_or_process(
|
||||||
|
expr: &Expr,
|
||||||
|
func: &Expr,
|
||||||
|
args: &[Expr],
|
||||||
|
) -> Option<Check> {
|
||||||
|
if let ExprKind::Name { id: outer, .. } = &func.node {
|
||||||
|
if outer == "list"
|
||||||
|
|| outer == "tuple"
|
||||||
|
|| outer == "set"
|
||||||
|
|| outer == "reversed"
|
||||||
|
|| outer == "sorted"
|
||||||
|
{
|
||||||
|
if let Some(arg) = args.first() {
|
||||||
|
if let ExprKind::Call { func, .. } = &arg.node {
|
||||||
|
if let ExprKind::Name { id: inner, .. } = &func.node {
|
||||||
|
// Ex) set(tuple(...))
|
||||||
|
if (outer == "set" || outer == "sorted")
|
||||||
|
&& (inner == "list"
|
||||||
|
|| inner == "tuple"
|
||||||
|
|| inner == "reversed"
|
||||||
|
|| inner == "sorted")
|
||||||
|
{
|
||||||
|
return Some(Check::new(
|
||||||
|
CheckKind::UnnecessaryDoubleCastOrProcess(
|
||||||
|
inner.to_string(),
|
||||||
|
outer.to_string(),
|
||||||
|
),
|
||||||
|
Range::from_located(expr),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ex) list(tuple(...))
|
||||||
|
if (outer == "list" || outer == "tuple")
|
||||||
|
&& (inner == "list" || inner == "tuple")
|
||||||
|
{
|
||||||
|
return Some(Check::new(
|
||||||
|
CheckKind::UnnecessaryDoubleCastOrProcess(
|
||||||
|
inner.to_string(),
|
||||||
|
outer.to_string(),
|
||||||
|
),
|
||||||
|
Range::from_located(expr),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ex) set(set(...))
|
||||||
|
if outer == "set" && inner == "set" {
|
||||||
|
return Some(Check::new(
|
||||||
|
CheckKind::UnnecessaryDoubleCastOrProcess(
|
||||||
|
inner.to_string(),
|
||||||
|
outer.to_string(),
|
||||||
|
),
|
||||||
|
Range::from_located(expr),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
pub fn unnecessary_subscript_reversal(expr: &Expr, func: &Expr, args: &[Expr]) -> Option<Check> {
|
pub fn unnecessary_subscript_reversal(expr: &Expr, func: &Expr, args: &[Expr]) -> Option<Check> {
|
||||||
if let Some(first_arg) = args.first() {
|
if let Some(first_arg) = args.first() {
|
||||||
if let ExprKind::Name { id, .. } = &func.node {
|
if let ExprKind::Name { id, .. } = &func.node {
|
||||||
|
|
|
||||||
|
|
@ -827,6 +827,15 @@ where
|
||||||
self.checks.push(check);
|
self.checks.push(check);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.settings.enabled.contains(&CheckCode::C414) {
|
||||||
|
if let Some(check) =
|
||||||
|
checkers::unnecessary_double_cast_or_process(expr, func, args)
|
||||||
|
{
|
||||||
|
self.checks.push(check);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if self.settings.enabled.contains(&CheckCode::C415) {
|
if self.settings.enabled.contains(&CheckCode::C415) {
|
||||||
if let Some(check) = checkers::unnecessary_subscript_reversal(expr, func, args)
|
if let Some(check) = checkers::unnecessary_subscript_reversal(expr, func, args)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -137,6 +137,7 @@ pub enum CheckCode {
|
||||||
C408,
|
C408,
|
||||||
C409,
|
C409,
|
||||||
C410,
|
C410,
|
||||||
|
C414,
|
||||||
C415,
|
C415,
|
||||||
// flake8-print
|
// flake8-print
|
||||||
T201,
|
T201,
|
||||||
|
|
@ -259,6 +260,7 @@ pub enum CheckKind {
|
||||||
UnnecessaryCollectionCall(String),
|
UnnecessaryCollectionCall(String),
|
||||||
UnnecessaryLiteralWithinTupleCall(String),
|
UnnecessaryLiteralWithinTupleCall(String),
|
||||||
UnnecessaryLiteralWithinListCall(String),
|
UnnecessaryLiteralWithinListCall(String),
|
||||||
|
UnnecessaryDoubleCastOrProcess(String, String),
|
||||||
UnnecessarySubscriptReversal(String),
|
UnnecessarySubscriptReversal(String),
|
||||||
// flake8-print
|
// flake8-print
|
||||||
PrintFound,
|
PrintFound,
|
||||||
|
|
@ -388,6 +390,10 @@ impl CheckCode {
|
||||||
CheckCode::C410 => {
|
CheckCode::C410 => {
|
||||||
CheckKind::UnnecessaryLiteralWithinListCall("<list/tuple>".to_string())
|
CheckKind::UnnecessaryLiteralWithinListCall("<list/tuple>".to_string())
|
||||||
}
|
}
|
||||||
|
CheckCode::C414 => CheckKind::UnnecessaryDoubleCastOrProcess(
|
||||||
|
"<list/reversed/set/sorted/tuple>".to_string(),
|
||||||
|
"<list/set/sorted/tuple>".to_string(),
|
||||||
|
),
|
||||||
CheckCode::C415 => {
|
CheckCode::C415 => {
|
||||||
CheckKind::UnnecessarySubscriptReversal("<reversed/set/sorted>".to_string())
|
CheckKind::UnnecessarySubscriptReversal("<reversed/set/sorted>".to_string())
|
||||||
}
|
}
|
||||||
|
|
@ -506,6 +512,7 @@ impl CheckKind {
|
||||||
CheckKind::UnnecessaryCollectionCall(_) => &CheckCode::C408,
|
CheckKind::UnnecessaryCollectionCall(_) => &CheckCode::C408,
|
||||||
CheckKind::UnnecessaryLiteralWithinTupleCall(..) => &CheckCode::C409,
|
CheckKind::UnnecessaryLiteralWithinTupleCall(..) => &CheckCode::C409,
|
||||||
CheckKind::UnnecessaryLiteralWithinListCall(..) => &CheckCode::C410,
|
CheckKind::UnnecessaryLiteralWithinListCall(..) => &CheckCode::C410,
|
||||||
|
CheckKind::UnnecessaryDoubleCastOrProcess(..) => &CheckCode::C414,
|
||||||
CheckKind::UnnecessarySubscriptReversal(_) => &CheckCode::C415,
|
CheckKind::UnnecessarySubscriptReversal(_) => &CheckCode::C415,
|
||||||
// flake8-print
|
// flake8-print
|
||||||
CheckKind::PrintFound => &CheckCode::T201,
|
CheckKind::PrintFound => &CheckCode::T201,
|
||||||
|
|
@ -757,6 +764,9 @@ impl CheckKind {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
CheckKind::UnnecessaryDoubleCastOrProcess(inner, outer) => {
|
||||||
|
format!("Unnecessary {inner} call within {outer}().")
|
||||||
|
}
|
||||||
CheckKind::UnnecessarySubscriptReversal(func) => {
|
CheckKind::UnnecessarySubscriptReversal(func) => {
|
||||||
format!("Unnecessary subscript reversal of iterable within {func}()")
|
format!("Unnecessary subscript reversal of iterable within {func}()")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -996,6 +996,18 @@ mod tests {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn c414() -> Result<()> {
|
||||||
|
let mut checks = check_path(
|
||||||
|
Path::new("./resources/test/fixtures/C414.py"),
|
||||||
|
&settings::Settings::for_rule(CheckCode::C414),
|
||||||
|
&fixer::Mode::Generate,
|
||||||
|
)?;
|
||||||
|
checks.sort_by_key(|check| check.location);
|
||||||
|
insta::assert_yaml_snapshot!(checks);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn c415() -> Result<()> {
|
fn c415() -> Result<()> {
|
||||||
let mut checks = check_path(
|
let mut checks = check_path(
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,148 @@
|
||||||
|
---
|
||||||
|
source: src/linter.rs
|
||||||
|
expression: checks
|
||||||
|
---
|
||||||
|
- kind:
|
||||||
|
UnnecessaryDoubleCastOrProcess:
|
||||||
|
- list
|
||||||
|
- list
|
||||||
|
location:
|
||||||
|
row: 2
|
||||||
|
column: 1
|
||||||
|
end_location:
|
||||||
|
row: 2
|
||||||
|
column: 14
|
||||||
|
fix: ~
|
||||||
|
- kind:
|
||||||
|
UnnecessaryDoubleCastOrProcess:
|
||||||
|
- tuple
|
||||||
|
- list
|
||||||
|
location:
|
||||||
|
row: 3
|
||||||
|
column: 1
|
||||||
|
end_location:
|
||||||
|
row: 3
|
||||||
|
column: 15
|
||||||
|
fix: ~
|
||||||
|
- kind:
|
||||||
|
UnnecessaryDoubleCastOrProcess:
|
||||||
|
- list
|
||||||
|
- tuple
|
||||||
|
location:
|
||||||
|
row: 4
|
||||||
|
column: 1
|
||||||
|
end_location:
|
||||||
|
row: 4
|
||||||
|
column: 15
|
||||||
|
fix: ~
|
||||||
|
- kind:
|
||||||
|
UnnecessaryDoubleCastOrProcess:
|
||||||
|
- tuple
|
||||||
|
- tuple
|
||||||
|
location:
|
||||||
|
row: 5
|
||||||
|
column: 1
|
||||||
|
end_location:
|
||||||
|
row: 5
|
||||||
|
column: 16
|
||||||
|
fix: ~
|
||||||
|
- kind:
|
||||||
|
UnnecessaryDoubleCastOrProcess:
|
||||||
|
- set
|
||||||
|
- set
|
||||||
|
location:
|
||||||
|
row: 6
|
||||||
|
column: 1
|
||||||
|
end_location:
|
||||||
|
row: 6
|
||||||
|
column: 12
|
||||||
|
fix: ~
|
||||||
|
- kind:
|
||||||
|
UnnecessaryDoubleCastOrProcess:
|
||||||
|
- list
|
||||||
|
- set
|
||||||
|
location:
|
||||||
|
row: 7
|
||||||
|
column: 1
|
||||||
|
end_location:
|
||||||
|
row: 7
|
||||||
|
column: 13
|
||||||
|
fix: ~
|
||||||
|
- kind:
|
||||||
|
UnnecessaryDoubleCastOrProcess:
|
||||||
|
- tuple
|
||||||
|
- set
|
||||||
|
location:
|
||||||
|
row: 8
|
||||||
|
column: 1
|
||||||
|
end_location:
|
||||||
|
row: 8
|
||||||
|
column: 14
|
||||||
|
fix: ~
|
||||||
|
- kind:
|
||||||
|
UnnecessaryDoubleCastOrProcess:
|
||||||
|
- sorted
|
||||||
|
- set
|
||||||
|
location:
|
||||||
|
row: 9
|
||||||
|
column: 1
|
||||||
|
end_location:
|
||||||
|
row: 9
|
||||||
|
column: 15
|
||||||
|
fix: ~
|
||||||
|
- kind:
|
||||||
|
UnnecessaryDoubleCastOrProcess:
|
||||||
|
- reversed
|
||||||
|
- set
|
||||||
|
location:
|
||||||
|
row: 10
|
||||||
|
column: 1
|
||||||
|
end_location:
|
||||||
|
row: 10
|
||||||
|
column: 17
|
||||||
|
fix: ~
|
||||||
|
- kind:
|
||||||
|
UnnecessaryDoubleCastOrProcess:
|
||||||
|
- list
|
||||||
|
- sorted
|
||||||
|
location:
|
||||||
|
row: 11
|
||||||
|
column: 1
|
||||||
|
end_location:
|
||||||
|
row: 11
|
||||||
|
column: 16
|
||||||
|
fix: ~
|
||||||
|
- kind:
|
||||||
|
UnnecessaryDoubleCastOrProcess:
|
||||||
|
- tuple
|
||||||
|
- sorted
|
||||||
|
location:
|
||||||
|
row: 12
|
||||||
|
column: 1
|
||||||
|
end_location:
|
||||||
|
row: 12
|
||||||
|
column: 17
|
||||||
|
fix: ~
|
||||||
|
- kind:
|
||||||
|
UnnecessaryDoubleCastOrProcess:
|
||||||
|
- sorted
|
||||||
|
- sorted
|
||||||
|
location:
|
||||||
|
row: 13
|
||||||
|
column: 1
|
||||||
|
end_location:
|
||||||
|
row: 13
|
||||||
|
column: 18
|
||||||
|
fix: ~
|
||||||
|
- kind:
|
||||||
|
UnnecessaryDoubleCastOrProcess:
|
||||||
|
- reversed
|
||||||
|
- sorted
|
||||||
|
location:
|
||||||
|
row: 14
|
||||||
|
column: 1
|
||||||
|
end_location:
|
||||||
|
row: 14
|
||||||
|
column: 20
|
||||||
|
fix: ~
|
||||||
|
|
||||||
Loading…
Reference in New Issue