def calculate_rate(phone_number, address_country_code=None, address_exception=None):
    """
    Calculates the VAT rate based on a telephone number

    :param phone_number:
        The string phone number, in international format with leading +

    :param address_country_code:
        The user's country_code, as detected from billing_address or
        declared_residence. This prevents an UndefinitiveError from being
        raised.

    :param address_exception:
        The user's exception name, as detected from billing_address or
        declared_residence. This prevents an UndefinitiveError from being
        raised.

    :raises:
        ValueError - error with phone number provided
        UndefinitiveError - when no address_country_code and address_exception are provided and the phone number area code matching isn't specific enough

    :return:
        A tuple of (Decimal percentage rate, country code, exception name [or None])
    """

    if not phone_number:
        raise ValueError('No phone number provided')

    if not isinstance(phone_number, str_cls):
        raise ValueError('Phone number is not a string')

    phone_number = phone_number.strip()
    phone_number = re.sub('[^+0-9]', '', phone_number)

    if not phone_number or phone_number[0] != '+':
        raise ValueError('Phone number is not in international format with a leading +')

    phone_number = phone_number[1:]

    if not phone_number:
        raise ValueError('Phone number does not appear to contain any digits')

    country_code = _lookup_country_code(phone_number)
    if not country_code:
        raise ValueError('Phone number does not appear to be a valid international phone number')

    if country_code in CALLING_CODE_EXCEPTIONS:
        for info in CALLING_CODE_EXCEPTIONS[country_code]:
            if not re.match(info['regex'], phone_number):
                continue

            mapped_country = info['country_code']
            mapped_name = info['name']

            if not info['definitive']:
                if address_country_code is None:
                    raise UndefinitiveError('It is not possible to determine the users VAT rates based on the information provided')

                if address_country_code != mapped_country:
                    continue

                if address_exception != info['name']:
                    continue

            rate = rates.BY_COUNTRY[mapped_country]['exceptions'][mapped_name]
            return (rate, mapped_country, mapped_name)

    if country_code not in rates.BY_COUNTRY:
        return (Decimal('0.0'), country_code, None)

    return (rates.BY_COUNTRY[country_code]['rate'], country_code, None)
Calculates the VAT rate based on a telephone number

    :param phone_number:
        The string phone number, in international format with leading +

    :param address_country_code:
        The user's country_code, as detected from billing_address or
        declared_residence. This prevents an UndefinitiveError from being
        raised.

    :param address_exception:
        The user's exception name, as detected from billing_address or
        declared_residence. This prevents an UndefinitiveError from being
        raised.

    :raises:
        ValueError - error with phone number provided
        UndefinitiveError - when no address_country_code and address_exception are provided and the phone number area code matching isn't specific enough

    :return:
        A tuple of (Decimal percentage rate, country code, exception name [or None])