docs: def merge_errors(errors1, errors2):
      """Deeply merges two error messages. Error messages can be
      string, list of strings or dict of error messages (recursively).
      Format is the same as accepted by :exc:`ValidationError`.
      Returns new error messages.
      """
      if errors1 is None:
          return errors2
      elif errors2 is None:
          return errors1
  
      if isinstance(errors1, list):
          if not errors1:
              return errors2
  
          if isinstance(errors2, list):
              return errors1 + errors2
          elif isinstance(errors2, dict):
              return dict(
                  errors2,
                  **{SCHEMA: merge_errors(errors1, errors2.get(SCHEMA))}
              )
          else:
              return errors1 + [errors2]
      elif isinstance(errors1, dict):
          if isinstance(errors2, list):
              return dict(
                  errors1,
                  **{SCHEMA: merge_errors(errors1.get(SCHEMA), errors2)}
              )
          elif isinstance(errors2, dict):
              errors = dict(errors1)
              for k, v in iteritems(errors2):
                  if k in errors:
                      errors[k] = merge_errors(errors[k], v)
                  else:
                      errors[k] = v
              return errors
          else:
              return dict(
                  errors1,
                  **{SCHEMA: merge_errors(errors1.get(SCHEMA), errors2)}
              )
      else:
          if isinstance(errors2, list):
              return [errors1] + errors2 if errors2 else errors1
          elif isinstance(errors2, dict):
              return dict(
                  errors2,
                  **{SCHEMA: merge_errors(errors1, errors2.get(SCHEMA))}
              )
          else:
              return [errors1, errors2]