[utils] Let traverse_obj accept functions as keys

This commit is contained in:
pukkandan 2021-10-09 08:14:41 +05:30
parent b922db9fe5
commit 2614f64600
No known key found for this signature in database
GPG Key ID: 0F00D95A001F4698

View File

@ -6335,7 +6335,9 @@ def traverse_obj(
''' Traverse nested list/dict/tuple ''' Traverse nested list/dict/tuple
@param path_list A list of paths which are checked one by one. @param path_list A list of paths which are checked one by one.
Each path is a list of keys where each key is a string, Each path is a list of keys where each key is a string,
a tuple of strings or "...". When a tuple is given, a function, a tuple of strings or "...".
When a fuction is given, it takes the key as argument and
returns whether the key matches or not. When a tuple is given,
all the keys given in the tuple are traversed, and all the keys given in the tuple are traversed, and
"..." traverses all the keys in the object "..." traverses all the keys in the object
@param default Default value to return @param default Default value to return
@ -6368,6 +6370,18 @@ def _traverse_obj(obj, path, _current_depth=0):
_current_depth += 1 _current_depth += 1
depth = max(depth, _current_depth) depth = max(depth, _current_depth)
return [_traverse_obj(inner_obj, path[i + 1:], _current_depth) for inner_obj in obj] return [_traverse_obj(inner_obj, path[i + 1:], _current_depth) for inner_obj in obj]
elif callable(key):
if isinstance(obj, (list, tuple, LazyList)):
obj = enumerate(obj)
elif isinstance(obj, dict):
obj = obj.items()
else:
if not traverse_string:
return None
obj = str(obj)
_current_depth += 1
depth = max(depth, _current_depth)
return [_traverse_obj(v, path[i + 1:], _current_depth) for k, v in obj if key(k)]
elif isinstance(obj, dict) and not (is_user_input and key == ':'): elif isinstance(obj, dict) and not (is_user_input and key == ':'):
obj = (obj.get(key) if casesense or (key in obj) obj = (obj.get(key) if casesense or (key in obj)
else next((v for k, v in obj.items() if _lower(k) == key), None)) else next((v for k, v in obj.items() if _lower(k) == key), None))