Ticket #14317: ticket14317.2.diff

File ticket14317.2.diff, 5.4 KB (added by Florian Apolloner, 11 years ago)
  • django/utils/numberformat.py

    diff --git a/django/utils/numberformat.py b/django/utils/numberformat.py
    index 6a31237..7939d8d 100644
    a b from django.utils.safestring import mark_safe  
    33from django.utils import six
    44
    55
    6 def format(number, decimal_sep, decimal_pos=None, grouping=0, thousand_sep='',
    7            force_grouping=False):
     6def format(number, decimal_sep, decimal_pos=None, grouping=0, thousand_sep='', force_grouping=False):
    87    """
    98    Gets a number (as a number or string), and returns it as a string,
    109    using formats defined as arguments:
    def format(number, decimal_sep, decimal_pos=None, grouping=0, thousand_sep='',  
    1716    use_grouping = settings.USE_L10N and settings.USE_THOUSAND_SEPARATOR
    1817    use_grouping = use_grouping or force_grouping
    1918    use_grouping = use_grouping and grouping > 0
     19    use_grouping = use_grouping and thousand_sep
     20
    2021    # Make the common case fast
    2122    if isinstance(number, int) and not use_grouping and not decimal_pos:
    2223        return mark_safe(six.text_type(number))
    23     # sign
    24     sign = ''
     24
     25    float_number = float(number)
    2526    str_number = six.text_type(number)
    26     if str_number[0] == '-':
     27
     28    if decimal_pos is not None:
     29        # Use the %f format string. This gives us rounding and the
     30        # right number of decimal positions automatically. This also
     31        # removes any 'e' if the number is really small or really large
     32        str_number = six.text_type(('%.' + str(decimal_pos) + 'f') % float_number)
     33
     34    if not use_grouping:
     35        return str_number.replace('.', decimal_sep)
     36
     37    # For grouping, we need to separate the sign, int_part and decimal part
     38    if float_number < 0:
    2739        sign = '-'
    2840        str_number = str_number[1:]
    29     # decimal part
    30     if '.' in str_number:
     41    else:
     42        sign = ''
     43
     44    if decimal_pos is not None or '.' in str_number:
    3145        int_part, dec_part = str_number.split('.')
    32         if decimal_pos is not None:
    33             dec_part = dec_part[:decimal_pos]
     46        dec_part = decimal_sep + dec_part
    3447    else:
    3548        int_part, dec_part = str_number, ''
    36     if decimal_pos is not None:
    37         dec_part = dec_part + ('0' * (decimal_pos - len(dec_part)))
    38     if dec_part:
    39         dec_part = decimal_sep + dec_part
    40     # grouping
    41     if use_grouping:
    42         int_part_gd = ''
    43         for cnt, digit in enumerate(int_part[::-1]):
    44             if cnt and not cnt % grouping:
    45                 int_part_gd += thousand_sep
    46             int_part_gd += digit
    47         int_part = int_part_gd[::-1]
    48     return sign + int_part + dec_part
     49
     50    first_part_len = len(int_part) % grouping
     51    full_parts = int_part[first_part_len:]
     52    groups = [full_parts[i:i + grouping] for i in range(0, len(full_parts), grouping)]
     53
     54    if first_part_len > 0:
     55        groups.insert(0, int_part[0:first_part_len])
     56
     57    return sign + thousand_sep.join(groups) + dec_part
  • tests/i18n/tests.py

    diff --git a/tests/i18n/tests.py b/tests/i18n/tests.py
    index 1022c8d..1368dbe 100644
    a b class FormattingTests(TestCase):  
    357357        Localization of numbers
    358358        """
    359359        with self.settings(USE_THOUSAND_SEPARATOR=False):
    360             self.assertEqual('66666.66', nformat(self.n, decimal_sep='.', decimal_pos=2, grouping=3, thousand_sep=','))
    361             self.assertEqual('66666A6', nformat(self.n, decimal_sep='A', decimal_pos=1, grouping=1, thousand_sep='B'))
    362             self.assertEqual('66666', nformat(self.n, decimal_sep='X', decimal_pos=0, grouping=1, thousand_sep='Y'))
     360            self.assertEqual('66666.67', nformat(self.n, decimal_sep='.', decimal_pos=2, grouping=3, thousand_sep=','))
     361            self.assertEqual('66666A7', nformat(self.n, decimal_sep='A', decimal_pos=1, grouping=1, thousand_sep='B'))
     362            self.assertEqual('66667', nformat(self.n, decimal_sep='X', decimal_pos=0, grouping=1, thousand_sep='Y'))
     363
     364            # ticket #14317
     365            self.assertEqual(u'0,00', nformat(0.000000001, decimal_sep=',', decimal_pos=2))
     366            self.assertEqual(u'0,00', nformat(0.00000000000099, decimal_sep=',', decimal_pos=2))
     367            self.assertEqual(u'0,00', nformat(decimal.Decimal(1e-37), decimal_sep=',', decimal_pos=2))
     368            self.assertEqual(u'0,67', nformat(0.666, decimal_sep=',', decimal_pos=2))
     369            self.assertEqual(u'0,67', nformat('0.666', decimal_sep=',', decimal_pos=2))
    363370
    364371        with self.settings(USE_THOUSAND_SEPARATOR=True):
    365             self.assertEqual('66,666.66', nformat(self.n, decimal_sep='.', decimal_pos=2, grouping=3, thousand_sep=','))
    366             self.assertEqual('6B6B6B6B6A6', nformat(self.n, decimal_sep='A', decimal_pos=1, grouping=1, thousand_sep='B'))
    367             self.assertEqual('-66666.6', nformat(-66666.666, decimal_sep='.', decimal_pos=1))
     372            self.assertEqual('66,666.67', nformat(self.n, decimal_sep='.', decimal_pos=2, grouping=3, thousand_sep=','))
     373            self.assertEqual('6B6B6B6B6A7', nformat(self.n, decimal_sep='A', decimal_pos=1, grouping=1, thousand_sep='B'))
     374            self.assertEqual('-66666.7', nformat(-66666.666, decimal_sep='.', decimal_pos=1))
     375
    368376            self.assertEqual('-66666.0', nformat(int('-66666'), decimal_sep='.', decimal_pos=1))
    369377            self.assertEqual('10000.0', nformat(self.l, decimal_sep='.', decimal_pos=1))
    370378            # This unusual grouping/force_grouping combination may be triggered by the intcomma filter (#17414)
Back to Top