Make sure string-based non-matches return default

This commit is contained in:
Erik Johnson 2020-04-20 16:02:20 -05:00 committed by Daniel Wozniak
parent 22d3087e6b
commit 1782743bed
2 changed files with 21 additions and 2 deletions

View file

@ -831,12 +831,21 @@ def traverse_dict_and_list(data, key, default=None, delimiter=DEFAULT_TARGET_DEL
# Late import to avoid circular import
import salt.utils.args
# YAML-load the current key (catches integer dict keys)
# YAML-load the current key (catches integer/float dict keys)
try:
loaded_key = salt.utils.args.yamlify_arg(each)
except Exception: # pylint: disable=broad-except
return default
if loaded_key != each:
if loaded_key == each:
# After YAML-loading, the desired key is unchanged. This
# means that the KeyError caught above is a legitimate
# failure to match the desired key. Therefore, return the
# default.
return default
else:
# YAML-loading the key changed its value, so re-check with
# the loaded key. This is how we can match a numeric key
# with a string-based expression.
try:
ptr = ptr[loaded_key]
except (KeyError, TypeError):

View file

@ -226,6 +226,7 @@ class DataTestCase(TestCase):
{"not_found": "not_found"},
),
)
# Traverse and match integer key in a nested dict
# https://github.com/saltstack/salt/issues/56444
self.assertEqual(
@ -234,6 +235,15 @@ class DataTestCase(TestCase):
{"foo": {1234: "it worked"}}, "foo:1234", "it didn't work",
),
)
# Make sure that we properly return the default value when the initial
# attempt fails and YAML-loading the target key doesn't change its
# value.
self.assertEqual(
"default",
salt.utils.data.traverse_dict_and_list(
{"foo": {"baz": "didn't work"}}, "foo:bar", "default",
),
)
def test_compare_dicts(self):
ret = salt.utils.data.compare_dicts(old={"foo": "bar"}, new={"foo": "bar"})