A built-in solution for validating dictionaries… here is a solution to the problem.
A built-in solution for validating dictionaries
I’m using the following code to validate a dictionary (a) against another dictionary (check_against). Unfortunately, my code isn’t very readable, so I’m wondering if there’s a faster/cleaner built-in solution to achieve the same result. Maybe I just didn’t Google the right keywords, but I didn’t find any discussion about what I thought were fairly common tasks.
check_against = {
'a' : str,
'b' : {
'c': int,
'd': int,
}
}
a = {
'a' : 1,
'c' : 1
}
def get_type_at_path(obj, chain):
_key = chain.pop(0)
if _key in obj:
return key_exists(obj[_key], chain) if chain else type(obj[_key])
def root_to_leaf_paths(tree, cur=()):
if isinstance(tree,dict):
for n, s in tree.items():
for path in root_to_leaf_paths(s, cur+(n,)):
yield path
else:
yield [cur,tree]
for path,value_type in root_to_leaf_paths(check_against):
a_value_type = get_type_at_path(a,list(path))
if a_value_type == None:
print(f"Missing key at path \"{list(path)}\"")
elif not a_value_type == value_type:
print(f"Value at path \"{list(path)}\" should be of type \"{value_type}\" but got {a_value_type}")
Output
Value at path "['a']" should be of type "<class 'str'>" but got <class 'int'>
Missing key at path "['b', 'c']"
Missing key at path "['b', 'd']"