Use `Context` for pep8-naming helpers (#4068)

This commit is contained in:
Charlie Marsh 2023-04-22 16:44:54 -06:00 committed by GitHub
parent 2da149fd7e
commit 260138b427
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 28 additions and 36 deletions

View File

@ -1,15 +1,14 @@
use itertools::Itertools; use itertools::Itertools;
use ruff_python_semantic::context::Context;
use rustpython_parser::ast::{Expr, ExprKind, Stmt, StmtKind}; use rustpython_parser::ast::{Expr, ExprKind, Stmt, StmtKind};
use ruff_python_stdlib::str::{is_lower, is_upper}; use ruff_python_stdlib::str::{is_lower, is_upper};
use crate::checkers::ast::Checker; pub(crate) fn is_camelcase(name: &str) -> bool {
pub fn is_camelcase(name: &str) -> bool {
!is_lower(name) && !is_upper(name) && !name.contains('_') !is_lower(name) && !is_upper(name) && !name.contains('_')
} }
pub fn is_mixed_case(name: &str) -> bool { pub(crate) fn is_mixed_case(name: &str) -> bool {
!is_lower(name) !is_lower(name)
&& name && name
.strip_prefix('_') .strip_prefix('_')
@ -19,61 +18,54 @@ pub fn is_mixed_case(name: &str) -> bool {
.map_or_else(|| false, char::is_lowercase) .map_or_else(|| false, char::is_lowercase)
} }
pub fn is_acronym(name: &str, asname: &str) -> bool { pub(crate) fn is_acronym(name: &str, asname: &str) -> bool {
name.chars().filter(|c| c.is_uppercase()).join("") == asname name.chars().filter(|c| c.is_uppercase()).join("") == asname
} }
pub fn is_namedtuple_assignment(checker: &Checker, stmt: &Stmt) -> bool { pub(crate) fn is_named_tuple_assignment(context: &Context, stmt: &Stmt) -> bool {
let StmtKind::Assign { value, .. } = &stmt.node else { let StmtKind::Assign { value, .. } = &stmt.node else {
return false; return false;
}; };
let ExprKind::Call {func, ..} = &value.node else { let ExprKind::Call {func, ..} = &value.node else {
return false; return false;
}; };
checker context.resolve_call_path(func).map_or(false, |call_path| {
.ctx matches!(
.resolve_call_path(func) call_path.as_slice(),
.map_or(false, |call_path| { ["collections", "namedtuple"] | ["typing", "NamedTuple"]
call_path.as_slice() == ["collections", "namedtuple"] )
|| call_path.as_slice() == ["typing", "NamedTuple"] })
})
} }
pub fn is_typeddict_assignment(checker: &Checker, stmt: &Stmt) -> bool { pub(crate) fn is_typed_dict_assignment(context: &Context, stmt: &Stmt) -> bool {
let StmtKind::Assign { value, .. } = &stmt.node else { let StmtKind::Assign { value, .. } = &stmt.node else {
return false; return false;
}; };
let ExprKind::Call {func, ..} = &value.node else { let ExprKind::Call {func, ..} = &value.node else {
return false; return false;
}; };
checker context.resolve_call_path(func).map_or(false, |call_path| {
.ctx call_path.as_slice() == ["typing", "TypedDict"]
.resolve_call_path(func) })
.map_or(false, |call_path| {
call_path.as_slice() == ["typing", "TypedDict"]
})
} }
pub fn is_type_var_assignment(checker: &Checker, stmt: &Stmt) -> bool { pub(crate) fn is_type_var_assignment(context: &Context, stmt: &Stmt) -> bool {
let StmtKind::Assign { value, .. } = &stmt.node else { let StmtKind::Assign { value, .. } = &stmt.node else {
return false; return false;
}; };
let ExprKind::Call {func, ..} = &value.node else { let ExprKind::Call {func, ..} = &value.node else {
return false; return false;
}; };
checker context.resolve_call_path(func).map_or(false, |call_path| {
.ctx call_path.as_slice() == ["typing", "TypeVar"]
.resolve_call_path(func) || call_path.as_slice() == ["typing", "NewType"]
.map_or(false, |call_path| { })
call_path.as_slice() == ["typing", "TypeVar"]
|| call_path.as_slice() == ["typing", "NewType"]
})
} }
pub fn is_typeddict(checker: &Checker, bases: &[Expr]) -> bool { pub(crate) fn is_typed_dict_class(context: &Context, bases: &[Expr]) -> bool {
bases bases
.iter() .iter()
.any(|base| checker.ctx.match_typing_expr(base, "TypedDict")) .any(|base| context.match_typing_expr(base, "TypedDict"))
} }
#[cfg(test)] #[cfg(test)]

View File

@ -38,8 +38,8 @@ pub fn mixed_case_variable_in_class_scope(
return; return;
} }
if helpers::is_mixed_case(name) if helpers::is_mixed_case(name)
&& !helpers::is_namedtuple_assignment(checker, stmt) && !helpers::is_named_tuple_assignment(&checker.ctx, stmt)
&& !helpers::is_typeddict(checker, bases) && !helpers::is_typed_dict_class(&checker.ctx, bases)
{ {
checker.diagnostics.push(Diagnostic::new( checker.diagnostics.push(Diagnostic::new(
MixedCaseVariableInClassScope { MixedCaseVariableInClassScope {

View File

@ -36,7 +36,7 @@ pub fn mixed_case_variable_in_global_scope(
{ {
return; return;
} }
if helpers::is_mixed_case(name) && !helpers::is_namedtuple_assignment(checker, stmt) { if helpers::is_mixed_case(name) && !helpers::is_named_tuple_assignment(&checker.ctx, stmt) {
checker.diagnostics.push(Diagnostic::new( checker.diagnostics.push(Diagnostic::new(
MixedCaseVariableInGlobalScope { MixedCaseVariableInGlobalScope {
name: name.to_string(), name: name.to_string(),

View File

@ -67,9 +67,9 @@ pub fn non_lowercase_variable_in_function(
} }
if name.to_lowercase() != name if name.to_lowercase() != name
&& !helpers::is_namedtuple_assignment(checker, stmt) && !helpers::is_named_tuple_assignment(&checker.ctx, stmt)
&& !helpers::is_typeddict_assignment(checker, stmt) && !helpers::is_typed_dict_assignment(&checker.ctx, stmt)
&& !helpers::is_type_var_assignment(checker, stmt) && !helpers::is_type_var_assignment(&checker.ctx, stmt)
{ {
checker.diagnostics.push(Diagnostic::new( checker.diagnostics.push(Diagnostic::new(
NonLowercaseVariableInFunction { NonLowercaseVariableInFunction {