Beispiel #1
0
 def test_can_parse_decimals(self):
     self.assertEqual(decimal.Decimal('1099.98'),
                      numbers.parse_decimal('1,099.98', locale='en_US'))
     self.assertEqual(decimal.Decimal('1099.98'),
                      numbers.parse_decimal('1.099,98', locale='de'))
     self.assertRaises(numbers.NumberFormatError,
                       lambda: numbers.parse_decimal('2,109,998', locale='de'))
Beispiel #2
0
def test_parse_decimal():
    assert (numbers.parse_decimal('1,099.98', locale='en_US')
            == decimal.Decimal('1099.98'))
    assert numbers.parse_decimal('1.099,98', locale='de') == decimal.Decimal('1099.98')

    with pytest.raises(numbers.NumberFormatError) as excinfo:
        numbers.parse_decimal('2,109,998', locale='de')
    assert excinfo.value.args[0] == "'2,109,998' is not a valid decimal number"
Beispiel #3
0
def test_smoke_numbers(locale):
    locale = Locale.parse(locale)
    for number in (
        decimal.Decimal("-33.76"),  # Negative Decimal
        decimal.Decimal("13.37"),  # Positive Decimal
        1.2 - 1.0,  # Inaccurate float
        10,  # Plain old integer
        0,  # Zero
    ):
        assert numbers.format_number(number, locale=locale)
Beispiel #4
0
 def apply(self, value, locale, currency=None, force_frac=None):
     frac_prec = force_frac or self.frac_prec
     if not isinstance(value, decimal.Decimal):
         value = decimal.Decimal(str(value))
     value = value.scaleb(self.scale)
     is_negative = int(value.is_signed())
     if self.exp_prec:  # Scientific notation
         exp = value.adjusted()
         value = abs(value)
         # Minimum number of integer digits
         if self.int_prec[0] == self.int_prec[1]:
             exp -= self.int_prec[0] - 1
         # Exponent grouping
         elif self.int_prec[1]:
             exp = int(exp / self.int_prec[1]) * self.int_prec[1]
         if exp < 0:
             value = value * 10**(-exp)
         else:
             value = value / 10**exp
         exp_sign = ''
         if exp < 0:
             exp_sign = get_minus_sign_symbol(locale)
         elif self.exp_plus:
             exp_sign = get_plus_sign_symbol(locale)
         exp = abs(exp)
         number = u'%s%s%s%s' % \
             (self._format_significant(value, frac_prec[0], frac_prec[1]),
              get_exponential_symbol(locale), exp_sign,
              self._format_int(str(exp), self.exp_prec[0],
                               self.exp_prec[1], locale))
     elif '@' in self.pattern:  # Is it a siginificant digits pattern?
         text = self._format_significant(abs(value), self.int_prec[0],
                                         self.int_prec[1])
         a, sep, b = text.partition(".")
         number = self._format_int(a, 0, 1000, locale)
         if sep:
             number += get_decimal_symbol(locale) + b
     else:  # A normal number pattern
         precision = decimal.Decimal('1.' + '1' * frac_prec[1])
         rounded = value.quantize(precision)
         a, sep, b = str(abs(rounded)).partition(".")
         number = (self._format_int(a, self.int_prec[0], self.int_prec[1],
                                    locale) +
                   self._format_frac(b or '0', locale, force_frac))
     retval = u'%s%s%s' % (self.prefix[is_negative], number,
                           self.suffix[is_negative])
     if u'¤' in retval:
         retval = retval.replace(u'¤¤¤',
                                 get_currency_name(currency, value, locale))
         retval = retval.replace(u'¤¤', currency.upper())
         retval = retval.replace(u'¤',
                                 get_currency_symbol(currency, locale))
     return retval
