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.
|
Remove the polymorphic key from the initial data.
|
||||||
"""
|
"""
|
||||||
for subtype_key in cls.__dict__.get('_subtype_map', {}).keys():
|
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:
|
if response_key in response:
|
||||||
subtype_value = response.pop(response_key)
|
subtype_value = response.pop(response_key)
|
||||||
flatten_mapping_type = cls._flatten_subtype(subtype_key, objects)
|
flatten_mapping_type = cls._flatten_subtype(subtype_key, objects)
|
||||||
return objects[flatten_mapping_type[subtype_value]]
|
return objects[flatten_mapping_type[subtype_value]]
|
||||||
return cls
|
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):
|
def _convert_to_datatype(data, data_type, localtypes):
|
||||||
if data is None:
|
if data is None:
|
||||||
return data
|
return data
|
||||||
|
@ -247,7 +255,7 @@ class Serializer(object):
|
||||||
debug_name = "{}.{}".format(class_name, attr_name)
|
debug_name = "{}.{}".format(class_name, attr_name)
|
||||||
try:
|
try:
|
||||||
keys = self.flatten.split(map['key'])
|
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']
|
attr_type = map['type']
|
||||||
orig_attr = getattr(target_obj, attr)
|
orig_attr = getattr(target_obj, attr)
|
||||||
validation = target_obj._validation.get(attr_name, {})
|
validation = target_obj._validation.get(attr_name, {})
|
||||||
|
@ -752,9 +760,9 @@ class Deserializer(object):
|
||||||
while '.' in key:
|
while '.' in key:
|
||||||
dict_keys = self.flatten.split(key)
|
dict_keys = self.flatten.split(key)
|
||||||
if len(dict_keys) == 1:
|
if len(dict_keys) == 1:
|
||||||
key = dict_keys[0].replace('\\.', '.')
|
key = _decode_attribute_map_key(dict_keys[0])
|
||||||
break
|
break
|
||||||
working_key = dict_keys[0].replace('\\.', '.')
|
working_key = _decode_attribute_map_key(dict_keys[0])
|
||||||
working_data = working_data.get(working_key, data)
|
working_data = working_data.get(working_key, data)
|
||||||
key = '.'.join(dict_keys[1:])
|
key = '.'.join(dict_keys[1:])
|
||||||
|
|
||||||
|
|
|
@ -1253,5 +1253,49 @@ class TestRuntimeDeserialized(unittest.TestCase):
|
||||||
self.assertEqual(animals[2].color, message['Animals'][2]["Color"])
|
self.assertEqual(animals[2].color, message['Animals'][2]["Color"])
|
||||||
self.assertTrue(animals[2].likes_mice)
|
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__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
Загрузка…
Ссылка в новой задаче