Skip to content

Commit 261c7ab

Browse files
Fix: dataclass InitVars shouldn't be required on serialization (#1602)
1 parent 82b7aa7 commit 261c7ab

File tree

2 files changed

+54
-9
lines changed

2 files changed

+54
-9
lines changed

src/serializers/type_serializers/dataclass.rs

+11-9
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,17 @@ impl BuildSerializer for DataclassArgsBuilder {
4343

4444
let key_py: Py<PyString> = PyString::new(py, &name).into();
4545

46-
if field_info.get_as(intern!(py, "serialization_exclude"))? == Some(true) {
47-
fields.insert(name, SerField::new(py, key_py, None, None, true));
48-
} else {
49-
let schema = field_info.get_as_req(intern!(py, "schema"))?;
50-
let serializer = CombinedSerializer::build(&schema, config, definitions)
51-
.map_err(|e| py_schema_error_type!("Field `{}`:\n {}", index, e))?;
52-
53-
let alias = field_info.get_as(intern!(py, "serialization_alias"))?;
54-
fields.insert(name, SerField::new(py, key_py, alias, Some(serializer), true));
46+
if !field_info.get_as(intern!(py, "init_only"))?.unwrap_or(false) {
47+
if field_info.get_as(intern!(py, "serialization_exclude"))? == Some(true) {
48+
fields.insert(name, SerField::new(py, key_py, None, None, true));
49+
} else {
50+
let schema = field_info.get_as_req(intern!(py, "schema"))?;
51+
let serializer = CombinedSerializer::build(&schema, config, definitions)
52+
.map_err(|e| py_schema_error_type!("Field `{}`:\n {}", index, e))?;
53+
54+
let alias = field_info.get_as(intern!(py, "serialization_alias"))?;
55+
fields.insert(name, SerField::new(py, key_py, alias, Some(serializer), true));
56+
}
5557
}
5658
}
5759

tests/serializers/test_dataclasses.py

+43
Original file line numberDiff line numberDiff line change
@@ -192,3 +192,46 @@ class Model:
192192
m = v.validate_python({'extra': 'extra'})
193193

194194
assert s.to_python(m) == {'extra': 'extra bam!'}
195+
196+
197+
def test_dataclass_initvar_not_required_on_union_ser() -> None:
198+
@dataclasses.dataclass
199+
class Foo:
200+
x: int
201+
init_var: dataclasses.InitVar[int] = 1
202+
203+
@dataclasses.dataclass
204+
class Bar:
205+
x: int
206+
207+
schema = core_schema.union_schema(
208+
[
209+
core_schema.dataclass_schema(
210+
Foo,
211+
core_schema.dataclass_args_schema(
212+
'Foo',
213+
[
214+
core_schema.dataclass_field(name='x', schema=core_schema.int_schema()),
215+
core_schema.dataclass_field(
216+
name='init_var',
217+
init_only=True,
218+
schema=core_schema.with_default_schema(core_schema.int_schema(), default=1),
219+
),
220+
],
221+
),
222+
['x'],
223+
post_init=True,
224+
),
225+
core_schema.dataclass_schema(
226+
Bar,
227+
core_schema.dataclass_args_schema(
228+
'Bar', [core_schema.dataclass_field(name='x', schema=core_schema.int_schema())]
229+
),
230+
['x'],
231+
),
232+
]
233+
)
234+
235+
s = SchemaSerializer(schema)
236+
assert s.to_python(Foo(x=1), warnings='error') == {'x': 1}
237+
assert s.to_python(Foo(x=1, init_var=2), warnings='error') == {'x': 1}

0 commit comments

Comments
 (0)