Unescape key on subtyping
This commit is contained in:
Родитель
0ac64550c1
Коммит
cfc0f372d9
|
@ -129,13 +129,21 @@ class Model(object):
|
|||
Remove the polymorphic key from the initial data.
|
||||
"""
|
||||
for subtype_key in cls.__dict__.get('_subtype_map', {}).keys():
|
||||
response_key = cls._attribute_map[subtype_key]['key']
|
||||
response_key = _decode_attribute_map_key(cls._attribute_map[subtype_key]['key'])
|
||||
if response_key in response:
|
||||
subtype_value = response.pop(response_key)
|
||||
flatten_mapping_type = cls._flatten_subtype(subtype_key, objects)
|
||||
return objects[flatten_mapping_type[subtype_value]]
|
||||
return cls
|
||||
|
||||
def _decode_attribute_map_key(key):
|
||||
"""This decode a key in an _attribute_map to the actual key we want to look at
|
||||
inside the received data.
|
||||
|
||||
:param str key: A key string from the generated code
|
||||
"""
|
||||
return key.replace('\\.', '.')
|
||||
|
||||
def _convert_to_datatype(data, data_type, localtypes):
|
||||
if data is None:
|
||||
return data
|
||||
|
@ -247,7 +255,7 @@ class Serializer(object):
|
|||
debug_name = "{}.{}".format(class_name, attr_name)
|
||||
try:
|
||||
keys = self.flatten.split(map['key'])
|
||||
keys = [k.replace('\\.', '.') for k in keys]
|
||||
keys = [_decode_attribute_map_key(k) for k in keys]
|
||||
attr_type = map['type']
|
||||
orig_attr = getattr(target_obj, attr)
|
||||
validation = target_obj._validation.get(attr_name, {})
|
||||
|
@ -752,9 +760,9 @@ class Deserializer(object):
|
|||
while '.' in key:
|
||||
dict_keys = self.flatten.split(key)
|
||||
if len(dict_keys) == 1:
|
||||
key = dict_keys[0].replace('\\.', '.')
|
||||
key = _decode_attribute_map_key(dict_keys[0])
|
||||
break
|
||||
working_key = dict_keys[0].replace('\\.', '.')
|
||||
working_key = _decode_attribute_map_key(dict_keys[0])
|
||||
working_data = working_data.get(working_key, data)
|
||||
key = '.'.join(dict_keys[1:])
|
||||
|
||||
|
|
|
@ -1253,5 +1253,49 @@ class TestRuntimeDeserialized(unittest.TestCase):
|
|||
self.assertEqual(animals[2].color, message['Animals'][2]["Color"])
|
||||
self.assertTrue(animals[2].likes_mice)
|
||||
|
||||
def test_polymorphic_deserialization_with_escape(self):
|
||||
|
||||
class Animal(Model):
|
||||
|
||||
_attribute_map = {
|
||||
"name":{"key":"Name", "type":"str"},
|
||||
"d_type":{"key":"odata\\.type", "type":"str"}
|
||||
}
|
||||
|
||||
_subtype_map = {
|
||||
'd_type': {"dog":"Dog"}
|
||||
}
|
||||
|
||||
def __init__(self, name=None):
|
||||
self.name = name
|
||||
|
||||
class Dog(Animal):
|
||||
|
||||
_attribute_map = {
|
||||
"name":{"key":"Name", "type":"str"},
|
||||
"likes_dog_food":{"key":"likesDogFood","type":"bool"},
|
||||
"d_type":{"key":"odata\\.type", "type":"str"}
|
||||
}
|
||||
|
||||
def __init__(self, name=None, likes_dog_food=None):
|
||||
self.likes_dog_food = likes_dog_food
|
||||
super(Dog, self).__init__(name)
|
||||
self.d_type = 'dog'
|
||||
|
||||
message = {
|
||||
"odata.type": "dog",
|
||||
"likesDogFood": True,
|
||||
"Name": "Fido"
|
||||
}
|
||||
|
||||
self.d.dependencies = {
|
||||
'Animal':Animal, 'Dog':Dog}
|
||||
|
||||
animal = self.d('Animal', message)
|
||||
|
||||
self.assertIsInstance(animal, Dog)
|
||||
self.assertTrue(animal.likes_dog_food)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
Загрузка…
Ссылка в новой задаче