def cast(type_, value, default=ABSENT):
    """Cast a value to given type, optionally returning a default, if provided.

    :param type_: Type to cast the ``value`` into
    :param value: Value to cast into ``type_``

    :return: ``value`` casted to ``type_``.
             If cast was unsuccessful and ``default`` was provided,
             it is returned instead.

    :raise AssertionError: When ``type_`` is not actually a Python type
    :raise TypeError: When cast was unsuccessful and no ``default`` was given
    """
    # ``type_`` not being a type would theoretically be grounds for TypeError,
    # but since that kind of exception is a valid and expected outcome here
    # in some cases, we use the closest Python has to compilation error instead
    assert isinstance(type_, type)

    # conunterintuitively, invalid conversions to numeric types
    # would raise ValueError rather than the more appropriate TypeError,
    # so we correct this inconsistency
    to_number = issubclass(type_, Number)
    exception = ValueError if to_number else TypeError

    try:
        return type_(value)
    except exception as e:
        if default is ABSENT:
            if to_number:
                # since Python 3 chains exceptions, we can supply slightly
                # more relevant error message while still retaining
                # the original information of ValueError as the cause
                msg = ("cannot convert %r to %r" % (value, type_) if IS_PY3
                       else str(e))
                raise TypeError(msg)
            else:
                raise
        return type_(default)
Cast a value to given type, optionally returning a default, if provided.

    :param type_: Type to cast the ``value`` into
    :param value: Value to cast into ``type_``

    :return: ``value`` casted to ``type_``.
             If cast was unsuccessful and ``default`` was provided,
             it is returned instead.

    :raise AssertionError: When ``type_`` is not actually a Python type
    :raise TypeError: When cast was unsuccessful and no ``default`` was given