mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-01 14:21:24 +00:00
Avoid mutable-class-default
violations for Pydantic subclasses (#9187)
Only applies to subclasses defined within the same file, as elsewhere. See: https://github.com/astral-sh/ruff/issues/5243#issuecomment-1860776975.
This commit is contained in:
parent
c532089fb3
commit
0bf7683a3f
2 changed files with 17 additions and 16 deletions
|
@ -59,3 +59,11 @@ class F(BaseSettings):
|
||||||
without_annotation = []
|
without_annotation = []
|
||||||
class_variable: ClassVar[list[int]] = []
|
class_variable: ClassVar[list[int]] = []
|
||||||
final_variable: Final[list[int]] = []
|
final_variable: Final[list[int]] = []
|
||||||
|
|
||||||
|
|
||||||
|
class G(F):
|
||||||
|
mutable_default: list[int] = []
|
||||||
|
immutable_annotation: Sequence[int] = []
|
||||||
|
without_annotation = []
|
||||||
|
class_variable: ClassVar[list[int]] = []
|
||||||
|
final_variable: Final[list[int]] = []
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use ruff_python_ast::{self as ast, Arguments, Expr};
|
|
||||||
|
|
||||||
use ruff_python_ast::helpers::{map_callable, map_subscript};
|
use ruff_python_ast::helpers::{map_callable, map_subscript};
|
||||||
use ruff_python_semantic::{BindingKind, SemanticModel};
|
use ruff_python_ast::{self as ast, Expr};
|
||||||
|
use ruff_python_semantic::{analyze, BindingKind, SemanticModel};
|
||||||
|
|
||||||
/// Return `true` if the given [`Expr`] is a special class attribute, like `__slots__`.
|
/// Return `true` if the given [`Expr`] is a special class attribute, like `__slots__`.
|
||||||
///
|
///
|
||||||
|
@ -57,19 +56,13 @@ pub(super) fn has_default_copy_semantics(
|
||||||
class_def: &ast::StmtClassDef,
|
class_def: &ast::StmtClassDef,
|
||||||
semantic: &SemanticModel,
|
semantic: &SemanticModel,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let Some(Arguments { args: bases, .. }) = class_def.arguments.as_deref() else {
|
analyze::class::any_over_body(class_def, semantic, &|call_path| {
|
||||||
return false;
|
matches!(
|
||||||
};
|
call_path.as_slice(),
|
||||||
|
["pydantic", "BaseModel" | "BaseSettings"]
|
||||||
bases.iter().any(|expr| {
|
| ["pydantic_settings", "BaseSettings"]
|
||||||
semantic.resolve_call_path(expr).is_some_and(|call_path| {
|
| ["msgspec", "Struct"]
|
||||||
matches!(
|
)
|
||||||
call_path.as_slice(),
|
|
||||||
["pydantic", "BaseModel" | "BaseSettings"]
|
|
||||||
| ["pydantic_settings", "BaseSettings"]
|
|
||||||
| ["msgspec", "Struct"]
|
|
||||||
)
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue