Skip to content

Commit 4ef09c0

Browse files
committed
union ser fix for various lookup key types
1 parent 6169ea9 commit 4ef09c0

File tree

2 files changed

+36
-30
lines changed

2 files changed

+36
-30
lines changed

src/lookup_key.rs

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -191,34 +191,10 @@ impl LookupKey {
191191
}
192192
}
193193

194-
pub fn py_get_attr<'py, 's>(
195-
&'s self,
196-
obj: &Bound<'py, PyAny>,
197-
kwargs: Option<&Bound<'py, PyDict>>,
198-
) -> ValResult<Option<(&'s LookupPath, Bound<'py, PyAny>)>> {
199-
match self._py_get_attr(obj, kwargs) {
200-
Ok(v) => Ok(v),
201-
Err(err) => {
202-
let error = py_err_string(obj.py(), err);
203-
Err(ValError::new(
204-
ErrorType::GetAttributeError { error, context: None },
205-
obj,
206-
))
207-
}
208-
}
209-
}
210-
211-
pub fn _py_get_attr<'py, 's>(
194+
pub fn simple_py_get_attr<'py, 's>(
212195
&'s self,
213196
obj: &Bound<'py, PyAny>,
214-
kwargs: Option<&Bound<'py, PyDict>>,
215197
) -> PyResult<Option<(&'s LookupPath, Bound<'py, PyAny>)>> {
216-
if let Some(dict) = kwargs {
217-
if let Ok(Some(item)) = self.py_get_dict_item(dict) {
218-
return Ok(Some(item));
219-
}
220-
}
221-
222198
match self {
223199
Self::Simple { py_key, path, .. } => match py_get_attrs(obj, py_key)? {
224200
Some(value) => Ok(Some((path, value))),
@@ -260,6 +236,37 @@ impl LookupKey {
260236
}
261237
}
262238

239+
pub fn py_get_attr<'py, 's>(
240+
&'s self,
241+
obj: &Bound<'py, PyAny>,
242+
kwargs: Option<&Bound<'py, PyDict>>,
243+
) -> ValResult<Option<(&'s LookupPath, Bound<'py, PyAny>)>> {
244+
match self._py_get_attr(obj, kwargs) {
245+
Ok(v) => Ok(v),
246+
Err(err) => {
247+
let error = py_err_string(obj.py(), err);
248+
Err(ValError::new(
249+
ErrorType::GetAttributeError { error, context: None },
250+
obj,
251+
))
252+
}
253+
}
254+
}
255+
256+
pub fn _py_get_attr<'py, 's>(
257+
&'s self,
258+
obj: &Bound<'py, PyAny>,
259+
kwargs: Option<&Bound<'py, PyDict>>,
260+
) -> PyResult<Option<(&'s LookupPath, Bound<'py, PyAny>)>> {
261+
if let Some(dict) = kwargs {
262+
if let Ok(Some(item)) = self.py_get_dict_item(dict) {
263+
return Ok(Some(item));
264+
}
265+
}
266+
267+
self.simple_py_get_attr(obj)
268+
}
269+
263270
pub fn json_get<'a, 'data, 's>(
264271
&'s self,
265272
dict: &'a JsonObject<'data>,

src/serializers/type_serializers/union.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ use std::borrow::Cow;
88
use crate::build_tools::py_schema_err;
99
use crate::common::union::{Discriminator, SMALL_UNION_THRESHOLD};
1010
use crate::definitions::DefinitionsBuilder;
11-
use crate::lookup_key::LookupKey;
1211
use crate::serializers::type_serializers::py_err_se_err;
1312
use crate::tools::{truncate_safe_repr, SchemaDict};
1413
use crate::PydanticSerializationUnexpectedValue;
@@ -438,10 +437,10 @@ impl TaggedUnionSerializer {
438437
fn get_discriminator_value(&self, value: &Bound<'_, PyAny>, extra: &Extra) -> Option<Py<PyAny>> {
439438
let py = value.py();
440439
let discriminator_value = match &self.discriminator {
441-
Discriminator::LookupKey(lookup_key) => match lookup_key {
442-
LookupKey::Simple { py_key, .. } => value.getattr(py_key).ok().map(|obj| obj.to_object(py)),
443-
_ => None,
444-
},
440+
Discriminator::LookupKey(lookup_key) => lookup_key
441+
.simple_py_get_attr(value)
442+
.ok()
443+
.and_then(|opt| opt.map(|(_, bound)| bound.to_object(py))),
445444
Discriminator::Function(func) => func.call1(py, (value,)).ok(),
446445
};
447446
if discriminator_value.is_none() {

0 commit comments

Comments
 (0)