Ticket #14317: ticket14317.diff

File ticket14317.diff, 4.7 KB (added by akaariai, 4 years ago)
  • django/utils/numberformat.py

    diff --git a/django/utils/numberformat.py b/django/utils/numberformat.py
    index 069f498..603ce1c 100644
    a b def format(number, decimal_sep, decimal_pos, grouping=0, thousand_sep=''): 
    1414
    1515    """
    1616    use_grouping = settings.USE_L10N and \
    17         settings.USE_THOUSAND_SEPARATOR and grouping
     17        settings.USE_THOUSAND_SEPARATOR and grouping and thousand_sep
    1818    # Make the common case fast:
    1919    if isinstance(number, int) and not use_grouping and not decimal_pos:
    2020        return mark_safe(unicode(number))
    21     # sign
    22     if float(number) < 0:
     21    float_number = float(number)
     22    if decimal_pos:
     23        # Need to use %f format string, as unicode(number) can yield
     24        # exponents for sufficiently small numbers. As a bonus, we get
     25        # rounding and right amount of decimal positions directly.
     26        str_number = unicode(('%.' + str(decimal_pos) + 'f') % (num_number))
     27    else:
     28        # If decimal_pos is not given, use unicode(number), as %f will
     29        # give 6 decimal positions even if the number doesn't have that
     30        # many decimals.
     31        str_number = unicode(number)
     32    if 'e' in str_number:
     33        # The number is either too small and no decimal_pos was given,
     34        # or the number is too big. The number could be converted to
     35        # wanted format, but it is probably better to return it in
     36        # exponent form (need for documentation?)
     37        return str_number
     38    if not use_grouping:
     39        return str_number.replace('.', decimal_sep)
     40    # Using grouping, need to separate sign, int_part, decimal part
     41    if num_number < 0:
    2342        sign = '-'
     43        str_number = str_number[1:]
    2444    else:
    2545        sign = ''
    26     str_number = unicode(number)
    27     if str_number[0] == '-':
    28         str_number = str_number[1:]
    29     # decimal part
    30     if '.' in str_number:
     46    if decimal_pos or '.' in str_number:
    3147        int_part, dec_part = str_number.split('.')
    32         if decimal_pos:
    33             dec_part = dec_part[:decimal_pos]
     48        dec_part = decimal_sep + dec_part
    3449    else:
    3550        int_part, dec_part = str_number, ''
    36     if decimal_pos:
    37         dec_part = dec_part + ('0' * (decimal_pos - len(dec_part)))
    38     if dec_part: dec_part = decimal_sep + dec_part
    39     # grouping
    40     if use_grouping:
    41         int_part_gd = ''
    42         for cnt, digit in enumerate(int_part[::-1]):
    43             if cnt and not cnt % grouping:
    44                 int_part_gd += thousand_sep
    45             int_part_gd += digit
    46         int_part = int_part_gd[::-1]
    47     return sign + int_part + dec_part
     51    first_part_len = len(int_part) % grouping
     52    full_parts = int_part[first_part_len:]
     53    groups = [full_parts[i:i+grouping] \
     54        for i in range(0, len(full_parts), grouping)]
     55    if first_part_len > 0:
     56        groups.insert(0, int_part[0:first_part_len])
     57    return sign + thousand_sep.join(groups) + dec_part
    4858
  • tests/regressiontests/i18n/tests.py

    diff --git a/tests/regressiontests/i18n/tests.py b/tests/regressiontests/i18n/tests.py
    index 4aa52b6..785b7ec 100644
    a b class FormattingTests(TestCase): 
    148148        """
    149149        settings.USE_L10N = True
    150150        settings.USE_THOUSAND_SEPARATOR = False
    151         self.assertEqual(u'66666.66', nformat(self.n, decimal_sep='.', decimal_pos=2, grouping=3, thousand_sep=','))
    152         self.assertEqual(u'66666A6', nformat(self.n, decimal_sep='A', decimal_pos=1, grouping=1, thousand_sep='B'))
     151        self.assertEqual(u'66666.67', nformat(self.n, decimal_sep='.', decimal_pos=2, grouping=3, thousand_sep=','))
     152        self.assertEqual(u'66666A7', nformat(self.n, decimal_sep='A', decimal_pos=1, grouping=1, thousand_sep='B'))
     153        # ticket #14317
     154        self.assertEqual(u'0,00', nformat(0.000000001, decimal_sep=',', decimal_pos=2))
    153155
    154156        settings.USE_THOUSAND_SEPARATOR = True
    155         self.assertEqual(u'66,666.66', nformat(self.n, decimal_sep='.', decimal_pos=2, grouping=3, thousand_sep=','))
    156         self.assertEqual(u'6B6B6B6B6A6', nformat(self.n, decimal_sep='A', decimal_pos=1, grouping=1, thousand_sep='B'))
    157         self.assertEqual(u'-66666.6', nformat(-66666.666, decimal_sep='.', decimal_pos=1))
     157        self.assertEqual(u'66,666.67', nformat(self.n, decimal_sep='.', decimal_pos=2, grouping=3, thousand_sep=','))
     158        self.assertEqual(u'6B6B6B6B6A7', nformat(self.n, decimal_sep='A', decimal_pos=1, grouping=1, thousand_sep='B'))
     159        self.assertEqual(u'-66666.7', nformat(-66666.666, decimal_sep='.', decimal_pos=1))
    158160        self.assertEqual(u'-66666.0', nformat(int('-66666'), decimal_sep='.', decimal_pos=1))
    159161        self.assertEqual(u'10000.0', nformat(self.l, decimal_sep='.', decimal_pos=1))
    160162
Back to Top