changeset 762:3eb2c451026b

Implement Configuration.copy_new_config_without()
author Franz Glasner <fzglas.hg@dom66.de>
date Thu, 07 Dec 2023 08:43:04 +0100
parents 72d317c255d4
children f7d888526349
files CHANGES.txt configmix/config.py tests/test.py
diffstat 3 files changed, 57 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGES.txt	Thu Dec 07 08:42:33 2023 +0100
+++ b/CHANGES.txt	Thu Dec 07 08:43:04 2023 +0100
@@ -15,6 +15,11 @@
 n/a (n/a)
 ~~~~~~~~~
 
+- **[feature]**
+  Implement new method
+  :py:meth:`~configmix.config.Configuration.copy_new_config_without`
+  for simple cases.
+
 - **[bugfix,tests]**
   Add missing test data file(s).
   
--- a/configmix/config.py	Thu Dec 07 08:42:33 2023 +0100
+++ b/configmix/config.py	Thu Dec 07 08:43:04 2023 +0100
@@ -1184,12 +1184,36 @@
     def extract_new_config(self, *path, **kwds):
         """Get the value at `path` and make a new :class:`~.Configuration` from it.
 
-        The new config is a deepcopy and completely independent of the source
-        configuration.
+        The new configuration is a deepcopy and completely independent
+        of the source configuration.
 
         """
         return self.__class__(copy.deepcopy(self.getvarl(*path, **kwds)))
 
+    def copy_new_config_without(self, *path):
+        """Copy the current configuration but leave out the value at key
+        `path`.
+
+        The new configuration is a deepcopy and completely independent
+        of the source configuration.
+
+        .. note:: Currently only a "simple" `path` with length 1 is
+                  supported. References are not supported.
+
+        """
+        #
+        # Manual copy: avoid direct and indirect calls to self.__getitem__
+        # because it interpolates.
+        #
+        if path:
+            if len(path) != 1:
+                raise ValueError("Only a `path' with length 1 is supported")
+        nc = {}
+        for i in self:
+            if (not path) or (i != path[0]):
+                nc[i] = copy.deepcopy(self.getvarl(i))
+        return self.__class__(nc)
+
 
 class _JailedConfiguration(CoercingMethodsMixin):
 
--- a/tests/test.py	Thu Dec 07 08:42:33 2023 +0100
+++ b/tests/test.py	Thu Dec 07 08:43:04 2023 +0100
@@ -2635,6 +2635,32 @@
         self.assertEqual(u("abcQQQ123456"),
                          self._cfg.getvarl(u("globals"), u("user2"), u("pwd")))
 
+    def test_copy_new_config_complex_path(self):
+        with self.assertRaises(ValueError):
+            nc = self._cfg.copy_new_config_without("globals", "user1")
+
+    def test_copy_new_config_empty(self):
+        nc = self._cfg.copy_new_config_without()
+        nc.getvarl("globals")
+        nc.getvarl("pool")
+        nc.getvarl("section")
+        nc.getvarl("parts")
+
+    def test_copy_new_config_unexisting_path(self):
+        nc = self._cfg.copy_new_config_without("unexisting")
+        nc.getvarl("globals")
+        nc.getvarl("pool")
+        nc.getvarl("section")
+        nc.getvarl("parts")
+
+    def test_copy_new_config_existing(self):
+        nc = self._cfg.copy_new_config_without("globals")
+        with self.assertRaises(KeyError):
+            nc.getvarl("globals")
+        nc.getvarl("pool")
+        nc.getvarl("section")
+        nc.getvarl("parts")
+
 
 if __name__ == "__main__":
     unittest.main()