def jsonify(o, max_depth=-1, parse_enums=PARSE_KEEP):
    if max_depth == 0:
        return o
    max_depth -= 1
    if isinstance(o, dict):
        keyattrs = getattr(o.__class__, '_altnames', {})
        def _getter(key, value):
            key = keyattrs.get(key, key)
            other = getattr(o, key, value)
            if callable(other):
                other = value
            if isinstance(key, Enum):
                key = key.name
            return key, jsonify(other, max_depth=max_depth, parse_enums=parse_enums)
        return dict(_getter(key, value) for key, value in six.iteritems(o))
    elif isinstance(o, list):
        return [jsonify(x, max_depth=max_depth, parse_enums=parse_enums) for x in o]
    elif isinstance(o, tuple):
        return (jsonify(x, max_depth=max_depth, parse_enums=parse_enums) for x in o)
    elif isinstance(o, Enum):
        o = _parse_enum(o, parse_enums=parse_enums)
    return o