changeset 417:83d537f1dfbb

Implement sub-jails: allow to get a jailed configuration from a jail
author Franz Glasner <fzglas.hg@dom66.de>
date Wed, 01 Dec 2021 23:10:20 +0100
parents 2abde0d3c735
children bb5f11abd12a
files CHANGES.txt configmix/config.py tests/test.py
diffstat 3 files changed, 74 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGES.txt	Wed Dec 01 23:09:00 2021 +0100
+++ b/CHANGES.txt	Wed Dec 01 23:10:20 2021 +0100
@@ -12,6 +12,13 @@
 Pre-1.0 Series
 --------------
 
+n/a
+~~~
+
+- **[feature]**
+  Allow to get sub-jails from an already jailed configuration.
+
+
 0.17 (2021-11-22)
 ~~~~~~~~~~~~~~~~~
 
--- a/configmix/config.py	Wed Dec 01 23:09:00 2021 +0100
+++ b/configmix/config.py	Wed Dec 01 23:10:20 2021 +0100
@@ -815,3 +815,38 @@
     def getfirstvar_s(self, *varnames, **kwds):
         real_varnames = [self._pathstr + vn for vn in varnames]
         return self._base.getfirstvar_s(*real_varnames, **kwds)
+
+    def jailed(self, rootpath=None, root=None, bind_root=True):
+        """Return a "jailed" configuration that effectively is a
+        subjail of the current jail
+
+        For a more complete description see :meth:`.Configuration.jailed`.
+
+        """
+        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 rootpath is not None and not isinstance(rootpath, (list, tuple)):
+            raise TypeError("`rootpath' must be a list or a tuple")
+        if root is not None:
+            # convert to path
+            varns, varname = self._base._split_ns(root)
+            if varns:
+                raise ValueError(
+                    "sub-jails do not support namespaces")
+            if varname:
+                rootpath = [
+                    self._base.unquote(p) for p in varname.split(
+                        self._base._HIER_SEPARATOR)
+                ]
+            else:
+                rootpath = tuple()
+        if self._path:
+            new_rootpath = self._path + tuple(rootpath)
+        else:
+            new_rootpath = rootpath
+        sjc = _JailedConfiguration(*new_rootpath)
+        if bind_root:
+            sjc.rebind(self._base)
+        return sjc
--- a/tests/test.py	Wed Dec 01 23:09:00 2021 +0100
+++ b/tests/test.py	Wed Dec 01 23:10:20 2021 +0100
@@ -1243,6 +1243,11 @@
         cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py"))
         jcfg = cfg.jailed(root=u"")
 
+        self.assertFalse(jcfg._path)
+        self.assertFalse(jcfg._pathstr)
+        self.assertTrue(jcfg._path is not None)
+        self.assertTrue(jcfg._pathstr is not None)
+
         self.assertTrue(jcfg.getvarl(u"tree1", u"tree2", u"key5"))
         self.assertTrue(jcfg.getvarl_s(u"tree1", u"tree2", u"key5"))
         self.assertEqual(
@@ -1259,6 +1264,11 @@
         cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py"))
         jcfg = cfg.jailed(rootpath=tuple())
 
+        self.assertFalse(jcfg._path)
+        self.assertFalse(jcfg._pathstr)
+        self.assertTrue(jcfg._path is not None)
+        self.assertTrue(jcfg._pathstr is not None)
+
         self.assertTrue(jcfg.getvarl(u"tree1", u"tree2", u"key5"))
         self.assertTrue(jcfg.getvarl_s(u"tree1", u"tree2", u"key5"))
         self.assertEqual(
@@ -1439,6 +1449,28 @@
         self.assertEqual(u"off", jcfg.getvarl_s(u"key6"))
         self.assertTrue(jcfg.getvar_s(u"key6"))
 
+    def test_subjail_from_rootpath_empty(self):
+        cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py"))
+        jcfg = cfg.jailed(rootpath=tuple())
+
+        sjcfg = jcfg.jailed(rootpath=(u"tree1",))
+
+        self.assertTrue(sjcfg._path)
+        self.assertTrue(sjcfg._pathstr)
+
+        self.assertEqual(0x20, sjcfg.getintvar_s(u"key3"))
+
+    def test_subjail_from_root_empty(self):
+        cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py"))
+        jcfg = cfg.jailed(root=u"")
+
+        sjcfg = jcfg.jailed(root=u"tree1")
+
+        self.assertTrue(sjcfg._path)
+        self.assertTrue(sjcfg._pathstr)
+
+        self.assertEqual(0x20, sjcfg.getintvar_s(u"key3"))
+
 
 if __name__ == "__main__":
     unittest.main()