docs: def update_dict(d, u=None, depth=-1, take_new=True, default_mapping_type=dict, prefer_update_type=False, copy=False):
      """
      Recursively merge (union or update) dict-like objects (Mapping) to the specified depth.
  
      >>> update_dict({'k1': {'k2': 2}}, {'k1': {'k2': {'k3': 3}}, 'k4': 4}) == {'k1': {'k2': {'k3': 3}}, 'k4': 4}
      True
      >>> update_dict(OrderedDict([('k1', OrderedDict([('k2', 2)]))]), {'k1': {'k2': {'k3': 3}}, 'k4': 4})
      OrderedDict([('k1', OrderedDict([('k2', {'k3': 3})])), ('k4', 4)])
      >>> update_dict(OrderedDict([('k1', dict([('k2', 2)]))]), {'k1': {'k2': {'k3': 3}}, 'k4': 4})
      OrderedDict([('k1', {'k2': {'k3': 3}}), ('k4', 4)])
      >>> orig = {'orig_key': 'orig_value'}
      >>> updated = update_dict(orig, {'new_key': 'new_value'}, copy=True)
      >>> updated == orig
      False
      >>> updated2 = update_dict(orig, {'new_key2': 'new_value2'})
      >>> updated2 == orig
      True
      >>> update_dict({'k1': {'k2': {'k3': 3}}, 'k4': 4}, {'k1': {'k2': 2}},
      ...             depth=1, take_new=False) == {'k1': {'k2': 2}, 'k4': 4}
      True
      >>> update_dict({'k1': {'k2': {'k3': 3}}, 'k4': 4}, None) == {'k1': {'k2': {'k3': 3}}, 'k4': 4}
      True
      >>> update_dict({'k1': {'k2': {'k3': 3}}, 'k4': 4}, {'k1': ()}) == {'k1': (), 'k4': 4}
      True
      >>> # FIXME: this result is unexpected the same as for `take_new=False`
      >>> update_dict({'k1': {'k2': {'k3': 3}}, 'k4': 4}, {'k1': {'k2': 2}},
      ...             depth=1, take_new=True) == {'k4': 4, 'k1': {'k2': 2}}
      True
      """
      u = u or {}
      orig_mapping_type = type(d)
      if prefer_update_type and isinstance(u, Mapping):
          dictish = type(u)
      elif isinstance(d, Mapping):
          dictish = orig_mapping_type
      else:
          dictish = default_mapping_type
      if copy:
          d = dictish(d)
      for k, v in viewitems(u):
          if isinstance(d, Mapping):
              if isinstance(v, Mapping) and not depth == 0:
                  r = update_dict(d.get(k, dictish()), v, depth=max(depth - 1, -1), copy=copy)
                  d[k] = r
              elif take_new:
                  d[k] = u[k]
          elif take_new:
              d = dictish([(k, u[k])])
      return d