Ignore namedtuple assignment in N806, N815, and N816 (#735)

This commit is contained in:
Harutaka Kawamura
2022-11-15 03:21:04 +09:00
committed by GitHub
parent 9047bf680d
commit 3e3c3c7421
11 changed files with 118 additions and 84 deletions

View File

@@ -1,5 +1,11 @@
import collections
from collections import namedtuple
def f():
lower = 0
Camel = 0
CONSTANT = 0
_ = 0
MyObj1 = collections.namedtuple("MyObj1", ["a", "b"])
MyObj2 = namedtuple("MyObj12", ["a", "b"])

View File

@@ -1,6 +1,12 @@
import collections
from collections import namedtuple
class C:
lower = 0
CONSTANT = 0
mixedCase = 0
_mixedCase = 0
mixed_Case = 0
myObj1 = collections.namedtuple("MyObj1", ["a", "b"])
myObj2 = namedtuple("MyObj2", ["a", "b"])

View File

@@ -1,5 +1,10 @@
import collections
from collections import namedtuple
lower = 0
CONSTANT = 0
mixedCase = 0
_mixedCase = 0
mixed_Case = 0
myObj1 = collections.namedtuple("MyObj1", ["a", "b"])
myObj2 = namedtuple("MyObj2", ["a", "b"])

View File

@@ -2174,32 +2174,22 @@ impl<'a> Checker<'a> {
}
if self.settings.enabled.contains(&CheckCode::N806) {
let current =
&self.scopes[*(self.scope_stack.last().expect("No current scope found."))];
if let Some(check) =
pep8_naming::checks::non_lowercase_variable_in_function(current, expr, id)
{
self.add_check(check);
if matches!(self.current_scope().kind, ScopeKind::Function(..)) {
pep8_naming::plugins::non_lowercase_variable_in_function(self, expr, parent, id)
}
}
if self.settings.enabled.contains(&CheckCode::N815) {
let current =
&self.scopes[*(self.scope_stack.last().expect("No current scope found."))];
if let Some(check) =
pep8_naming::checks::mixed_case_variable_in_class_scope(current, expr, id)
{
self.add_check(check);
if matches!(self.current_scope().kind, ScopeKind::Class(..)) {
pep8_naming::plugins::mixed_case_variable_in_class_scope(self, expr, parent, id)
}
}
if self.settings.enabled.contains(&CheckCode::N816) {
let current =
&self.scopes[*(self.scope_stack.last().expect("No current scope found."))];
if let Some(check) =
pep8_naming::checks::mixed_case_variable_in_global_scope(current, expr, id)
{
self.add_check(check);
if matches!(self.current_scope().kind, ScopeKind::Module) {
pep8_naming::plugins::mixed_case_variable_in_global_scope(
self, expr, parent, id,
)
}
}

View File

@@ -1,11 +1,11 @@
use rustpython_ast::{Arguments, Expr, ExprKind, Stmt};
use crate::ast::types::{FunctionScope, Range, Scope, ScopeKind};
use crate::ast::types::{Range, Scope, ScopeKind};
use crate::checks::{Check, CheckKind};
use crate::pep8_naming::helpers;
use crate::pep8_naming::helpers::FunctionType;
use crate::pep8_naming::settings::Settings;
use crate::python::string;
use crate::python::string::{self};
/// N801
pub fn invalid_class_name(class_def: &Stmt, name: &str) -> Option<Check> {
@@ -100,20 +100,6 @@ pub fn invalid_first_argument_name_for_method(
None
}
/// N806
pub fn non_lowercase_variable_in_function(scope: &Scope, expr: &Expr, name: &str) -> Option<Check> {
if !matches!(scope.kind, ScopeKind::Function(FunctionScope { .. })) {
return None;
}
if name.to_lowercase() != name {
return Some(Check::new(
CheckKind::NonLowercaseVariableInFunction(name.to_string()),
Range::from_located(expr),
));
}
None
}
/// N807
pub fn dunder_function_name(scope: &Scope, stmt: &Stmt, name: &str) -> Option<Check> {
if matches!(scope.kind, ScopeKind::Class(_)) {
@@ -192,38 +178,6 @@ pub fn camelcase_imported_as_constant(
None
}
/// N815
pub fn mixed_case_variable_in_class_scope(scope: &Scope, expr: &Expr, name: &str) -> Option<Check> {
if !matches!(scope.kind, ScopeKind::Class(_)) {
return None;
}
if helpers::is_mixed_case(name) {
return Some(Check::new(
CheckKind::MixedCaseVariableInClassScope(name.to_string()),
Range::from_located(expr),
));
}
None
}
/// N816
pub fn mixed_case_variable_in_global_scope(
scope: &Scope,
expr: &Expr,
name: &str,
) -> Option<Check> {
if !matches!(scope.kind, ScopeKind::Module) {
return None;
}
if helpers::is_mixed_case(name) {
return Some(Check::new(
CheckKind::MixedCaseVariableInGlobalScope(name.to_string()),
Range::from_located(expr),
));
}
None
}
/// N817
pub fn camelcase_imported_as_acronym(
import_from: &Stmt,

View File

@@ -1,7 +1,8 @@
use fnv::{FnvHashMap, FnvHashSet};
use itertools::Itertools;
use rustpython_ast::{Expr, ExprKind};
use rustpython_ast::{Expr, ExprKind, Stmt, StmtKind};
use crate::ast::helpers::match_name_or_attr;
use crate::ast::helpers::{compose_call_path, match_call_path, match_name_or_attr};
use crate::ast::types::{Scope, ScopeKind};
use crate::pep8_naming::settings::Settings;
use crate::python::string::{is_lower, is_upper};
@@ -78,6 +79,19 @@ pub fn is_acronym(name: &str, asname: &str) -> bool {
name.chars().filter(|c| c.is_uppercase()).join("") == asname
}
pub fn is_namedtuple_assignment(
stmt: &Stmt,
from_imports: &FnvHashMap<&str, FnvHashSet<&str>>,
) -> bool {
if let StmtKind::Assign { value, .. } = &stmt.node {
compose_call_path(value)
.map(|call_path| match_call_path(&call_path, "collections.namedtuple", from_imports))
.unwrap_or(false)
} else {
false
}
}
#[cfg(test)]
mod tests {
use crate::pep8_naming::helpers::{is_acronym, is_camelcase, is_mixed_case};

View File

@@ -1,3 +1,4 @@
pub mod checks;
mod helpers;
pub mod plugins;
pub mod settings;

View File

@@ -0,0 +1,58 @@
use rustpython_ast::{Expr, Stmt};
use crate::ast::types::Range;
use crate::check_ast::Checker;
use crate::checks::CheckKind;
use crate::pep8_naming::helpers;
use crate::Check;
/// N806
pub fn non_lowercase_variable_in_function(
checker: &mut Checker,
expr: &Expr,
stmt: &Stmt,
name: &str,
) {
if name.to_lowercase() != name
&& !helpers::is_namedtuple_assignment(stmt, &checker.from_imports)
{
checker.add_check(Check::new(
CheckKind::NonLowercaseVariableInFunction(name.to_string()),
Range::from_located(expr),
));
}
}
/// N815
pub fn mixed_case_variable_in_class_scope(
checker: &mut Checker,
expr: &Expr,
stmt: &Stmt,
name: &str,
) {
if helpers::is_mixed_case(name)
&& !helpers::is_namedtuple_assignment(stmt, &checker.from_imports)
{
checker.add_check(Check::new(
CheckKind::MixedCaseVariableInClassScope(name.to_string()),
Range::from_located(expr),
));
}
}
/// N816
pub fn mixed_case_variable_in_global_scope(
checker: &mut Checker,
expr: &Expr,
stmt: &Stmt,
name: &str,
) {
if helpers::is_mixed_case(name)
&& !helpers::is_namedtuple_assignment(stmt, &checker.from_imports)
{
checker.add_check(Check::new(
CheckKind::MixedCaseVariableInGlobalScope(name.to_string()),
Range::from_located(expr),
));
}
}

View File

@@ -5,19 +5,19 @@ expression: checks
- kind:
NonLowercaseVariableInFunction: Camel
location:
row: 3
row: 7
column: 4
end_location:
row: 3
row: 7
column: 9
fix: ~
- kind:
NonLowercaseVariableInFunction: CONSTANT
location:
row: 4
row: 8
column: 4
end_location:
row: 4
row: 8
column: 12
fix: ~

View File

@@ -5,28 +5,28 @@ expression: checks
- kind:
MixedCaseVariableInClassScope: mixedCase
location:
row: 4
row: 8
column: 4
end_location:
row: 4
row: 8
column: 13
fix: ~
- kind:
MixedCaseVariableInClassScope: _mixedCase
location:
row: 5
row: 9
column: 4
end_location:
row: 5
row: 9
column: 14
fix: ~
- kind:
MixedCaseVariableInClassScope: mixed_Case
location:
row: 6
row: 10
column: 4
end_location:
row: 6
row: 10
column: 14
fix: ~

View File

@@ -5,28 +5,28 @@ expression: checks
- kind:
MixedCaseVariableInGlobalScope: mixedCase
location:
row: 3
row: 6
column: 0
end_location:
row: 3
row: 6
column: 9
fix: ~
- kind:
MixedCaseVariableInGlobalScope: _mixedCase
location:
row: 4
row: 7
column: 0
end_location:
row: 4
row: 7
column: 10
fix: ~
- kind:
MixedCaseVariableInGlobalScope: mixed_Case
location:
row: 5
row: 8
column: 0
end_location:
row: 5
row: 8
column: 10
fix: ~