# HG changeset patch # User Franz Glasner # Date 1521903968 -3600 # Node ID 29cf359ddf4d87e1206d8c5c806a0ed451fd67e5 # Parent 057d87d030f12fc35f1c3f53e5c3e487ceb9ce50 Remove the "_first" parameter from "merge" and "safe_merge" by splitting into two functions diff -r 057d87d030f1 -r 29cf359ddf4d configmix/__init__.py --- a/configmix/__init__.py Sat Mar 24 16:04:52 2018 +0100 +++ b/configmix/__init__.py Sat Mar 24 16:06:08 2018 +0100 @@ -82,39 +82,53 @@ return result -def merge(user, default, _first=True): - """A simple (YAML-)tree-merge. +def merge(user, default): + """Logically merge the configuration in `user` into `default`. :param ~configmix.config.Configuration user: - the new configuration that will be merged into `default` + the new configuration that will be logically merged + into `default` :param ~configmix.config.Configuration default: - the base configuration where `user` is merged into - :param bool _first: an intexrnal argument for controlling recursion + the base configuration where `user` is logically merged into + :returns: `user` with the necessary amendments from `default`. + If `user` is ``None`` then `default` is returned. + + .. note:: The configuration in `default` is not changed but the + configuration given in `user` is changed **inplace**. From http://stackoverflow.com/questions/823196/yaml-merge-in-python - .. note:: `_first` is an internal argument. - """ - if _first and (user is None): + if user is None: return default if isinstance(user, dict) and isinstance(default, dict): for k, v in default.items(): if k not in user: user[k] = v else: - user[k] = merge(user[k], v, False) + user[k] = _merge(user[k], v) return user -def safe_merge(user, default, _first=True): - """A more safe version of :func:`merge()` that makes shallow copies of +def _merge(user, default): + """Recursion helper for :meth:`merge` + + """ + if isinstance(user, dict) and isinstance(default, dict): + for k, v in default.items(): + if k not in user: + user[k] = v + else: + user[k] = _merge(user[k], v) + return user + + +def safe_merge(user, default): + """A more safe version of :func:`merge` that makes shallow copies of the returned container objects. - .. note:: `_first` is an internal argument. - """ - if _first and (user is None): + if user is None: return copy.copy(default) user = copy.copy(user) if isinstance(user, dict) and isinstance(default, dict): @@ -122,5 +136,5 @@ if k not in user: user[k] = copy.copy(v) else: - user[k] = merge(user[k], v, False) + user[k] = _merge(user[k], v) return user