Beispiel #5
0
 def test_decimals(self):
     """Test significant digits patterns"""
     self.assertEqual(numbers.format_decimal(decimal.Decimal('1.2345'),
                                             '#.00', locale='en_US'),
                      '1.23')
     self.assertEqual(numbers.format_decimal(decimal.Decimal('1.2345000'),
                                             '#.00', locale='en_US'),
                      '1.23')
     self.assertEqual(numbers.format_decimal(decimal.Decimal('1.2345000'),
                                             '@@', locale='en_US'),
                      '1.2')
     self.assertEqual(numbers.format_decimal(decimal.Decimal('12345678901234567890.12345'),
                                             '#.00', locale='en_US'),
                      '12345678901234567890.12')
Beispiel #6
0
def extract_operands(source):
    """Extract operands from a decimal, a float or an int, according to
    `CLDR rules`_.

    .. _`CLDR rules`: http://www.unicode.org/reports/tr35/tr35-33/tr35-numbers.html#Operands
    """
    n = abs(source)
    i = int(n)
    if isinstance(n, float):
        if i == n:
            n = i
        else:
            # 2.6's Decimal cannot convert from float directly
            if sys.version_info < (2, 7):
                n = str(n)
            n = decimal.Decimal(n)

    if isinstance(n, decimal.Decimal):
        dec_tuple = n.as_tuple()
        exp = dec_tuple.exponent
        fraction_digits = dec_tuple.digits[exp:] if exp < 0 else ()
        trailing = ''.join(str(d) for d in fraction_digits)
        no_trailing = trailing.rstrip('0')
        v = len(trailing)
        w = len(no_trailing)
        f = int(trailing or 0)
        t = int(no_trailing or 0)
    else:
        v = w = f = t = 0
    return n, i, v, w, f, t
Beispiel #7
0
def parse_decimal(string, locale=LC_NUMERIC):
    """Parse localized decimal string into a decimal.

    >>> parse_decimal('1,099.98', locale='en_US')
    Decimal('1099.98')
    >>> parse_decimal('1.099,98', locale='de')
    Decimal('1099.98')

    When the given string cannot be parsed, an exception is raised:

    >>> parse_decimal('2,109,998', locale='de')
    Traceback (most recent call last):
        ...
    NumberFormatError: '2,109,998' is not a valid decimal number

    :param string: the string to parse
    :param locale: the `Locale` object or locale identifier
    :raise NumberFormatError: if the string can not be converted to a
                              decimal number
    """
    locale = Locale.parse(locale)
    try:
        return decimal.Decimal(
            string.replace(get_group_symbol(locale),
                           '').replace(get_decimal_symbol(locale), '.'))
    except decimal.InvalidOperation:
        raise NumberFormatError('%r is not a valid decimal number' % string)
Beispiel #8
0
 def test_scientific_notation(self):
     fmt = numbers.format_scientific(0.1, '#E0', locale='en_US')
     self.assertEqual(fmt, '1E-1')
     fmt = numbers.format_scientific(0.01, '#E0', locale='en_US')
     self.assertEqual(fmt, '1E-2')
     fmt = numbers.format_scientific(10, '#E0', locale='en_US')
     self.assertEqual(fmt, '1E1')
     fmt = numbers.format_scientific(1234, '0.###E0', locale='en_US')
     self.assertEqual(fmt, '1.234E3')
     fmt = numbers.format_scientific(1234, '0.#E0', locale='en_US')
     self.assertEqual(fmt, '1.2E3')
     # Exponent grouping
     fmt = numbers.format_scientific(12345, '##0.####E0', locale='en_US')
     self.assertEqual(fmt, '1.2345E4')
     # Minimum number of int digits
     fmt = numbers.format_scientific(12345, '00.###E0', locale='en_US')
     self.assertEqual(fmt, '12.345E3')
     fmt = numbers.format_scientific(-12345.6, '00.###E0', locale='en_US')
     self.assertEqual(fmt, '-12.346E3')
     fmt = numbers.format_scientific(-0.01234, '00.###E0', locale='en_US')
     self.assertEqual(fmt, '-12.34E-3')
     # Custom pattern suffic
     fmt = numbers.format_scientific(123.45, '#.##E0 m/s', locale='en_US')
     self.assertEqual(fmt, '1.23E2 m/s')
     # Exponent patterns
     fmt = numbers.format_scientific(123.45, '#.##E00 m/s', locale='en_US')
     self.assertEqual(fmt, '1.23E02 m/s')
     fmt = numbers.format_scientific(0.012345, '#.##E00 m/s', locale='en_US')
     self.assertEqual(fmt, '1.23E-02 m/s')
     fmt = numbers.format_scientific(decimal.Decimal('12345'), '#.##E+00 m/s',
                                     locale='en_US')
     self.assertEqual(fmt, '1.23E+04 m/s')
     # 0 (see ticket #99)
     fmt = numbers.format_scientific(0, '#E0', locale='en_US')
     self.assertEqual(fmt, '0E0')
