def diff_config(base, target):
if not isinstance(base, collections.Mapping):<EOL><INDENT>if base == target:<EOL><INDENT>return {}<EOL><DEDENT>return target<EOL><DEDENT>if not isinstance(target, collections.Mapping):<EOL><INDENT>return target<EOL><DEDENT>result = dict()<EOL>for k in iterkeys(base):<EOL><INDENT>if k not in target:<EOL><INDENT>result[k] = None<EOL><DEDENT><DEDENT>for k, v in iteritems(target):<EOL><INDENT>if k in base:<EOL><INDENT>merged = diff_config(base[k], v)<EOL>if merged != {}:<EOL><INDENT>result[k] = merged<EOL><DEDENT><DEDENT>else:<EOL><INDENT>result[k] = v<EOL><DEDENT><DEDENT>return result<EOL>
Find the differences between two configurations.

    This finds a delta configuration from `base` to `target`, such that
    calling :func:`overlay_config` with `base` and the result of this
    function yields `target`.  This works as follows:

    * If both are identical (of any type), returns an empty dictionary.
    * If either isn't a dictionary, returns `target`.
    * Any key in `target` not present in `base` is included in the output
      with its value from `target`.
    * Any key in `base` not present in `target` is included in the output
      with value :const:`None`.
    * Any keys present in both dictionaries are recursively merged.

    >>> diff_config({'a': 'b'}, {})
    {'a': None}
    >>> diff_config({'a': 'b'}, {'a': 'b', 'c': 'd'})
    {'c': 'd'}

    :param dict base: original configuration
    :param dict target: new configuration
    :return: overlay configuration
    :returntype dict: