@@ -159,21 +159,28 @@ impl GeneralFieldsSerializer {
159159 if matches ! ( extra. sort_keys, SortKeysMode :: Unsorted ) {
160160 for result in main_iter {
161161 let ( key, value) = result?;
162+ let key_str = key_str ( & key) ?;
162163 if let Some ( is_required) =
163- self . process_field_entry_python ( & key, & value, & output_dict, include, exclude, & extra) ?
164+ self . process_field_entry_python ( key_str , & key, & value, & output_dict, include, exclude, & extra) ?
164165 {
165166 if is_required {
166167 used_req_fields += 1 ;
167168 }
168169 }
169170 }
170171 } else {
171- let mut items = main_iter. collect :: < PyResult < Vec < _ > > > ( ) ?;
172- items. sort_by_cached_key ( |( key, _) | key_str ( key) . unwrap_or_default ( ) . to_string ( ) ) ;
173-
174- for ( key, value) in items {
172+ let mut items = main_iter
173+ . map ( |r| -> PyResult < _ > {
174+ let ( k, v) = r?;
175+ let k_str = key_str ( & k) ?. to_owned ( ) ;
176+ Ok ( ( k_str, k, v) )
177+ } )
178+ . collect :: < PyResult < Vec < _ > > > ( ) ?;
179+ items. sort_by ( |( a, _, _) , ( b, _, _) | a. cmp ( b) ) ;
180+
181+ for ( key_str, key, value) in items {
175182 if let Some ( is_required) =
176- self . process_field_entry_python ( & key, & value, & output_dict, include, exclude, & extra) ?
183+ self . process_field_entry_python ( & key_str , & key, & value, & output_dict, include, exclude, & extra) ?
177184 {
178185 if is_required {
179186 used_req_fields += 1 ;
@@ -218,8 +225,10 @@ impl GeneralFieldsSerializer {
218225 Ok ( sorted_dict)
219226 }
220227
228+ #[ allow( clippy:: too_many_arguments) ]
221229 fn process_field_entry_python < ' py > (
222230 & self ,
231+ key_str : & str ,
223232 key : & Bound < ' py , PyAny > ,
224233 value : & Bound < ' py , PyAny > ,
225234 output_dict : & Bound < ' py , PyDict > ,
@@ -231,7 +240,6 @@ impl GeneralFieldsSerializer {
231240 // - Some(true) -> Field was required and processed
232241 // - Some(false) -> Field was processed but not required
233242 // - None -> Field was filtered out or skipped
234- let key_str = key_str ( key) ?;
235243 let op_field = self . fields . get ( key_str) ;
236244
237245 if extra. exclude_none && value. is_none ( ) {
@@ -301,11 +309,11 @@ impl GeneralFieldsSerializer {
301309 None => infer_to_python ( value, next_include. as_ref ( ) , next_exclude. as_ref ( ) , & field_extra) ?,
302310 }
303311 } ;
304- output_dict. set_item ( key , processed_value) ?;
312+ output_dict. set_item ( key_str , processed_value) ?;
305313 return Ok ( None ) ;
306314 } else if field_extra. check == SerCheck :: Strict {
307315 return Err ( PydanticSerializationUnexpectedValue :: new (
308- Some ( format ! ( "Unexpected field `{key }`" ) ) ,
316+ Some ( format ! ( "Unexpected field `{key_str }`" ) ) ,
309317 field_extra. model_type_name ( ) . map ( |bound| bound. to_string ( ) ) ,
310318 None ,
311319 )
@@ -332,20 +340,30 @@ impl GeneralFieldsSerializer {
332340 if matches ! ( extra. sort_keys, SortKeysMode :: Unsorted ) {
333341 for result in main_iter {
334342 let ( key, value) = result. map_err ( py_err_se_err) ?;
335- self . process_field_entry :: < S > ( & key, & value, & mut map, include, exclude, & extra) ?;
343+ let key_str = key_str ( & key) . map_err ( py_err_se_err) ?;
344+ self . process_field_entry :: < S > ( key_str, & key, & value, & mut map, include, exclude, & extra) ?;
336345 }
337346 } else {
338- let mut items = main_iter. collect :: < PyResult < Vec < _ > > > ( ) . map_err ( py_err_se_err) ?;
339- items. sort_by_cached_key ( |( key, _) | key_str ( key) . unwrap_or_default ( ) . to_string ( ) ) ;
340- for ( key, value) in items {
341- self . process_field_entry :: < S > ( & key, & value, & mut map, include, exclude, & extra) ?;
347+ let mut items = main_iter
348+ . map ( |r| -> PyResult < _ > {
349+ let ( k, v) = r?;
350+ let k_str = key_str ( & k) ?. to_owned ( ) ;
351+ Ok ( ( k_str, k, v) )
352+ } )
353+ . collect :: < PyResult < Vec < _ > > > ( )
354+ . map_err ( py_err_se_err) ?;
355+ items. sort_by ( |( a, _, _) , ( b, _, _) | a. cmp ( b) ) ;
356+ for ( key_str, key, value) in items {
357+ self . process_field_entry :: < S > ( & key_str, & key, & value, & mut map, include, exclude, & extra) ?;
342358 }
343359 }
344360 Ok ( map)
345361 }
346362
363+ #[ allow( clippy:: too_many_arguments) ]
347364 fn process_field_entry < ' py , S : serde:: ser:: Serializer > (
348365 & self ,
366+ key_str : & str ,
349367 key : & Bound < ' py , PyAny > ,
350368 value : & Bound < ' py , PyAny > ,
351369 map : & mut S :: SerializeMap ,
@@ -356,15 +374,14 @@ impl GeneralFieldsSerializer {
356374 if extra. exclude_none && value. is_none ( ) {
357375 return Ok ( ( ) ) ;
358376 }
359- let field_key_str = key_str ( key) . map_err ( py_err_se_err) ?;
360377 let field_extra = Extra {
361- field_name : Some ( field_key_str ) ,
378+ field_name : Some ( key_str ) ,
362379 ..* extra
363380 } ;
364381
365382 let filter = self . filter . key_filter ( key, include, exclude) . map_err ( py_err_se_err) ?;
366383 if let Some ( ( next_include, next_exclude) ) = filter {
367- if let Some ( field) = self . fields . get ( field_key_str ) {
384+ if let Some ( field) = self . fields . get ( key_str ) {
368385 if let Some ( ref serializer) = field. serializer {
369386 if !exclude_default ( value, & field_extra, serializer) . map_err ( py_err_se_err) ? {
370387 if matches ! ( extra. sort_keys, SortKeysMode :: Recursive ) && value. downcast :: < PyDict > ( ) . is_ok ( ) {
@@ -376,7 +393,7 @@ impl GeneralFieldsSerializer {
376393 next_exclude. as_ref ( ) ,
377394 & field_extra,
378395 ) ;
379- let output_key = field. get_key_json ( field_key_str , & field_extra) ;
396+ let output_key = field. get_key_json ( key_str , & field_extra) ;
380397 map. serialize_entry ( & output_key, & s) ?;
381398 } else {
382399 let s = PydanticSerializer :: new (
@@ -386,7 +403,7 @@ impl GeneralFieldsSerializer {
386403 next_exclude. as_ref ( ) ,
387404 & field_extra,
388405 ) ;
389- let output_key = field. get_key_json ( field_key_str , & field_extra) ;
406+ let output_key = field. get_key_json ( key_str , & field_extra) ;
390407 map. serialize_entry ( & output_key, & s) ?;
391408 }
392409 }
0 commit comments