changeset 448:b95c12781497

Attribute-style access for jailed configurations
author Franz Glasner <fzglas.hg@dom66.de>
date Sat, 11 Dec 2021 19:56:35 +0100
parents 4505ef8a1b56
children 5864977bb44f
files configmix/config.py tests/test.py
diffstat 2 files changed, 37 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/configmix/config.py	Fri Dec 10 12:00:24 2021 +0100
+++ b/configmix/config.py	Sat Dec 11 19:56:35 2021 +0100
@@ -847,6 +847,18 @@
         if self._path:
             new_base.getvarl(*self._path)
 
+    def __getattr__(self, name):
+        try:
+            v = self._base.getvarl_s(*(self._path + (name, )))
+        except KeyError:
+            raise AttributeError("%s has no attribute %r" % (type(self), name))
+        else:
+            # Wrap a dict into another dict with attribute access support
+            if isinstance(v, dict):
+                return _AttributeDict(v)
+            else:
+                return v
+
     def __getitem__(self, key):
         """Mapping interface that forwards to :meth:`~.getvarl_s`
 
--- a/tests/test.py	Fri Dec 10 12:00:24 2021 +0100
+++ b/tests/test.py	Sat Dec 11 19:56:35 2021 +0100
@@ -1680,6 +1680,31 @@
         self.assertTrue(
             jcfg.get([u"no", u"key"]) is None)
 
+    def test_attribute_access(self):
+        cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py"))
+        jcfg = cfg.jailed(rootpath=(u"tree1",))
+
+        self.assertEqual(0x20, jcfg.key3)
+        self.assertEqual(u"off", jcfg.tree2.key6)
+
+    def test_attribute_access_non_existing(self):
+        cfg = configmix.load(os.path.join(TESTDATADIR, "conf10.py"))
+        jcfg = cfg.jailed(rootpath=(u"tree1",))
+
+        try:
+            jcfg.non_existing
+        except AttributeError:
+            pass
+        else:
+            self.fail("AttributeError expected")
+
+        try:
+            jcfg.tree2.non_existing
+        except AttributeError:
+            pass
+        else:
+            self.fail("AttributeError expected")
+
 
 if __name__ == "__main__":
     unittest.main()