Better handling of non-dict values passed to DataModel

This commit is contained in:
Ivan Kravets
2019-10-02 12:34:50 +03:00
parent c2970631a5
commit a1ed99962c
2 changed files with 29 additions and 8 deletions

View File

@ -99,7 +99,7 @@ class DataField(object):
if value is None:
return self.default
if inspect.isclass(self.type) and issubclass(self.type, DataModel):
return self.type(**value)
return self.type(**self._ensure_value_is_dict(value))
if isinstance(self.type, ListOfType):
return self._validate_list_of_type(self.type.type, value)
if isinstance(self.type, DictOfType):
@ -110,20 +110,26 @@ class DataField(object):
raise DataFieldException(self, str(e))
return value
@staticmethod
def _ensure_value_is_dict(value):
if not isinstance(value, dict):
raise ValueError("Value should be type of dict, not `%s`" % type(value))
return value
def _validate_list_of_type(self, list_of_type, value):
if not isinstance(value, list):
raise ValueError("Value should be a list")
if isinstance(list_of_type, DataField):
return [list_of_type.validate(self.parent, self.name, v) for v in value]
assert issubclass(list_of_type, DataModel)
return [list_of_type(**v) for v in value]
return [list_of_type(**self._ensure_value_is_dict(v)) for v in value]
@staticmethod
def _validate_dict_of_type(dict_of_type, value):
if not isinstance(value, dict):
raise ValueError("Value should be a dict")
def _validate_dict_of_type(self, dict_of_type, value):
assert issubclass(dict_of_type, DataModel)
return {k: dict_of_type(**v) for k, v in value.items()}
value = self._ensure_value_is_dict(value)
return {
k: dict_of_type(**self._ensure_value_is_dict(v)) for k, v in value.items()
}
def _validate_str_value(self, value):
if not isinstance(value, string_types):

View File

@ -439,7 +439,10 @@ def test_broken_models():
# broken SemVer
with pytest.raises(
DataFieldException,
match="Invalid semantic versioning format for `StrictManifestModel.version` field",
match=(
"Invalid semantic versioning format for "
"`StrictManifestModel.version` field"
),
):
assert StrictManifestModel(
name="MyPackage",
@ -448,3 +451,15 @@ def test_broken_models():
authors=[{"name": "Author"}],
version="broken_version",
)
# broken value for DataModel
with pytest.raises(
DataFieldException, match="Value should be type of dict, not `<type 'str'>"
):
assert StrictManifestModel(
name="MyPackage",
description="MyDescription",
keywords=["a", "b"],
authors=["should be dict here"],
version="1.2.3",
)