Mercurial > hgrepos > Python > libs > ConfigMix
changeset 134:2f2e819e8d17
Check the return type of the JSON and YAML loading functions: they must be a dict alike
| author | Franz Glasner <hg@dom66.de> |
|---|---|
| date | Thu, 05 Apr 2018 09:12:29 +0200 |
| parents | 05cb18c8697a |
| children | b7b0cea8ec6e |
| files | configmix/json.py configmix/yaml.py doc/introduction.rst tests/test.py |
| diffstat | 4 files changed, 34 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/configmix/json.py Wed Apr 04 23:51:07 2018 +0200 +++ b/configmix/json.py Thu Apr 05 09:12:29 2018 +0200 @@ -53,4 +53,7 @@ if _with_object_pairs_hook: kwds["object_pairs_hook"] = DictImpl decoder = json.decoder.JSONDecoder(**kwds) - return decoder.decode(jsfp.read()) + data = decoder.decode(jsfp.read()) + if not isinstance(data, DictImpl): + raise TypeError("JSON root must be an object") + return data
--- a/configmix/yaml.py Wed Apr 04 23:51:07 2018 +0200 +++ b/configmix/yaml.py Thu Apr 05 09:12:29 2018 +0200 @@ -151,16 +151,34 @@ def load(stream, Loader=ConfigLoader): - return yaml.load(stream, Loader) + data = yaml.load(stream, Loader) + if OrderedDict: + if not isinstance(data, OrderedDict): + raise TypeError("YAML root object must be a mapping") + return data def load_all(stream, Loader=ConfigLoader): - return yaml.load_all(stream, Loader) + data_all = yaml.load_all(stream, Loader) + if OrderedDict: + for data in data_all: + if not isinstance(data, OrderedDict): + raise TypeError("YAML root object must be a mapping") + return data_all def safe_load(stream): - return yaml.load(stream, Loader=ConfigSafeLoader) + data = yaml.load(stream, Loader=ConfigSafeLoader) + if OrderedDict: + if not isinstance(data, OrderedDict): + raise TypeError("YAML root object must be a mapping") + return data def safe_load_all(stream): - return yaml.load_all(stream, Loader=ConfigSafeLoader) + data_all = yaml.load_all(stream, Loader=ConfigSafeLoader) + if OrderedDict: + for data in data_all: + if not isinstance(data, OrderedDict): + raise TypeError("YAML root object must be a mapping") + return data_all
--- a/doc/introduction.rst Wed Apr 04 23:51:07 2018 +0200 +++ b/doc/introduction.rst Thu Apr 05 09:12:29 2018 +0200 @@ -22,8 +22,9 @@ .. note:: All strings are returned as Unicode text strings. -.. note:: The root object must be a *mapping* and therefore decode into - a Python :class:`dict` alike. +.. note:: The root object must be a *mapping* and therefore decode + into a Python :class:`dict` alike. This is checked by the + implementation. An example is: @@ -40,8 +41,9 @@ .. note:: All strings are returned as Unicode text strings. -.. note:: The root object must be an *object* and therefore decode into - a Python :class:`dict` alike. +.. note:: The root object must be an *object* and therefore decode + into a Python :class:`dict` alike. This is checked by the + implementation. .. todo:: Handle JSON comments by special attributes which will filtered out on further processing. Javascript comments are
--- a/tests/test.py Wed Apr 04 23:51:07 2018 +0200 +++ b/tests/test.py Thu Apr 05 09:12:29 2018 +0200 @@ -66,6 +66,8 @@ with io.open(os.path.join(TESTDATADIR, "conf1.yml"), "rt", encoding="utf-8") as f: cfg = configmix.yaml.safe_load(f) + if configmix.yaml.OrderedDict: + self.assertTrue(isinstance(cfg, configmix.yaml.OrderedDict)) self.__check_types(cfg) def test04_json_types(self):
