Skip to content

Commit e285d06

Browse files
hramezaniadriangb
authored andcommitted
Add slots to dataclass schema
1 parent 4dbc875 commit e285d06

File tree

3 files changed

+13
-2
lines changed

3 files changed

+13
-2
lines changed

pydantic_core/core_schema.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3101,6 +3101,7 @@ class DataclassSchema(TypedDict, total=False):
31013101
ref: str
31023102
metadata: Any
31033103
serialization: SerSchema
3104+
slots: bool
31043105

31053106

31063107
def dataclass_schema(
@@ -3115,6 +3116,7 @@ def dataclass_schema(
31153116
metadata: Any = None,
31163117
serialization: SerSchema | None = None,
31173118
frozen: bool | None = None,
3119+
slots: bool = False,
31183120
) -> DataclassSchema:
31193121
"""
31203122
Returns a schema for a dataclass. As with `ModelSchema`, this schema can only be used as a field within
@@ -3145,6 +3147,7 @@ def dataclass_schema(
31453147
metadata=metadata,
31463148
serialization=serialization,
31473149
frozen=frozen,
3150+
slots=slots,
31483151
)
31493152

31503153

src/validators/dataclass.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,7 @@ pub struct DataclassValidator {
415415
revalidate: Revalidate,
416416
name: String,
417417
frozen: bool,
418+
slots: bool,
418419
}
419420

420421
impl BuildValidator for DataclassValidator {
@@ -453,6 +454,7 @@ impl BuildValidator for DataclassValidator {
453454
)?)?,
454455
name,
455456
frozen: schema.get_as(intern!(py, "frozen"))?.unwrap_or(false),
457+
slots: schema.get_as(intern!(py, "slots"))?.unwrap_or(false),
456458
}
457459
.into())
458460
}
@@ -595,7 +597,13 @@ impl DataclassValidator {
595597
input: &'data impl Input<'data>,
596598
) -> ValResult<'data, ()> {
597599
let (dc_dict, post_init_kwargs): (&PyAny, &PyAny) = val_output.extract(py)?;
598-
force_setattr(py, dc, intern!(py, "__dict__"), dc_dict)?;
600+
if self.slots {
601+
for (key, value) in dc_dict.downcast::<PyDict>()?.iter() {
602+
force_setattr(py, dc, key, value)?;
603+
}
604+
} else {
605+
force_setattr(py, dc, intern!(py, "__dict__"), dc_dict)?;
606+
}
599607

600608
if let Some(ref post_init) = self.post_init {
601609
let post_init = post_init.as_ref(py);

tests/test_schema_functions.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ def args(*args, **kwargs):
250250
core_schema.dataclass_schema,
251251
# MyModel should be a dataclass, but I'm being lazy here
252252
args(MyModel, {'type': 'int'}),
253-
{'type': 'dataclass', 'schema': {'type': 'int'}, 'cls': MyModel},
253+
{'type': 'dataclass', 'schema': {'type': 'int'}, 'cls': MyModel, 'slots': False},
254254
),
255255
]
256256

0 commit comments

Comments
 (0)