# HG changeset patch # User Franz Glasner # Date 1654215432 -7200 # Node ID 0eff8441c4b9d3e21a84aac66e1f994bd06e777d # Parent 9f0842a942b2ecee18ed8f015032cc162acb9260 Implement iteration support that yields properly jailed configurations for each container item diff -r 9f0842a942b2 -r 0eff8441c4b9 CHANGES.txt --- a/CHANGES.txt Fri Jun 03 01:38:04 2022 +0200 +++ b/CHANGES.txt Fri Jun 03 02:17:12 2022 +0200 @@ -20,6 +20,12 @@ path string representation like ``~NNN~`` - **[feature]** + Implement methods :py:meth:`configmix.config.Configuration.iter_jailed` and + :py:meth:`configmix.config._JailedConfiguration.iter_jailed` that yield + properly jailed configurations for container items (for lists and dicts, + no sets). + +- **[feature]** Allow to enable and disable the internal caching - **[feature]** diff -r 9f0842a942b2 -r 0eff8441c4b9 configmix/config.py --- a/configmix/config.py Fri Jun 03 01:38:04 2022 +0200 +++ b/configmix/config.py Fri Jun 03 02:17:12 2022 +0200 @@ -1099,6 +1099,14 @@ jc.rebind(self) return jc + def iter_jailed(self, rootpath=None, root=None): + """Iterator that yields properly jailed configurations. + + `rootpath` or `root` must refer to a `list` or `dict` container. + + """ + return self.jailed(rootpath=rootpath, root=root).iter_jailed() + class _JailedConfiguration(CoercingMethodsMixin): @@ -1282,6 +1290,27 @@ """Length support for containers""" return len(self._base.getvarl_s(*self._path)) + def iter_jailed(self): + """Iteration support for containers which yields properly jailed + sub-jails. + + Only supported for type `list` or type `dict` jails. + + """ + container = self._base.getvarl(*self._path) + if isinstance(container, dict): + for k in container: + yield self.jailed(rootpath=(k, )) + elif isinstance(container, list): + len_container = len(container) + idx = 0 + while idx < len_container: + yield self.jailed(rootpath=(idx, )) + idx += 1 + else: + raise TypeError( + "jailed iterators only supported for lists and dicts") + if PY2: def __nonzero__(self): diff -r 9f0842a942b2 -r 0eff8441c4b9 tests/test.py --- a/tests/test.py Fri Jun 03 01:38:04 2022 +0200 +++ b/tests/test.py Fri Jun 03 02:17:12 2022 +0200 @@ -1946,6 +1946,29 @@ self.assertEqual((u"the-list", idx), jcfg2._path) self.assertEqual(u"the-list.~%d~." % (idx, ), jcfg2._pathstr) + def test_direct_iter_jailed(self): + cfg = configmix.load(os.path.join( + TESTDATADIR, "index-access-for-jails.yml")) + testidx = -1 + for jcfg2 in cfg.iter_jailed(rootpath=(u"the-list", )): + testidx += 1 + self.assertEqual(1, len(jcfg2)) + self.assertEqual(testidx, jcfg2.getvarl_s(u"entry")) + self.assertEqual((u"the-list", testidx), jcfg2._path) + self.assertEqual(u"the-list.~%d~." % (testidx, ), jcfg2._pathstr) + + def test_iter_jailed(self): + cfg = configmix.load(os.path.join( + TESTDATADIR, "index-access-for-jails.yml")) + jcfg = cfg.jailed(rootpath=(u"the-list",)) + testidx = -1 + for jcfg2 in jcfg.iter_jailed(): + testidx += 1 + self.assertEqual(1, len(jcfg2)) + self.assertEqual(testidx, jcfg2.getvarl_s(u"entry")) + self.assertEqual((u"the-list", testidx), jcfg2._path) + self.assertEqual(u"the-list.~%d~." % (testidx, ), jcfg2._pathstr) + def test_negative_index_jail_access(self): cfg = configmix.load(os.path.join( TESTDATADIR, "index-access-for-jails.yml"))