def METHOD_NAME(obj, key=False):
    if key:
        if not isinstance(obj, string_types):
            obj = str(obj)
        if _nameonly_re.match(obj) and obj not in reswords:
            return obj  # return it as a bare word
        else:
            return encode_string(obj)
    if obj is None:
        return 'null'
    elif obj is True or obj is False:
        return obj and 'true' or 'false'
    elif isinstance(obj, integer_types + (float,)):
        return str(obj)
    elif isinstance(obj, dict):
        return '{%s}' % ','.join(sorted('%s:%s' % (
            METHOD_NAME(key, True),
            METHOD_NAME(value)
        ) for key, value in iteritems(obj)))
    elif isinstance(obj, set):
        return '[%s]' % ','.join(sorted(METHOD_NAME(x) for x in obj))
    elif isinstance(obj, (tuple, list)):
        return '[%s]' % ','.join(METHOD_NAME(x) for x in obj)
    elif isinstance(obj, string_types):
        return encode_string(obj)
    raise TypeError(type(obj))