diff --git a/podman/api/http_utils.py b/podman/api/http_utils.py index cf759ac2..41036d02 100644 --- a/podman/api/http_utils.py +++ b/podman/api/http_utils.py @@ -66,26 +66,33 @@ def prepare_body(body: Mapping[str, Any]) -> str: return json.dumps(body, sort_keys=True) -def _filter_values(mapping: Mapping[str, Any]) -> Dict[str, Any]: +def _filter_values(mapping: Mapping[str, Any], recursion=False) -> Dict[str, Any]: """Returns a canonical dictionary with values == None or empty Iterables removed. Dictionary is walked using recursion. """ canonical = {} + for key, value in mapping.items(): # quick filter if possible... - if value is None or (isinstance(value, collections.abc.Sized) and len(value) <= 0): + if ( + value is None + or (isinstance(value, collections.abc.Sized) and len(value) <= 0) + and not recursion + ): continue # depending on type we need details... if isinstance(value, collections.abc.Mapping): - proposal = _filter_values(value) + proposal = _filter_values(value, recursion=True) elif isinstance(value, collections.abc.Iterable) and not isinstance(value, str): proposal = [i for i in value if i is not None] else: proposal = value - if proposal not in (None, str(), [], {}): + if not recursion and proposal not in (None, str(), [], {}): + canonical[key] = proposal + elif recursion and proposal not in (None, [], {}): canonical[key] = proposal return canonical diff --git a/podman/tests/unit/test_api_utils.py b/podman/tests/unit/test_api_utils.py index b58466e2..dcafc294 100644 --- a/podman/tests/unit/test_api_utils.py +++ b/podman/tests/unit/test_api_utils.py @@ -154,6 +154,16 @@ def test_prepare_body_embedded(self): self.assertDictEqual(actual_dict["Dictionary"], payload["Dictionary"]) self.assertEqual(set(actual_dict["Set1"]), {"item1", "item2"}) + def test_prepare_body_dict_empty_string(self): + payload = {"Dictionary": {"key1": "", "key2": {"key3": ""}, "key4": [], "key5": {}}} + + actual = api.prepare_body(payload) + actual_dict = json.loads(actual) + payload["Dictionary"].pop("key4") + payload["Dictionary"].pop("key5") + + self.assertDictEqual(payload, actual_dict) + if __name__ == '__main__': unittest.main()