Beispiel #9
0
def test_format_currency_precision(input_value, expected_value):
    # Test precision conservation.
    assert numbers.format_currency(
        decimal.Decimal(input_value),
        'USD',
        locale='en_US',
        decimal_quantization=False) == expected_value
Beispiel #10
0
def test_extract_operands(source, n, i, v, w, f, t):
    e_n, e_i, e_v, e_w, e_f, e_t = plural.extract_operands(source)
    assert abs(e_n - decimal.Decimal(n)) <= EPSILON  # float-decimal conversion inaccuracy
    assert e_i == i
    assert e_v == v
    assert e_w == w
    assert e_f == f
    assert e_t == t
Beispiel #11
0
    def apply(self, value, locale, currency=None, currency_digits=True):
        """Renders into a string a number following the defined pattern.
        """
        if not isinstance(value, decimal.Decimal):
            value = decimal.Decimal(str(value))

        value = value.scaleb(self.scale)

        # Separate the absolute value from its sign.
        is_negative = int(value.is_signed())
        value = abs(value).normalize()

        # Prepare scientific notation metadata.
        if self.exp_prec:
            value, exp, exp_sign = self.scientific_notation_elements(
                value, locale)

        # Adjust the precision of the fractionnal part and force it to the
        # currency's if neccessary.
        frac_prec = self.frac_prec
        if currency and currency_digits:
            frac_prec = (get_currency_precision(currency), ) * 2

        # Render scientific notation.
        if self.exp_prec:
            number = ''.join([
                self._quantize_value(value, locale, frac_prec),
                get_exponential_symbol(locale), exp_sign,
                self._format_int(str(exp), self.exp_prec[0], self.exp_prec[1],
                                 locale)
            ])

        # Is it a siginificant digits pattern?
        elif '@' in self.pattern:
            text = self._format_significant(value, self.int_prec[0],
                                            self.int_prec[1])
            a, sep, b = text.partition(".")
            number = self._format_int(a, 0, 1000, locale)
            if sep:
                number += get_decimal_symbol(locale) + b

        # A normal number pattern.
        else:
            number = self._quantize_value(value, locale, frac_prec)

        retval = ''.join(
            [self.prefix[is_negative], number, self.suffix[is_negative]])

        if u'¤' in retval:
            retval = retval.replace(u'¤¤¤',
                                    get_currency_name(currency, value, locale))
            retval = retval.replace(u'¤¤', currency.upper())
            retval = retval.replace(u'¤',
                                    get_currency_symbol(currency, locale))

        return retval
Beispiel #12
0
def test_parse_decimal_nbsp_heuristics():
    # Re https://github.com/python-babel/babel/issues/637 –
    #    for locales (of which there are many) that use U+00A0 as the group
    #    separator in numbers, it's reasonable to assume that input strings
    #    with plain spaces actually should have U+00A0s instead.
    #    This heuristic is only applied when strict=False.
    n = decimal.Decimal("12345.123")
    assert numbers.parse_decimal("12 345.123", locale="fi") == n
    assert numbers.parse_decimal(numbers.format_decimal(n, locale="fi"),
                                 locale="fi") == n
