@@ -52,7 +52,7 @@ def get_tzinfo(self):
5252 """
5353 Callback to make serializer aware of user's timezone. Should be redefined if needed
5454 Example:
55- return pytz.timezone('Asia/Krasnoyarsk ')
55+ return pytz.timezone('Africa/Abidjan ')
5656
5757 :return: datetime.tzinfo
5858 """
@@ -114,10 +114,33 @@ class Serializer:
114114 )
115115
116116 def __init__ (self , ** kwargs ):
117- self .serialization_depth = 0
118- self .opts = Options (** kwargs )
117+ self .set_serialization_depth (0 )
118+ self .set_options (Options (** kwargs ))
119+ self .init_callbacks ()
120+
119121 self .schema = Schema ()
120122
123+ def __call__ (self , value , only = (), extend = ()):
124+ """
125+ Serialization starts here
126+ :param value: Value to serialize
127+ :param only: Exclusive schema of serialization
128+ :param extend: Rules that extend default schema
129+ :return: object: JSON-compatible object
130+ """
131+ self .schema .update (only = only , extend = extend )
132+
133+ logger .debug ("Call serializer for type:%s" , get_type (value ))
134+ return self .serialize (value )
135+
136+ def set_serialization_depth (self , value : int ):
137+ self .serialization_depth = value
138+
139+ def set_options (self , opts : Options ):
140+ self .opts = opts
141+
142+ def init_callbacks (self ):
143+ """Initialize callbacks"""
121144 self .serialize_types = (
122145 * (self .opts .serialize_types or ()),
123146 (self .atomic_types , lambda x : x ), # Should be checked before any other type
@@ -141,22 +164,6 @@ def __init__(self, **kwargs):
141164 (SerializerMixin , self .serialize_model ),
142165 )
143166
144- def __call__ (self , value , only = (), extend = ()):
145- """
146- Serialization starts here
147- :param value: Value to serialize
148- :param only: Exclusive schema of serialization
149- :param extend: Rules that extend default schema
150- :return: object: JSON-compatible object
151- """
152- self .schema .update (only = only , extend = extend )
153-
154- logger .debug ("Call serializer for type:%s" , get_type (value ))
155- return self .serialize (value )
156-
157- def set_serialization_depth (self , value : int ):
158- self .serialization_depth = value
159-
160167 @staticmethod
161168 def is_valid_callable (func ) -> bool :
162169 """
@@ -181,17 +188,17 @@ def is_forkable(self, value):
181188 value , (Iterable , dict , SerializerMixin )
182189 )
183190
184- def fork (self , value , key : str ):
191+ def fork (self , key : str ) -> "Serializer" :
185192 """
186- Process data in a separate serializer
193+ Return new serializer for a key
187194 :return: serialized value
188195 """
189196 serializer = Serializer (** self .opts ._asdict ())
190197 serializer .set_serialization_depth (self .serialization_depth + 1 )
191198 serializer .schema = self .schema .fork (key = key )
192199
193- logger .debug ("Fork serializer for type:%s key:%s" , get_type ( value ) , key )
194- return serializer ( value )
200+ logger .debug ("Fork serializer for key:%s" , key )
201+ return serializer
195202
196203 def serialize (self , value ):
197204 if self .is_valid_callable (value ):
@@ -202,12 +209,23 @@ def serialize(self, value):
202209 return callback (value )
203210 raise IsNotSerializable (f"Unserializable type:{ type (value )} value:{ value } " )
204211
212+ def serialize_with_fork (self , value , key ):
213+ # TODO: merge this function with the serialize function
214+ # TODO: this should be performed after is_valid_callable check
215+ serializer = self
216+ if self .is_forkable (value ):
217+ serializer = self .fork (key = key )
218+
219+ return serializer .serialize (value )
220+
205221 def serialize_iter (self , value : Iterable ) -> list :
206222 res = []
207223 for v in value :
208224 try :
209225 r = self .serialize (v )
210- except IsNotSerializable :
226+ except (
227+ IsNotSerializable
228+ ): # FIXME: Why we swallow exception only in iterable?
211229 logger .warning ("Can not serialize type:%s" , get_type (v ))
212230 continue
213231
@@ -219,10 +237,8 @@ def serialize_dict(self, value: dict) -> dict:
219237 for k , v in value .items ():
220238 if self .schema .is_included (k ): # TODO: Skip check if is NOT greedy
221239 logger .debug ("Serialize key:%s type:%s of dict" , k , get_type (v ))
222- if self .is_forkable (v ):
223- res [k ] = self .fork (key = k , value = v )
224- else :
225- res [k ] = self .serialize (v )
240+
241+ res [k ] = self .serialize_with_fork (value = v , key = k )
226242 else :
227243 logger .debug ("Skip key:%s of dict" , k )
228244 return res
@@ -241,10 +257,7 @@ def serialize_model(self, value) -> dict:
241257 logger .debug (
242258 "Serialize key:%s type:%s model:%s" , k , get_type (v ), get_type (value )
243259 )
244- if self .is_forkable (v ):
245- res [k ] = self .fork (key = k , value = v )
246- else :
247- res [k ] = self .serialize (v )
260+ res [k ] = self .serialize_with_fork (value = v , key = k )
248261
249262 else :
250263 logger .debug ("Skip key:%s of model:%s" , k , get_type (value ))
0 commit comments