comparison piecrust/configuration.py @ 805:fd694f1297c7

config: Cleanup config loading code. Add support for a `local.yml` config.
author Ludovic Chabant <ludovic@chabant.com>
date Mon, 10 Oct 2016 21:41:59 -0700
parents 7705b3d981ca
children 4850f8c21b6e
comparison
equal deleted inserted replaced
804:08e6484a2600 805:fd694f1297c7
122 for b in bits: 122 for b in bits:
123 cur = cur[b] 123 cur = cur[b]
124 return cur 124 return cur
125 125
126 126
127 def try_get_dict_value(d, key, default=None): 127 def get_dict_values(*args):
128 for d, key in args:
129 try:
130 return get_dict_value(d, key)
131 except KeyError:
132 continue
133 raise KeyError()
134
135
136 def try_get_dict_value(d, key, *, default=None):
128 try: 137 try:
129 return get_dict_value(d, key) 138 return get_dict_value(d, key)
130 except KeyError: 139 except KeyError:
131 return default 140 return default
132 141
151 if b not in cur: 160 if b not in cur:
152 cur[b] = {} 161 cur[b] = {}
153 cur = cur[b] 162 cur = cur[b]
154 163
155 164
156 def merge_dicts(source, merging, validator=None, *args): 165 MERGE_NEW_VALUES = 0
157 _recurse_merge_dicts(source, merging, None, validator) 166 MERGE_OVERWRITE_VALUES = 1
167 MERGE_PREPEND_LISTS = 2
168 MERGE_APPEND_LISTS = 4
169 MERGE_ALL = MERGE_OVERWRITE_VALUES | MERGE_PREPEND_LISTS
170
171
172 def merge_dicts(source, merging, *args,
173 validator=None, mode=MERGE_ALL):
174 _recurse_merge_dicts(source, merging, None, validator, mode)
158 for other in args: 175 for other in args:
159 _recurse_merge_dicts(source, other, None, validator) 176 _recurse_merge_dicts(source, other, None, validator, mode)
160 return source 177 return source
161 178
162 179
163 def _recurse_merge_dicts(local_cur, incoming_cur, parent_path, validator): 180 def _recurse_merge_dicts(local_cur, incoming_cur, parent_path,
181 validator, mode):
164 for k, v in incoming_cur.items(): 182 for k, v in incoming_cur.items():
165 key_path = k 183 key_path = k
166 if parent_path is not None: 184 if parent_path is not None:
167 key_path = parent_path + '/' + k 185 key_path = parent_path + '/' + k
168 186
169 local_v = local_cur.get(k) 187 local_v = local_cur.get(k)
170 if local_v is not None: 188 if local_v is not None:
171 if isinstance(v, dict) and isinstance(local_v, dict): 189 if isinstance(v, dict) and isinstance(local_v, dict):
172 _recurse_merge_dicts(local_v, v, key_path, validator) 190 _recurse_merge_dicts(local_v, v, key_path,
191 validator, mode)
173 elif isinstance(v, list) and isinstance(local_v, list): 192 elif isinstance(v, list) and isinstance(local_v, list):
174 local_cur[k] = v + local_v 193 if mode & MERGE_PREPEND_LISTS:
194 local_cur[k] = v + local_v
195 elif mode & MERGE_APPEND_LISTS:
196 local_cur[k] = local_v + v
175 else: 197 else:
198 if mode & MERGE_OVERWRITE_VALUES:
199 if validator is not None:
200 v = validator(key_path, v)
201 local_cur[k] = v
202 else:
203 if ((mode & (MERGE_PREPEND_LISTS | MERGE_APPEND_LISTS)) or
204 not isinstance(v, list)):
176 if validator is not None: 205 if validator is not None:
177 v = validator(key_path, v) 206 v = validator(key_path, v)
178 local_cur[k] = v 207 local_cur[k] = v
179 else:
180 if validator is not None:
181 v = validator(key_path, v)
182 local_cur[k] = v
183 208
184 209
185 def visit_dict(subject, visitor): 210 def visit_dict(subject, visitor):
186 _recurse_visit_dict(subject, None, visitor) 211 _recurse_visit_dict(subject, None, visitor)
187 212