Beispiel #13
0
def extract_operands(source):
    """Extract operands from a decimal, a float or an int, according to `CLDR rules`_.

    The result is a 6-tuple (n, i, v, w, f, t), where those symbols are as follows:

    ====== ===============================================================
    Symbol Value
    ------ ---------------------------------------------------------------
    n      absolute value of the source number (integer and decimals).
    i      integer digits of n.
    v      number of visible fraction digits in n, with trailing zeros.
    w      number of visible fraction digits in n, without trailing zeros.
    f      visible fractional digits in n, with trailing zeros.
    t      visible fractional digits in n, without trailing zeros.
    ====== ===============================================================

    .. _`CLDR rules`: http://www.unicode.org/reports/tr35/tr35-33/tr35-numbers.html#Operands

    :param source: A real number
    :type source: int|float|decimal.Decimal
    :return: A n-i-v-w-f-t tuple
    :rtype: tuple[decimal.Decimal, int, int, int, int, int]
    """
    n = abs(source)
    i = int(n)
    if isinstance(n, float):
        if i == n:
            n = i
        else:
            # Cast the `float` to a number via the string representation.
            # This is required for Python 2.6 anyway (it will straight out fail to
            # do the conversion otherwise), and it's highly unlikely that the user
            # actually wants the lossless conversion behavior (quoting the Python
            # documentation):
            # > If value is a float, the binary floating point value is losslessly
            # > converted to its exact decimal equivalent.
            # > This conversion can often require 53 or more digits of precision.
            # Should the user want that behavior, they can simply pass in a pre-
            # converted `Decimal` instance of desired accuracy.
            n = decimal.Decimal(str(n))

    if isinstance(n, decimal.Decimal):
        dec_tuple = n.as_tuple()
        exp = dec_tuple.exponent
        fraction_digits = dec_tuple.digits[exp:] if exp < 0 else ()
        trailing = ''.join(str(d) for d in fraction_digits)
        no_trailing = trailing.rstrip('0')
        v = len(trailing)
        w = len(no_trailing)
        f = int(trailing or 0)
        t = int(no_trailing or 0)
    else:
        v = w = f = t = 0
    return n, i, v, w, f, t
Beispiel #14
0
 def _format_significant(self, value, minimum, maximum):
     exp = value.adjusted()
     scale = maximum - 1 - exp
     digits = str(value.scaleb(scale).quantize(decimal.Decimal(1)))
     if scale <= 0:
         result = digits + '0' * -scale
     else:
         intpart = digits[:-scale]
         i = len(intpart)
         j = i + max(minimum - i, 0)
         result = "{intpart}.{pad:0<{fill}}{fracpart}{fracextra}".format(
             intpart=intpart or '0',
             pad='',
             fill=-min(exp + 1, 0),
             fracpart=digits[i:j],
             fracextra=digits[j:].rstrip('0'),
         ).rstrip('.')
     return result
Beispiel #15
0
def test_very_small_decimal_no_quantization():
    assert numbers.format_decimal(decimal.Decimal('1E-7'),
                                  locale='en',
                                  decimal_quantization=False) == '0.0000001'
