11use std:: borrow:: Cow ;
22
3- use pyo3:: intern;
43use pyo3:: prelude:: * ;
5- use pyo3:: types:: { PyDict , PyType } ;
4+ use pyo3:: types:: PyDict ;
65
7- use crate :: tools :: SchemaDict ;
6+ use crate :: common :: prebuilt :: get_prebuilt ;
87use crate :: SchemaSerializer ;
98
109use super :: extra:: Extra ;
1110use super :: shared:: { CombinedSerializer , TypeSerializer } ;
1211
1312#[ derive( Debug ) ]
1413pub struct PrebuiltSerializer {
15- serializer : Py < SchemaSerializer > ,
14+ schema_serializer : Py < SchemaSerializer > ,
1615}
1716
1817impl PrebuiltSerializer {
1918 pub fn try_get_from_schema ( type_ : & str , schema : & Bound < ' _ , PyDict > ) -> PyResult < Option < CombinedSerializer > > {
20- let py = schema. py ( ) ;
21-
22- // we can only use prebuilt serializeres from models, typed dicts, and dataclasses
23- // however, we don't want to use a prebuilt serializer for dataclasses if we have a generic_origin
24- // because __pydantic_serializer__ is cached on the unparametrized dataclass
25- if !matches ! ( type_, "model" | "typed-dict" )
26- || matches ! ( type_, "dataclass" ) && schema. contains ( intern ! ( py, "generic_origin" ) ) ?
27- {
28- return Ok ( None ) ;
29- }
30-
31- let class: Bound < ' _ , PyType > = schema. get_as_req ( intern ! ( py, "cls" ) ) ?;
32-
33- // Note: we NEED to use the __dict__ here (and perform get_item calls rather than getattr)
34- // because we don't want to fetch prebuilt validators from parent classes.
35- // We don't downcast here because __dict__ on a class is a readonly mappingproxy,
36- // so we can just leave it as is and do get_item checks.
37- let class_dict = class. getattr ( intern ! ( py, "__dict__" ) ) ?;
38-
39- let is_complete: bool = class_dict
40- . get_item ( intern ! ( py, "__pydantic_complete__" ) )
41- . is_ok_and ( |b| b. extract ( ) . unwrap_or ( false ) ) ;
42-
43- if !is_complete {
44- return Ok ( None ) ;
45- }
46-
47- // Retrieve the prebuilt validator if available
48- let prebuilt_serializer: Bound < ' _ , PyAny > = class_dict. get_item ( intern ! ( py, "__pydantic_serializer__" ) ) ?;
49- let serializer: Py < SchemaSerializer > = prebuilt_serializer. extract ( ) ?;
50-
51- Ok ( Some ( Self { serializer } . into ( ) ) )
19+ get_prebuilt ( type_, schema, "__pydantic_serializer__" , |py_any| {
20+ py_any
21+ . extract :: < Py < SchemaSerializer > > ( )
22+ . map ( |schema_serializer| Self { schema_serializer } . into ( ) )
23+ } )
5224 }
5325}
5426
55- impl_py_gc_traverse ! ( PrebuiltSerializer { serializer } ) ;
27+ impl_py_gc_traverse ! ( PrebuiltSerializer { schema_serializer } ) ;
5628
5729impl TypeSerializer for PrebuiltSerializer {
5830 fn to_python (
@@ -62,14 +34,14 @@ impl TypeSerializer for PrebuiltSerializer {
6234 exclude : Option < & Bound < ' _ , PyAny > > ,
6335 extra : & Extra ,
6436 ) -> PyResult < PyObject > {
65- self . serializer
37+ self . schema_serializer
6638 . get ( )
6739 . serializer
6840 . to_python ( value, include, exclude, extra)
6941 }
7042
7143 fn json_key < ' a > ( & self , key : & ' a Bound < ' _ , PyAny > , extra : & Extra ) -> PyResult < Cow < ' a , str > > {
72- self . serializer . get ( ) . serializer . json_key ( key, extra)
44+ self . schema_serializer . get ( ) . serializer . json_key ( key, extra)
7345 }
7446
7547 fn serde_serialize < S : serde:: ser:: Serializer > (
@@ -80,17 +52,17 @@ impl TypeSerializer for PrebuiltSerializer {
8052 exclude : Option < & Bound < ' _ , PyAny > > ,
8153 extra : & Extra ,
8254 ) -> Result < S :: Ok , S :: Error > {
83- self . serializer
55+ self . schema_serializer
8456 . get ( )
8557 . serializer
8658 . serde_serialize ( value, serializer, include, exclude, extra)
8759 }
8860
8961 fn get_name ( & self ) -> & str {
90- self . serializer . get ( ) . serializer . get_name ( )
62+ self . schema_serializer . get ( ) . serializer . get_name ( )
9163 }
9264
9365 fn retry_with_lax_check ( & self ) -> bool {
94- self . serializer . get ( ) . serializer . retry_with_lax_check ( )
66+ self . schema_serializer . get ( ) . serializer . retry_with_lax_check ( )
9567 }
9668}
0 commit comments