typedpy 2.2.3__tar.gz → 2.2.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- home/dannyloya/github/typedpy/venv39/lib/python3.9/site-packages/typedpy/__pycache__/serialization.cpython-39.pyc +0 -0
- home/dannyloya/github/typedpy/venv39/lib/python3.9/site-packages/typedpy/__pycache__/serialization_wrappers.cpython-39.pyc +0 -0
- home/dannyloya/github/typedpy/venv39/lib/python3.9/site-packages/typedpy/serialization.py +129 -52
- home/dannyloya/github/typedpy/venv39/lib/python3.9/site-packages/typedpy/serialization_wrappers.py +23 -3
- home/dannyloya/github/typedpy/venv39/lib/python3.9/site-packages/{typedpy-2.2.3-py3.9.egg-info → typedpy-2.2.4-py3.9.egg-info}/PKG-INFO +2 -2
- /home/dannyloya/github/typedpy/venv39/lib/python3.9/site-packages/{typedpy-2.2.3-py3.9.egg-info → typedpy-2.2.4-py3.9.egg-info}/SOURCES.txt +0 -0
- /home/dannyloya/github/typedpy/venv39/lib/python3.9/site-packages/{typedpy-2.2.3-py3.9.egg-info → typedpy-2.2.4-py3.9.egg-info}/dependency_links.txt +0 -0
- /home/dannyloya/github/typedpy/venv39/lib/python3.9/site-packages/{typedpy-2.2.3-py3.9.egg-info → typedpy-2.2.4-py3.9.egg-info}/top_level.txt +0 -0
|
Binary file
|
|
Binary file
|
|
@@ -10,7 +10,7 @@ from typedpy.structures import (
|
|
|
10
10
|
Structure,
|
|
11
11
|
_get_all_fields_by_name,
|
|
12
12
|
ADDITIONAL_PROPERTIES,
|
|
13
|
-
REQUIRED_FIELDS,
|
|
13
|
+
REQUIRED_FIELDS, IGNORE_NONE_VALUES,
|
|
14
14
|
)
|
|
15
15
|
from typedpy.fields import (
|
|
16
16
|
Field,
|
|
@@ -39,7 +39,8 @@ from typedpy.fields import (
|
|
|
39
39
|
|
|
40
40
|
|
|
41
41
|
def deserialize_list_like(
|
|
42
|
-
field, content_type, value, name, *, keep_undefined=True, mapper=None
|
|
42
|
+
field, content_type, value, name, *, keep_undefined=True, mapper=None,
|
|
43
|
+
camel_case_convert=False
|
|
43
44
|
):
|
|
44
45
|
if not isinstance(value, (list, tuple, set)):
|
|
45
46
|
raise ValueError("{}: must be list, set, or tuple; got {}".format(name, value))
|
|
@@ -47,11 +48,14 @@ def deserialize_list_like(
|
|
|
47
48
|
values = []
|
|
48
49
|
items = field.items
|
|
49
50
|
if isinstance(items, Field):
|
|
51
|
+
ignore_none = getattr(items, IGNORE_NONE_VALUES, False)
|
|
50
52
|
for i, v in enumerate(value):
|
|
51
53
|
item_name = "{}_{}".format(name, i)
|
|
52
54
|
try:
|
|
53
55
|
list_item = deserialize_single_field(
|
|
54
|
-
items, v, item_name, keep_undefined=keep_undefined, mapper=mapper
|
|
56
|
+
items, v, item_name, keep_undefined=keep_undefined, mapper=mapper,
|
|
57
|
+
camel_case_convert=camel_case_convert,
|
|
58
|
+
ignore_none=ignore_none
|
|
55
59
|
)
|
|
56
60
|
except (ValueError, TypeError) as e:
|
|
57
61
|
prefix = (
|
|
@@ -62,8 +66,11 @@ def deserialize_list_like(
|
|
|
62
66
|
elif isinstance(items, (list, tuple)):
|
|
63
67
|
for i, item in enumerate(items):
|
|
64
68
|
try:
|
|
69
|
+
ignore_none = getattr(item, IGNORE_NONE_VALUES, False)
|
|
65
70
|
res = deserialize_single_field(
|
|
66
|
-
item, value[i], name, keep_undefined=keep_undefined, mapper=mapper
|
|
71
|
+
item, value[i], name, keep_undefined=keep_undefined, mapper=mapper,
|
|
72
|
+
camel_case_convert=camel_case_convert,
|
|
73
|
+
ignore_none=ignore_none
|
|
67
74
|
)
|
|
68
75
|
except (ValueError, TypeError) as e:
|
|
69
76
|
raise ValueError("{}_{}: {}".format(name, i, str(e))) from e
|
|
@@ -74,13 +81,14 @@ def deserialize_list_like(
|
|
|
74
81
|
return content_type(values)
|
|
75
82
|
|
|
76
83
|
|
|
77
|
-
def deserialize_array(array_field, value, name, *, keep_undefined=True, mapper):
|
|
84
|
+
def deserialize_array(array_field, value, name, *, keep_undefined=True, mapper,camel_case_convert=False):
|
|
78
85
|
return deserialize_list_like(
|
|
79
|
-
array_field, list, value, name, keep_undefined=keep_undefined, mapper=mapper
|
|
86
|
+
array_field, list, value, name, keep_undefined=keep_undefined, mapper=mapper,
|
|
87
|
+
camel_case_convert=camel_case_convert
|
|
80
88
|
)
|
|
81
89
|
|
|
82
90
|
|
|
83
|
-
def deserialize_deque(array_field, value, name, *, keep_undefined=True, mapper):
|
|
91
|
+
def deserialize_deque(array_field, value, name, *, keep_undefined=True, mapper, camel_case_convert=False):
|
|
84
92
|
return deserialize_list_like(
|
|
85
93
|
array_field,
|
|
86
94
|
collections.deque,
|
|
@@ -88,23 +96,27 @@ def deserialize_deque(array_field, value, name, *, keep_undefined=True, mapper):
|
|
|
88
96
|
name,
|
|
89
97
|
keep_undefined=keep_undefined,
|
|
90
98
|
mapper=mapper,
|
|
99
|
+
camel_case_convert=camel_case_convert
|
|
91
100
|
)
|
|
92
101
|
|
|
93
102
|
|
|
94
|
-
def deserialize_tuple(tuple_field, value, name, *, keep_undefined=True, mapper):
|
|
103
|
+
def deserialize_tuple(tuple_field, value, name, *, keep_undefined=True, mapper, camel_case_convert=False):
|
|
95
104
|
return deserialize_list_like(
|
|
96
|
-
tuple_field, tuple, value, name, keep_undefined=keep_undefined, mapper=mapper
|
|
105
|
+
tuple_field, tuple, value, name, keep_undefined=keep_undefined, mapper=mapper,
|
|
106
|
+
camel_case_convert=camel_case_convert
|
|
97
107
|
)
|
|
98
108
|
|
|
99
109
|
|
|
100
|
-
def deserialize_set(set_field, value, name, *, keep_undefined=True, mapper):
|
|
110
|
+
def deserialize_set(set_field, value, name, *, keep_undefined=True, mapper, camel_case_convert=False):
|
|
101
111
|
return deserialize_list_like(
|
|
102
|
-
set_field, set, value, name, keep_undefined=keep_undefined, mapper=mapper
|
|
112
|
+
set_field, set, value, name, keep_undefined=keep_undefined, mapper=mapper,
|
|
113
|
+
camel_case_convert=camel_case_convert
|
|
103
114
|
)
|
|
104
115
|
|
|
105
116
|
|
|
106
117
|
def deserialize_multifield_wrapper(
|
|
107
|
-
field, source_val, name, *, keep_undefined=True, mapper=None
|
|
118
|
+
field, source_val, name, *, keep_undefined=True, mapper=None,
|
|
119
|
+
camel_case_convert=False
|
|
108
120
|
):
|
|
109
121
|
"""
|
|
110
122
|
Only primitive values are supported, otherwise deserialization is ambiguous,
|
|
@@ -114,12 +126,16 @@ def deserialize_multifield_wrapper(
|
|
|
114
126
|
found_previous_match = False
|
|
115
127
|
for field_option in field.get_fields():
|
|
116
128
|
try:
|
|
129
|
+
ignore_none = getattr(field_option, IGNORE_NONE_VALUES, False)
|
|
130
|
+
|
|
117
131
|
deserialized = deserialize_single_field(
|
|
118
132
|
field_option,
|
|
119
133
|
source_val,
|
|
120
134
|
name,
|
|
121
135
|
keep_undefined=keep_undefined,
|
|
122
136
|
mapper=mapper,
|
|
137
|
+
camel_case_convert=camel_case_convert,
|
|
138
|
+
ignore_none=ignore_none
|
|
123
139
|
)
|
|
124
140
|
if isinstance(field, AnyOf):
|
|
125
141
|
return deserialized
|
|
@@ -146,7 +162,7 @@ def deserialize_multifield_wrapper(
|
|
|
146
162
|
return deserialized
|
|
147
163
|
|
|
148
164
|
|
|
149
|
-
def deserialize_map(map_field, source_val, name):
|
|
165
|
+
def deserialize_map(map_field, source_val, name, camel_case_convert=False):
|
|
150
166
|
if not isinstance(source_val, dict):
|
|
151
167
|
raise TypeError(
|
|
152
168
|
"{}: expected a dict. Got {}".format(name, wrap_val(source_val))
|
|
@@ -157,15 +173,26 @@ def deserialize_map(map_field, source_val, name):
|
|
|
157
173
|
key_field, value_field = None, None
|
|
158
174
|
res = {}
|
|
159
175
|
for key, val in source_val.items():
|
|
160
|
-
|
|
161
|
-
|
|
176
|
+
ignore_none = getattr(value_field, IGNORE_NONE_VALUES, False)
|
|
177
|
+
|
|
178
|
+
res[deserialize_single_field(key_field, key, name,
|
|
179
|
+
camel_case_convert=camel_case_convert)] = deserialize_single_field(
|
|
180
|
+
value_field, val, name,
|
|
181
|
+
camel_case_convert=camel_case_convert,
|
|
182
|
+
ignore_none=ignore_none
|
|
162
183
|
)
|
|
163
184
|
return res
|
|
164
185
|
|
|
165
186
|
|
|
166
187
|
def deserialize_single_field(
|
|
167
|
-
field, source_val, name, *,
|
|
188
|
+
field, source_val, name, *,
|
|
189
|
+
mapper=None,
|
|
190
|
+
keep_undefined=True,
|
|
191
|
+
camel_case_convert=False,
|
|
192
|
+
ignore_none=False,
|
|
168
193
|
):
|
|
194
|
+
if source_val is None and ignore_none:
|
|
195
|
+
return source_val
|
|
169
196
|
if isinstance(field, (Number, String, Enum, Boolean)):
|
|
170
197
|
field._validate(source_val)
|
|
171
198
|
value = source_val
|
|
@@ -177,23 +204,28 @@ def deserialize_single_field(
|
|
|
177
204
|
value = source_val
|
|
178
205
|
elif isinstance(field, Array):
|
|
179
206
|
value = deserialize_array(
|
|
180
|
-
field, source_val, name, keep_undefined=keep_undefined, mapper=mapper
|
|
207
|
+
field, source_val, name, keep_undefined=keep_undefined, mapper=mapper,
|
|
208
|
+
camel_case_convert=camel_case_convert
|
|
181
209
|
)
|
|
182
210
|
elif isinstance(field, Deque):
|
|
183
211
|
value = deserialize_deque(
|
|
184
|
-
field, source_val, name, keep_undefined=keep_undefined, mapper=mapper
|
|
212
|
+
field, source_val, name, keep_undefined=keep_undefined, mapper=mapper,
|
|
213
|
+
camel_case_convert=camel_case_convert
|
|
185
214
|
)
|
|
186
215
|
elif isinstance(field, Tuple):
|
|
187
216
|
value = deserialize_tuple(
|
|
188
|
-
field, source_val, name, keep_undefined=keep_undefined, mapper=mapper
|
|
217
|
+
field, source_val, name, keep_undefined=keep_undefined, mapper=mapper,
|
|
218
|
+
camel_case_convert=camel_case_convert
|
|
189
219
|
)
|
|
190
220
|
elif isinstance(field, Set):
|
|
191
221
|
value = deserialize_set(
|
|
192
|
-
field, source_val, name, keep_undefined=keep_undefined, mapper=mapper
|
|
222
|
+
field, source_val, name, keep_undefined=keep_undefined, mapper=mapper,
|
|
223
|
+
camel_case_convert=camel_case_convert
|
|
193
224
|
)
|
|
194
225
|
elif isinstance(field, MultiFieldWrapper):
|
|
195
226
|
value = deserialize_multifield_wrapper(
|
|
196
|
-
field, source_val, name, keep_undefined=keep_undefined, mapper=mapper
|
|
227
|
+
field, source_val, name, keep_undefined=keep_undefined, mapper=mapper,
|
|
228
|
+
camel_case_convert=camel_case_convert
|
|
197
229
|
)
|
|
198
230
|
elif isinstance(field, ClassReference):
|
|
199
231
|
value = deserialize_structure_internal(
|
|
@@ -202,6 +234,7 @@ def deserialize_single_field(
|
|
|
202
234
|
name,
|
|
203
235
|
keep_undefined=keep_undefined,
|
|
204
236
|
mapper=mapper,
|
|
237
|
+
camel_case_convert=camel_case_convert
|
|
205
238
|
)
|
|
206
239
|
elif isinstance(field, StructureReference):
|
|
207
240
|
value = deserialize_structure_reference(
|
|
@@ -209,9 +242,10 @@ def deserialize_single_field(
|
|
|
209
242
|
source_val,
|
|
210
243
|
keep_undefined=keep_undefined,
|
|
211
244
|
mapper=mapper,
|
|
245
|
+
camel_case_convert=camel_case_convert
|
|
212
246
|
)
|
|
213
247
|
elif isinstance(field, Map):
|
|
214
|
-
value = deserialize_map(field, source_val, name)
|
|
248
|
+
value = deserialize_map(field, source_val, name, camel_case_convert=camel_case_convert)
|
|
215
249
|
elif isinstance(field, SerializableField):
|
|
216
250
|
value = field.deserialize(source_val)
|
|
217
251
|
elif isinstance(field, Anything) or field is None:
|
|
@@ -231,7 +265,7 @@ def deserialize_single_field(
|
|
|
231
265
|
return value
|
|
232
266
|
|
|
233
267
|
|
|
234
|
-
def deserialize_structure_reference(cls, the_dict: dict, *, keep_undefined, mapper):
|
|
268
|
+
def deserialize_structure_reference(cls, the_dict: dict, *, keep_undefined, mapper, camel_case_convert=False):
|
|
235
269
|
field_by_name = {k: v for k, v in cls.__dict__.items() if isinstance(v, Field)}
|
|
236
270
|
kwargs = dict(
|
|
237
271
|
[
|
|
@@ -241,30 +275,36 @@ def deserialize_structure_reference(cls, the_dict: dict, *, keep_undefined, mapp
|
|
|
241
275
|
]
|
|
242
276
|
)
|
|
243
277
|
|
|
244
|
-
kwargs.update(construct_fields_map(field_by_name, keep_undefined, mapper, the_dict
|
|
278
|
+
kwargs.update(construct_fields_map(field_by_name, keep_undefined, mapper, the_dict,
|
|
279
|
+
camel_case_convert=camel_case_convert))
|
|
245
280
|
cls(**kwargs)
|
|
246
281
|
return kwargs
|
|
247
282
|
|
|
248
283
|
|
|
249
|
-
def construct_fields_map(field_by_name, keep_undefined, mapper,
|
|
284
|
+
def construct_fields_map(field_by_name, keep_undefined, mapper, input_dict,
|
|
285
|
+
camel_case_convert=False,
|
|
286
|
+
ignore_none=False):
|
|
250
287
|
result = {}
|
|
251
288
|
for key, field in field_by_name.items():
|
|
289
|
+
converted_key = _convert_to_camel_case_if_required(key, camel_case_convert=camel_case_convert)
|
|
252
290
|
process = False
|
|
253
291
|
processed_input = None
|
|
254
|
-
if
|
|
255
|
-
processed_input =
|
|
292
|
+
if converted_key in input_dict and key not in mapper:
|
|
293
|
+
processed_input = input_dict[converted_key]
|
|
256
294
|
process = True
|
|
257
295
|
elif key in mapper:
|
|
258
|
-
processed_input = get_processed_input(key, mapper,
|
|
296
|
+
processed_input = get_processed_input(key, mapper, input_dict)
|
|
259
297
|
process = True
|
|
260
298
|
if process:
|
|
261
|
-
sub_mapper = mapper.get(f"{
|
|
299
|
+
sub_mapper = mapper.get(f"{converted_key}._mapper", {})
|
|
262
300
|
result[key] = deserialize_single_field(
|
|
263
301
|
field,
|
|
264
302
|
processed_input,
|
|
265
303
|
key,
|
|
266
304
|
mapper=sub_mapper,
|
|
267
305
|
keep_undefined=keep_undefined,
|
|
306
|
+
camel_case_convert=camel_case_convert,
|
|
307
|
+
ignore_none=ignore_none
|
|
268
308
|
)
|
|
269
309
|
return result
|
|
270
310
|
|
|
@@ -288,7 +328,10 @@ class FunctionCall(Structure):
|
|
|
288
328
|
|
|
289
329
|
|
|
290
330
|
def deserialize_structure_internal(
|
|
291
|
-
cls, the_dict, name=None, *,
|
|
331
|
+
cls, the_dict, name=None, *,
|
|
332
|
+
mapper=None,
|
|
333
|
+
keep_undefined=True,
|
|
334
|
+
camel_case_convert=False
|
|
292
335
|
):
|
|
293
336
|
"""
|
|
294
337
|
Deserialize a dict to a Structure instance, Jackson style.
|
|
@@ -314,6 +357,7 @@ def deserialize_structure_internal(
|
|
|
314
357
|
"""
|
|
315
358
|
if mapper is None:
|
|
316
359
|
mapper = {}
|
|
360
|
+
ignore_none = getattr(cls, IGNORE_NONE_VALUES, False)
|
|
317
361
|
if not isinstance(mapper, (collections.abc.Mapping,)):
|
|
318
362
|
raise TypeError("Mapper must be a mapping")
|
|
319
363
|
field_by_name = _get_all_fields_by_name(cls)
|
|
@@ -326,7 +370,7 @@ def deserialize_structure_internal(
|
|
|
326
370
|
if len(fields) == 1 and required == fields and additional_props is False:
|
|
327
371
|
field_name = fields[0]
|
|
328
372
|
return cls(
|
|
329
|
-
deserialize_single_field(getattr(cls, field_name), the_dict, field_name)
|
|
373
|
+
deserialize_single_field(getattr(cls, field_name), the_dict, field_name, ignore_none=ignore_none)
|
|
330
374
|
)
|
|
331
375
|
raise TypeError(
|
|
332
376
|
"{}: Expected a dictionary; Got {}".format(name, wrap_val(the_dict))
|
|
@@ -339,12 +383,17 @@ def deserialize_structure_internal(
|
|
|
339
383
|
if k not in field_by_name and keep_undefined
|
|
340
384
|
]
|
|
341
385
|
)
|
|
342
|
-
kwargs.update(construct_fields_map(field_by_name, keep_undefined, mapper, the_dict
|
|
386
|
+
kwargs.update(construct_fields_map(field_by_name, keep_undefined, mapper, the_dict,
|
|
387
|
+
camel_case_convert=camel_case_convert,
|
|
388
|
+
ignore_none=ignore_none))
|
|
343
389
|
|
|
344
390
|
return cls(**kwargs)
|
|
345
391
|
|
|
346
392
|
|
|
347
|
-
def deserialize_structure(cls, the_dict, *,
|
|
393
|
+
def deserialize_structure(cls, the_dict, *,
|
|
394
|
+
mapper=None,
|
|
395
|
+
keep_undefined=True,
|
|
396
|
+
camel_case_convert=False):
|
|
348
397
|
"""
|
|
349
398
|
Deserialize a dict to a Structure instance, Jackson style.
|
|
350
399
|
Note the top level must be a python dict - which implies that a JSON of
|
|
@@ -370,7 +419,9 @@ def deserialize_structure(cls, the_dict, *, mapper=None, keep_undefined=True):
|
|
|
370
419
|
an instance of the provided :class:`Structure` deserialized
|
|
371
420
|
"""
|
|
372
421
|
return deserialize_structure_internal(
|
|
373
|
-
cls, the_dict, mapper=mapper,
|
|
422
|
+
cls, the_dict, mapper=mapper,
|
|
423
|
+
keep_undefined=keep_undefined,
|
|
424
|
+
camel_case_convert=camel_case_convert
|
|
374
425
|
)
|
|
375
426
|
|
|
376
427
|
|
|
@@ -399,7 +450,7 @@ def get_processed_input(key, mapper, the_dict):
|
|
|
399
450
|
return processed_input
|
|
400
451
|
|
|
401
452
|
|
|
402
|
-
def serialize_val(field_definition, name, val, mapper=None):
|
|
453
|
+
def serialize_val(field_definition, name, val, mapper=None, camel_case_convert=False):
|
|
403
454
|
if isinstance(field_definition, SerializableField) and isinstance(
|
|
404
455
|
field_definition, Field
|
|
405
456
|
):
|
|
@@ -416,32 +467,37 @@ def serialize_val(field_definition, name, val, mapper=None):
|
|
|
416
467
|
):
|
|
417
468
|
key_type, value_type = field_definition.items
|
|
418
469
|
return {
|
|
419
|
-
serialize_val(key_type, name, k
|
|
470
|
+
serialize_val(key_type, name, k, camel_case_convert=camel_case_convert):
|
|
471
|
+
serialize_val(value_type, name, v, camel_case_convert=camel_case_convert)
|
|
420
472
|
for (k, v) in val.items()
|
|
421
473
|
}
|
|
422
474
|
else:
|
|
423
475
|
return {
|
|
424
|
-
serialize_val(Anything, name, k
|
|
476
|
+
serialize_val(Anything, name, k, camel_case_convert=camel_case_convert):
|
|
477
|
+
serialize_val(Anything, name, v, camel_case_convert=camel_case_convert)
|
|
425
478
|
for (k, v) in val.items()
|
|
426
479
|
}
|
|
427
480
|
if isinstance(field_definition.items, list):
|
|
428
481
|
return [
|
|
429
|
-
serialize_val(field_definition.items[ind], name, v, mapper=mapper
|
|
482
|
+
serialize_val(field_definition.items[ind], name, v, mapper=mapper,
|
|
483
|
+
camel_case_convert=camel_case_convert)
|
|
430
484
|
for ind, v in enumerate(val)
|
|
431
485
|
]
|
|
432
486
|
elif isinstance(field_definition.items, Field):
|
|
433
487
|
return [
|
|
434
|
-
serialize_val(field_definition.items, name, i, mapper=mapper
|
|
488
|
+
serialize_val(field_definition.items, name, i, mapper=mapper,
|
|
489
|
+
camel_case_convert=camel_case_convert)
|
|
435
490
|
for i in val
|
|
436
491
|
]
|
|
437
492
|
else:
|
|
438
|
-
return [serialize_val(None, name, i, mapper=mapper)
|
|
493
|
+
return [serialize_val(None, name, i, mapper=mapper, camel_case_convert=camel_case_convert)
|
|
494
|
+
for i in val]
|
|
439
495
|
if isinstance(val, (list, set, tuple)):
|
|
440
|
-
return [serialize_val(None, name, i) for i in val]
|
|
496
|
+
return [serialize_val(None, name, i, camel_case_convert=camel_case_convert) for i in val]
|
|
441
497
|
if isinstance(field_definition, Anything) and isinstance(val, Structure):
|
|
442
|
-
return serialize(val, mapper=mapper)
|
|
498
|
+
return serialize(val, mapper=mapper, camel_case_convert=camel_case_convert)
|
|
443
499
|
if isinstance(val, Structure) or isinstance(field_definition, Field):
|
|
444
|
-
return serialize_internal(val, mapper=mapper)
|
|
500
|
+
return serialize_internal(val, mapper=mapper, camel_case_convert=camel_case_convert)
|
|
445
501
|
|
|
446
502
|
# nothing worked. Not a typedpy field. Last ditch effort.
|
|
447
503
|
try:
|
|
@@ -450,7 +506,7 @@ def serialize_val(field_definition, name, val, mapper=None):
|
|
|
450
506
|
raise ValueError(f"{name}: cannot serialize value: {ex}") from ex
|
|
451
507
|
|
|
452
508
|
|
|
453
|
-
def serialize_field(field_definition: Field, value):
|
|
509
|
+
def serialize_field(field_definition: Field, value, camel_case_convert=False):
|
|
454
510
|
"""
|
|
455
511
|
Serialize a specific :class:`Field` from a structure to a JSON-like dict.
|
|
456
512
|
Example:
|
|
@@ -479,7 +535,8 @@ def serialize_field(field_definition: Field, value):
|
|
|
479
535
|
Returns:
|
|
480
536
|
a serialized Python object that can be directly converted to JSON
|
|
481
537
|
"""
|
|
482
|
-
return serialize_val(field_definition, field_definition._name, value
|
|
538
|
+
return serialize_val(field_definition, field_definition._name, value,
|
|
539
|
+
camel_case_convert=camel_case_convert)
|
|
483
540
|
|
|
484
541
|
|
|
485
542
|
def _get_mapped_value(mapper, key, items):
|
|
@@ -498,7 +555,23 @@ def _get_mapped_value(mapper, key, items):
|
|
|
498
555
|
return None
|
|
499
556
|
|
|
500
557
|
|
|
501
|
-
def
|
|
558
|
+
def _convert_to_camel_case_if_required(key, camel_case_convert):
|
|
559
|
+
if camel_case_convert:
|
|
560
|
+
words = key.split('_')
|
|
561
|
+
return words[0] + ''.join(w.title() for w in words[1:])
|
|
562
|
+
else:
|
|
563
|
+
return key
|
|
564
|
+
|
|
565
|
+
def _convert_to_snake_case_if_required(key, camel_case_convert):
|
|
566
|
+
if camel_case_convert:
|
|
567
|
+
return ''.join(['_' + char.lower() if char.isupper()
|
|
568
|
+
else char for char in key]).lstrip('_')
|
|
569
|
+
else:
|
|
570
|
+
return key
|
|
571
|
+
|
|
572
|
+
|
|
573
|
+
|
|
574
|
+
def serialize_internal(structure, mapper=None, compact=False, camel_case_convert=False):
|
|
502
575
|
if mapper is None:
|
|
503
576
|
mapper = {}
|
|
504
577
|
field_by_name = _get_all_fields_by_name(structure.__class__)
|
|
@@ -520,7 +593,8 @@ def serialize_internal(structure, mapper=None, compact=False):
|
|
|
520
593
|
):
|
|
521
594
|
key = fields[0]
|
|
522
595
|
result = serialize_val(
|
|
523
|
-
field_by_name.get(key, None), key, getattr(structure, key)
|
|
596
|
+
field_by_name.get(key, None), key, getattr(structure, key),
|
|
597
|
+
camel_case_convert=camel_case_convert
|
|
524
598
|
)
|
|
525
599
|
else:
|
|
526
600
|
result = {}
|
|
@@ -531,7 +605,7 @@ def serialize_internal(structure, mapper=None, compact=False):
|
|
|
531
605
|
mapped_key = (
|
|
532
606
|
mapper[key]
|
|
533
607
|
if key in mapper and isinstance(mapper[key], (str,))
|
|
534
|
-
else key
|
|
608
|
+
else _convert_to_camel_case_if_required(key, camel_case_convert)
|
|
535
609
|
)
|
|
536
610
|
mapped_value = _get_mapped_value(mapper, key, items_map)
|
|
537
611
|
the_field_definition = (
|
|
@@ -539,12 +613,14 @@ def serialize_internal(structure, mapper=None, compact=False):
|
|
|
539
613
|
)
|
|
540
614
|
sub_mapper = mapper.get(f"{key}._mapper", {})
|
|
541
615
|
result[mapped_key] = serialize_val(
|
|
542
|
-
the_field_definition, key, mapped_value or val,
|
|
616
|
+
the_field_definition, key, mapped_value or val,
|
|
617
|
+
mapper=sub_mapper,
|
|
618
|
+
camel_case_convert=camel_case_convert
|
|
543
619
|
)
|
|
544
620
|
return result
|
|
545
621
|
|
|
546
622
|
|
|
547
|
-
def serialize(value, *, mapper: Dict = None, compact=False):
|
|
623
|
+
def serialize(value, *, mapper: Dict = None, compact=False, camel_case_convert=False):
|
|
548
624
|
"""
|
|
549
625
|
Serialize an instance of :class:`Structure` to a JSON-like dict.
|
|
550
626
|
`See working examples in test. <https://github.com/loyada/typedpy/tree/master/tests/test_serialization.py>`_
|
|
@@ -580,11 +656,12 @@ def serialize(value, *, mapper: Dict = None, compact=False):
|
|
|
580
656
|
return value
|
|
581
657
|
if isinstance(value, (_ListStruct, _DictStruct)):
|
|
582
658
|
field_definition = value._field_definition
|
|
583
|
-
return serialize_val(field_definition, field_definition._name, value
|
|
659
|
+
return serialize_val(field_definition, field_definition._name, value,
|
|
660
|
+
camel_case_convert=camel_case_convert)
|
|
584
661
|
if isinstance(value, (enum.Enum,)):
|
|
585
662
|
return value.name
|
|
586
663
|
raise TypeError(
|
|
587
664
|
"serialize: Not a Structure or Field that with an obvious serialization. Got: {}."
|
|
588
665
|
" Maybe try serialize_field() instead?".format(value)
|
|
589
666
|
)
|
|
590
|
-
return serialize_internal(value, mapper=mapper, compact=compact)
|
|
667
|
+
return serialize_internal(value, mapper=mapper, compact=compact, camel_case_convert=camel_case_convert)
|
home/dannyloya/github/typedpy/venv39/lib/python3.9/site-packages/typedpy/serialization_wrappers.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from typedpy import Structure
|
|
2
|
-
from typedpy.fields import StructureClass, Map, String, OneOf
|
|
2
|
+
from typedpy.fields import StructureClass, Map, String, OneOf, Boolean
|
|
3
3
|
from typedpy.serialization import FunctionCall, deserialize_structure, serialize
|
|
4
4
|
from typedpy.structures import _get_all_fields_by_name
|
|
5
5
|
|
|
@@ -49,11 +49,15 @@ class Deserializer(Structure):
|
|
|
49
49
|
}
|
|
50
50
|
Deserializer(target_class=Foo, mapper = mapper).deserializer(the_input_dict)
|
|
51
51
|
|
|
52
|
+
camel_case_convert(bool): Optional
|
|
53
|
+
If true, will convert any camelCase key that does not have explicit mapping to a snake_case attribute
|
|
54
|
+
name. Default is False.
|
|
52
55
|
|
|
53
56
|
"""
|
|
54
57
|
|
|
55
58
|
target_class = StructureClass
|
|
56
59
|
mapper = Map[String, OneOf[String, FunctionCall, Map]]
|
|
60
|
+
camel_case_convert = Boolean(default = False)
|
|
57
61
|
|
|
58
62
|
_required = ["target_class"]
|
|
59
63
|
|
|
@@ -74,6 +78,7 @@ class Deserializer(Structure):
|
|
|
74
78
|
input_data,
|
|
75
79
|
mapper=self.mapper,
|
|
76
80
|
keep_undefined=keep_undefined,
|
|
81
|
+
camel_case_convert=self.camel_case_convert
|
|
77
82
|
)
|
|
78
83
|
|
|
79
84
|
|
|
@@ -155,5 +160,20 @@ class Serializer(Structure):
|
|
|
155
160
|
for key in self.mapper:
|
|
156
161
|
verify_key_in_mapper(key, valid_keys, source_class)
|
|
157
162
|
|
|
158
|
-
def serialize(self, compact=True):
|
|
159
|
-
|
|
163
|
+
def serialize(self, compact=True, camel_case_convert=False):
|
|
164
|
+
"""
|
|
165
|
+
|
|
166
|
+
Arguments:
|
|
167
|
+
compact(boolean): optional
|
|
168
|
+
whether to use a compact form for Structure that is a simple wrapper of a field.
|
|
169
|
+
for example: if a Structure has only one field of an int, if compact is True
|
|
170
|
+
it will serialize the structure as an int instead of a dictionary.
|
|
171
|
+
Default is False.
|
|
172
|
+
|
|
173
|
+
camel_case_convert(dict): optional
|
|
174
|
+
If True, convert any camel-case key that does not have a mapping in the mapper to a snake-case
|
|
175
|
+
attribute.
|
|
176
|
+
Default is False.
|
|
177
|
+
"""
|
|
178
|
+
return serialize(self.source, mapper=self.mapper, compact=compact,
|
|
179
|
+
camel_case_convert=camel_case_convert)
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: typedpy
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.4
|
|
4
4
|
Summary: Type-safe Python
|
|
5
5
|
Home-page: http://github.com/loyada/typedpy
|
|
6
6
|
Author: Danny Loya
|
|
7
7
|
Author-email: dan.loya@gmail.com
|
|
8
8
|
License: MIT
|
|
9
|
-
Download-URL: https://github.com/loyada/typedpy/archive/v2.2.
|
|
9
|
+
Download-URL: https://github.com/loyada/typedpy/archive/v2.2.4.tar.gz
|
|
10
10
|
Description: [![][travis img]][travis]
|
|
11
11
|
[![][docs img]][docs]
|
|
12
12
|
|
|
File without changes
|
|
File without changes
|