# HG changeset patch # User Franz Glasner # Date 1701934984 -3600 # Node ID 3eb2c451026b804df77e75ff41d9897bad6162f4 # Parent 72d317c255d428c87373e8262fa12e15455f1b3f Implement Configuration.copy_new_config_without() diff -r 72d317c255d4 -r 3eb2c451026b CHANGES.txt --- 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). diff -r 72d317c255d4 -r 3eb2c451026b configmix/config.py --- 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): diff -r 72d317c255d4 -r 3eb2c451026b tests/test.py --- 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()