Ticket #14317: diff_14317_rvarshney.patch

File diff_14317_rvarshney.patch, 2.9 KB (added by lukenio, 11 years ago)

copy of https://github.com/rvarshney/django/commit/fda8ffc71d69eeee1721e5f595fc48e8abaab84c

  • 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
Back to Top