code: def update(d1, d2):
      
      NoneType = type(None)
  
      if d2.get("__delete__", False):
          return {}
  
      for k, v in d2.items():
          if isinstance(v, dict):
              if v.get("__delete__", False):
                  # allow a __delete__ property to be set to delete objects
                  del d1[k]
              else:
                  d1[k] = update(d1.get(k, {}), v)
          elif isinstance(v, (tuple, list)) and all(isinstance(li, (NoneType, dict)) for li in v):
              # a list of dicts and/or NoneType
              orig_list = d1.get(k, [])
              new_list = []
              pairs = list(zip_longest(orig_list, v, fillvalue=None))
              for orig_item, new_item in pairs:
                  if orig_item is None:
                      orig_item = {}  # can't use {} for fillvalue as only one dict created/modified!
                  if new_item is None:
                      new_item = {}
  
                  if new_item.get("__delete__", False):
                      d = None  # orig_list.remove(orig_item) # remove the item to delete
                  else:
                      d = update(orig_item, new_item)
  
                  if d is not None:
                      new_list.append(d)
              d1[k] = new_list
          else:
              if k in d1 and v == "__delete__":
                  del d1[k]
              else:
                  d1[k] = v
      return d1
docs: 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