mirror of https://github.com/astral-sh/ruff
Implement C408 (#364)
This commit is contained in:
parent
346610c2e3
commit
5ccd907398
|
|
@ -284,6 +284,8 @@ The 🛠 emoji indicates that a rule is automatically fixable by the `--fix` com
|
||||||
| C403 | UnnecessaryListComprehensionSet | Unnecessary list comprehension - rewrite as a set comprehension | | |
|
| C403 | UnnecessaryListComprehensionSet | Unnecessary list comprehension - rewrite as a set comprehension | | |
|
||||||
| C404 | UnnecessaryListComprehensionDict | Unnecessary list comprehension - rewrite as a dict comprehension | | |
|
| C404 | UnnecessaryListComprehensionDict | Unnecessary list comprehension - rewrite as a dict comprehension | | |
|
||||||
| C405 | UnnecessaryLiteralSet | Unnecessary <list/tuple> literal - rewrite as a set literal | | |
|
| C405 | UnnecessaryLiteralSet | Unnecessary <list/tuple> literal - rewrite as a set literal | | |
|
||||||
|
| C406 | UnnecessaryLiteralDict | Unnecessary <list/tuple> literal - rewrite as a dict literal | | |
|
||||||
|
| C408 | UnnecessaryCollectionCall | Unnecessary <dict/list/tuple> call - rewrite as a literal | | |
|
||||||
| SPR001 | SuperCallWithParameters | Use `super()` instead of `super(__class__, self)` | | 🛠 |
|
| SPR001 | SuperCallWithParameters | Use `super()` instead of `super(__class__, self)` | | 🛠 |
|
||||||
| T201 | PrintFound | `print` found | | 🛠 |
|
| T201 | PrintFound | `print` found | | 🛠 |
|
||||||
| T203 | PPrintFound | `pprint` found | | 🛠 |
|
| T203 | PPrintFound | `pprint` found | | 🛠 |
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
t = tuple()
|
||||||
|
l = list()
|
||||||
|
d1 = dict()
|
||||||
|
d2 = dict(a=1)
|
||||||
|
d3 = dict(**d2)
|
||||||
|
|
@ -4,7 +4,7 @@ use itertools::izip;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use rustpython_parser::ast::{
|
use rustpython_parser::ast::{
|
||||||
Arg, ArgData, Arguments, Cmpop, Constant, Excepthandler, ExcepthandlerKind, Expr, ExprKind,
|
Arg, ArgData, Arguments, Cmpop, Constant, Excepthandler, ExcepthandlerKind, Expr, ExprKind,
|
||||||
Stmt, StmtKind, Unaryop,
|
KeywordData, Located, Stmt, StmtKind, Unaryop,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
|
@ -957,6 +957,34 @@ pub fn unnecessary_literal_dict(expr: &Expr, func: &Expr, args: &Vec<Expr>) -> O
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn unnecessary_collection_call(
|
||||||
|
expr: &Expr,
|
||||||
|
func: &Expr,
|
||||||
|
args: &Vec<Expr>,
|
||||||
|
keywords: &Vec<Located<KeywordData>>,
|
||||||
|
) -> Option<Check> {
|
||||||
|
if args.is_empty() {
|
||||||
|
if let ExprKind::Name { id, .. } = &func.node {
|
||||||
|
if id == "list" || id == "tuple" {
|
||||||
|
// list() or tuple()
|
||||||
|
return Some(Check::new(
|
||||||
|
CheckKind::UnnecessaryCollectionCall(id.to_string()),
|
||||||
|
Range::from_located(expr),
|
||||||
|
));
|
||||||
|
} else if id == "dict" {
|
||||||
|
// dict() or dict(a=1)
|
||||||
|
if keywords.is_empty() || keywords.iter().all(|kw| kw.node.arg.is_some()) {
|
||||||
|
return Some(Check::new(
|
||||||
|
CheckKind::UnnecessaryCollectionCall(id.to_string()),
|
||||||
|
Range::from_located(expr),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
// flake8-super
|
// flake8-super
|
||||||
/// Check that `super()` has no args
|
/// Check that `super()` has no args
|
||||||
pub fn check_super_args(
|
pub fn check_super_args(
|
||||||
|
|
|
||||||
|
|
@ -748,7 +748,12 @@ where
|
||||||
}
|
}
|
||||||
ExprContext::Del => self.handle_node_delete(expr),
|
ExprContext::Del => self.handle_node_delete(expr),
|
||||||
},
|
},
|
||||||
ExprKind::Call { func, args, .. } => {
|
ExprKind::Call {
|
||||||
|
func,
|
||||||
|
args,
|
||||||
|
keywords,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
if self.settings.enabled.contains(&CheckCode::U005) {
|
if self.settings.enabled.contains(&CheckCode::U005) {
|
||||||
plugins::assert_equals(self, func);
|
plugins::assert_equals(self, func);
|
||||||
}
|
}
|
||||||
|
|
@ -812,6 +817,14 @@ where
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.settings.enabled.contains(&CheckCode::C408) {
|
||||||
|
if let Some(check) =
|
||||||
|
checks::unnecessary_collection_call(expr, func, args, keywords)
|
||||||
|
{
|
||||||
|
self.checks.push(check);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// pyupgrade
|
// pyupgrade
|
||||||
if self.settings.enabled.contains(&CheckCode::U002)
|
if self.settings.enabled.contains(&CheckCode::U002)
|
||||||
&& self.settings.target_version >= PythonVersion::Py310
|
&& self.settings.target_version >= PythonVersion::Py310
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ pub const DEFAULT_CHECK_CODES: [CheckCode; 43] = [
|
||||||
CheckCode::F901,
|
CheckCode::F901,
|
||||||
];
|
];
|
||||||
|
|
||||||
pub const ALL_CHECK_CODES: [CheckCode; 62] = [
|
pub const ALL_CHECK_CODES: [CheckCode; 63] = [
|
||||||
// pycodestyle errors
|
// pycodestyle errors
|
||||||
CheckCode::E402,
|
CheckCode::E402,
|
||||||
CheckCode::E501,
|
CheckCode::E501,
|
||||||
|
|
@ -116,6 +116,7 @@ pub const ALL_CHECK_CODES: [CheckCode; 62] = [
|
||||||
CheckCode::C404,
|
CheckCode::C404,
|
||||||
CheckCode::C405,
|
CheckCode::C405,
|
||||||
CheckCode::C406,
|
CheckCode::C406,
|
||||||
|
CheckCode::C408,
|
||||||
// flake8-super
|
// flake8-super
|
||||||
CheckCode::SPR001,
|
CheckCode::SPR001,
|
||||||
// flake8-print
|
// flake8-print
|
||||||
|
|
@ -191,6 +192,7 @@ pub enum CheckCode {
|
||||||
C404,
|
C404,
|
||||||
C405,
|
C405,
|
||||||
C406,
|
C406,
|
||||||
|
C408,
|
||||||
// flake8-super
|
// flake8-super
|
||||||
SPR001,
|
SPR001,
|
||||||
// flake8-print
|
// flake8-print
|
||||||
|
|
@ -269,6 +271,7 @@ impl FromStr for CheckCode {
|
||||||
"C404" => Ok(CheckCode::C404),
|
"C404" => Ok(CheckCode::C404),
|
||||||
"C405" => Ok(CheckCode::C405),
|
"C405" => Ok(CheckCode::C405),
|
||||||
"C406" => Ok(CheckCode::C406),
|
"C406" => Ok(CheckCode::C406),
|
||||||
|
"C408" => Ok(CheckCode::C408),
|
||||||
// flake8-super
|
// flake8-super
|
||||||
"SPR001" => Ok(CheckCode::SPR001),
|
"SPR001" => Ok(CheckCode::SPR001),
|
||||||
// flake8-print
|
// flake8-print
|
||||||
|
|
@ -348,6 +351,7 @@ impl CheckCode {
|
||||||
CheckCode::C404 => "C404",
|
CheckCode::C404 => "C404",
|
||||||
CheckCode::C405 => "C405",
|
CheckCode::C405 => "C405",
|
||||||
CheckCode::C406 => "C406",
|
CheckCode::C406 => "C406",
|
||||||
|
CheckCode::C408 => "C408",
|
||||||
// flake8-super
|
// flake8-super
|
||||||
CheckCode::SPR001 => "SPR001",
|
CheckCode::SPR001 => "SPR001",
|
||||||
// flake8-print
|
// flake8-print
|
||||||
|
|
@ -436,6 +440,9 @@ impl CheckCode {
|
||||||
CheckCode::C404 => CheckKind::UnnecessaryListComprehensionDict,
|
CheckCode::C404 => CheckKind::UnnecessaryListComprehensionDict,
|
||||||
CheckCode::C405 => CheckKind::UnnecessaryLiteralSet("<list/tuple>".to_string()),
|
CheckCode::C405 => CheckKind::UnnecessaryLiteralSet("<list/tuple>".to_string()),
|
||||||
CheckCode::C406 => CheckKind::UnnecessaryLiteralDict("<list/tuple>".to_string()),
|
CheckCode::C406 => CheckKind::UnnecessaryLiteralDict("<list/tuple>".to_string()),
|
||||||
|
CheckCode::C408 => {
|
||||||
|
CheckKind::UnnecessaryCollectionCall("<dict/list/tuple>".to_string())
|
||||||
|
}
|
||||||
// flake8-super
|
// flake8-super
|
||||||
CheckCode::SPR001 => CheckKind::SuperCallWithParameters,
|
CheckCode::SPR001 => CheckKind::SuperCallWithParameters,
|
||||||
// flake8-print
|
// flake8-print
|
||||||
|
|
@ -524,6 +531,7 @@ pub enum CheckKind {
|
||||||
UnnecessaryListComprehensionDict,
|
UnnecessaryListComprehensionDict,
|
||||||
UnnecessaryLiteralSet(String),
|
UnnecessaryLiteralSet(String),
|
||||||
UnnecessaryLiteralDict(String),
|
UnnecessaryLiteralDict(String),
|
||||||
|
UnnecessaryCollectionCall(String),
|
||||||
// flake8-super
|
// flake8-super
|
||||||
SuperCallWithParameters,
|
SuperCallWithParameters,
|
||||||
// flake8-print
|
// flake8-print
|
||||||
|
|
@ -599,6 +607,7 @@ impl CheckKind {
|
||||||
CheckKind::UnnecessaryListComprehensionDict => "UnnecessaryListComprehensionDict",
|
CheckKind::UnnecessaryListComprehensionDict => "UnnecessaryListComprehensionDict",
|
||||||
CheckKind::UnnecessaryLiteralSet(_) => "UnnecessaryLiteralSet",
|
CheckKind::UnnecessaryLiteralSet(_) => "UnnecessaryLiteralSet",
|
||||||
CheckKind::UnnecessaryLiteralDict(_) => "UnnecessaryLiteralDict",
|
CheckKind::UnnecessaryLiteralDict(_) => "UnnecessaryLiteralDict",
|
||||||
|
CheckKind::UnnecessaryCollectionCall(_) => "UnnecessaryCollectionCall",
|
||||||
// flake8-super
|
// flake8-super
|
||||||
CheckKind::SuperCallWithParameters => "SuperCallWithParameters",
|
CheckKind::SuperCallWithParameters => "SuperCallWithParameters",
|
||||||
// flake8-print
|
// flake8-print
|
||||||
|
|
@ -674,6 +683,7 @@ impl CheckKind {
|
||||||
CheckKind::UnnecessaryListComprehensionDict => &CheckCode::C404,
|
CheckKind::UnnecessaryListComprehensionDict => &CheckCode::C404,
|
||||||
CheckKind::UnnecessaryLiteralSet(_) => &CheckCode::C405,
|
CheckKind::UnnecessaryLiteralSet(_) => &CheckCode::C405,
|
||||||
CheckKind::UnnecessaryLiteralDict(_) => &CheckCode::C406,
|
CheckKind::UnnecessaryLiteralDict(_) => &CheckCode::C406,
|
||||||
|
CheckKind::UnnecessaryCollectionCall(_) => &CheckCode::C408,
|
||||||
// flake8-super
|
// flake8-super
|
||||||
CheckKind::SuperCallWithParameters => &CheckCode::SPR001,
|
CheckKind::SuperCallWithParameters => &CheckCode::SPR001,
|
||||||
// flake8-print
|
// flake8-print
|
||||||
|
|
@ -854,6 +864,9 @@ impl CheckKind {
|
||||||
CheckKind::UnnecessaryLiteralDict(obj_type) => {
|
CheckKind::UnnecessaryLiteralDict(obj_type) => {
|
||||||
format!("Unnecessary {obj_type} literal - rewrite as a dict literal")
|
format!("Unnecessary {obj_type} literal - rewrite as a dict literal")
|
||||||
}
|
}
|
||||||
|
CheckKind::UnnecessaryCollectionCall(obj_type) => {
|
||||||
|
format!("Unnecessary {obj_type} call - rewrite as a literal")
|
||||||
|
}
|
||||||
// flake8-super
|
// flake8-super
|
||||||
CheckKind::SuperCallWithParameters => {
|
CheckKind::SuperCallWithParameters => {
|
||||||
"Use `super()` instead of `super(__class__, self)`".to_string()
|
"Use `super()` instead of `super(__class__, self)`".to_string()
|
||||||
|
|
|
||||||
|
|
@ -870,6 +870,18 @@ mod tests {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn c408() -> Result<()> {
|
||||||
|
let mut checks = check_path(
|
||||||
|
Path::new("./resources/test/fixtures/C408.py"),
|
||||||
|
&settings::Settings::for_rule(CheckCode::C408),
|
||||||
|
&fixer::Mode::Generate,
|
||||||
|
)?;
|
||||||
|
checks.sort_by_key(|check| check.location);
|
||||||
|
insta::assert_yaml_snapshot!(checks);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn spr001() -> Result<()> {
|
fn spr001() -> Result<()> {
|
||||||
let mut checks = check_path(
|
let mut checks = check_path(
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
---
|
||||||
|
source: src/linter.rs
|
||||||
|
expression: checks
|
||||||
|
---
|
||||||
|
- kind:
|
||||||
|
UnnecessaryCollectionCall: tuple
|
||||||
|
location:
|
||||||
|
row: 1
|
||||||
|
column: 5
|
||||||
|
end_location:
|
||||||
|
row: 1
|
||||||
|
column: 12
|
||||||
|
fix: ~
|
||||||
|
- kind:
|
||||||
|
UnnecessaryCollectionCall: list
|
||||||
|
location:
|
||||||
|
row: 2
|
||||||
|
column: 5
|
||||||
|
end_location:
|
||||||
|
row: 2
|
||||||
|
column: 11
|
||||||
|
fix: ~
|
||||||
|
- kind:
|
||||||
|
UnnecessaryCollectionCall: dict
|
||||||
|
location:
|
||||||
|
row: 3
|
||||||
|
column: 6
|
||||||
|
end_location:
|
||||||
|
row: 3
|
||||||
|
column: 12
|
||||||
|
fix: ~
|
||||||
|
- kind:
|
||||||
|
UnnecessaryCollectionCall: dict
|
||||||
|
location:
|
||||||
|
row: 4
|
||||||
|
column: 6
|
||||||
|
end_location:
|
||||||
|
row: 4
|
||||||
|
column: 15
|
||||||
|
fix: ~
|
||||||
|
|
||||||
Loading…
Reference in New Issue