def deserialize_iterable_abstract_type(cls, cls_origin_type, data):
abstract_type_map = {
typing.Sequence: list,
typing.List: list,
typing.Set: set,
typing.AbstractSet: set,
typing.Mapping: Map,
}
deserialized_data = data
cls_primitive_type = abstract_type_map[cls_origin_type]
# Whereas on Python/typing < 3.5.2 type parameters are stored in
# __parameters__ attribute, on Python/typing >= 3.5.2 __parameters__
# attribute is gone and __args__ comes instead.
type_params = (cls.__args__
if hasattr(cls, '__args__')
else cls.__parameters__)
if len(type_params) == 1:
elem_type, = type_params
if isinstance(elem_type, typing.TypeVar):
deserialized_data = cls_primitive_type(data)
else:
deserialized_data = cls_primitive_type(
deserialize_meta(elem_type, d) for d in data
)
elif len(type_params) == 2:
# Key-value
key_type, value_type = type_params
assert not (isinstance(key_type, typing.TypeVar) or
isinstance(value_type, typing.TypeVar))
if not isinstance(data, collections.Sequence):
raise ValueError('map must be an array of item objects e.g. '
'[{"key": ..., "value": ...}, ...]')
def parse_pair(pair):
if not isinstance(pair, collections.Mapping):
raise ValueError('map item must be a JSON object')
try:
key = pair['key']
value = pair['value']
except KeyError:
raise ValueError('map item must consist of "key" and "value" '
'fields e.g. {"key": ..., "value": ...}')
return (
deserialize_meta(key_type, key),
deserialize_meta(value_type, value),
)
deserialized_data = cls_primitive_type(map(parse_pair, data))
return deserialized_data
评论列表
文章目录