Mercurial > hgrepos > Python > libs > ConfigMix
diff configmix/__init__.py @ 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 |
line wrap: on
line diff
--- 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
