diff piecrust/configuration.py @ 584:9ccc933ac2c7

internal: Refactor the app configuration class. * Moved to its own module. * More extensible validation. * Allow easier setup of defaults so `showconfig` shows more useful stuff.
author Ludovic Chabant <ludovic@chabant.com>
date Fri, 01 Jan 2016 23:18:26 -0800
parents 1359b2b0cc73
children 81d9c3a3a0b5
line wrap: on
line diff
--- a/piecrust/configuration.py	Wed Dec 30 20:42:45 2015 -0800
+++ b/piecrust/configuration.py	Fri Jan 01 23:18:26 2016 -0800
@@ -1,5 +1,6 @@
 import re
 import logging
+import collections
 import collections.abc
 import yaml
 from yaml.constructor import ConstructorError
@@ -69,7 +70,7 @@
 
     def setAll(self, values, validate=False):
         if validate:
-            self._validateAll(values)
+            values = self._validateAll(values)
         self._values = values
 
     def getAll(self):
@@ -129,11 +130,10 @@
 
 
 def merge_dicts(source, merging, validator=None, *args):
-    if validator is None:
-        validator = lambda k, v: v
     _recurse_merge_dicts(source, merging, None, validator)
     for other in args:
         _recurse_merge_dicts(source, other, None, validator)
+    return source
 
 
 def _recurse_merge_dicts(local_cur, incoming_cur, parent_path, validator):
@@ -149,9 +149,28 @@
             elif isinstance(v, list) and isinstance(local_v, list):
                 local_cur[k] = v + local_v
             else:
-                local_cur[k] = validator(key_path, v)
+                if validator is not None:
+                    v = validator(key_path, v)
+                local_cur[k] = v
         else:
-            local_cur[k] = validator(key_path, v)
+            if validator is not None:
+                v = validator(key_path, v)
+            local_cur[k] = v
+
+
+def visit_dict(subject, visitor):
+    _recurse_visit_dict(subject, None, visitor)
+
+
+def _recurse_visit_dict(cur, parent_path, visitor):
+    for k, v in cur.items():
+        key_path = k
+        if parent_path is not None:
+            key_path = parent_path + '/' + k
+
+        visitor(key_path, v, cur, k)
+        if isinstance(v, dict):
+            _recurse_visit_dict(v, key_path, visitor)
 
 
 header_regex = re.compile(