Elron commited on
Commit
6ffc9c6
1 Parent(s): 2fb8752

Upload dict_utils.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. dict_utils.py +121 -0
dict_utils.py ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from typing import Sequence
3
+
4
+ import dpath
5
+ from dpath import MutableSequence
6
+ from dpath.segments import extend
7
+
8
+
9
+ def is_subpath(subpath, fullpath):
10
+ # Normalize the paths to handle different formats and separators
11
+ subpath = os.path.normpath(subpath)
12
+ fullpath = os.path.normpath(fullpath)
13
+
14
+ # Split the paths into individual components
15
+ subpath_components = subpath.split(os.path.sep)
16
+ fullpath_components = fullpath.split(os.path.sep)
17
+
18
+ # Check if the full path starts with the subpath
19
+ return fullpath_components[: len(subpath_components)] == subpath_components
20
+
21
+
22
+ def dpath_get(dic, query_path):
23
+ return [v for _, v in dpath.search(dic, query_path, yielded=True)]
24
+
25
+
26
+ def dpath_set_one(dic, query_path, value):
27
+ n = dpath.set(dic, query_path, value)
28
+ if n != 1:
29
+ raise ValueError(f'query "{query_path}" matched multiple items in dict: {dic}')
30
+
31
+
32
+ def dict_delete(dic, query_path):
33
+ n = dpath.delete(dic, query_path)
34
+
35
+
36
+ def dict_creator(current, segments, i, hints=()):
37
+ """
38
+ Create missing path components. If the segment is an int, then it will
39
+ create a list. Otherwise a dictionary is created.
40
+
41
+ set(obj, segments, value) -> obj
42
+ """
43
+ segment = segments[i]
44
+ length = len(segments)
45
+
46
+ if isinstance(current, Sequence):
47
+ segment = int(segment)
48
+
49
+ if isinstance(current, MutableSequence):
50
+ extend(current, segment)
51
+
52
+ # Infer the type from the hints provided.
53
+ if i < len(hints):
54
+ current[segment] = hints[i][1]()
55
+ else:
56
+ # Peek at the next segment to determine if we should be
57
+ # creating an array for it to access or dictionary.
58
+ if i + 1 < length:
59
+ segment_next = segments[i + 1]
60
+ else:
61
+ segment_next = None
62
+
63
+ if isinstance(segment_next, int) or (isinstance(segment_next, str) and segment_next.isdecimal()):
64
+ current[segment] = []
65
+ else:
66
+ current[segment] = {}
67
+
68
+
69
+ def dpath_set(dic, query_path, value, not_exist_ok=True):
70
+ paths = [p for p, _ in dpath.search(dic, query_path, yielded=True)]
71
+ if len(paths) == 0 and not_exist_ok:
72
+ dpath.new(dic, query_path, value, creator=dict_creator)
73
+ else:
74
+ if len(paths) != 1:
75
+ raise ValueError(f'query "{query_path}" matched {len(paths)} items in dict: {dic}. should match only one.')
76
+ for path in paths:
77
+ dpath_set_one(dic, path, value)
78
+
79
+
80
+ def dpath_set_multiple(dic, query_path, values, not_exist_ok=True):
81
+ paths = [p for p, _ in dpath.search(dic, query_path, yielded=True)]
82
+ if len(paths) == 0:
83
+ if not_exist_ok:
84
+ raise ValueError(f"Cannot set multiple values to non-existing path: {query_path}")
85
+ raise ValueError(f'query "{query_path}" did not match any item in dict: {dic}')
86
+ else:
87
+ if len(paths) != len(values):
88
+ raise ValueError(
89
+ f'query "{query_path}" matched {len(paths)} items in dict: {dic} but {len(values)} values are provided. should match only one.'
90
+ )
91
+ for path, value in zip(paths, values):
92
+ dpath_set_one(dic, path, value)
93
+
94
+
95
+ def dict_get(dic, query, use_dpath=True, not_exist_ok=False, default=None):
96
+ if use_dpath:
97
+ values = dpath_get(dic, query)
98
+ if len(values) == 0 and not_exist_ok:
99
+ return default
100
+ elif len(values) == 0:
101
+ raise ValueError(f'query "{query}" did not match any item in dict: {dic}')
102
+
103
+ if len(values) == 1:
104
+ return values[0]
105
+
106
+ return values
107
+ else:
108
+ if not_exist_ok:
109
+ return dic.get(query, default)
110
+ else:
111
+ return dic[query]
112
+
113
+
114
+ def dict_set(dic, query, value, use_dpath=True, not_exist_ok=True, set_multiple=False):
115
+ if use_dpath:
116
+ if set_multiple:
117
+ dpath_set_multiple(dic, query, value, not_exist_ok=not_exist_ok)
118
+ else:
119
+ dpath_set(dic, query, value, not_exist_ok=not_exist_ok)
120
+ else:
121
+ dic[query] = value