Implement C404 (#338)

This commit is contained in:
Harutaka Kawamura 2022-10-07 21:53:18 +09:00 committed by GitHub
parent d5b33cdb40
commit bd34850f98
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 91 additions and 10 deletions

View File

@ -276,6 +276,7 @@ The 🛠 emoji indicates that a rule is automatically fixable by the `--fix` com
| A002 | BuiltinArgumentShadowing | Argument `...` is shadowing a python builtin | | | | A002 | BuiltinArgumentShadowing | Argument `...` is shadowing a python builtin | | |
| A003 | BuiltinAttributeShadowing | Class attribute `...` is shadowing a python builtin | | | | A003 | BuiltinAttributeShadowing | Class attribute `...` is shadowing a python builtin | | |
| 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 | | |
| 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 | | 🛠 |

1
resources/test/fixtures/C404.py vendored Normal file
View File

@ -0,0 +1 @@
d = dict([(i, i) for i in range(3)])

View File

@ -714,9 +714,15 @@ pub fn is_super_call_with_arguments(func: &Expr, args: &Vec<Expr>) -> bool {
} }
// flakes8-comprehensions // flakes8-comprehensions
pub fn unnecessary_list_comprehension(expr: &Expr, func: &Expr, args: &Vec<Expr>) -> Option<Check> { /// Check `set([...])` compliance.
pub fn unnecessary_list_comprehension_set(
expr: &Expr,
func: &Expr,
args: &Vec<Expr>,
) -> Option<Check> {
if args.len() == 1 {
if let ExprKind::Name { id, .. } = &func.node { if let ExprKind::Name { id, .. } = &func.node {
if id == "set" && args.len() == 1 { if id == "set" {
if let ExprKind::ListComp { .. } = &args[0].node { if let ExprKind::ListComp { .. } = &args[0].node {
return Some(Check::new( return Some(Check::new(
CheckKind::UnnecessaryListComprehensionSet, CheckKind::UnnecessaryListComprehensionSet,
@ -725,6 +731,33 @@ pub fn unnecessary_list_comprehension(expr: &Expr, func: &Expr, args: &Vec<Expr>
} }
} }
} }
}
None
}
/// Check `dict([...])` compliance.
pub fn unnecessary_list_comprehension_dict(
expr: &Expr,
func: &Expr,
args: &Vec<Expr>,
) -> Option<Check> {
if args.len() == 1 {
if let ExprKind::Name { id, .. } = &func.node {
if id == "dict" {
if let ExprKind::ListComp { elt, .. } = &args[0].node {
match &elt.node {
ExprKind::Tuple { elts, .. } if elts.len() == 2 => {
return Some(Check::new(
CheckKind::UnnecessaryListComprehensionDict,
Range::from_located(expr),
));
}
_ => {}
}
}
}
}
}
None None
} }

View File

@ -767,7 +767,17 @@ where
// flake8-comprehensions // flake8-comprehensions
if self.settings.enabled.contains(&CheckCode::C403) { if self.settings.enabled.contains(&CheckCode::C403) {
if let Some(check) = checks::unnecessary_list_comprehension(expr, func, args) { if let Some(check) =
checks::unnecessary_list_comprehension_set(expr, func, args)
{
self.checks.push(check);
};
}
if self.settings.enabled.contains(&CheckCode::C404) {
if let Some(check) =
checks::unnecessary_list_comprehension_dict(expr, func, args)
{
self.checks.push(check); self.checks.push(check);
}; };
} }

View File

@ -53,7 +53,7 @@ pub const DEFAULT_CHECK_CODES: [CheckCode; 42] = [
CheckCode::F901, CheckCode::F901,
]; ];
pub const ALL_CHECK_CODES: [CheckCode; 54] = [ pub const ALL_CHECK_CODES: [CheckCode; 55] = [
// pycodestyle // pycodestyle
CheckCode::E402, CheckCode::E402,
CheckCode::E501, CheckCode::E501,
@ -104,6 +104,7 @@ pub const ALL_CHECK_CODES: [CheckCode; 54] = [
CheckCode::A003, CheckCode::A003,
// flake8-comprehensions // flake8-comprehensions
CheckCode::C403, CheckCode::C403,
CheckCode::C404,
// flake8-super // flake8-super
CheckCode::SPR001, CheckCode::SPR001,
// flake8-print // flake8-print
@ -171,6 +172,7 @@ pub enum CheckCode {
A003, A003,
// flake8-comprehensions // flake8-comprehensions
C403, C403,
C404,
// flake8-super // flake8-super
SPR001, SPR001,
// flake8-print // flake8-print
@ -241,6 +243,7 @@ impl FromStr for CheckCode {
"A003" => Ok(CheckCode::A003), "A003" => Ok(CheckCode::A003),
// flake8-comprehensions // flake8-comprehensions
"C403" => Ok(CheckCode::C403), "C403" => Ok(CheckCode::C403),
"C404" => Ok(CheckCode::C404),
// flake8-super // flake8-super
"SPR001" => Ok(CheckCode::SPR001), "SPR001" => Ok(CheckCode::SPR001),
// flake8-print // flake8-print
@ -312,6 +315,7 @@ impl CheckCode {
CheckCode::A003 => "A003", CheckCode::A003 => "A003",
// flake8-comprehensions // flake8-comprehensions
CheckCode::C403 => "C403", CheckCode::C403 => "C403",
CheckCode::C404 => "C404",
// flake8-super // flake8-super
CheckCode::SPR001 => "SPR001", CheckCode::SPR001 => "SPR001",
// flake8-print // flake8-print
@ -392,6 +396,7 @@ impl CheckCode {
CheckCode::A003 => CheckKind::BuiltinAttributeShadowing("...".to_string()), CheckCode::A003 => CheckKind::BuiltinAttributeShadowing("...".to_string()),
// flake8-comprehensions // flake8-comprehensions
CheckCode::C403 => CheckKind::UnnecessaryListComprehensionSet, CheckCode::C403 => CheckKind::UnnecessaryListComprehensionSet,
CheckCode::C404 => CheckKind::UnnecessaryListComprehensionDict,
// flake8-super // flake8-super
CheckCode::SPR001 => CheckKind::SuperCallWithParameters, CheckCode::SPR001 => CheckKind::SuperCallWithParameters,
// flake8-print // flake8-print
@ -472,6 +477,7 @@ pub enum CheckKind {
BuiltinAttributeShadowing(String), BuiltinAttributeShadowing(String),
// flakes8-comprehensions // flakes8-comprehensions
UnnecessaryListComprehensionSet, UnnecessaryListComprehensionSet,
UnnecessaryListComprehensionDict,
// flake8-super // flake8-super
SuperCallWithParameters, SuperCallWithParameters,
// flake8-print // flake8-print
@ -539,6 +545,7 @@ impl CheckKind {
CheckKind::BuiltinAttributeShadowing(_) => "BuiltinAttributeShadowing", CheckKind::BuiltinAttributeShadowing(_) => "BuiltinAttributeShadowing",
// flake8-comprehensions // flake8-comprehensions
CheckKind::UnnecessaryListComprehensionSet => "UnnecessaryListComprehensionSet", CheckKind::UnnecessaryListComprehensionSet => "UnnecessaryListComprehensionSet",
CheckKind::UnnecessaryListComprehensionDict => "UnnecessaryListComprehensionDict",
// flake8-super // flake8-super
CheckKind::SuperCallWithParameters => "SuperCallWithParameters", CheckKind::SuperCallWithParameters => "SuperCallWithParameters",
// flake8-print // flake8-print
@ -606,6 +613,7 @@ impl CheckKind {
CheckKind::BuiltinAttributeShadowing(_) => &CheckCode::A003, CheckKind::BuiltinAttributeShadowing(_) => &CheckCode::A003,
// flake8-comprehensions // flake8-comprehensions
CheckKind::UnnecessaryListComprehensionSet => &CheckCode::C403, CheckKind::UnnecessaryListComprehensionSet => &CheckCode::C403,
CheckKind::UnnecessaryListComprehensionDict => &CheckCode::C404,
// flake8-super // flake8-super
CheckKind::SuperCallWithParameters => &CheckCode::SPR001, CheckKind::SuperCallWithParameters => &CheckCode::SPR001,
// flake8-print // flake8-print
@ -764,6 +772,9 @@ impl CheckKind {
CheckKind::UnnecessaryListComprehensionSet => { CheckKind::UnnecessaryListComprehensionSet => {
"Unnecessary list comprehension - rewrite as a set comprehension".to_string() "Unnecessary list comprehension - rewrite as a set comprehension".to_string()
} }
CheckKind::UnnecessaryListComprehensionDict => {
"Unnecessary list comprehension - rewrite as a dict comprehension".to_string()
}
// 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()

View File

@ -798,6 +798,18 @@ mod tests {
Ok(()) Ok(())
} }
#[test]
fn c404() -> Result<()> {
let mut checks = check_path(
Path::new("./resources/test/fixtures/C404.py"),
&settings::Settings::for_rule(CheckCode::C404),
&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(

View File

@ -0,0 +1,13 @@
---
source: src/linter.rs
expression: checks
---
- kind: UnnecessaryListComprehensionDict
location:
row: 1
column: 5
end_location:
row: 1
column: 37
fix: ~