mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-04 02:38:25 +00:00
Add base-class inheritance detection to flake8-django rules (#9151)
## Summary As elsewhere, this only applies to classes defined within the same file. Closes https://github.com/astral-sh/ruff/issues/9150.
This commit is contained in:
parent
82731b8194
commit
6ecf844214
11 changed files with 189 additions and 199 deletions
57
crates/ruff_python_semantic/src/analyze/class.rs
Normal file
57
crates/ruff_python_semantic/src/analyze/class.rs
Normal file
|
@ -0,0 +1,57 @@
|
|||
use rustc_hash::FxHashSet;
|
||||
|
||||
use ruff_python_ast as ast;
|
||||
use ruff_python_ast::call_path::CallPath;
|
||||
use ruff_python_ast::helpers::map_subscript;
|
||||
|
||||
use crate::{BindingId, SemanticModel};
|
||||
|
||||
/// Return `true` if any base class of a class definition matches a predicate.
|
||||
pub fn any_over_body(
|
||||
class_def: &ast::StmtClassDef,
|
||||
semantic: &SemanticModel,
|
||||
func: &dyn Fn(CallPath) -> bool,
|
||||
) -> bool {
|
||||
fn inner(
|
||||
class_def: &ast::StmtClassDef,
|
||||
semantic: &SemanticModel,
|
||||
func: &dyn Fn(CallPath) -> bool,
|
||||
seen: &mut FxHashSet<BindingId>,
|
||||
) -> bool {
|
||||
class_def.bases().iter().any(|expr| {
|
||||
// If the base class itself matches the pattern, then this does too.
|
||||
// Ex) `class Foo(BaseModel): ...`
|
||||
if semantic
|
||||
.resolve_call_path(map_subscript(expr))
|
||||
.is_some_and(func)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// If the base class extends a class that matches the pattern, then this does too.
|
||||
// Ex) `class Bar(BaseModel): ...; class Foo(Bar): ...`
|
||||
if let Some(id) = semantic.lookup_attribute(map_subscript(expr)) {
|
||||
if seen.insert(id) {
|
||||
let binding = semantic.binding(id);
|
||||
if let Some(base_class) = binding
|
||||
.kind
|
||||
.as_class_definition()
|
||||
.map(|id| &semantic.scopes[*id])
|
||||
.and_then(|scope| scope.kind.as_class())
|
||||
{
|
||||
if inner(base_class, semantic, func, seen) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
})
|
||||
}
|
||||
|
||||
if class_def.bases().is_empty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
inner(class_def, semantic, func, &mut FxHashSet::default())
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
pub mod class;
|
||||
pub mod function_type;
|
||||
pub mod imports;
|
||||
pub mod logging;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue