From 32f08561bba5ac2f01b621be4ed519d880ce3591 Mon Sep 17 00:00:00 2001 From: Jonathan Plasse <13716151+JonathanPlasse@users.noreply.github.com> Date: Sat, 22 Apr 2023 17:39:36 +0200 Subject: [PATCH 1/2] Ignore N815 for TypedDict --- .../ruff/resources/test/fixtures/pep8_naming/N815.py | 8 ++++++++ crates/ruff/src/checkers/ast/mod.rs | 10 ++++++++-- .../rules/mixed_case_variable_in_class_scope.rs | 11 ++++++++++- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/crates/ruff/resources/test/fixtures/pep8_naming/N815.py b/crates/ruff/resources/test/fixtures/pep8_naming/N815.py index db767423d2eb8..d3578d3cfbd7d 100644 --- a/crates/ruff/resources/test/fixtures/pep8_naming/N815.py +++ b/crates/ruff/resources/test/fixtures/pep8_naming/N815.py @@ -13,3 +13,11 @@ class C: myObj2 = namedtuple("MyObj2", ["a", "b"]) Employee = NamedTuple('Employee', [('name', str), ('id', int)]) Point2D = TypedDict('Point2D', {'in': int, 'x-y': int}) + + +class D(TypedDict): + lower: int + CONSTANT: str + mixedCase: bool + _mixedCase: list + mixed_Case: set diff --git a/crates/ruff/src/checkers/ast/mod.rs b/crates/ruff/src/checkers/ast/mod.rs index b2800250ec64e..bb4b6119f7b2e 100644 --- a/crates/ruff/src/checkers/ast/mod.rs +++ b/crates/ruff/src/checkers/ast/mod.rs @@ -4456,8 +4456,14 @@ impl<'a> Checker<'a> { .rules .enabled(Rule::MixedCaseVariableInClassScope) { - if matches!(self.ctx.scope().kind, ScopeKind::Class(..)) { - pep8_naming::rules::mixed_case_variable_in_class_scope(self, expr, parent, id); + if let ScopeKind::Class(class) = &self.ctx.scope().kind { + pep8_naming::rules::mixed_case_variable_in_class_scope( + self, + expr, + parent, + id, + class.bases, + ); } } diff --git a/crates/ruff/src/rules/pep8_naming/rules/mixed_case_variable_in_class_scope.rs b/crates/ruff/src/rules/pep8_naming/rules/mixed_case_variable_in_class_scope.rs index 68534cf6c43d1..b440d8779bbf5 100644 --- a/crates/ruff/src/rules/pep8_naming/rules/mixed_case_variable_in_class_scope.rs +++ b/crates/ruff/src/rules/pep8_naming/rules/mixed_case_variable_in_class_scope.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, Stmt}; +use rustpython_parser::ast::{Expr, ExprKind, Stmt}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -26,6 +26,7 @@ pub fn mixed_case_variable_in_class_scope( expr: &Expr, stmt: &Stmt, name: &str, + bases: &[Expr], ) { if checker .settings @@ -36,6 +37,14 @@ pub fn mixed_case_variable_in_class_scope( { return; } + if bases.iter().any(|base| { + if let ExprKind::Name { id, .. } = &base.node { + return id == "TypedDict"; + } + false + }) { + return; + } if helpers::is_mixed_case(name) && !helpers::is_namedtuple_assignment(checker, stmt) { checker.diagnostics.push(Diagnostic::new( MixedCaseVariableInClassScope { From c8a5aba59d911fc5715ed12c25f27cf1b041f258 Mon Sep 17 00:00:00 2001 From: Jonathan Plasse <13716151+JonathanPlasse@users.noreply.github.com> Date: Sat, 22 Apr 2023 18:55:09 +0200 Subject: [PATCH 2/2] Move is_typeddict() in a helper --- crates/ruff/src/rules/pep8_naming/helpers.rs | 8 +++++++- .../rules/mixed_case_variable_in_class_scope.rs | 15 +++++---------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/crates/ruff/src/rules/pep8_naming/helpers.rs b/crates/ruff/src/rules/pep8_naming/helpers.rs index 85133ac6fdadc..4e64ec65a804f 100644 --- a/crates/ruff/src/rules/pep8_naming/helpers.rs +++ b/crates/ruff/src/rules/pep8_naming/helpers.rs @@ -1,5 +1,5 @@ use itertools::Itertools; -use rustpython_parser::ast::{ExprKind, Stmt, StmtKind}; +use rustpython_parser::ast::{Expr, ExprKind, Stmt, StmtKind}; use ruff_python_stdlib::str::{is_lower, is_upper}; @@ -70,6 +70,12 @@ pub fn is_type_var_assignment(checker: &Checker, stmt: &Stmt) -> bool { }) } +pub fn is_typeddict(checker: &Checker, bases: &[Expr]) -> bool { + bases + .iter() + .any(|base| checker.ctx.match_typing_expr(base, "TypedDict")) +} + #[cfg(test)] mod tests { use super::{is_acronym, is_camelcase, is_mixed_case}; diff --git a/crates/ruff/src/rules/pep8_naming/rules/mixed_case_variable_in_class_scope.rs b/crates/ruff/src/rules/pep8_naming/rules/mixed_case_variable_in_class_scope.rs index b440d8779bbf5..eaac8576d46df 100644 --- a/crates/ruff/src/rules/pep8_naming/rules/mixed_case_variable_in_class_scope.rs +++ b/crates/ruff/src/rules/pep8_naming/rules/mixed_case_variable_in_class_scope.rs @@ -1,4 +1,4 @@ -use rustpython_parser::ast::{Expr, ExprKind, Stmt}; +use rustpython_parser::ast::{Expr, Stmt}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -37,15 +37,10 @@ pub fn mixed_case_variable_in_class_scope( { return; } - if bases.iter().any(|base| { - if let ExprKind::Name { id, .. } = &base.node { - return id == "TypedDict"; - } - false - }) { - return; - } - if helpers::is_mixed_case(name) && !helpers::is_namedtuple_assignment(checker, stmt) { + if helpers::is_mixed_case(name) + && !helpers::is_namedtuple_assignment(checker, stmt) + && !helpers::is_typeddict(checker, bases) + { checker.diagnostics.push(Diagnostic::new( MixedCaseVariableInClassScope { name: name.to_string(),