Mercurial > hgrepos > Python > libs > ConfigMix
changeset 111:d51a18e5b0e3
Reimplement configmix.safe_merge() do to a deepcopy of all source configurations when merging.
configmix.safe_merge() does now a deepcopy of all source
configurations when merging. Changes in configuration instances after
will not be reflected in the merged configuration any more.
| author | Franz Glasner <hg@dom66.de> |
|---|---|
| date | Sat, 24 Mar 2018 18:47:54 +0100 |
| parents | 29cf359ddf4d |
| children | c50ad93eb5dc |
| files | CHANGES.txt configmix/__init__.py doc/changes.rst doc/conf.py |
| diffstat | 4 files changed, 43 insertions(+), 11 deletions(-) [+] |
line wrap: on
line diff
--- a/CHANGES.txt Sat Mar 24 16:06:08 2018 +0100 +++ b/CHANGES.txt Sat Mar 24 18:47:54 2018 +0100 @@ -1,7 +1,7 @@ .. -*- coding: utf-8; mode: rst; indent-tabs-mode: nil; -*- .. -.. Valid tags: doc, feature, bugfix, test +.. Valid tags: doc, feature, bugfix, test, breaking .. .. _changelog: @@ -16,6 +16,12 @@ :version: 0.6 .. change:: + :tags: breaking, feature + + Reimplement :py:func:`configmix.safe_merge` do to a deepcopy of all + source configurations when merging + + .. change:: :tags: doc Begin the documentation with `Sphinx <http://www.sphinx-doc.org>`_ @@ -30,6 +36,7 @@ Build a tree of configuration settings from INI files + .. changelog:: :version: 0.5 :released: 2016-04-19
--- a/configmix/__init__.py Sat Mar 24 16:06:08 2018 +0100 +++ b/configmix/__init__.py Sat Mar 24 18:47:54 2018 +0100 @@ -124,17 +124,34 @@ def safe_merge(user, default): - """A more safe version of :func:`merge` that makes shallow copies of + """A more safe version of :func:`merge` that makes deep copies of the returned container objects. + No given argument is ever changed inplace. Every object from `default` + is decoupled from the result -- so changing the `default` configuration + lates does not yield into a merged configuration later. + """ if user is None: - return copy.copy(default) - user = copy.copy(user) + return copy.deepcopy(default) + user = copy.deepcopy(user) if isinstance(user, dict) and isinstance(default, dict): for k, v in default.items(): if k not in user: - user[k] = copy.copy(v) + user[k] = copy.deepcopy(v) else: - user[k] = _merge(user[k], v) + user[k] = _safe_merge(user[k], v) return user + + +def _safe_merge(user, default): + """Recursion helper for :meth:`safe_merge` + + """ + if isinstance(user, dict) and isinstance(default, dict): + for k, v in default.items(): + if k not in user: + user[k] = copy.deepcopy(v) + else: + user[k] = _safe_merge(user[k], v) + return user
--- a/doc/changes.rst Sat Mar 24 16:06:08 2018 +0100 +++ b/doc/changes.rst Sat Mar 24 18:47:54 2018 +0100 @@ -4,7 +4,7 @@ Changes ========= -All major changes over the versions are listed here. For API breaking +All major changes over the versions are listed here. For breaking changes have a look at :ref:`api-changes`, they are listed there in detail. @@ -13,7 +13,15 @@ .. _api-changes: -API Breaking Changes -==================== +Breaking Changes +================ + +0.6 +--- -No incompatible changes yet. +- :py:func:`configmix.safe_merge` does now a deepcopy of all source + configurations when merging. Changes in configuration instances after + will not be reflected in the merged configuration any more. + + The public signature of :py:func:`configmix.safe_merge` has *not* + changed.
--- a/doc/conf.py Sat Mar 24 16:06:08 2018 +0100 +++ b/doc/conf.py Sat Mar 24 18:47:54 2018 +0100 @@ -211,4 +211,4 @@ # -- Options for changelog --------------------------------------------------- -changelog_inner_tag_sort = ['feature', 'bugfix', 'test', 'doc'] +changelog_inner_tag_sort = ['breaking', 'feature', 'bugfix', 'test', 'doc']
