Skip to content

Commit e375b85

Browse files
committed
fix union wrap combo
1 parent 72b1c8e commit e375b85

File tree

3 files changed

+31
-11
lines changed

3 files changed

+31
-11
lines changed

src/serializers/extra.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,10 @@ impl<'a> Extra<'a> {
198198
pub fn serialize_infer<'py>(&'py self, value: &'py Bound<'py, PyAny>) -> super::infer::SerializeInfer<'py> {
199199
super::infer::SerializeInfer::new(value, None, None, self)
200200
}
201+
202+
pub(crate) fn model_type_name(&self) -> Option<Bound<'a, PyString>> {
203+
self.model.and_then(|model| model.get_type().name().ok())
204+
}
201205
}
202206

203207
#[derive(Clone, Copy, PartialEq, Eq)]

src/serializers/fields.rs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,15 @@ impl GeneralFieldsSerializer {
200200
};
201201
output_dict.set_item(key, value)?;
202202
} else if field_extra.check == SerCheck::Strict {
203-
return Err(PydanticSerializationUnexpectedValue::new_err(None));
203+
let type_name = field_extra.model_type_name();
204+
return Err(PydanticSerializationUnexpectedValue::new_err(Some(format!(
205+
"Unexpected field `{key}`{for_type_name}",
206+
for_type_name = if let Some(type_name) = type_name {
207+
format!(" for type `{type_name}`")
208+
} else {
209+
String::new()
210+
},
211+
))));
204212
}
205213
}
206214
}
@@ -212,22 +220,15 @@ impl GeneralFieldsSerializer {
212220
&& self.required_fields > used_req_fields
213221
{
214222
let required_fields = self.required_fields;
215-
let type_name = match extra.model {
216-
Some(model) => model
217-
.get_type()
218-
.qualname()
219-
.ok()
220-
.unwrap_or_else(|| PyString::new_bound(py, "<unknown python object>"))
221-
.to_string(),
222-
None => "<unknown python object>".to_string(),
223-
};
223+
let type_name = extra.model_type_name();
224224
let field_value = match extra.model {
225225
Some(model) => truncate_safe_repr(model, Some(100)),
226226
None => "<unknown python object>".to_string(),
227227
};
228228

229229
Err(PydanticSerializationUnexpectedValue::new_err(Some(format!(
230-
"Expected {required_fields} fields but got {used_req_fields} for type `{type_name}` with value `{field_value}` - serialized value may not be as expected."
230+
"Expected {required_fields} fields but got {used_req_fields}{for_type_name} with value `{field_value}` - serialized value may not be as expected.",
231+
for_type_name = if let Some(type_name) = type_name { format!(" for type `{type_name}`") } else { String::new() },
231232
))))
232233
} else {
233234
Ok(output_dict)

src/serializers/type_serializers/function.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,13 @@ impl FunctionPlainSerializer {
179179
.expect("fallback_serializer unexpectedly none")
180180
.as_ref()
181181
}
182+
183+
fn retry_with_lax_check(&self) -> bool {
184+
self.fallback_serializer
185+
.as_ref()
186+
.map_or(false, |f| f.retry_with_lax_check())
187+
|| self.return_serializer.retry_with_lax_check()
188+
}
182189
}
183190

184191
fn on_error(py: Python, err: PyErr, function_name: &str, extra: &Extra) -> PyResult<()> {
@@ -271,6 +278,10 @@ macro_rules! function_type_serializer {
271278
fn get_name(&self) -> &str {
272279
&self.name
273280
}
281+
282+
fn retry_with_lax_check(&self) -> bool {
283+
self.retry_with_lax_check()
284+
}
274285
}
275286
};
276287
}
@@ -409,6 +420,10 @@ impl FunctionWrapSerializer {
409420
fn get_fallback_serializer(&self) -> &CombinedSerializer {
410421
self.serializer.as_ref()
411422
}
423+
424+
fn retry_with_lax_check(&self) -> bool {
425+
self.serializer.retry_with_lax_check() || self.return_serializer.retry_with_lax_check()
426+
}
412427
}
413428

414429
impl_py_gc_traverse!(FunctionWrapSerializer {

0 commit comments

Comments
 (0)