Skip to content

Commit 9457352

Browse files
authored
Fix type of self argument for model serializer's to_json method (#461)
1 parent fe4601a commit 9457352

File tree

3 files changed

+101
-5
lines changed

3 files changed

+101
-5
lines changed

src/serializers/type_serializers/model.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,17 @@ impl TypeSerializer for ModelSerializer {
9898
exclude: Option<&PyAny>,
9999
extra: &Extra,
100100
) -> Result<S::Ok, S::Error> {
101-
if self.allow_value(value, extra).map_err(py_err_se_err)? {
102-
let dict = object_to_dict(value, true, extra).map_err(py_err_se_err)?;
101+
let extra = Extra {
102+
model: Some(value),
103+
..*extra
104+
};
105+
if self.allow_value(value, &extra).map_err(py_err_se_err)? {
106+
let dict = object_to_dict(value, true, &extra).map_err(py_err_se_err)?;
103107
self.serializer
104-
.serde_serialize(dict, serializer, include, exclude, extra)
108+
.serde_serialize(dict, serializer, include, exclude, &extra)
105109
} else {
106-
extra.warnings.on_fallback_ser::<S>(self.get_name(), value, extra)?;
107-
infer_serialize(value, serializer, include, exclude, extra)
110+
extra.warnings.on_fallback_ser::<S>(self.get_name(), value, &extra)?;
111+
infer_serialize(value, serializer, include, exclude, &extra)
108112
}
109113
}
110114

tests/serializers/test_model.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,7 @@ class Model:
403403
x: int
404404

405405
def ser_x(self, v: Any, _) -> str:
406+
assert self.x == 1_000
406407
return f'{v:_}'
407408

408409
s = SchemaSerializer(
@@ -427,6 +428,7 @@ class Model:
427428

428429
def ser_x(self, v: Any, serializer: core_schema.SerializeWrapHandler, _) -> str:
429430
x = serializer(v)
431+
assert self.x == 1_000
430432
return f'{x:_}'
431433

432434
s = SchemaSerializer(
@@ -454,6 +456,7 @@ class Model:
454456
x: int
455457

456458
def ser_x(self, v: Any, _) -> str:
459+
assert self.x == 1_000
457460
return f'{v:_}'
458461

459462
s = SchemaSerializer(
@@ -477,6 +480,7 @@ class Model:
477480
x: int
478481

479482
def ser_x(self, v: Any, serializer: core_schema.SerializeWrapHandler, _) -> str:
483+
assert self.x == 1_000
480484
x = serializer(v)
481485
return f'{x:_}'
482486

tests/serializers/test_typed_dict.py

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import json
2+
from typing import Any
23

34
import pytest
45
from dirty_equals import IsStrictDict
6+
from typing_extensions import TypedDict
57

68
from pydantic_core import SchemaSerializer, core_schema
79

@@ -159,3 +161,89 @@ def test_exclude_default():
159161

160162
assert v.to_json({'foo': 1, 'bar': b'[default]'}) == b'{"foo":1,"bar":"[default]"}'
161163
assert v.to_json({'foo': 1, 'bar': b'[default]'}, exclude_defaults=True) == b'{"foo":1}'
164+
165+
166+
def test_function_plain_field_serializer_to_python():
167+
class Model(TypedDict):
168+
x: int
169+
170+
def ser_x(data: Model, v: Any, _) -> str:
171+
assert data['x'] == 1_000
172+
return f'{v:_}'
173+
174+
s = SchemaSerializer(
175+
core_schema.typed_dict_schema(
176+
{
177+
'x': core_schema.typed_dict_field(
178+
core_schema.int_schema(serialization=core_schema.field_function_plain_ser_schema(ser_x))
179+
)
180+
}
181+
)
182+
)
183+
assert s.to_python(Model(x=1000)) == {'x': '1_000'}
184+
185+
186+
def test_function_wrap_field_serializer_to_python():
187+
class Model(TypedDict):
188+
x: int
189+
190+
def ser_x(data: Model, v: Any, serializer: core_schema.SerializeWrapHandler, _) -> str:
191+
x = serializer(v)
192+
assert data['x'] == 1_000
193+
return f'{x:_}'
194+
195+
s = SchemaSerializer(
196+
core_schema.typed_dict_schema(
197+
{
198+
'x': core_schema.typed_dict_field(
199+
core_schema.int_schema(
200+
serialization=core_schema.field_function_wrap_ser_schema(ser_x, schema=core_schema.any_schema())
201+
)
202+
)
203+
}
204+
)
205+
)
206+
assert s.to_python(Model(x=1000)) == {'x': '1_000'}
207+
208+
209+
def test_function_plain_field_serializer_to_json():
210+
class Model(TypedDict):
211+
x: int
212+
213+
def ser_x(data: Model, v: Any, _) -> str:
214+
assert data['x'] == 1_000
215+
return f'{v:_}'
216+
217+
s = SchemaSerializer(
218+
core_schema.typed_dict_schema(
219+
{
220+
'x': core_schema.typed_dict_field(
221+
core_schema.int_schema(serialization=core_schema.field_function_plain_ser_schema(ser_x))
222+
)
223+
}
224+
)
225+
)
226+
assert json.loads(s.to_json(Model(x=1000))) == {'x': '1_000'}
227+
228+
229+
def test_function_wrap_field_serializer_to_json():
230+
class Model(TypedDict):
231+
x: int
232+
233+
def ser_x(data: Model, v: Any, serializer: core_schema.SerializeWrapHandler, _) -> str:
234+
assert data['x'] == 1_000
235+
x = serializer(v)
236+
return f'{x:_}'
237+
238+
s = SchemaSerializer(
239+
core_schema.typed_dict_schema(
240+
{
241+
'x': core_schema.typed_dict_field(
242+
core_schema.int_schema(
243+
serialization=core_schema.field_function_wrap_ser_schema(ser_x, schema=core_schema.any_schema())
244+
)
245+
)
246+
}
247+
)
248+
)
249+
assert json.loads(s.to_json(Model(x=1000))) == {'x': '1_000'}

0 commit comments

Comments
 (0)