From a1ed99962c903c2c90c4fc426e85053309fd69af Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Wed, 2 Oct 2019 12:34:50 +0300 Subject: [PATCH] Better handling of non-dict values passed to DataModel --- platformio/datamodel.py | 20 +++++++++++++------- tests/test_pkgmanifest.py | 17 ++++++++++++++++- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/platformio/datamodel.py b/platformio/datamodel.py index 4583646a..3dc4111f 100644 --- a/platformio/datamodel.py +++ b/platformio/datamodel.py @@ -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): diff --git a/tests/test_pkgmanifest.py b/tests/test_pkgmanifest.py index 72712674..ec19b29d 100644 --- a/tests/test_pkgmanifest.py +++ b/tests/test_pkgmanifest.py @@ -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 `" + ): + assert StrictManifestModel( + name="MyPackage", + description="MyDescription", + keywords=["a", "b"], + authors=["should be dict here"], + version="1.2.3", + )