Opened 9 years ago

Closed 9 years ago

#24382 closed Cleanup/optimization (fixed)

django.utils.numberformat should be UTF-8 safe

Reported by: Jacob Rief Owned by: alainivars
Component: Utilities Version: 1.8alpha1
Severity: Normal Keywords:
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: yes UI/UX: no

Description

By adding

from __future__ import unicode_literals

to django/utils/numberformat.py, one could write formatters for numbers in charsets other than ASCII, for instance code block U+2150 through U+218F, which contains the representation of Roman numbers in UTF-8.

Change History (16)

comment:1 by Claude Paroz, 9 years ago

Component: Core (Other)Utilities
Needs tests: set
Triage Stage: UnreviewedAccepted
Type: UncategorizedCleanup/optimization

Patch with tests welcome!

comment:2 by Jacob Rief, 9 years ago

Most other files in folder django/utils.py are UTF-8 safe. Therefore I assume that this line simply has been forgotten - unless there is another good reason.

Before writing a unit test - I don't know where to start from - I'd first like to ask, if this patch will be accepted.

comment:3 by Claude Paroz, 9 years ago

I'm sure it will. As for tests, see tests/utils_tests/test_numberformat.py.

comment:4 by Zweedeend, 9 years ago

Owner: changed from nobody to Zweedeend
Status: newassigned

comment:5 by Zweedeend, 9 years ago

Owner: Zweedeend removed
Status: assignednew

comment:6 by Tayfun Sen, 9 years ago

Owner: set to Tayfun Sen
Status: newassigned

comment:7 by Tayfun Sen, 9 years ago

Owner: Tayfun Sen removed
Status: assignednew

comment:8 by alainivars, 9 years ago

Owner: set to alainivars
Status: newassigned

comment:9 by alainivars, 9 years ago

Resolution: needsinfo
Status: assignedclosed

I try to work on this ticket but I missing information about the actual problem. I try to impose unicode string as number, decimal_sep and thousand_sep but none of them failed. Can you give additional information what you are trying to accomplish.

comment:10 by Jacob Rief, 9 years ago

My concrete problem is an implementation of a class derived from Decimal: https://github.com/jrief/django-shop/blob/0.3.0.dev/shop/money/money_maker.py

This class overrides the __format__ method, so that Django's numberformat can render instances of that type in the current locale. But my class also uses unicode symbols, for instance the € symbol. Therefore strings in numberformat shall be mixable with unicode strings from other modules.

You can also see it from another perspective.
Most Python files in Django contain this line:

from __future__ import unicode_literals

without that line, unicode literals only work with Python-3. By not adding this, Django intentionally behaves differently in Py-2 and Py-3.

Last edited 9 years ago by Markus Holtermann (previous) (diff)

comment:11 by Aymeric Augustin, 9 years ago

Resolution: needsinfo
Status: closednew

comment:12 by Claude Paroz, 9 years ago

It would still be nice to have some code with an error traceback to be able to reproduce the failure and build a test.

comment:13 by Jacob Rief, 9 years ago

Well, without making numberformat.py UTF-8 safe, I get this error:

    str_number = '{:f}'.format(number)
UnicodeEncodeError: 'ascii' codec can't encode character u'\u20ac' in position 0: ordinal not in range(128)

in https://github.com/django/django/blob/stable/1.8.x/django/utils/numberformat.py#L28

You can emulate this by implementing a special Decimal class, say

# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from decimal import Decimal

class EuroDecimal(Decimal):
    """
    Wrapper for Decimal which prefixes each amount with the € symbol.
    """
    def __format__(self, specifier, context=None, _localeconv=None):
        amount = Decimal.__format__(self, specifier, context, _localeconv)
        return '€ {}'.format(amount)

# print amount in Euros using the current locale
from django.utils.formats import number_format

price = EuroDecimal('1.23')
print number_format(price)

comment:15 by Tim Graham, 9 years ago

Triage Stage: AcceptedReady for checkin

comment:16 by Claude Paroz <claude@…>, 9 years ago

Resolution: fixed
Status: newclosed

In df193b3cefda982dfcd4813bf4e2ac09b1358f21:

Fixed #24382 -- Allowed unicode chars inside formatted numbers

Thanks Jacob Rief for the report and Tim Graham for the review.

Note: See TracTickets for help on using tickets.
Back to Top