Skip to content

Commit 40da0ee

Browse files
committed
WIP
1 parent 26e3ec4 commit 40da0ee

File tree

3 files changed

+51
-42
lines changed

3 files changed

+51
-42
lines changed

src/py_gc.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,16 @@ impl<T: PyGcTraverse> PyGcTraverse for Option<T> {
5858
}
5959
}
6060

61+
impl<T: PyGcTraverse, E> PyGcTraverse for Result<T, E> {
62+
fn py_gc_traverse(&self, visit: &PyVisit<'_>) -> Result<(), PyTraverseError> {
63+
match self {
64+
Ok(v) => T::py_gc_traverse(v, visit),
65+
// FIXME(BoxyUwU): Lol
66+
Err(_) => Ok(()),
67+
}
68+
}
69+
}
70+
6171
impl<T: PyGcTraverse> PyGcTraverse for OnceLock<T> {
6272
fn py_gc_traverse(&self, visit: &PyVisit<'_>) -> Result<(), PyTraverseError> {
6373
match self.get() {

src/serializers/type_serializers/nested_model.rs

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@ use crate::{
1515
SchemaSerializer,
1616
};
1717

18-
#[derive(Debug, Clone)]
18+
#[derive(Debug)]
1919
pub struct NestedModelSerializer {
2020
model: Py<PyType>,
2121
name: String,
2222
get_serializer: Py<PyAny>,
23-
serializer: OnceLock<Py<SchemaSerializer>>,
23+
serializer: OnceLock<PyResult<Py<SchemaSerializer>>>,
2424
}
2525

2626
impl_py_gc_traverse!(NestedModelSerializer {
@@ -41,14 +41,14 @@ impl BuildSerializer for NestedModelSerializer {
4141

4242
let get_serializer = schema
4343
.get_item(intern!(py, "get_info"))?
44-
.expect("Invalid core schema for `nested-model` type")
44+
.expect("Invalid core schema for `nested-model` type, no `get_info`")
4545
.unbind();
4646

4747
let model = schema
4848
.get_item(intern!(py, "model"))?
49-
.expect("Invalid core schema for `nested-model` type")
49+
.expect("Invalid core schema for `nested-model` type, no `model`")
5050
.downcast::<PyType>()
51-
.expect("Invalid core schema for `nested-model` type")
51+
.expect("Invalid core schema for `nested-model` type, not a `PyType`")
5252
.clone();
5353

5454
let name = model.getattr(intern!(py, "__name__"))?.extract()?;
@@ -63,23 +63,21 @@ impl BuildSerializer for NestedModelSerializer {
6363
}
6464

6565
impl NestedModelSerializer {
66-
fn nested_serializer<'py>(&self, py: Python<'py>) -> Py<SchemaSerializer> {
66+
fn nested_serializer<'py>(&self, py: Python<'py>) -> PyResult<&Py<SchemaSerializer>> {
6767
self.serializer
6868
.get_or_init(|| {
69-
self.get_serializer
69+
Ok(self
70+
.get_serializer
7071
.bind(py)
71-
.call((), None)
72-
.expect("Invalid core schema for `nested-model`")
73-
.downcast::<PyTuple>()
74-
.expect("Invalid return value from `nested-model`'s `get_info` callable")
75-
.get_item(2)
76-
.expect("Invalid return value from `nested-model`'s `get_info` callable")
77-
.downcast::<SchemaSerializer>()
78-
.expect("Invalid return value from `nested-model`'s `get_info` callable")
72+
.call((), None)?
73+
.downcast::<PyTuple>()?
74+
.get_item(2)?
75+
.downcast::<SchemaSerializer>()?
7976
.clone()
80-
.unbind()
77+
.unbind())
8178
})
82-
.clone()
79+
.as_ref()
80+
.map_err(|e| e.clone_ref(py))
8381
}
8482
}
8583

@@ -93,15 +91,15 @@ impl TypeSerializer for NestedModelSerializer {
9391
) -> PyResult<PyObject> {
9492
let mut guard = extra.recursion_guard(value, self.model.as_ptr() as usize)?;
9593

96-
self.nested_serializer(value.py())
94+
self.nested_serializer(value.py())?
9795
.bind(value.py())
9896
.get()
9997
.serializer
10098
.to_python(value, include, exclude, guard.state())
10199
}
102100

103101
fn json_key<'a>(&self, key: &'a Bound<'_, PyAny>, extra: &Extra) -> PyResult<Cow<'a, str>> {
104-
self.nested_serializer(key.py())
102+
self.nested_serializer(key.py())?
105103
.bind(key.py())
106104
.get()
107105
.serializer
@@ -123,6 +121,8 @@ impl TypeSerializer for NestedModelSerializer {
123121
.map_err(py_err_se_err)?;
124122

125123
self.nested_serializer(value.py())
124+
// FIXME(BoxyUwU): Don't unwrap this
125+
.unwrap()
126126
.bind(value.py())
127127
.get()
128128
.serializer

src/validators/nested_model.rs

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@ use crate::{
1515

1616
use super::{BuildValidator, CombinedValidator, SchemaValidator, ValidationState, Validator};
1717

18-
#[derive(Debug, Clone)]
18+
#[derive(Debug)]
1919
pub struct NestedModelValidator {
2020
model: Py<PyType>,
2121
name: String,
2222
get_validator: Py<PyAny>,
23-
validator: OnceLock<Py<SchemaValidator>>,
23+
validator: OnceLock<PyResult<Py<SchemaValidator>>>,
2424
}
2525

2626
impl_py_gc_traverse!(NestedModelValidator {
@@ -39,16 +39,12 @@ impl BuildValidator for NestedModelValidator {
3939
) -> PyResult<super::CombinedValidator> {
4040
let py = schema.py();
4141

42-
let get_validator = schema
43-
.get_item(intern!(py, "get_info"))?
44-
.expect("Invalid core schema for `nested-model` type")
45-
.unbind();
42+
let get_validator = schema.get_item(intern!(py, "get_info"))?.unwrap().unbind();
4643

4744
let model = schema
4845
.get_item(intern!(py, "model"))?
49-
.expect("Invalid core schema for `nested-model` type")
50-
.downcast::<PyType>()
51-
.expect("Invalid core schema for `nested-model` type")
46+
.unwrap()
47+
.downcast::<PyType>()?
5248
.clone();
5349

5450
let name = model.getattr(intern!(py, "__name__"))?.extract()?;
@@ -63,23 +59,21 @@ impl BuildValidator for NestedModelValidator {
6359
}
6460

6561
impl NestedModelValidator {
66-
fn nested_validator<'py>(&self, py: Python<'py>) -> Py<SchemaValidator> {
62+
fn nested_validator<'py>(&self, py: Python<'py>) -> PyResult<&Py<SchemaValidator>> {
6763
self.validator
6864
.get_or_init(|| {
69-
self.get_validator
65+
Ok(self
66+
.get_validator
7067
.bind(py)
71-
.call((), None)
72-
.expect("Invalid core schema for `nested-model`")
73-
.downcast::<PyTuple>()
74-
.expect("Invalid return value from `nested-model`'s `get_info` callable")
75-
.get_item(1)
76-
.expect("Invalid return value from `nested-model`'s `get_info` callable")
77-
.downcast::<SchemaValidator>()
78-
.expect("Invalid return value from `nested-model`'s `get_info` callable")
68+
.call((), None)?
69+
.downcast::<PyTuple>()?
70+
.get_item(1)?
71+
.downcast::<SchemaValidator>()?
7972
.clone()
80-
.unbind()
73+
.unbind())
8174
})
82-
.clone()
75+
.as_ref()
76+
.map_err(|e| e.clone_ref(py))
8377
}
8478
}
8579

@@ -91,15 +85,20 @@ impl Validator for NestedModelValidator {
9185
state: &mut ValidationState<'_, 'py>,
9286
) -> ValResult<PyObject> {
9387
let Some(id) = input.as_python().map(py_identity) else {
94-
panic!("")
88+
return self
89+
.nested_validator(py)?
90+
.bind(py)
91+
.get()
92+
.validator
93+
.validate(py, input, state);
9594
};
9695

9796
// Python objects can be cyclic, so need recursion guard
9897
let Ok(mut guard) = RecursionGuard::new(state, id, self.model.as_ptr() as usize) else {
9998
return Err(ValError::new(ErrorTypeDefaults::RecursionLoop, input));
10099
};
101100

102-
self.nested_validator(py)
101+
self.nested_validator(py)?
103102
.bind(py)
104103
.get()
105104
.validator

0 commit comments

Comments
 (0)