Skip to content

Commit

Permalink
Fix: dataclass InitVars shouldn't be required on serialization (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
sydney-runkle authored Jan 23, 2025
1 parent 82b7aa7 commit 261c7ab
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 9 deletions.
20 changes: 11 additions & 9 deletions src/serializers/type_serializers/dataclass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,17 @@ impl BuildSerializer for DataclassArgsBuilder {

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

if field_info.get_as(intern!(py, "serialization_exclude"))? == Some(true) {
fields.insert(name, SerField::new(py, key_py, None, None, true));
} else {
let schema = field_info.get_as_req(intern!(py, "schema"))?;
let serializer = CombinedSerializer::build(&schema, config, definitions)
.map_err(|e| py_schema_error_type!("Field `{}`:\n {}", index, e))?;

let alias = field_info.get_as(intern!(py, "serialization_alias"))?;
fields.insert(name, SerField::new(py, key_py, alias, Some(serializer), true));
if !field_info.get_as(intern!(py, "init_only"))?.unwrap_or(false) {
if field_info.get_as(intern!(py, "serialization_exclude"))? == Some(true) {
fields.insert(name, SerField::new(py, key_py, None, None, true));
} else {
let schema = field_info.get_as_req(intern!(py, "schema"))?;
let serializer = CombinedSerializer::build(&schema, config, definitions)
.map_err(|e| py_schema_error_type!("Field `{}`:\n {}", index, e))?;

let alias = field_info.get_as(intern!(py, "serialization_alias"))?;
fields.insert(name, SerField::new(py, key_py, alias, Some(serializer), true));
}
}
}

Expand Down
43 changes: 43 additions & 0 deletions tests/serializers/test_dataclasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,3 +192,46 @@ class Model:
m = v.validate_python({'extra': 'extra'})

assert s.to_python(m) == {'extra': 'extra bam!'}


def test_dataclass_initvar_not_required_on_union_ser() -> None:
@dataclasses.dataclass
class Foo:
x: int
init_var: dataclasses.InitVar[int] = 1

@dataclasses.dataclass
class Bar:
x: int

schema = core_schema.union_schema(
[
core_schema.dataclass_schema(
Foo,
core_schema.dataclass_args_schema(
'Foo',
[
core_schema.dataclass_field(name='x', schema=core_schema.int_schema()),
core_schema.dataclass_field(
name='init_var',
init_only=True,
schema=core_schema.with_default_schema(core_schema.int_schema(), default=1),
),
],
),
['x'],
post_init=True,
),
core_schema.dataclass_schema(
Bar,
core_schema.dataclass_args_schema(
'Bar', [core_schema.dataclass_field(name='x', schema=core_schema.int_schema())]
),
['x'],
),
]
)

s = SchemaSerializer(schema)
assert s.to_python(Foo(x=1), warnings='error') == {'x': 1}
assert s.to_python(Foo(x=1, init_var=2), warnings='error') == {'x': 1}

0 comments on commit 261c7ab

Please sign in to comment.