def update(d1, d2):
NoneType = type(None)<EOL>if d2.get("<STR_LIT>", False):<EOL><INDENT>return {}<EOL><DEDENT>for k, v in d2.items():<EOL><INDENT>if isinstance(v, dict):<EOL><INDENT>if v.get("<STR_LIT>", False):<EOL><INDENT>del d1[k]<EOL><DEDENT>else:<EOL><INDENT>d1[k] = update(d1.get(k, {}), v)<EOL><DEDENT><DEDENT>elif isinstance(v, (tuple, list)) and all(isinstance(li, (NoneType, dict)) for li in v):<EOL><INDENT>orig_list = d1.get(k, [])<EOL>new_list = []<EOL>pairs = list(zip_longest(orig_list, v, fillvalue=None))<EOL>for orig_item, new_item in pairs:<EOL><INDENT>if orig_item is None:<EOL><INDENT>orig_item = {}  <EOL><DEDENT>if new_item is None:<EOL><INDENT>new_item = {}<EOL><DEDENT>if new_item.get("<STR_LIT>", False):<EOL><INDENT>d = None  <EOL><DEDENT>else:<EOL><INDENT>d = update(orig_item, new_item)<EOL><DEDENT>if d is not None:<EOL><INDENT>new_list.append(d)<EOL><DEDENT><DEDENT>d1[k] = new_list<EOL><DEDENT>else:<EOL><INDENT>if k in d1 and v == "<STR_LIT>":<EOL><INDENT>del d1[k]<EOL><DEDENT>else:<EOL><INDENT>d1[k] = v<EOL><DEDENT><DEDENT><DEDENT>return d1<EOL>
Update dict d1 with properties from d2

Note
----

Allows deletion of objects with a special ``__delete__`` key
For any list of dicts new items can be added when updating

Parameters
----------

d1: dict
    A Python dictionary
d2: dict
    A Python dictionary that will be used to update any keys with the same name in d1

Returns
-------

dict
    The updated dictionary