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: if value is None:
return self.default return self.default
if inspect.isclass(self.type) and issubclass(self.type, DataModel): 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): if isinstance(self.type, ListOfType):
return self._validate_list_of_type(self.type.type, value) return self._validate_list_of_type(self.type.type, value)
if isinstance(self.type, DictOfType): if isinstance(self.type, DictOfType):
@@ -110,20 +110,26 @@ class DataField(object):
raise DataFieldException(self, str(e)) raise DataFieldException(self, str(e))
return value 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): def _validate_list_of_type(self, list_of_type, value):
if not isinstance(value, list): if not isinstance(value, list):
raise ValueError("Value should be a list") raise ValueError("Value should be a list")
if isinstance(list_of_type, DataField): if isinstance(list_of_type, DataField):
return [list_of_type.validate(self.parent, self.name, v) for v in value] return [list_of_type.validate(self.parent, self.name, v) for v in value]
assert issubclass(list_of_type, DataModel) 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(self, dict_of_type, value):
def _validate_dict_of_type(dict_of_type, value):
if not isinstance(value, dict):
raise ValueError("Value should be a dict")
assert issubclass(dict_of_type, DataModel) 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): def _validate_str_value(self, value):
if not isinstance(value, string_types): if not isinstance(value, string_types):

View File

@@ -439,7 +439,10 @@ def test_broken_models():
# broken SemVer # broken SemVer
with pytest.raises( with pytest.raises(
DataFieldException, DataFieldException,
match="Invalid semantic versioning format for `StrictManifestModel.version` field", match=(
"Invalid semantic versioning format for "
"`StrictManifestModel.version` field"
),
): ):
assert StrictManifestModel( assert StrictManifestModel(
name="MyPackage", name="MyPackage",
@@ -448,3 +451,15 @@ def test_broken_models():
authors=[{"name": "Author"}], authors=[{"name": "Author"}],
version="broken_version", 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",
)