def METHOD_NAME(obj: Any) -> JsonValue:
    """Convert *obj* into a JSON-serializable object.
    :param obj: A Python object.
    :return: A JSON-serializable version of *obj*, or *obj*
        if *obj* is already JSON-serializable.
    :raises TypeError: If *obj* cannot be made JSON-serializable
    """
    if obj is None:
        return None
    converted_obj = _convert_default(obj)
    if converted_obj is not obj:
        return converted_obj
    obj_type = type(obj)
    if obj_type in _PRIMITIVE_JSON_TYPES:
        return obj
    for t in _PRIMITIVE_JSON_TYPES:
        if isinstance(obj, t):
            return t(obj)
    if obj_type is dict:
        converted_obj = {_key(k): METHOD_NAME(v) for k, v in obj.items()}
        if any(converted_obj[k] is not obj[k] for k in obj.keys()):
            return converted_obj
        else:
            return obj
    if obj_type is list:
        converted_obj = [METHOD_NAME(item) for item in obj]
        if any(o1 is not o2 for o1, o2 in zip(converted_obj, obj)):
            return converted_obj
        else:
            return obj
    try:
        return {_key(k): METHOD_NAME(v) for k, v in obj.items()}
    except AttributeError:
        try:
            return [METHOD_NAME(item) for item in obj]
        except TypeError:
            # Same as json.JSONEncoder.default(self, obj)
            raise TypeError(f'Object of type'
                            f' {obj.__class__.__name__}'
                            f' is not JSON serializable')