@@ -9,7 +9,6 @@ use crate::build_tools::py_schema_err;
99use crate :: common:: union:: { Discriminator , SMALL_UNION_THRESHOLD } ;
1010use crate :: definitions:: DefinitionsBuilder ;
1111use crate :: tools:: { truncate_safe_repr, SchemaDict } ;
12- use crate :: PydanticSerializationUnexpectedValue ;
1312
1413use super :: {
1514 infer_json_key, infer_serialize, infer_to_python, BuildSerializer , CombinedSerializer , Extra , SerCheck ,
@@ -93,7 +92,8 @@ fn union_serialize<S, R>(
9392 }
9493 }
9594
96- if retry_with_lax_check {
95+ // If extra.check is SerCheck::Strict, we're in a nested union
96+ if extra. check != SerCheck :: Strict && retry_with_lax_check {
9797 new_extra. check = SerCheck :: Lax ;
9898 for comb_serializer in choices {
9999 if let Ok ( v) = selector ( comb_serializer, & new_extra) {
@@ -102,72 +102,23 @@ fn union_serialize<S, R>(
102102 }
103103 }
104104
105- for err in & errors {
106- extra. warnings . custom_warning ( err. to_string ( ) ) ;
105+ // If extra.check is SerCheck::None, we're in a top-level union. We should thus raise the warnings
106+ if extra. check == SerCheck :: None {
107+ for err in & errors {
108+ extra. warnings . custom_warning ( err. to_string ( ) ) ;
109+ }
107110 }
111+ // Otherwise, if we've encountered errors, return them to the parent union, which should take
112+ // care of the formatting for us
113+ // TODO: change up return type to support this
114+ // else if !errors.is_empty() {
115+ // let message = errors.iter().map(ToString::to_string).collect::<Vec<_>>().join("\n");
116+ // return Err(PydanticSerializationUnexpectedValue::new_err(Some(message)));
117+ // }
108118
109119 finalizer ( None )
110120}
111121
112- fn to_python (
113- value : & Bound < ' _ , PyAny > ,
114- include : Option < & Bound < ' _ , PyAny > > ,
115- exclude : Option < & Bound < ' _ , PyAny > > ,
116- extra : & Extra ,
117- choices : & [ CombinedSerializer ] ,
118- retry_with_lax_check : bool ,
119- ) -> PyResult < PyObject > {
120- union_serialize (
121- |comb_serializer, new_extra| comb_serializer. to_python ( value, include, exclude, new_extra) ,
122- |v| v. map_or_else ( || infer_to_python ( value, include, exclude, extra) , Ok ) ,
123- extra,
124- choices,
125- retry_with_lax_check,
126- )
127- }
128-
129- fn json_key < ' a > (
130- key : & ' a Bound < ' _ , PyAny > ,
131- extra : & Extra ,
132- choices : & [ CombinedSerializer ] ,
133- retry_with_lax_check : bool ,
134- ) -> PyResult < Cow < ' a , str > > {
135- union_serialize (
136- |comb_serializer, new_extra| comb_serializer. json_key ( key, new_extra) ,
137- |v| v. map_or_else ( || infer_json_key ( key, extra) , Ok ) ,
138- extra,
139- choices,
140- retry_with_lax_check,
141- )
142- }
143-
144- #[ allow( clippy:: too_many_arguments) ]
145- fn serde_serialize < S : serde:: ser:: Serializer > (
146- value : & Bound < ' _ , PyAny > ,
147- serializer : S ,
148- include : Option < & Bound < ' _ , PyAny > > ,
149- exclude : Option < & Bound < ' _ , PyAny > > ,
150- extra : & Extra ,
151- choices : & [ CombinedSerializer ] ,
152- retry_with_lax_check : bool ,
153- ) -> Result < S :: Ok , S :: Error > {
154- union_serialize (
155- |comb_serializer, new_extra| comb_serializer. to_python ( value, include, exclude, new_extra) ,
156- |v| {
157- infer_serialize (
158- v. as_ref ( ) . map_or ( value, |v| v. bind ( value. py ( ) ) ) ,
159- serializer,
160- None ,
161- None ,
162- extra,
163- )
164- } ,
165- extra,
166- choices,
167- retry_with_lax_check,
168- )
169- }
170-
171122impl TypeSerializer for UnionSerializer {
172123 fn to_python (
173124 & self ,
@@ -176,18 +127,23 @@ impl TypeSerializer for UnionSerializer {
176127 exclude : Option < & Bound < ' _ , PyAny > > ,
177128 extra : & Extra ,
178129 ) -> PyResult < PyObject > {
179- to_python (
180- value,
181- include,
182- exclude,
130+ union_serialize (
131+ |comb_serializer, new_extra| comb_serializer. to_python ( value, include, exclude, new_extra) ,
132+ |v| v. map_or_else ( || infer_to_python ( value, include, exclude, extra) , Ok ) ,
183133 extra,
184134 & self . choices ,
185135 self . retry_with_lax_check ( ) ,
186136 )
187137 }
188138
189139 fn json_key < ' a > ( & self , key : & ' a Bound < ' _ , PyAny > , extra : & Extra ) -> PyResult < Cow < ' a , str > > {
190- json_key ( key, extra, & self . choices , self . retry_with_lax_check ( ) )
140+ union_serialize (
141+ |comb_serializer, new_extra| comb_serializer. json_key ( key, new_extra) ,
142+ |v| v. map_or_else ( || infer_json_key ( key, extra) , Ok ) ,
143+ extra,
144+ & self . choices ,
145+ self . retry_with_lax_check ( ) ,
146+ )
191147 }
192148
193149 fn serde_serialize < S : serde:: ser:: Serializer > (
@@ -198,11 +154,17 @@ impl TypeSerializer for UnionSerializer {
198154 exclude : Option < & Bound < ' _ , PyAny > > ,
199155 extra : & Extra ,
200156 ) -> Result < S :: Ok , S :: Error > {
201- serde_serialize (
202- value,
203- serializer,
204- include,
205- exclude,
157+ union_serialize (
158+ |comb_serializer, new_extra| comb_serializer. to_python ( value, include, exclude, new_extra) ,
159+ |v| {
160+ infer_serialize (
161+ v. as_ref ( ) . map_or ( value, |v| v. bind ( value. py ( ) ) ) ,
162+ serializer,
163+ None ,
164+ None ,
165+ extra,
166+ )
167+ } ,
206168 extra,
207169 & self . choices ,
208170 self . retry_with_lax_check ( ) ,
@@ -296,10 +258,9 @@ impl TypeSerializer for TaggedUnionSerializer {
296258 }
297259 }
298260
299- to_python (
300- value,
301- include,
302- exclude,
261+ union_serialize (
262+ |comb_serializer, new_extra| comb_serializer. to_python ( value, include, exclude, new_extra) ,
263+ |v| v. map_or_else ( || infer_to_python ( value, include, exclude, extra) , Ok ) ,
303264 extra,
304265 & self . choices ,
305266 self . retry_with_lax_check ( ) ,
@@ -329,7 +290,13 @@ impl TypeSerializer for TaggedUnionSerializer {
329290 }
330291 }
331292
332- json_key ( key, extra, & self . choices , self . retry_with_lax_check ( ) )
293+ union_serialize (
294+ |comb_serializer, new_extra| comb_serializer. json_key ( key, new_extra) ,
295+ |v| v. map_or_else ( || infer_json_key ( key, extra) , Ok ) ,
296+ extra,
297+ & self . choices ,
298+ self . retry_with_lax_check ( ) ,
299+ )
333300 }
334301
335302 fn serde_serialize < S : serde:: ser:: Serializer > (
@@ -363,11 +330,17 @@ impl TypeSerializer for TaggedUnionSerializer {
363330 }
364331 }
365332
366- serde_serialize (
367- value,
368- serializer,
369- include,
370- exclude,
333+ union_serialize (
334+ |comb_serializer, new_extra| comb_serializer. to_python ( value, include, exclude, new_extra) ,
335+ |v| {
336+ infer_serialize (
337+ v. as_ref ( ) . map_or ( value, |v| v. bind ( value. py ( ) ) ) ,
338+ serializer,
339+ None ,
340+ None ,
341+ extra,
342+ )
343+ } ,
371344 extra,
372345 & self . choices ,
373346 self . retry_with_lax_check ( ) ,
0 commit comments