def merge_dicts(d1, d2, _path=None):
if _path is None:<EOL><INDENT>_path = ()<EOL><DEDENT>if isinstance(d1, dict) and isinstance(d2, dict):<EOL><INDENT>for k, v in d2.items():<EOL><INDENT>if isinstance(v, MissingValue) and v.name is None:<EOL><INDENT>v.name = '<STR_LIT:.>'.join(_path + (k,))<EOL><DEDENT>if isinstance(v, DeletedValue):<EOL><INDENT>d1.pop(k, None)<EOL><DEDENT>elif k not in d1:<EOL><INDENT>if isinstance(v, dict):<EOL><INDENT>d1[k] = merge_dicts({}, v, _path + (k,))<EOL><DEDENT>else:<EOL><INDENT>d1[k] = v<EOL><DEDENT><DEDENT>else:<EOL><INDENT>if isinstance(d1[k], dict) and isinstance(v, dict):<EOL><INDENT>d1[k] = merge_dicts(d1[k], v, _path + (k,))<EOL><DEDENT>elif isinstance(d1[k], list) and isinstance(v, list):<EOL><INDENT>d1[k] += v<EOL><DEDENT>elif isinstance(d1[k], MissingValue):<EOL><INDENT>d1[k] = v<EOL><DEDENT>elif d1[k] is None:<EOL><INDENT>d1[k] = v<EOL><DEDENT>elif type(d1[k]) == type(v):<EOL><INDENT>d1[k] = v<EOL><DEDENT>else:<EOL><INDENT>raise TypeError('<STR_LIT>'<EOL>% (type(d1[k]), type(v)))<EOL><DEDENT><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>raise TypeError('<STR_LIT>' % (type(d1), type(d2)))<EOL><DEDENT>return d1<EOL>
Merge dictionary d2 into d1, overriding entries in d1 with values from d2.

d1 is mutated.

_path is for internal, recursive use.