Skip to content
This repository was archived by the owner on Feb 3, 2021. It is now read-only.

Commit 1eeff23

Browse files
authored
Fix: models v2 deserialization (#584)
* fix model deserialization * whitespace
1 parent 49a890a commit 1eeff23

File tree

5 files changed

+60
-46
lines changed

5 files changed

+60
-46
lines changed

.style.yapf

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
[style]
2-
based_on_style = pep8
3-
spaces_before_comment = 4
4-
split_before_logical_operator = true
5-
indent_width = 4
6-
column_limit = 140
2+
based_on_style=pep8
3+
spaces_before_comment=4
4+
split_before_logical_operator=True
5+
indent_width=4
6+
column_limit=140
7+
split_arguments_when_comma_terminated=True

.vscode/settings.json

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,6 @@
1212
"${workspaceRoot}/node_scripts"
1313
],
1414
"python.formatting.provider": "yapf",
15-
"python.formatting.yapfArgs": [
16-
"--style=.style.yapf"
17-
],
1815
"python.venvPath": "${workspaceFolder}/.venv/",
1916
"python.pythonPath": "${workspaceFolder}/.venv/Scripts/python.exe",
2017
"python.unitTest.pyTestEnabled": true

aztk/core/models/model.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ def __setstate__(self, state):
6868
"""
6969
For pickle serialization. This update the current model with the given state
7070
"""
71-
self._update(state)
71+
self._update(state, ignore_missing=True)
7272

7373
def validate(self):
7474
"""
@@ -110,9 +110,13 @@ def to_dict(self):
110110
def __str__(self):
111111
return yaml.dump(self.to_dict(), default_flow_style=False)
112112

113-
def _update(self, values):
113+
def _update(self, values, ignore_missing=False):
114114
for k, v in values.items():
115-
self[k] = v
115+
try:
116+
self[k] = v
117+
except AztkAttributeError as e:
118+
if not ignore_missing:
119+
raise e
116120

117121
def _process_field_error(self, e: InvalidModelFieldError, field: str):
118122
if not e.field:

aztk/models/plugins/plugin_configuration.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,17 @@ class PluginPort(Model):
3030
public = fields.Field(default=None)
3131
name = fields.Integer()
3232

33-
def __init__(self, *args, **kwargs):
34-
super().__init__(*args, **kwargs)
35-
self.expose_publicly = bool(self.public)
36-
self.public_port = None
33+
@property
34+
def expose_publicly(self):
35+
return bool(self.public)
36+
37+
@property
38+
def public_port(self):
3739
if self.expose_publicly:
3840
if self.public is True:
39-
self.public_port = self.internal
40-
else:
41-
self.public_port = self.public
42-
41+
return self.internal
42+
return self.public
43+
return None
4344

4445
class PluginConfiguration(Model):
4546
"""

tests/core/test_models.py

Lines changed: 38 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,18 @@
88

99
# pylint: disable=C1801
1010

11+
1112
class UserState(Enum):
1213
Creating = "creating"
1314
Ready = "ready"
1415
Deleting = "deleting"
1516

17+
1618
class UserInfo(Model):
1719
name = fields.String()
1820
age = fields.Integer()
1921

22+
2023
class User(Model):
2124
info = fields.Model(UserInfo)
2225
enabled = fields.Boolean(default=True)
@@ -38,6 +41,7 @@ def test_models():
3841
assert user.enabled is False
3942
assert user.state == UserState.Creating
4043

44+
4145
def test_inherited_models():
4246
class ServiceUser(User):
4347
service = fields.String()
@@ -58,25 +62,27 @@ class ServiceUser(User):
5862
assert user.state == UserState.Ready
5963
assert user.service == "bus"
6064

65+
6166
def test_raise_error_if_extra_parameters():
6267
class SimpleNameModel(Model):
6368
name = fields.String()
6469

6570
with pytest.raises(AztkAttributeError, match="SimpleNameModel doesn't have an attribute called abc"):
6671
SimpleNameModel(name="foo", abc="123")
6772

73+
6874
def test_enum_invalid_type_raise_error():
6975
class SimpleStateModel(Model):
7076
state = fields.Enum(UserState)
7177

72-
7378
with pytest.raises(
74-
InvalidModelFieldError,
75-
match="SimpleStateModel state unknown is not a valid option. Use one of \\['creating', 'ready', 'deleting'\\]"):
79+
InvalidModelFieldError,
80+
match="SimpleStateModel state unknown is not a valid option. Use one of \\['creating', 'ready', 'deleting'\\]"):
7681

7782
obj = SimpleStateModel(state="unknown")
7883
obj.validate()
7984

85+
8086
def test_enum_parse_string():
8187
class SimpleStateModel(Model):
8288
state = fields.Enum(UserState)
@@ -87,7 +93,6 @@ class SimpleStateModel(Model):
8793
assert obj.state == UserState.Creating
8894

8995

90-
9196
def test_convert_nested_dict_to_model():
9297
user = User(
9398
info=dict(
@@ -103,6 +108,7 @@ def test_convert_nested_dict_to_model():
103108
assert user.enabled is False
104109
assert user.state == UserState.Deleting
105110

111+
106112
def test_raise_error_if_missing_required_field():
107113
class SimpleRequiredModel(Model):
108114
name = fields.String()
@@ -112,6 +118,7 @@ class SimpleRequiredModel(Model):
112118
with pytest.raises(InvalidModelFieldError, match="SimpleRequiredModel name is required"):
113119
missing.validate()
114120

121+
115122
def test_raise_error_if_string_field_invalid_type():
116123
class SimpleStringModel(Model):
117124
name = fields.String()
@@ -121,6 +128,7 @@ class SimpleStringModel(Model):
121128
with pytest.raises(InvalidModelFieldError, match="SimpleStringModel name 123 should be a string"):
122129
missing.validate()
123130

131+
124132
def test_raise_error_if_int_field_invalid_type():
125133
class SimpleIntegerModel(Model):
126134
age = fields.Integer()
@@ -130,6 +138,7 @@ class SimpleIntegerModel(Model):
130138
with pytest.raises(InvalidModelFieldError, match="SimpleIntegerModel age 123 should be an integer"):
131139
missing.validate()
132140

141+
133142
def test_raise_error_if_bool_field_invalid_type():
134143
class SimpleBoolModel(Model):
135144
enabled = fields.Boolean()
@@ -139,6 +148,7 @@ class SimpleBoolModel(Model):
139148
with pytest.raises(InvalidModelFieldError, match="SimpleBoolModel enabled false should be a boolean"):
140149
missing.validate()
141150

151+
142152
def test_merge_with_default_value():
143153
class SimpleMergeModel(Model):
144154
name = fields.String()
@@ -164,13 +174,9 @@ class ComplexModel(Model):
164174
info=dict(
165175
name="John",
166176
age=29,
167-
)
168-
)
169-
obj2 = ComplexModel(
170-
info=dict(
171-
age=38,
172-
)
177+
),
173178
)
179+
obj2 = ComplexModel(info=dict(age=38))
174180

175181
assert obj1.info.age == 29
176182
assert obj2.info.age == 38
@@ -179,6 +185,7 @@ class ComplexModel(Model):
179185
assert obj1.info.name == "John"
180186
assert obj1.info.age == 38
181187

188+
182189
def test_merge_nested_model_override_strategy():
183190
class ComplexModel(Model):
184191
model_id = fields.String()
@@ -188,13 +195,9 @@ class ComplexModel(Model):
188195
info=dict(
189196
name="John",
190197
age=29,
191-
)
192-
)
193-
obj2 = ComplexModel(
194-
info=dict(
195-
age=38,
196-
)
198+
),
197199
)
200+
obj2 = ComplexModel(info=dict(age=38))
198201

199202
assert obj1.info.age == 29
200203
assert obj2.info.age == 38
@@ -203,6 +206,7 @@ class ComplexModel(Model):
203206
assert obj1.info.name is None
204207
assert obj1.info.age == 38
205208

209+
206210
def test_list_field_convert_model_correctly():
207211
class UserList(Model):
208212
infos = fields.List(UserInfo)
@@ -212,8 +216,8 @@ class UserList(Model):
212216
dict(
213217
name="John",
214218
age=29,
215-
)
216-
]
219+
),
220+
],
217221
)
218222
obj.validate()
219223

@@ -222,34 +226,37 @@ class UserList(Model):
222226
assert obj.infos[0].name == "John"
223227
assert obj.infos[0].age == 29
224228

229+
225230
def test_list_field_is_never_required():
226231
class UserList(Model):
227232
infos = fields.List(UserInfo)
228233

229234
obj = UserList()
230235
obj.validate()
231236

232-
assert isinstance(obj.infos, (list,))
237+
assert isinstance(obj.infos, (list, ))
233238
assert len(obj.infos) == 0
234239

235240
infos = obj.infos
236241
infos.append(UserInfo())
237242
assert len(obj.infos) == 1
238243

239244
obj2 = UserList(infos=None)
240-
assert isinstance(obj2.infos, (list,))
245+
assert isinstance(obj2.infos, (list, ))
241246
assert len(obj2.infos) == 0
242247

248+
243249
def test_list_field_ignore_none_entries():
244250
class UserList(Model):
245251
infos = fields.List(UserInfo)
246252

247253
obj = UserList(infos=[None, None])
248254
obj.validate()
249255

250-
assert isinstance(obj.infos, (list,))
256+
assert isinstance(obj.infos, (list, ))
251257
assert len(obj.infos) == 0
252258

259+
253260
def test_merge_nested_model_append_strategy():
254261
class UserList(Model):
255262
infos = fields.List(UserInfo, merge_strategy=ListMergeStrategy.Append)
@@ -259,14 +266,17 @@ class UserList(Model):
259266
dict(
260267
name="John",
261268
age=29,
262-
)
263-
]
269+
),
270+
],
264271
)
272+
265273
obj2 = UserList(
266-
infos=[dict(
267-
name="Frank",
268-
age=38,
269-
)]
274+
infos=[
275+
dict(
276+
name="Frank",
277+
age=38,
278+
),
279+
],
270280
)
271281

272282
assert len(obj1.infos) == 1
@@ -296,6 +306,7 @@ def test_serialize_simple_model_to_yaml():
296306
assert info_parsed.name == "John"
297307
assert info_parsed.age == 29
298308

309+
299310
def test_serialize_nested_model_to_yaml():
300311
user = User(
301312
info=dict(name="John", age=29),

0 commit comments

Comments
 (0)