Skip to content

Commit

Permalink
Unescape key on subtyping
Browse files Browse the repository at this point in the history
  • Loading branch information
lmazuel committed Feb 2, 2017
1 parent 0ac6455 commit cfc0f37
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 4 deletions.
16 changes: 12 additions & 4 deletions msrest/serialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,13 +129,21 @@ def _classify(cls, response, objects):
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
Expand Down Expand Up @@ -247,7 +255,7 @@ def _serialize(self, target_obj, data_type=None, **kwargs):
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, {})
Expand Down Expand Up @@ -752,9 +760,9 @@ def __call__(self, target_obj, response_data):
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:])

Expand Down
44 changes: 44 additions & 0 deletions test/unittest_serialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -1253,5 +1253,49 @@ def __init__(self, name=None, likes_mice=None, dislikes = None, color=None):
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()

0 comments on commit cfc0f37

Please sign in to comment.