@@ -97,12 +97,15 @@ impl PySome {
9797 }
9898}
9999
100- #[ pyclass( module = "pydantic_core._pydantic_core" ) ]
100+ #[ pyclass( module = "pydantic_core._pydantic_core" , frozen ) ]
101101#[ derive( Debug ) ]
102102pub struct SchemaValidator {
103103 validator : CombinedValidator ,
104104 definitions : Definitions < CombinedValidator > ,
105- schema : PyObject ,
105+ // References to the Python schema and config objects are saved to enable
106+ // reconstructing the object for cloudpickle support (see `__reduce__`).
107+ py_schema : Py < PyAny > ,
108+ py_config : Option < Py < PyDict > > ,
106109 #[ pyo3( get) ]
107110 title : PyObject ,
108111 hide_input_in_errors : bool ,
@@ -121,6 +124,11 @@ impl SchemaValidator {
121124 for val in definitions. values ( ) {
122125 val. get ( ) . unwrap ( ) . complete ( ) ?;
123126 }
127+ let py_schema = schema. into_py ( py) ;
128+ let py_config = match config {
129+ Some ( c) if !c. is_empty ( ) => Some ( c. into_py ( py) ) ,
130+ _ => None ,
131+ } ;
124132 let config_title = match config {
125133 Some ( c) => c. get_item ( "title" ) ,
126134 None => None ,
@@ -134,18 +142,20 @@ impl SchemaValidator {
134142 Ok ( Self {
135143 validator,
136144 definitions,
137- schema : schema. into_py ( py) ,
145+ py_schema,
146+ py_config,
138147 title,
139148 hide_input_in_errors,
140149 validation_error_cause,
141150 } )
142151 }
143152
144- pub fn __reduce__ ( slf : & PyCell < Self > ) -> PyResult < PyObject > {
153+ pub fn __reduce__ ( slf : & PyCell < Self > ) -> PyResult < ( PyObject , ( PyObject , PyObject ) ) > {
154+ // Enables support for `pickle` serialization.
145155 let py = slf. py ( ) ;
146- let args = ( slf. try_borrow ( ) ? . schema . to_object ( py ) , ) ;
147- let cls = slf. getattr ( "__class__" ) ? ;
148- Ok ( ( cls, args ) . into_py ( py ) )
156+ let cls = slf. get_type ( ) . into ( ) ;
157+ let init_args = ( slf. get ( ) . py_schema . to_object ( py ) , slf . get ( ) . py_config . to_object ( py ) ) ;
158+ Ok ( ( cls, init_args ) )
149159 }
150160
151161 #[ pyo3( signature = ( input, * , strict=None , from_attributes=None , context=None , self_instance=None ) ) ]
@@ -307,7 +317,10 @@ impl SchemaValidator {
307317
308318 fn __traverse__ ( & self , visit : PyVisit < ' _ > ) -> Result < ( ) , PyTraverseError > {
309319 self . validator . py_gc_traverse ( & visit) ?;
310- visit. call ( & self . schema ) ?;
320+ visit. call ( & self . py_schema ) ?;
321+ if let Some ( ref py_config) = self . py_config {
322+ visit. call ( py_config) ?;
323+ }
311324 Ok ( ( ) )
312325 }
313326}
@@ -396,7 +409,8 @@ impl<'py> SelfValidator<'py> {
396409 Ok ( SchemaValidator {
397410 validator,
398411 definitions,
399- schema : py. None ( ) ,
412+ py_schema : py. None ( ) ,
413+ py_config : None ,
400414 title : "Self Schema" . into_py ( py) ,
401415 hide_input_in_errors : false ,
402416 validation_error_cause : false ,
0 commit comments