Beispiel #16
0
    def apply(self,
              value,
              locale,
              currency=None,
              currency_digits=True,
              decimal_quantization=True):
        """Renders into a string a number following the defined pattern.

        Forced decimal quantization is active by default so we'll produce a
        number string that is strictly following CLDR pattern definitions.
        """
        if not isinstance(value, decimal.Decimal):
            value = decimal.Decimal(str(value))

        value = value.scaleb(self.scale)

        # Separate the absolute value from its sign.
        is_negative = int(value.is_signed())
        value = abs(value).normalize()

        # Prepare scientific notation metadata.
        if self.exp_prec:
            value, exp, exp_sign = self.scientific_notation_elements(
                value, locale)

        # Adjust the precision of the fractionnal part and force it to the
        # currency's if neccessary.
        frac_prec = self.frac_prec
        if currency and currency_digits:
            frac_prec = (get_currency_precision(currency), ) * 2

        # Bump decimal precision to the natural precision of the number if it
        # exceeds the one we're about to use. This adaptative precision is only
        # triggered if the decimal quantization is disabled or if a scientific
        # notation pattern has a missing mandatory fractional part (as in the
        # default '#E0' pattern). This special case has been extensively
        # discussed at https://github.com/python-babel/babel/pull/494#issuecomment-307649969 .
        if not decimal_quantization or (self.exp_prec and frac_prec == (0, 0)):
            frac_prec = (frac_prec[0],
                         max([frac_prec[1],
                              get_decimal_precision(value)]))

        # Render scientific notation.
        if self.exp_prec:
            number = ''.join([
                self._quantize_value(value, locale, frac_prec),
                get_exponential_symbol(locale), exp_sign,
                self._format_int(str(exp), self.exp_prec[0], self.exp_prec[1],
                                 locale)
            ])

        # Is it a siginificant digits pattern?
        elif '@' in self.pattern:
            text = self._format_significant(value, self.int_prec[0],
                                            self.int_prec[1])
            a, sep, b = text.partition(".")
            number = self._format_int(a, 0, 1000, locale)
            if sep:
                number += get_decimal_symbol(locale) + b

        # A normal number pattern.
        else:
            number = self._quantize_value(value, locale, frac_prec)

        retval = ''.join(
            [self.prefix[is_negative], number, self.suffix[is_negative]])

        if u'¤' in retval:
            retval = retval.replace(u'¤¤¤',
                                    get_currency_name(currency, value, locale))
            retval = retval.replace(u'¤¤', currency.upper())
            retval = retval.replace(u'¤',
                                    get_currency_symbol(currency, locale))

        return retval
Beispiel #17
0
def test_format_percent_precision(input_value, expected_value):
    # Test precision conservation.
    assert numbers.format_percent(decimal.Decimal(input_value),
                                  locale='en_US') == expected_value
Beispiel #18
0
def test_plural_rule_operands_t():
    rule = plural.PluralRule({'one': 't = 5'})
    assert rule(decimal.Decimal('1.53')) == 'other'
    assert rule(decimal.Decimal('1.50')) == 'one'
    assert rule(1.5) == 'one'
Beispiel #19
0
def parse_decimal(string, locale=LC_NUMERIC, strict=False):
    """Parse localized decimal string into a decimal.

    >>> parse_decimal('1,099.98', locale='en_US')
    Decimal('1099.98')
    >>> parse_decimal('1.099,98', locale='de')
    Decimal('1099.98')

    When the given string cannot be parsed, an exception is raised:

    >>> parse_decimal('2,109,998', locale='de')
    Traceback (most recent call last):
        ...
    NumberFormatError: '2,109,998' is not a valid decimal number

    If `strict` is set to `True` and the given string contains a number
    formatted in an irregular way, an exception is raised:

    >>> parse_decimal('30.00', locale='de', strict=True)
    Traceback (most recent call last):
        ...
    NumberFormatError: '30.00' is not a properly formatted decimal number. Did you mean '3.000'? Or maybe '30,00'?

    >>> parse_decimal('0.00', locale='de', strict=True)
    Traceback (most recent call last):
        ...
    NumberFormatError: '0.00' is not a properly formatted decimal number. Did you mean '0'?

    :param string: the string to parse
    :param locale: the `Locale` object or locale identifier
    :param strict: controls whether numbers formatted in a weird way are
                   accepted or rejected
    :raise NumberFormatError: if the string can not be converted to a
                              decimal number
    """
    locale = Locale.parse(locale)
    group_symbol = get_group_symbol(locale)
    decimal_symbol = get_decimal_symbol(locale)
    try:
        parsed = decimal.Decimal(string.replace(group_symbol, '')
                                       .replace(decimal_symbol, '.'))
    except decimal.InvalidOperation:
        raise NumberFormatError('%r is not a valid decimal number' % string)
    if strict and group_symbol in string:
        proper = format_decimal(parsed, locale=locale, decimal_quantization=False)
        if string != proper and string.rstrip('0') != (proper + decimal_symbol):
            try:
                parsed_alt = decimal.Decimal(string.replace(decimal_symbol, '')
                                                   .replace(group_symbol, '.'))
            except decimal.InvalidOperation:
                raise NumberFormatError((
                    "%r is not a properly formatted decimal number. Did you mean %r?" %
                    (string, proper)
                ), suggestions=[proper])
            else:
                proper_alt = format_decimal(parsed_alt, locale=locale, decimal_quantization=False)
                if proper_alt == proper:
                    raise NumberFormatError((
                            "%r is not a properly formatted decimal number. Did you mean %r?" %
                            (string, proper)
                    ), suggestions=[proper])
                else:
                    raise NumberFormatError((
                        "%r is not a properly formatted decimal number. Did you mean %r? Or maybe %r?" %
                        (string, proper, proper_alt)
                    ), suggestions=[proper, proper_alt])
    return parsed
