Fix #11 - Allo polymorphic serialization from JSON like objects

This commit is contained in:
Laurent Mazuel 2017-01-30 17:01:06 -08:00
Родитель cef4818746
Коммит 3c29e17baa
2 изменённых файлов: 71 добавлений и 14 удалений

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

@ -138,6 +138,28 @@ class Model(object):
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
def _convert_to_datatype(data, data_type, localtypes):
if data is None:
@ -157,6 +179,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)
result = {
key: _convert_to_datatype(
data[key],

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

@ -564,8 +564,8 @@ class TestRuntimeSerialized(unittest.TestCase):
"animals":{"key":"Animals", "type":"[Animal]"},
}
def __init__(self):
self.animals = None
def __init__(self, animals=None):
self.animals = animals
class Animal(Model):
@ -577,8 +577,8 @@ class TestRuntimeSerialized(unittest.TestCase):
'dType': {"cat":"Cat", "dog":"Dog"}
}
def __init__(self):
self.name = None
def __init__(self, name=None):
self.name = name
class Dog(Animal):
@ -587,9 +587,9 @@ class TestRuntimeSerialized(unittest.TestCase):
"likes_dog_food":{"key":"likesDogFood","type":"bool"}
}
def __init__(self):
self.likes_dog_food = None
super(Dog, self).__init__()
def __init__(self, name=None, likes_dog_food=None):
self.likes_dog_food = likes_dog_food
super(Dog, self).__init__(name)
class Cat(Animal):
@ -603,10 +603,10 @@ class TestRuntimeSerialized(unittest.TestCase):
"dType":{"siamese":"Siamese"}
}
def __init__(self):
self.likes_mice = None
self.dislikes = None
super(Cat, self).__init__()
def __init__(self, name=None, likes_mice=None, dislikes = None):
self.likes_mice = likes_mice
self.dislikes = dislikes
super(Cat, self).__init__(name)
class Siamese(Cat):
@ -617,9 +617,9 @@ class TestRuntimeSerialized(unittest.TestCase):
"color":{"key":"Color", "type":"str"}
}
def __init__(self):
self.color = None
super(Siamese, self).__init__()
def __init__(self, name=None, likes_mice=None, dislikes = None, color=None):
self.color = color
super(Siamese, self).__init__(name, likes_mice, dislikes)
message = {
"Animals": [
@ -669,6 +669,40 @@ class TestRuntimeSerialized(unittest.TestCase):
serialized = self.s._serialize(zoo)
self.assertEqual(serialized, message)
old_dependencies = self.s.dependencies
self.s.dependencies = {
'Zoo': Zoo,
'Animal': Animal,
'Dog': Dog,
'Cat': Cat,
'Siamese': Siamese
}
serialized = self.s.body({
"animals": [{
"dType": "dog",
"likes_dog_food": True,
"name": "Fido"
},{
"dType": "cat",
"likes_mice": False,
"dislikes": {
"dType": "dog",
"likes_dog_food": True,
"name": "Angry"
},
"name": "Felix"
},{
"dType": "siamese",
"color": "grey",
"likes_mice": True,
"name": "Finch"
}]
}, "Zoo")
self.assertEqual(serialized, message)
self.s.dependencies = old_dependencies
class TestRuntimeDeserialized(unittest.TestCase):