Refactor classify to fix deserialisation at the same time

This commit is contained in:
Laurent Mazuel 2017-02-01 09:43:29 -08:00
Родитель 3c29e17baa
Коммит 1353f5b701
1 изменённых файлов: 20 добавлений и 46 удалений

Просмотреть файл

@ -113,53 +113,27 @@ class Model(object):
return base._subtype_map
return {}
@classmethod
def _flatten_subtype(cls, key, objects):
if not '_subtype_map' in cls.__dict__:
return {}
result = dict(cls._subtype_map[key])
for valuetype in cls._subtype_map[key].values():
result.update(objects[valuetype]._flatten_subtype(key, objects))
return result
@classmethod
def _classify(cls, response, objects):
"""Check the class _subtype_map for any child classes.
We want to ignore any inheirited _subtype_maps.
We want to ignore any inherited _subtype_maps.
Remove the polymorphic key from the initial data.
"""
try:
map = cls.__dict__.get('_subtype_map', {})
for _type, _classes in map.items():
classification = response.get(_type)
try:
return objects[_classes[classification]]
except KeyError:
pass
for c in _classes:
try:
_cls = objects[_classes[c]]
return _cls._classify(response, objects)
except (KeyError, TypeError):
continue
raise TypeError("Object cannot be classified futher.")
except AttributeError:
raise TypeError("Object cannot be classified futher.")
def _flatten_subtype(data_obj, key, localtypes):
if not '_subtype_map' in data_obj.__dict__:
return {}
result = dict(data_obj._subtype_map[key])
for valuetype in data_obj._subtype_map[key].values():
result.update(_flatten_subtype(localtypes[valuetype], key, localtypes))
return result
def _infer_type(data, data_obj, localtypes):
"""Infer the type for polymorphic situation.
Remove the polymorphic key from the initial data.
"""
if '_subtype_map' in data_obj.__dict__:
for subtype_key, subtype_mapping in data_obj._subtype_map.items():
if subtype_key in data:
subtype_value = data.pop(subtype_key)
flatten_mapping_type = _flatten_subtype(data_obj, subtype_key, localtypes)
return localtypes.get(flatten_mapping_type[subtype_value])
return data_obj
for subtype_key in cls.__dict__.get('_subtype_map', {}).keys():
if subtype_key in response:
subtype_value = response.pop(subtype_key)
flatten_mapping_type = cls._flatten_subtype(subtype_key, objects)
return objects[flatten_mapping_type[subtype_value]]
return cls
def _convert_to_datatype(data, data_type, localtypes):
if data is None:
@ -179,7 +153,7 @@ def _convert_to_datatype(data, data_type, localtypes):
elif issubclass(data_obj, Enum):
return data
elif not isinstance(data, data_obj):
data_obj = _infer_type(data, data_obj, localtypes)
data_obj = data_obj._classify(data, localtypes)
result = {
key: _convert_to_datatype(
data[key],
@ -809,8 +783,8 @@ class Deserializer(object):
try:
target = target._classify(data, self.dependencies)
except (TypeError, AttributeError):
pass # Target has no subclasses, so can't classify further.
except AttributeError:
pass # Target is not a Model, no classify
return target, target.__class__.__name__
def _unpack_content(self, raw_data):