Skip to content

Commit 2faf807

Browse files
committed
writing tests, ofc
1 parent 84d43f1 commit 2faf807

File tree

1 file changed

+120
-0
lines changed

1 file changed

+120
-0
lines changed

tests/test_prebuilt.py

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,123 @@ class OuterModel:
4646
result = outer_validator.validate_python({'inner': {'x': 1}})
4747
assert result.inner.x == 1
4848
assert outer_serializer.to_python(result) == {'inner': {'x': 1}}
49+
50+
51+
def test_prebuilt_not_used_for_wrap_serializer_functions() -> None:
52+
class InnerModel:
53+
x: str
54+
55+
def __init__(self, x: str) -> None:
56+
self.x = x
57+
58+
def serialize_inner(v: InnerModel, serializer) -> str:
59+
v.x = v.x + ' modified'
60+
return serializer(v)
61+
62+
inner_schema = core_schema.model_schema(
63+
InnerModel,
64+
schema=core_schema.model_fields_schema(
65+
{'x': core_schema.model_field(schema=core_schema.str_schema())},
66+
),
67+
serialization=core_schema.wrap_serializer_function_ser_schema(serialize_inner),
68+
)
69+
70+
inner_schema_serializer = SchemaSerializer(inner_schema)
71+
InnerModel.__pydantic_complete__ = True # pyright: ignore[reportAttributeAccessIssue]
72+
InnerModel.__pydantic_serializer__ = inner_schema_serializer # pyright: ignore[reportAttributeAccessIssue]
73+
74+
class OuterModel:
75+
inner: InnerModel
76+
77+
def __init__(self, inner: InnerModel) -> None:
78+
self.inner = inner
79+
80+
outer_schema = core_schema.model_schema(
81+
OuterModel,
82+
schema=core_schema.model_fields_schema(
83+
{
84+
'inner': core_schema.model_field(
85+
schema=core_schema.model_schema(
86+
InnerModel,
87+
schema=core_schema.model_fields_schema(
88+
# note, we use a simple str schema (with no custom serialization)
89+
# in order to verify that the prebuilt serializer from InnerModel is not used
90+
{'x': core_schema.model_field(schema=core_schema.str_schema())},
91+
),
92+
)
93+
)
94+
}
95+
),
96+
)
97+
98+
inner_serializer = SchemaSerializer(inner_schema)
99+
outer_serializer = SchemaSerializer(outer_schema)
100+
101+
# the custom serialization function does apply for the inner model
102+
inner_instance = InnerModel(x='hello')
103+
assert inner_serializer.to_python(inner_instance) == {'x': 'hello modified'}
104+
105+
# but the outer model doesn't reuse the custom wrap serializer function, so we see simple str ser
106+
outer_instance = OuterModel(inner=InnerModel(x='hello'))
107+
assert outer_serializer.to_python(outer_instance) == {'inner': {'x': 'hello'}}
108+
109+
110+
def test_prebuilt_not_used_for_wrap_validator_functions() -> None:
111+
class InnerModel:
112+
x: str
113+
114+
def __init__(self, x: str) -> None:
115+
self.x = x
116+
117+
def validate_inner(data, validator) -> str:
118+
data['x'] = data['x'] + ' modified'
119+
return validator(data)
120+
121+
inner_schema = core_schema.no_info_wrap_validator_function(
122+
validate_inner,
123+
core_schema.model_schema(
124+
InnerModel,
125+
schema=core_schema.model_fields_schema(
126+
{'x': core_schema.model_field(schema=core_schema.str_schema())},
127+
),
128+
),
129+
)
130+
131+
inner_schema_validator = SchemaValidator(inner_schema)
132+
InnerModel.__pydantic_complete__ = True # pyright: ignore[reportAttributeAccessIssue]
133+
InnerModel.__pydantic_validator__ = inner_schema_validator # pyright: ignore[reportAttributeAccessIssue]
134+
135+
class OuterModel:
136+
inner: InnerModel
137+
138+
def __init__(self, inner: InnerModel) -> None:
139+
self.inner = inner
140+
141+
outer_schema = core_schema.model_schema(
142+
OuterModel,
143+
schema=core_schema.model_fields_schema(
144+
{
145+
'inner': core_schema.model_field(
146+
schema=core_schema.model_schema(
147+
InnerModel,
148+
schema=core_schema.model_fields_schema(
149+
# note, we use a simple str schema (with no custom validation)
150+
# in order to verify that the prebuilt validator from InnerModel is not used
151+
{'x': core_schema.model_field(schema=core_schema.str_schema())},
152+
),
153+
)
154+
)
155+
}
156+
),
157+
)
158+
159+
inner_validator = SchemaValidator(inner_schema)
160+
outer_validator = SchemaValidator(outer_schema)
161+
162+
# the custom validation function does apply for the inner model
163+
result_inner = inner_validator.validate_python({'x': 'hello'})
164+
assert result_inner.x == 'hello modified'
165+
166+
# but the outer model doesn't reuse the custom wrap validator function, so we see simple str val
167+
result_outer = outer_validator.validate_python({'inner': {'x': 'hello'}})
168+
assert result_outer.inner.x == 'hello'

0 commit comments

Comments
 (0)