diff configmix/config.py @ 395:0b3ffc34fa5c

Begin a jailed configuration with access to a sub-tree of the original configuration
author Franz Glasner <f.glasner@feldmann-mg.com>
date Thu, 18 Nov 2021 18:30:59 +0100
parents 44ef854da70a
children a50f8fb16b05
line wrap: on
line diff
--- a/configmix/config.py	Wed Nov 10 09:43:15 2021 +0100
+++ b/configmix/config.py	Thu Nov 18 18:30:59 2021 +0100
@@ -118,7 +118,7 @@
 
         Quoting of anything in `paths` is *not* needed and wrong.
 
-        """ 
+        """
         default = kwds.pop("default", _MARKER)
         for path in paths:
             if isinstance(path, (list, tuple)):
@@ -648,3 +648,61 @@
             else:
                 raise ValueError("unknown quote syntax string: {}".format(s))
         return ''.join(res)
+
+    def jailed(self, rootpath=None, root=None):
+        """Return a "jailed" configuration.
+
+        """
+        if rootpath is not None and root is not None:
+            raise ValueError("only one of `rootpath' or `root' can be given")
+        if rootpath is None and root is None:
+            raise ValueError("one of `rootpath' or `root' must be given")
+        if root is not None:
+            # convert to path
+            varns, varname = self._split_ns(root)
+            if varns:
+                raise ValueError(
+                    "jailed configurations do not support namespaces")
+            rootpath = [
+                self.unquote(p) for p in root.split(
+                    self._HIER_SEPARATOR)
+            ]
+            
+        return _JailedConfiguration(self, *rootpath)
+
+
+class _JailedConfiguration(object):
+
+    """Chrooted into a subtree of the configuration  -- no namespace support"""
+
+    __slots__ = ("_base", "_path", "_pathstr" )
+
+    def __init__(self, config, *path):
+        super(_JailedConfiguration, self).__init__()
+        self._base = config
+        self._path = path
+        if path:
+            self._pathstr = \
+                Configuration._HIER_SEPARATOR.join(
+                    [Configuration.quote(p) for p in path]) \
+                + Configuration._HIER_SEPARATOR
+        else:
+            self._pathstr = ''
+        #
+        # Early error out if the chroot does not exist but allow
+        # degenerated case if `self._path` is empty.
+        #
+        if self._path:
+            self._base.getvarl(*self._path)
+
+    def getvarl(self, *path, **kwds):
+        return self._base.getvarl(*(self._path + path), **kwds)
+
+    def getvarl_s(self, *path, **kwds):
+        return self._base.getvarl_s(*(self._path + path), **kwds)
+
+    def getvar(self, varname, default=_MARKER):
+        return self._base.getvar(self._pathstr + varname, default=default)
+
+    def getvar_s(self, varname, default=_MARKER):
+        return self._base.getvar_s(self._pathstr + varname, default=default)