Implement N811, 812, 813, 814, and 817 (#457)

This commit is contained in:
Harutaka Kawamura 2022-10-21 01:20:44 +09:00 committed by GitHub
parent aac1912ea7
commit b108c693fa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 282 additions and 0 deletions

View file

@ -349,6 +349,11 @@ The 🛠 emoji indicates that a rule is automatically fixable by the `--fix` com
| N804 | InvalidFirstArgumentNameForClassMethod | First argument of a class method should be named `cls` | |
| N805 | InvalidFirstArgumentNameForMethod | First argument of a method should be named `self` | |
| N807 | DunderFunctionName | function name should not start and end with '__' | |
| N811 | ConstantImportedAsNonConstant | constant '...' imported as non constant '...' | |
| N812 | LowercaseImportedAsNonLowercase | lowercase '...' imported as non lowercase '...' | |
| N813 | CamelcaseImportedAsLowercase | camelcase '...' imported as lowercase '...' | |
| N814 | CamelcaseImportedAsConstant | camelcase '...' imported as constant '...' | |
| N817 | CamelcaseImportedAsAcronym | camelcase '...' imported as acronym '...' | |
### flake8-comprehensions

1
resources/test/fixtures/N811.py vendored Normal file
View file

@ -0,0 +1 @@
from mod import BAD as bad

1
resources/test/fixtures/N812.py vendored Normal file
View file

@ -0,0 +1 @@
from mod import bad as Bad

1
resources/test/fixtures/N813.py vendored Normal file
View file

@ -0,0 +1 @@
from mod import CamelCase as camelcase

1
resources/test/fixtures/N814.py vendored Normal file
View file

@ -0,0 +1 @@
from mod import CamelCase as CAMELCASE

1
resources/test/fixtures/N817.py vendored Normal file
View file

@ -0,0 +1 @@
from mod import CamelCase as CC

View file

@ -533,6 +533,64 @@ where
},
)
}
if let Some(asname) = &alias.node.asname {
if self.settings.enabled.contains(&CheckCode::N811) {
if let Some(check) =
pep8_naming::checks::constant_imported_as_non_constant(
stmt,
&alias.node.name,
asname,
)
{
self.checks.push(check);
}
}
if self.settings.enabled.contains(&CheckCode::N812) {
if let Some(check) =
pep8_naming::checks::lowercase_imported_as_non_lowercase(
stmt,
&alias.node.name,
asname,
)
{
self.checks.push(check);
}
}
if self.settings.enabled.contains(&CheckCode::N813) {
if let Some(check) =
pep8_naming::checks::camelcase_imported_as_lowercase(
stmt,
&alias.node.name,
asname,
)
{
self.checks.push(check);
}
}
if self.settings.enabled.contains(&CheckCode::N814) {
if let Some(check) = pep8_naming::checks::camelcase_imported_as_constant(
stmt,
&alias.node.name,
asname,
) {
self.checks.push(check);
}
}
if self.settings.enabled.contains(&CheckCode::N817) {
if let Some(check) = pep8_naming::checks::camelcase_imported_as_acronym(
stmt,
&alias.node.name,
asname,
) {
self.checks.push(check);
}
}
}
}
}
StmtKind::Raise { exc, .. } => {

View file

@ -159,6 +159,11 @@ pub enum CheckCode {
N804,
N805,
N807,
N811,
N812,
N813,
N814,
N817,
// Meta
M001,
}
@ -344,6 +349,11 @@ pub enum CheckKind {
InvalidFirstArgumentNameForClassMethod,
InvalidFirstArgumentNameForMethod,
DunderFunctionName,
ConstantImportedAsNonConstant(String, String),
LowercaseImportedAsNonLowercase(String, String),
CamelcaseImportedAsLowercase(String, String),
CamelcaseImportedAsConstant(String, String),
CamelcaseImportedAsAcronym(String, String),
// Meta
UnusedNOQA(Option<Vec<String>>),
}
@ -520,6 +530,21 @@ impl CheckCode {
CheckCode::N804 => CheckKind::InvalidFirstArgumentNameForClassMethod,
CheckCode::N805 => CheckKind::InvalidFirstArgumentNameForMethod,
CheckCode::N807 => CheckKind::DunderFunctionName,
CheckCode::N811 => {
CheckKind::ConstantImportedAsNonConstant("...".to_string(), "...".to_string())
}
CheckCode::N812 => {
CheckKind::LowercaseImportedAsNonLowercase("...".to_string(), "...".to_string())
}
CheckCode::N813 => {
CheckKind::CamelcaseImportedAsLowercase("...".to_string(), "...".to_string())
}
CheckCode::N814 => {
CheckKind::CamelcaseImportedAsConstant("...".to_string(), "...".to_string())
}
CheckCode::N817 => {
CheckKind::CamelcaseImportedAsAcronym("...".to_string(), "...".to_string())
}
// Meta
CheckCode::M001 => CheckKind::UnusedNOQA(None),
}
@ -652,6 +677,11 @@ impl CheckCode {
CheckCode::N804 => CheckCategory::PEP8Naming,
CheckCode::N805 => CheckCategory::PEP8Naming,
CheckCode::N807 => CheckCategory::PEP8Naming,
CheckCode::N811 => CheckCategory::PEP8Naming,
CheckCode::N812 => CheckCategory::PEP8Naming,
CheckCode::N813 => CheckCategory::PEP8Naming,
CheckCode::N814 => CheckCategory::PEP8Naming,
CheckCode::N817 => CheckCategory::PEP8Naming,
CheckCode::M001 => CheckCategory::Meta,
}
}
@ -795,6 +825,11 @@ impl CheckKind {
CheckKind::InvalidFirstArgumentNameForClassMethod => &CheckCode::N804,
CheckKind::InvalidFirstArgumentNameForMethod => &CheckCode::N805,
CheckKind::DunderFunctionName => &CheckCode::N807,
CheckKind::ConstantImportedAsNonConstant(..) => &CheckCode::N811,
CheckKind::LowercaseImportedAsNonLowercase(..) => &CheckCode::N812,
CheckKind::CamelcaseImportedAsLowercase(..) => &CheckCode::N813,
CheckKind::CamelcaseImportedAsConstant(..) => &CheckCode::N814,
CheckKind::CamelcaseImportedAsAcronym(..) => &CheckCode::N817,
// Meta
CheckKind::UnusedNOQA(_) => &CheckCode::M001,
}
@ -1188,6 +1223,21 @@ impl CheckKind {
CheckKind::DunderFunctionName => {
"function name should not start and end with '__'".to_string()
}
CheckKind::ConstantImportedAsNonConstant(name, asname) => {
format!("constant '{name}' imported as non constant '{asname}'")
}
CheckKind::LowercaseImportedAsNonLowercase(name, asname) => {
format!("lowercase '{name}' imported as non lowercase '{asname}'")
}
CheckKind::CamelcaseImportedAsLowercase(name, asname) => {
format!("camelcase '{name}' imported as lowercase '{asname}'")
}
CheckKind::CamelcaseImportedAsConstant(name, asname) => {
format!("camelcase '{name}' imported as constant '{asname}'")
}
CheckKind::CamelcaseImportedAsAcronym(name, asname) => {
format!("camelcase '{name}' imported as acronym '{asname}'")
}
// Meta
CheckKind::UnusedNOQA(codes) => match codes {
None => "Unused `noqa` directive".to_string(),

View file

@ -359,6 +359,11 @@ mod tests {
#[test_case(CheckCode::N804, Path::new("N804.py"); "N804")]
#[test_case(CheckCode::N805, Path::new("N805.py"); "N805")]
#[test_case(CheckCode::N807, Path::new("N807.py"); "N807")]
#[test_case(CheckCode::N811, Path::new("N811.py"); "N811")]
#[test_case(CheckCode::N812, Path::new("N812.py"); "N812")]
#[test_case(CheckCode::N813, Path::new("N813.py"); "N813")]
#[test_case(CheckCode::N814, Path::new("N814.py"); "N814")]
#[test_case(CheckCode::N817, Path::new("N817.py"); "N817")]
#[test_case(CheckCode::T201, Path::new("T201.py"); "T201")]
#[test_case(CheckCode::T203, Path::new("T203.py"); "T203")]
#[test_case(CheckCode::U001, Path::new("U001.py"); "U001")]

View file

@ -1,3 +1,4 @@
use itertools::Itertools;
use rustpython_ast::{Arguments, Expr, ExprKind, Stmt};
use crate::ast::types::{Range, Scope, ScopeKind};
@ -112,3 +113,81 @@ pub fn dunder_function_name(func_def: &Stmt, scope: &Scope, name: &str) -> Optio
None
}
pub fn constant_imported_as_non_constant(
import_from: &Stmt,
name: &str,
asname: &str,
) -> Option<Check> {
if name.chars().all(|c| c.is_uppercase()) && !asname.chars().all(|c| c.is_uppercase()) {
return Some(Check::new(
CheckKind::ConstantImportedAsNonConstant(name.to_string(), asname.to_string()),
Range::from_located(import_from),
));
}
None
}
pub fn lowercase_imported_as_non_lowercase(
import_from: &Stmt,
name: &str,
asname: &str,
) -> Option<Check> {
if name.chars().all(|c| c.is_lowercase()) && asname.to_lowercase() != asname {
return Some(Check::new(
CheckKind::LowercaseImportedAsNonLowercase(name.to_string(), asname.to_string()),
Range::from_located(import_from),
));
}
None
}
fn is_camelcase(name: &str) -> bool {
!name.chars().all(|c| c.is_uppercase()) && !name.chars().all(|c| c.is_lowercase())
}
fn is_acronym(name: &str, asname: &str) -> bool {
name.chars().filter(|c| c.is_uppercase()).join("") == asname
}
pub fn camelcase_imported_as_lowercase(
import_from: &Stmt,
name: &str,
asname: &str,
) -> Option<Check> {
if is_camelcase(name) && asname.chars().all(|c| c.is_lowercase()) {
return Some(Check::new(
CheckKind::CamelcaseImportedAsLowercase(name.to_string(), asname.to_string()),
Range::from_located(import_from),
));
}
None
}
pub fn camelcase_imported_as_constant(
import_from: &Stmt,
name: &str,
asname: &str,
) -> Option<Check> {
if is_camelcase(name) && asname.chars().all(|c| c.is_uppercase()) && !is_acronym(name, asname) {
return Some(Check::new(
CheckKind::CamelcaseImportedAsConstant(name.to_string(), asname.to_string()),
Range::from_located(import_from),
));
}
None
}
pub fn camelcase_imported_as_acronym(
import_from: &Stmt,
name: &str,
asname: &str,
) -> Option<Check> {
if is_camelcase(name) && asname.chars().all(|c| c.is_uppercase()) && is_acronym(name, asname) {
return Some(Check::new(
CheckKind::CamelcaseImportedAsAcronym(name.to_string(), asname.to_string()),
Range::from_located(import_from),
));
}
None
}

View file

@ -0,0 +1,16 @@
---
source: src/linter.rs
expression: checks
---
- kind:
ConstantImportedAsNonConstant:
- BAD
- bad
location:
row: 1
column: 1
end_location:
row: 1
column: 27
fix: ~

View file

@ -0,0 +1,16 @@
---
source: src/linter.rs
expression: checks
---
- kind:
LowercaseImportedAsNonLowercase:
- bad
- Bad
location:
row: 1
column: 1
end_location:
row: 1
column: 27
fix: ~

View file

@ -0,0 +1,16 @@
---
source: src/linter.rs
expression: checks
---
- kind:
CamelcaseImportedAsLowercase:
- CamelCase
- camelcase
location:
row: 1
column: 1
end_location:
row: 1
column: 39
fix: ~

View file

@ -0,0 +1,16 @@
---
source: src/linter.rs
expression: checks
---
- kind:
CamelcaseImportedAsConstant:
- CamelCase
- CAMELCASE
location:
row: 1
column: 1
end_location:
row: 1
column: 39
fix: ~

View file

@ -0,0 +1,16 @@
---
source: src/linter.rs
expression: checks
---
- kind:
CamelcaseImportedAsAcronym:
- CamelCase
- CC
location:
row: 1
column: 1
end_location:
row: 1
column: 32
fix: ~