mirror of https://github.com/astral-sh/ruff
Recursively resolve `TypeDicts` for N815 violations (#10719)
## Summary Only works within a single file for now. Closes https://github.com/astral-sh/ruff/issues/10671.
This commit is contained in:
parent
200ebeebdc
commit
67f0f615b2
|
|
@ -21,3 +21,10 @@ class D(TypedDict):
|
||||||
mixedCase: bool
|
mixedCase: bool
|
||||||
_mixedCase: list
|
_mixedCase: list
|
||||||
mixed_Case: set
|
mixed_Case: set
|
||||||
|
|
||||||
|
class E(D):
|
||||||
|
lower: int
|
||||||
|
CONSTANT: str
|
||||||
|
mixedCase: bool
|
||||||
|
_mixedCase: list
|
||||||
|
mixed_Case: set
|
||||||
|
|
|
||||||
|
|
@ -223,14 +223,10 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if checker.enabled(Rule::MixedCaseVariableInClassScope) {
|
if checker.enabled(Rule::MixedCaseVariableInClassScope) {
|
||||||
if let ScopeKind::Class(ast::StmtClassDef { arguments, .. }) =
|
if let ScopeKind::Class(class_def) = &checker.semantic.current_scope().kind
|
||||||
&checker.semantic.current_scope().kind
|
|
||||||
{
|
{
|
||||||
pep8_naming::rules::mixed_case_variable_in_class_scope(
|
pep8_naming::rules::mixed_case_variable_in_class_scope(
|
||||||
checker,
|
checker, expr, id, class_def,
|
||||||
expr,
|
|
||||||
id,
|
|
||||||
arguments.as_deref(),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
use ruff_python_ast::name::UnqualifiedName;
|
use ruff_python_ast::name::UnqualifiedName;
|
||||||
use ruff_python_ast::{self as ast, Arguments, Expr, Stmt};
|
use ruff_python_ast::{self as ast, Expr, Stmt};
|
||||||
use ruff_python_semantic::SemanticModel;
|
use ruff_python_semantic::{analyze, SemanticModel};
|
||||||
use ruff_python_stdlib::str::{is_cased_lowercase, is_cased_uppercase};
|
use ruff_python_stdlib::str::{is_cased_lowercase, is_cased_uppercase};
|
||||||
|
|
||||||
pub(super) fn is_camelcase(name: &str) -> bool {
|
pub(super) fn is_camelcase(name: &str) -> bool {
|
||||||
|
|
@ -86,16 +86,13 @@ pub(super) fn is_type_alias_assignment(stmt: &Stmt, semantic: &SemanticModel) ->
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if the statement is an assignment to a `TypedDict`.
|
/// Returns `true` if the statement is an assignment to a `TypedDict`.
|
||||||
pub(super) fn is_typed_dict_class(arguments: Option<&Arguments>, semantic: &SemanticModel) -> bool {
|
pub(super) fn is_typed_dict_class(class_def: &ast::StmtClassDef, semantic: &SemanticModel) -> bool {
|
||||||
if !semantic.seen_typing() {
|
if !semantic.seen_typing() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
arguments.is_some_and(|arguments| {
|
analyze::class::any_qualified_name(class_def, semantic, &|qualified_name| {
|
||||||
arguments
|
semantic.match_typing_qualified_name(&qualified_name, "TypedDict")
|
||||||
.args
|
|
||||||
.iter()
|
|
||||||
.any(|base| semantic.match_typing_expr(base, "TypedDict"))
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
use ruff_python_ast::{Arguments, Expr};
|
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
use ruff_python_ast::{self as ast, Expr};
|
||||||
use ruff_text_size::Ranged;
|
use ruff_text_size::Ranged;
|
||||||
|
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
|
|
@ -55,7 +54,7 @@ pub(crate) fn mixed_case_variable_in_class_scope(
|
||||||
checker: &mut Checker,
|
checker: &mut Checker,
|
||||||
expr: &Expr,
|
expr: &Expr,
|
||||||
name: &str,
|
name: &str,
|
||||||
arguments: Option<&Arguments>,
|
class_def: &ast::StmtClassDef,
|
||||||
) {
|
) {
|
||||||
if !helpers::is_mixed_case(name) {
|
if !helpers::is_mixed_case(name) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -64,7 +63,7 @@ pub(crate) fn mixed_case_variable_in_class_scope(
|
||||||
let parent = checker.semantic().current_statement();
|
let parent = checker.semantic().current_statement();
|
||||||
|
|
||||||
if helpers::is_named_tuple_assignment(parent, checker.semantic())
|
if helpers::is_named_tuple_assignment(parent, checker.semantic())
|
||||||
|| helpers::is_typed_dict_class(arguments, checker.semantic())
|
|| helpers::is_typed_dict_class(class_def, checker.semantic())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue