view configmix/__init__.py @ 13:24ba462b9b4b

Return the `default' argument when the given `user' argument is `None' and when it is the first call on merge
author Franz Glasner <f.glasner@feldmann-mg.com>
date Wed, 09 Mar 2016 11:43:18 +0100
parents aecb36d4025f
children 6a91db2c2469
line wrap: on
line source

# -*- coding: utf-8 -*-
r"""

:Author:   Franz Glasner
:License:  BSD License.
           See LICENSE for details.

"""

from __future__ import division, print_function, absolute_import


__version__ = "0.0.dev0"


import copy


__all__ = []


if 0:
    #
    # From: https://github.com/jet9/python-yconfig/blob/master/yconfig.py
    # License: BSD License
    #
    def dict_merge(a, b):
        """Recursively merges dict's. not just simple a['key'] = b['key'], if
        both a and bhave a key who's value is a dict then dict_merge is called
        on both values and the result stored in the returned dictionary."""

        if not isinstance(b, dict):
            return b
        result = deepcopy(a)
        for k, v in b.iteritems():
            if k in result and isinstance(result[k], dict):
                result[k] = dict_merge(result[k], v)
            else:
                result[k] = deepcopy(v)
        return result


def merge(user, default, _first=True):
    """A simple (YAML-)tree merge.

    From http://stackoverflow.com/questions/823196/yaml-merge-in-python

    .. note:: `_first` is an internal argument.

    """
    if _first and (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)
    return user


def safe_merge(user, default, _first=True):
    """A more safe version of `merge()` that makes shallow copies of
    the returned container objects.

    .. note:: `_first` is an internal argument.

    """
    if _first and (user is None):
        return copy.copy(default)
    user = copy.copy(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)
            else:
                user[k] = merge(user[k], v, False)
    return user