@@ -19,7 +19,7 @@ use super::errors::{py_err_se_err, PydanticSerializationError};
1919use super :: extra:: { Extra , SerMode } ;
2020use super :: filter:: { AnyFilter , SchemaFilter } ;
2121use super :: ob_type:: ObType ;
22- use super :: shared:: { AnyDataclassIterator , DictIterator , PydanticSerializer , TypeSerializer } ;
22+ use super :: shared:: { any_dataclass_iter , PydanticSerializer , TypeSerializer } ;
2323use super :: SchemaSerializer ;
2424
2525pub ( crate ) fn infer_to_python (
@@ -151,7 +151,10 @@ pub(crate) fn infer_to_python_known(
151151 PyList :: new ( py, elements) . into_py ( py)
152152 }
153153 ObType :: Dict => {
154- serialize_pairs_python_mode_json ( py, DictIterator :: new ( value. downcast ( ) ?) , include, exclude, extra) ?
154+ let dict: & PyDict = value. downcast ( ) ?;
155+ serialize_pairs_python ( py, dict. iter ( ) . map ( Ok ) , include, exclude, extra, |k| {
156+ Ok ( PyString :: new ( py, & infer_json_key ( k, extra) ?) )
157+ } ) ?
155158 }
156159 ObType :: Datetime => {
157160 let py_dt: & PyDateTime = value. downcast ( ) ?;
@@ -190,7 +193,9 @@ pub(crate) fn infer_to_python_known(
190193 }
191194 ObType :: PydanticSerializable => serialize_with_serializer ( ) ?,
192195 ObType :: Dataclass => {
193- serialize_pairs_python_mode_json ( py, AnyDataclassIterator :: new ( value) ?, include, exclude, extra) ?
196+ serialize_pairs_python ( py, any_dataclass_iter ( value) ?. 0 , include, exclude, extra, |k| {
197+ Ok ( PyString :: new ( py, & infer_json_key ( k, extra) ?) )
198+ } ) ?
194199 }
195200 ObType :: Enum => {
196201 let v = value. getattr ( intern ! ( py, "value" ) ) ?;
@@ -241,11 +246,12 @@ pub(crate) fn infer_to_python_known(
241246 let elements = serialize_seq ! ( PyFrozenSet ) ;
242247 PyFrozenSet :: new ( py, & elements) ?. into_py ( py)
243248 }
244- ObType :: Dict => serialize_pairs_python ( py, DictIterator :: new ( value. downcast ( ) ?) , include, exclude, extra) ?,
245- ObType :: PydanticSerializable => serialize_with_serializer ( ) ?,
246- ObType :: Dataclass => {
247- serialize_pairs_python ( py, AnyDataclassIterator :: new ( value) ?, include, exclude, extra) ?
249+ ObType :: Dict => {
250+ let dict: & PyDict = value. downcast ( ) ?;
251+ serialize_pairs_python ( py, dict. iter ( ) . map ( Ok ) , include, exclude, extra, Ok ) ?
248252 }
253+ ObType :: PydanticSerializable => serialize_with_serializer ( ) ?,
254+ ObType :: Dataclass => serialize_pairs_python ( py, any_dataclass_iter ( value) ?. 0 , include, exclude, extra, Ok ) ?,
249255 ObType :: Generator => {
250256 let iter = super :: type_serializers:: generator:: SerializationIterator :: new (
251257 value. downcast ( ) ?,
@@ -404,7 +410,7 @@ pub(crate) fn infer_serialize_known<S: Serializer>(
404410 }
405411 ObType :: Dict => {
406412 let dict = value. downcast :: < PyDict > ( ) . map_err ( py_err_se_err) ?;
407- serialize_pairs_json ( DictIterator :: new ( dict) , serializer, include, exclude, extra)
413+ serialize_pairs_json ( dict . iter ( ) . map ( Ok ) , dict. len ( ) , serializer, include, exclude, extra)
408414 }
409415 ObType :: List => serialize_seq_filter ! ( PyList ) ,
410416 ObType :: Tuple => serialize_seq_filter ! ( PyTuple ) ,
@@ -463,13 +469,10 @@ pub(crate) fn infer_serialize_known<S: Serializer>(
463469 PydanticSerializer :: new ( value, & extracted_serializer. serializer , include, exclude, & extra) ;
464470 pydantic_serializer. serialize ( serializer)
465471 }
466- ObType :: Dataclass => serialize_pairs_json (
467- AnyDataclassIterator :: new ( value) . map_err ( py_err_se_err) ?,
468- serializer,
469- include,
470- exclude,
471- extra,
472- ) ,
472+ ObType :: Dataclass => {
473+ let ( pairs_iter, fields_dict) = any_dataclass_iter ( value) . map_err ( py_err_se_err) ?;
474+ serialize_pairs_json ( pairs_iter, fields_dict. len ( ) , serializer, include, exclude, extra)
475+ }
473476 ObType :: Uuid => {
474477 let py_uuid: & PyAny = value. downcast ( ) . map_err ( py_err_se_err) ?;
475478 let uuid = super :: type_serializers:: uuid:: uuid_to_string ( py_uuid) . map_err ( py_err_se_err) ?;
@@ -645,6 +648,7 @@ fn serialize_pairs_python<'py>(
645648 include : Option < & PyAny > ,
646649 exclude : Option < & PyAny > ,
647650 extra : & Extra ,
651+ key_transform : impl Fn ( & ' py PyAny ) -> PyResult < & ' py PyAny > ,
648652) -> PyResult < PyObject > {
649653 let new_dict = PyDict :: new ( py) ;
650654 let filter = AnyFilter :: new ( ) ;
@@ -653,29 +657,7 @@ fn serialize_pairs_python<'py>(
653657 let ( k, v) = result?;
654658 let op_next = filter. key_filter ( k, include, exclude) ?;
655659 if let Some ( ( next_include, next_exclude) ) = op_next {
656- let v = infer_to_python ( v, next_include, next_exclude, extra) ?;
657- new_dict. set_item ( k, v) ?;
658- }
659- }
660- Ok ( new_dict. into_py ( py) )
661- }
662-
663- fn serialize_pairs_python_mode_json < ' py > (
664- py : Python ,
665- pairs_iter : impl Iterator < Item = PyResult < ( & ' py PyAny , & ' py PyAny ) > > ,
666- include : Option < & PyAny > ,
667- exclude : Option < & PyAny > ,
668- extra : & Extra ,
669- ) -> PyResult < PyObject > {
670- let new_dict = PyDict :: new ( py) ;
671- let filter = AnyFilter :: new ( ) ;
672-
673- for result in pairs_iter {
674- let ( k, v) = result?;
675- let op_next = filter. key_filter ( k, include, exclude) ?;
676- if let Some ( ( next_include, next_exclude) ) = op_next {
677- let k_str = infer_json_key ( k, extra) ?;
678- let k = PyString :: new ( py, & k_str) ;
660+ let k = key_transform ( k) ?;
679661 let v = infer_to_python ( v, next_include, next_exclude, extra) ?;
680662 new_dict. set_item ( k, v) ?;
681663 }
@@ -685,13 +667,13 @@ fn serialize_pairs_python_mode_json<'py>(
685667
686668fn serialize_pairs_json < ' py , S : Serializer > (
687669 pairs_iter : impl Iterator < Item = PyResult < ( & ' py PyAny , & ' py PyAny ) > > ,
670+ iter_size : usize ,
688671 serializer : S ,
689672 include : Option < & PyAny > ,
690673 exclude : Option < & PyAny > ,
691674 extra : & Extra ,
692675) -> Result < S :: Ok , S :: Error > {
693- let ( _, expected) = pairs_iter. size_hint ( ) ;
694- let mut map = serializer. serialize_map ( expected) ?;
676+ let mut map = serializer. serialize_map ( Some ( iter_size) ) ?;
695677 let filter = AnyFilter :: new ( ) ;
696678
697679 for result in pairs_iter {
0 commit comments