@@ -251,9 +251,12 @@ def is_local(self):
251
251
pass
252
252
253
253
254
- def serialize (resource : Any , drop_dict_null_values = True ) -> dict :
255
- # TODO: make serialization pluggable
256
- # TODO: add empty dict/array cleanup
254
+ def serialize (resource : Any , remove_nulls = True ) -> dict :
255
+ """
256
+ * empty dicts/lists are always removed
257
+ * nulls are removed only for dicts if `remove_nulls` is set
258
+ * in lists empty dicts are transformed into nulls because nulls are used for alignment
259
+ """
257
260
258
261
def convert_fn (item ):
259
262
if isinstance (item , BaseResource ):
@@ -264,17 +267,40 @@ def convert_fn(item):
264
267
265
268
if _is_serializable_dict_like (item ):
266
269
# Handle dict-serializable structures like pydantic Model
267
- if drop_dict_null_values :
268
- return _remove_dict_null_values (dict (item )), False
269
- return dict (item ), False
270
+ item = _remove_dict_empty_values (dict (item ))
271
+
272
+ if remove_nulls :
273
+ return _remove_nulls (item ), False
274
+ return item , False
275
+
276
+ if isinstance (item , list ):
277
+ return _transform_list_empty_values_to_null (item ), False
270
278
271
279
return item , False
272
280
273
281
return convert_values (dict (resource ), convert_fn )
274
282
275
283
276
- def _remove_dict_null_values (d : dict ):
277
- return {key : value for key , value in d .items () if value is not None }
284
+ def _remove_dict_empty_values (d : dict ):
285
+ return {key : value for key , value in d .items () if not _is_empty (value )}
286
+
287
+
288
+ def _transform_list_empty_values_to_null (d : list ):
289
+ return [None if _is_empty (value ) else value for value in d ]
290
+
291
+
292
+ def _remove_nulls (d : dict ):
293
+ return {key : value for key , value in d .items () if not _is_null (value )}
294
+
295
+
296
+ def _is_empty (d : Any ):
297
+ if isinstance (d , (dict , list )):
298
+ return not d
299
+ return False
300
+
301
+
302
+ def _is_null (d : Any ):
303
+ return d is None
278
304
279
305
280
306
def _is_serializable_dict_like (item ):
0 commit comments