[ty] Dataclass transform: complete set of parameters (#21474)
## Summary
We previously only allowed models to overwrite the
`{eq,order,kw_only,frozen}_defaults` of the dataclass-transformer, but
all other standard-dataclass parameters should be equally supported with
the same behavior.
## Test Plan
Added regression tests.
This commit is contained in:
@@ -622,6 +622,19 @@ bitflags! {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) const DATACLASS_FLAGS: &[(&str, DataclassFlags)] = &[
|
||||
("init", DataclassFlags::INIT),
|
||||
("repr", DataclassFlags::REPR),
|
||||
("eq", DataclassFlags::EQ),
|
||||
("order", DataclassFlags::ORDER),
|
||||
("unsafe_hash", DataclassFlags::UNSAFE_HASH),
|
||||
("frozen", DataclassFlags::FROZEN),
|
||||
("match_args", DataclassFlags::MATCH_ARGS),
|
||||
("kw_only", DataclassFlags::KW_ONLY),
|
||||
("slots", DataclassFlags::SLOTS),
|
||||
("weakref_slot", DataclassFlags::WEAKREF_SLOT),
|
||||
];
|
||||
|
||||
impl get_size2::GetSize for DataclassFlags {}
|
||||
|
||||
impl Default for DataclassFlags {
|
||||
|
||||
@@ -35,11 +35,11 @@ use crate::types::generics::{
|
||||
use crate::types::signatures::{Parameter, ParameterForm, ParameterKind, Parameters};
|
||||
use crate::types::tuple::{TupleLength, TupleType};
|
||||
use crate::types::{
|
||||
BoundMethodType, BoundTypeVarIdentity, ClassLiteral, DataclassFlags, DataclassParams,
|
||||
FieldInstance, KnownBoundMethodType, KnownClass, KnownInstanceType, MemberLookupPolicy,
|
||||
NominalInstanceType, PropertyInstanceType, SpecialFormType, TrackedConstraintSet,
|
||||
TypeAliasType, TypeContext, TypeVarVariance, UnionBuilder, UnionType, WrapperDescriptorKind,
|
||||
enums, ide_support, infer_isolated_expression, todo_type,
|
||||
BoundMethodType, BoundTypeVarIdentity, ClassLiteral, DATACLASS_FLAGS, DataclassFlags,
|
||||
DataclassParams, FieldInstance, KnownBoundMethodType, KnownClass, KnownInstanceType,
|
||||
MemberLookupPolicy, NominalInstanceType, PropertyInstanceType, SpecialFormType,
|
||||
TrackedConstraintSet, TypeAliasType, TypeContext, TypeVarVariance, UnionBuilder, UnionType,
|
||||
WrapperDescriptorKind, enums, ide_support, infer_isolated_expression, todo_type,
|
||||
};
|
||||
use ruff_db::diagnostic::{Annotation, Diagnostic, SubDiagnostic, SubDiagnosticSeverity};
|
||||
use ruff_python_ast::{self as ast, ArgOrKeyword, PythonVersion};
|
||||
@@ -1134,28 +1134,12 @@ impl<'db> Bindings<'db> {
|
||||
);
|
||||
let mut flags = dataclass_params.flags(db);
|
||||
|
||||
if let Ok(Some(Type::BooleanLiteral(order))) =
|
||||
overload.parameter_type_by_name("order", false)
|
||||
{
|
||||
flags.set(DataclassFlags::ORDER, order);
|
||||
}
|
||||
|
||||
if let Ok(Some(Type::BooleanLiteral(eq))) =
|
||||
overload.parameter_type_by_name("eq", false)
|
||||
{
|
||||
flags.set(DataclassFlags::EQ, eq);
|
||||
}
|
||||
|
||||
if let Ok(Some(Type::BooleanLiteral(kw_only))) =
|
||||
overload.parameter_type_by_name("kw_only", false)
|
||||
{
|
||||
flags.set(DataclassFlags::KW_ONLY, kw_only);
|
||||
}
|
||||
|
||||
if let Ok(Some(Type::BooleanLiteral(frozen))) =
|
||||
overload.parameter_type_by_name("frozen", false)
|
||||
{
|
||||
flags.set(DataclassFlags::FROZEN, frozen);
|
||||
for (param, flag) in DATACLASS_FLAGS {
|
||||
if let Ok(Some(Type::BooleanLiteral(value))) =
|
||||
overload.parameter_type_by_name(param, false)
|
||||
{
|
||||
flags.set(*flag, value);
|
||||
}
|
||||
}
|
||||
|
||||
Type::DataclassDecorator(DataclassParams::new(
|
||||
|
||||
@@ -32,13 +32,13 @@ use crate::types::tuple::{TupleSpec, TupleType};
|
||||
use crate::types::typed_dict::typed_dict_params_from_class_def;
|
||||
use crate::types::visitor::{TypeCollector, TypeVisitor, walk_type_with_recursion_guard};
|
||||
use crate::types::{
|
||||
ApplyTypeMappingVisitor, Binding, BoundSuperType, CallableType, DataclassFlags,
|
||||
DataclassParams, DeprecatedInstance, FindLegacyTypeVarsVisitor, HasRelationToVisitor,
|
||||
IsDisjointVisitor, IsEquivalentVisitor, KnownInstanceType, ManualPEP695TypeAliasType,
|
||||
MaterializationKind, NormalizedVisitor, PropertyInstanceType, StringLiteralType, TypeAliasType,
|
||||
TypeContext, TypeMapping, TypeRelation, TypedDictParams, UnionBuilder, VarianceInferable,
|
||||
declaration_type, determine_upper_bound, exceeds_max_specialization_depth,
|
||||
infer_definition_types,
|
||||
ApplyTypeMappingVisitor, Binding, BoundSuperType, CallableType, DATACLASS_FLAGS,
|
||||
DataclassFlags, DataclassParams, DeprecatedInstance, FindLegacyTypeVarsVisitor,
|
||||
HasRelationToVisitor, IsDisjointVisitor, IsEquivalentVisitor, KnownInstanceType,
|
||||
ManualPEP695TypeAliasType, MaterializationKind, NormalizedVisitor, PropertyInstanceType,
|
||||
StringLiteralType, TypeAliasType, TypeContext, TypeMapping, TypeRelation, TypedDictParams,
|
||||
UnionBuilder, VarianceInferable, declaration_type, determine_upper_bound,
|
||||
exceeds_max_specialization_depth, infer_definition_types,
|
||||
};
|
||||
use crate::{
|
||||
Db, FxIndexMap, FxIndexSet, FxOrderSet, Program,
|
||||
@@ -2229,12 +2229,10 @@ impl<'db> ClassLiteral<'db> {
|
||||
if let Some(is_set) =
|
||||
keyword.value.as_boolean_literal_expr().map(|b| b.value)
|
||||
{
|
||||
match arg_name.as_str() {
|
||||
"eq" => flags.set(DataclassFlags::EQ, is_set),
|
||||
"order" => flags.set(DataclassFlags::ORDER, is_set),
|
||||
"kw_only" => flags.set(DataclassFlags::KW_ONLY, is_set),
|
||||
"frozen" => flags.set(DataclassFlags::FROZEN, is_set),
|
||||
_ => {}
|
||||
for (flag_name, flag) in DATACLASS_FLAGS {
|
||||
if arg_name.as_str() == *flag_name {
|
||||
flags.set(*flag, is_set);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user