Beispiel #20
0
 def test_formatting_of_very_small_decimals(self):
     # previously formatting very small decimals could lead to a type error
     # because the Decimal->string conversion was too simple (see #214)
     number = decimal.Decimal("7E-7")
     fmt = numbers.format_decimal(number, format="@@@", locale='en_US')
     self.assertEqual('0.000000700', fmt)
Beispiel #21
0
def get_decimal_quantum(precision):
    """Return minimal quantum of a number, as defined by precision."""
    assert isinstance(precision, (int, long, decimal.Decimal))
    return decimal.Decimal(10) ** (-precision)
Beispiel #22
0
# All rights reserved.
#
# This software is licensed as described in the file LICENSE, which
# you should have received as part of this distribution. The terms
# are also available at http://babel.edgewall.org/wiki/License.
#
# This software consists of voluntary contributions made by many
# individuals. For the exact contribution history, see the revision
# history and logs, available at http://babel.edgewall.org/log/.
import unittest
import pytest

from babel import plural, localedata
from babel._compat import decimal

EPSILON = decimal.Decimal("0.0001")


def test_plural_rule():
    rule = plural.PluralRule({'one': 'n is 1'})
    assert rule(1) == 'one'
    assert rule(2) == 'other'

    rule = plural.PluralRule({'one': 'n is 1'})
    assert rule.rules == {'one': 'n is 1'}


def test_plural_rule_operands_i():
    rule = plural.PluralRule({'one': 'i is 1'})
    assert rule(1.2) == 'one'
    assert rule(2) == 'other'
