docs: def kv_format_object(o, keys=None, separator=DEFAULT_SEPARATOR):
      """Formats an object's attributes.  Useful for object representation
      implementation.  Will skip methods or private attributes.
  
      For more details see :func:`kv_format`.
  
      :param o:
          Object to format.
      :param collections.Sequence keys:
          Explicit list of attributes to format.  ``None`` means all public
          visible attribute for the given object will be formatted.
      :param str separator:
          Value between two pairs.
      :return:
          Formatted Object attributes.
      :rtype:
          :data:`six.text_type <six:six.text_type>`
      """
      if keys is None:
          key_values = []
          for k, v in ((x, getattr(o, x)) for x in sorted(dir(o))):
              if k.startswith('_') or isroutine(v):
                  continue
              key_values += (k, v),
      else:
          key_values = ((k, getattr(o, k)) for k in keys)
  
      return kv_format_pairs(key_values, separator)