import warnings


def deepmerge(a, b, path=None, overwrite=True):
    """Merges dict b into dict a

    overwrite : bool
        Overwrites value in a with value in b if True with a warning, else raises Exception

    Based on: https://stackoverflow.com/questions/7204805/how-to-merge-dictionaries-of-dictionaries/7205107#7205107
    """
    if path is None:
        path = []
    for key in b:
        if key in a:
            if isinstance(a[key], dict) and isinstance(b[key], dict):
                deepmerge(a[key], b[key], path + [str(key)])
            elif a[key] == b[key]:
                pass  # same leaf value
            else:
                if overwrite:
                    warnings.warn(
                        "Overwrote value "
                        + str(a[key])
                        + " with "
                        + str(b[key])
                        + " while merging dicts."
                    )
                    a[key] = b[key]
                else:
                    raise Exception(
                        "Conflict at %s" % ".".join(path + [str(key)])
                        + str(a[key])
                        + " conflicts with "
                        + str(b[key])
                        + " while merging dicts."
                    )
        else:
            a[key] = b[key]
    return a