def deep_update(dict1, dict2):
def flatten(v):<EOL><INDENT>if isinstance(v, ModifyList):<EOL><INDENT>return v.apply([])<EOL><DEDENT>elif isinstance(v, dict):<EOL><INDENT>return dict((k, flatten(v_)) for k, v_ in v.iteritems())<EOL><DEDENT>else:<EOL><INDENT>return v<EOL><DEDENT><DEDENT>def merge(v1, v2):<EOL><INDENT>if isinstance(v1, dict) and isinstance(v2, dict):<EOL><INDENT>deep_update(v1, v2)<EOL>return v1<EOL><DEDENT>elif isinstance(v2, ModifyList):<EOL><INDENT>v1 = flatten(v1)<EOL>return v2.apply(v1)<EOL><DEDENT>else:<EOL><INDENT>return flatten(v2)<EOL><DEDENT><DEDENT>for k1, v1 in dict1.iteritems():<EOL><INDENT>if k1 not in dict2:<EOL><INDENT>dict1[k1] = flatten(v1)<EOL><DEDENT><DEDENT>for k2, v2 in dict2.iteritems():<EOL><INDENT>v1 = dict1.get(k2)<EOL>if v1 is KeyError:<EOL><INDENT>dict1[k2] = flatten(v2)<EOL><DEDENT>else:<EOL><INDENT>dict1[k2] = merge(v1, v2)<EOL><DEDENT><DEDENT>
Perform a deep merge of `dict2` into `dict1`.

    Note that `dict2` and any nested dicts are unchanged.

    Supports `ModifyList` instances.