Beispiel #23
0
    def apply(
        self,
        value,
        locale,
        currency=None,
        currency_digits=True,
        decimal_quantization=True,
        force_frac=None,
    ):
        """Renders into a string a number following the defined pattern.

        Forced decimal quantization is active by default so we'll produce a
        number string that is strictly following CLDR pattern definitions.

        :param value: The value to format. If this is not a Decimal object,
                      it will be cast to one.
        :type value: decimal.Decimal|float|int
        :param locale: The locale to use for formatting.
        :type locale: str|babel.core.Locale
        :param currency: Which currency, if any, to format as.
        :type currency: str|None
        :param currency_digits: Whether or not to use the currency's precision.
                                If false, the pattern's precision is used.
        :type currency_digits: bool
        :param decimal_quantization: Whether decimal numbers should be forcibly
                                     quantized to produce a formatted output
                                     strictly matching the CLDR definition for
                                     the locale.
        :type decimal_quantization: bool
        :param force_frac: DEPRECATED - a forced override for `self.frac_prec`
                           for a single formatting invocation.
        :return: Formatted decimal string.
        :rtype: str
        """
        if not isinstance(value, decimal.Decimal):
            value = decimal.Decimal(str(value))

        value = value.scaleb(self.scale)

        # Separate the absolute value from its sign.
        is_negative = int(value.is_signed())
        value = abs(value).normalize()

        # Prepare scientific notation metadata.
        if self.exp_prec:
            value, exp, exp_sign = self.scientific_notation_elements(value, locale)

        # Adjust the precision of the fractionnal part and force it to the
        # currency's if neccessary.
        if force_frac:
            # TODO (3.x?): Remove this parameter
            warnings.warn('The force_frac parameter to NumberPattern.apply() is deprecated.', DeprecationWarning)
            frac_prec = force_frac
        elif currency and currency_digits:
            frac_prec = (get_currency_precision(currency), ) * 2
        else:
            frac_prec = self.frac_prec

        # Bump decimal precision to the natural precision of the number if it
        # exceeds the one we're about to use. This adaptative precision is only
        # triggered if the decimal quantization is disabled or if a scientific
        # notation pattern has a missing mandatory fractional part (as in the
        # default '#E0' pattern). This special case has been extensively
        # discussed at https://github.com/python-babel/babel/pull/494#issuecomment-307649969 .
        if not decimal_quantization or (self.exp_prec and frac_prec == (0, 0)):
            frac_prec = (frac_prec[0], max([frac_prec[1], get_decimal_precision(value)]))

        # Render scientific notation.
        if self.exp_prec:
            number = ''.join([
                self._quantize_value(value, locale, frac_prec),
                get_exponential_symbol(locale),
                exp_sign,
                self._format_int(
                    str(exp), self.exp_prec[0], self.exp_prec[1], locale)])

        # Is it a siginificant digits pattern?
        elif '@' in self.pattern:
            text = self._format_significant(value,
                                            self.int_prec[0],
                                            self.int_prec[1])
            a, sep, b = text.partition(".")
            number = self._format_int(a, 0, 1000, locale)
            if sep:
                number += get_decimal_symbol(locale) + b

        # A normal number pattern.
        else:
            number = self._quantize_value(value, locale, frac_prec)

        retval = ''.join([
            self.prefix[is_negative],
            number,
            self.suffix[is_negative]])

        if u'¤' in retval:
            retval = retval.replace(u'¤¤¤',
                                    get_currency_name(currency, value, locale))
            retval = retval.replace(u'¤¤', currency.upper())
            retval = retval.replace(u'¤', get_currency_symbol(currency, locale))

        return retval
Beispiel #24
0
def test_plural_rule_operands_v():
    rule = plural.PluralRule({'one': 'v is 2'})
    assert rule(decimal.Decimal('1.20')) == 'one'
    assert rule(decimal.Decimal('1.2')) == 'other'
    assert rule(2) == 'other'
Beispiel #25
0
def test_decimal_precision():
    assert get_decimal_precision(decimal.Decimal('0.110')) == 2
    assert get_decimal_precision(decimal.Decimal('1.0')) == 0
    assert get_decimal_precision(decimal.Decimal('10000')) == 0
Beispiel #26
0
def test_plural_rule_operands_f():
    rule = plural.PluralRule({'one': 'f is 20'})
    assert rule(decimal.Decimal('1.23')) == 'other'
    assert rule(decimal.Decimal('1.20')) == 'one'
    assert rule(1.2) == 'other'
Beispiel #27
0
def test_format_scientific_precision(input_value, expected_value):
    # Test precision conservation.
    assert numbers.format_scientific(
        decimal.Decimal(input_value),
        locale='en_US',
        decimal_quantization=False) == expected_value
Beispiel #28
0
def test_extract_operands(source, n, i, v, w, f, t):
    source = decimal.Decimal(source) if isinstance(source, str) else source
    assert (plural.extract_operands(source) == decimal.Decimal(n), i, v, w, f,
            t)