Turn an arbitrary object into a unicode string. If complex (dict/list/tuple), will be json-encoded.
772849
def obj_to_string(obj, top=True):
    
    obj = prepare_for_json_encoding(obj)
    if type(obj) == six.text_type:
        return obj
    return json.dumps(obj)
213901
def unicode_obj(obj):
    
    if isinstance(obj, dict):
        return unicode_dict(obj)
    elif isinstance(obj, (list, tuple)):
        return unicode_list(obj)
    elif isinstance(obj, six.string_types):
        return unicode_string(obj)
    elif isinstance(obj, (int, float)):
        return obj
    elif obj is None:
        return obj
    else:
        try:
            return text(obj)
        except:
            return text(repr(obj))
743953
def json_dumps(obj,       # type: Any
               **kwargs   # type: Any
              ):  # type: (...) -> str
    
    if six.PY2:
        kwargs['encoding'] = 'utf-8'
    return json.dumps(convert_to_dict(obj), **kwargs)
81467
def get_unicode(data):
    
    # if this is a common string, return its unicode representation
    if isinstance(data, str):
        return safe_unicode(data)

    # if this is a list of values, return list of unicode values
    if isinstance(data, list):
        return [get_unicode(item) for item in data]

    # if this is a dictionary, return dictionary of unicode keys and values
    if isinstance(data, dict):
        return {
            get_unicode(key): get_unicode(value)
            for key, value in data.iteritems()
        }
    # if it's anything else, return it in its original form
    return data
87369
def unicode_convert(obj):
    
    try:
        if isinstance(obj, dict):
            return {unicode_convert(key): unicode_convert(value) for key, value in obj.items()}
        elif isinstance(obj, list):
            return [unicode_convert(element) for element in obj]
        elif isinstance(obj, str):
            return obj 
        elif isinstance(obj, six.text_type):
            return obj.encode('utf-8')
        elif isinstance(obj, six.integer_types):
            return obj
        else:
            return obj
    except:
        return obj
952393
def json_encode(obj, serialize):
    
    if hasattr(obj, 'to_dict'):
        return obj.to_dict(serialize=serialize)
    elif isinstance(obj, datetime):
        return obj.date().isoformat()
    elif isinstance(obj, date):
        return obj.isoformat()
    elif isinstance(obj, ProxyDict):
        return dict(obj)
    elif isinstance(obj, ProxyList):
        return list(obj)
    elif is_iterable_but_not_string(obj):
        return list(obj)
969297
def encode(obj):
    
    if hasattr(obj, 'json'):
        return obj.json
    if hasattr(obj, '__json__'):
        return obj.__json__()
    return dumps(obj)
1007820
def prepare_for_json_encoding(obj):
    
    obj_type = type(obj)
    if obj_type == list or obj_type == tuple:
        return [prepare_for_json_encoding(item) for item in obj]
    if obj_type == dict:
        # alphabetizing keys lets us compare attributes for equality across runs
        return OrderedDict(
            (prepare_for_json_encoding(k),
             prepare_for_json_encoding(obj[k])) for k in sorted(obj.keys())
        )
    if obj_type == six.binary_type:
        return smart_unicode_decode(obj)
    if obj_type == bool or obj is None or obj_type == six.text_type or isinstance(obj, numbers.Number):
        return obj
    if obj_type == PSLiteral:
        # special case because pdfminer.six currently adds extra quotes to PSLiteral.__repr__
        return u"/%s" % obj.name
    return six.text_type(obj)
602824
def to_json(value):
    
    if type(value) in JSON_TYPES:
        return value
    elif hasattr(value, "to_json"):
        return value.to_json()
    elif isinstance(value, list) or isinstance(value, set) or \
            isinstance(value, deque) or isinstance(value, tuple):
        return [to_json(v) for v in value]
    elif isinstance(value, dict):
        return {str(k): to_json(v) for k, v in value.items()}
    else:
        raise TypeError("{0} is not json serializable.".format(type(value)))
633613
def _structure_unicode(self, obj, cl):
        """"""
        if not isinstance(obj, (bytes, unicode)):
            return cl(str(obj))
        else:
            return obj
1307783
def unicode2str(content):
    """"""
    if isinstance(content, dict):
        result = {}
        for key in content.keys():
            result[unicode2str(key)] = unicode2str(content[key])
        return result
    elif isinstance(content, list):
        return [unicode2str(element) for element in content]
    elif isinstance(content, int) or isinstance(content, float):
        return content
    else:
        return content.encode("utf-8")
358345
def ensure_string(obj):
    

    if sys.version_info < (3, 2, 0) and isinstance(obj, unicode):
        return str(obj.encode('utf8'))
    else:
        return obj
1364253
def convert_unicode_to_str(data):
        
        if six.PY2 and isinstance(data, six.text_type):
            return data.encode('utf8')
        elif six.PY3 and isinstance(data, six.binary_type):
            return data.decode('utf8')
        elif isinstance(data, collections.Mapping):
            return dict((Util.convert_unicode_to_str(k), Util.convert_unicode_to_str(v))
                        for k, v in six.iteritems(data))
        elif isinstance(data, collections.Iterable) and not isinstance(data, (six.binary_type, six.string_types)):
            return type(data)(map(Util.convert_unicode_to_str, data))

        return data
926743
def to_unicode(obj, encoding='utf-8'):
    """"""
    if isinstance(obj, basestring):
        if not isinstance(obj, unicode):
            obj = unicode(obj, encoding)
    return obj
1007426
def utf8(item):
    """"""
    if isinstance(item, list):
        return [utf8(i) for i in item]
    if isinstance(item, tuple):
        return tuple([utf8(i) for i in item])
    if isinstance(item, dict):
        return {utf8(k): utf8(v) for k, v in item.items()}
    try:
        return item.decode('utf-8')
    except:  # bare except since this method is supposed to be safe anywhere
        return item
1088980
def to_unicode(obj, encoding='utf-8'):
    
    if isinstance(obj, string_types) or isinstance(obj, binary_type):
        if not isinstance(obj, text_type):
            obj = text_type(obj, encoding)
    return obj
3708
def encode(cls, value):
        
        try:
            coerced = list(value)
            if coerced == value:
                return json.dumps(coerced).encode(cls._encoding)
        except TypeError:
            pass

        raise InvalidValue('not a list')