Skip to content

Commit 271c36c

Browse files
authored
Fix additional properties and auto-mode serialization (#120)
* Fix additional properties and auto-mode serialization * msrest 0.5.5
1 parent 12fb980 commit 271c36c

File tree

5 files changed

+56
-9
lines changed

5 files changed

+56
-9
lines changed

README.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ To install:
2020
Release History
2121
---------------
2222

23+
2018-09-04 Version 0.5.5
24+
++++++++++++++++++++++++
25+
26+
**Bugfixes**
27+
28+
- Fix a serialization issue if additional_properties is declared, and "automatic model" syntax is used
29+
("automatic model" being the ability to pass a dict to command and have the model auto-created) # 120
30+
2331
2018-07-12 Version 0.5.4
2432
++++++++++++++++++++++++
2533

msrest/serialization.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -465,8 +465,9 @@ def _serialize(self, target_obj, data_type=None, **kwargs):
465465
if not keep_readonly and target_obj._validation.get(attr_name, {}).get('readonly', False):
466466
continue
467467

468-
if attr_name == "additional_properties" and attr_desc["key"] == '' and target_obj.additional_properties:
469-
serialized.update(target_obj.additional_properties)
468+
if attr_name == "additional_properties" and attr_desc["key"] == '':
469+
if target_obj.additional_properties is not None:
470+
serialized.update(target_obj.additional_properties)
470471
continue
471472
try:
472473
### Extract sub-data to serialize from model ###
@@ -548,6 +549,9 @@ def body(self, data, data_type, **kwargs):
548549
if internal_data_type and not isinstance(internal_data_type, Enum):
549550
try:
550551
deserializer = Deserializer(self.dependencies)
552+
# Since it's on serialization, it's almost sure that format is not JSON REST
553+
# We're not able to deal with additional properties for now.
554+
deserializer.additional_properties_detection = False
551555
if issubclass(internal_data_type, Model) and internal_data_type.is_xml_model():
552556
deserializer.key_extractors = [
553557
attribute_key_case_insensitive_extractor,
@@ -1196,6 +1200,13 @@ def __init__(self, classes=None):
11961200
rest_key_extractor,
11971201
xml_key_extractor
11981202
]
1203+
# Additional properties only works if the "rest_key_extractor" is used to
1204+
# extract the keys. Making it to work whatever the key extractor is too much
1205+
# complicated, with no real scenario for now.
1206+
# So adding a flag to disable additional properties detection. This flag should be
1207+
# used if your expect the deserialization to NOT come from a JSON REST syntax.
1208+
# Otherwise, result are unexpected
1209+
self.additional_properties_detection = True
11991210

12001211
def __call__(self, target_obj, response_data, content_type=None):
12011212
"""Call the deserializer to process a REST response.
@@ -1279,10 +1290,12 @@ def _deserialize(self, target_obj, data):
12791290
msg = "Unable to deserialize to object: " + class_name
12801291
raise_with_traceback(DeserializationError, msg, err)
12811292
else:
1282-
additional_properties = self._build_additional_properties(response._attribute_map, data)
1293+
additional_properties = self._build_additional_properties(attributes, data)
12831294
return self._instantiate_model(response, d_attrs, additional_properties)
12841295

12851296
def _build_additional_properties(self, attribute_map, data):
1297+
if not self.additional_properties_detection:
1298+
return None
12861299
if "additional_properties" in attribute_map and attribute_map.get("additional_properties", {}).get("key") != '':
12871300
# Check empty string. If it's not empty, someone has a real "additionalProperties"
12881301
return None

msrest/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,4 @@
2525
# --------------------------------------------------------------------------
2626

2727
#: version of this package. Use msrest.__version__ instead
28-
msrest_version = "0.5.4"
28+
msrest_version = "0.5.5"

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828

2929
setup(
3030
name='msrest',
31-
version='0.5.4',
31+
version='0.5.5',
3232
author='Microsoft Corporation',
3333
packages=find_packages(exclude=["tests", "tests.*"]),
3434
url=("https://github.com/Azure/msrest-for-python"),

tests/test_serialization.py

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1176,6 +1176,33 @@ def __init__(self, name=None, additional_properties=None):
11761176

11771177
self.assertEqual(serialized, expected_message)
11781178

1179+
1180+
def test_additional_properties_with_auto_model(self):
1181+
1182+
class AdditionalTest(Model):
1183+
1184+
_attribute_map = {
1185+
"name": {"key":"Name", "type":"str"},
1186+
"display_name": {"key":"DisplayName", "type":"str"},
1187+
'additional_properties': {'key': '', 'type': '{object}'}
1188+
}
1189+
1190+
o = {
1191+
'name': 'test',
1192+
'display_name': "display_name"
1193+
}
1194+
1195+
expected_message = {
1196+
"Name": "test",
1197+
"DisplayName": "display_name",
1198+
}
1199+
1200+
s = Serializer({'AdditionalTest': AdditionalTest})
1201+
1202+
serialized = s.body(o, 'AdditionalTest')
1203+
1204+
self.assertEqual(serialized, expected_message)
1205+
11791206
def test_additional_properties_declared(self):
11801207

11811208
class AdditionalTest(Model):
@@ -2133,15 +2160,13 @@ class AdditionalTest(Model):
21332160

21342161
_attribute_map = {
21352162
"name": {"key":"Name", "type":"str"},
2163+
"display_name": {"key":"DisplayName", "type":"str"},
21362164
'additional_properties': {'key': '', 'type': '{object}'}
21372165
}
21382166

2139-
def __init__(self, name=None, additional_properties=None):
2140-
self.name = name
2141-
self.additional_properties = additional_properties
2142-
21432167
message = {
21442168
"Name": "test",
2169+
"DisplayName": "diplay_name",
21452170
"PropInt": 2,
21462171
"PropStr": "AdditionalProperty",
21472172
"PropArray": [1,2,3],
@@ -2153,6 +2178,7 @@ def __init__(self, name=None, additional_properties=None):
21532178
m = d('AdditionalTest', message)
21542179

21552180
self.assertEquals(m.name, "test")
2181+
self.assertEquals(m.display_name, "diplay_name")
21562182
self.assertEquals(m.additional_properties['PropInt'], 2)
21572183
self.assertEquals(m.additional_properties['PropStr'], "AdditionalProperty")
21582184
self.assertEquals(m.additional_properties['PropArray'], [1,2,3])

0 commit comments

Comments
 (0)