grouping in module 'locale'

Roman Bertle bertle at smoerz.org
Fri Jan 25 11:46:13 EST 2008


Hello,

I try to format monetary values using the locale module, python2.5:

Python 2.5.2a0 (r251:54863, Jan  3 2008, 17:59:56) 
[GCC 4.2.3 20071123 (prerelease) (Debian 4.2.2-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import locale
>>> locale.setlocale(locale.LC_ALL, 'de_AT.utf8')
'de_AT.utf8'
>>> locale.localeconv()
{'mon_decimal_point': ',', 'int_frac_digits': 2, 'p_sep_by_space': 1,
'frac_digits': 2, 'thousands_sep': '', 'n_sign_posn': 1,
'decimal_point': ',', 'int_curr_symbol': 'EUR ', 'n_cs_precedes': 1,
'p_sign_posn': 1, 'mon_thousands_sep': ' ', 'negative_sign': '-',
'currency_symbol': '\xe2\x82\xac', 'n_sep_by_space': 1,
'mon_grouping': [3, 3, 0], 'p_cs_precedes': 1, 'positive_sign': '',
'grouping': []}
>>> locale.currency(1234.5678, grouping=True, symbol=False)
'1234,57'

As you can see, the decimal point is correctly set to ','. But the
grouping is not done, every 3 digits should be separated by space (' ').
Using the 'de_DE.utf8' locale, ist works:

>>> locale.setlocale(locale.LC_ALL, 'de_DE.utf8')
'de_DE.utf8'
>>> locale.localeconv()
{'mon_decimal_point': ',', 'int_frac_digits': 2, 'p_sep_by_space': 1,
'frac_digits': 2, 'thousands_sep': '.', 'n_sign_posn': 1,
'decimal_point': ',', 'int_curr_symbol': 'EUR ', 'n_cs_precedes': 0,
'p_sign_posn': 1, 'mon_thousands_sep': '.', 'negative_sign': '-',
'currency_symbol': '\xe2\x82\xac', 'n_sep_by_space': 1, 'mon_grouping':
[3, 3, 0], 'p_cs_precedes': 0, 'positive_sign': '', 'grouping': [3, 3,
0]}
>>> locale.currency(1234.5678, grouping=True, symbol=False)
'1.234,57'

The difference here is that thounds_sep is '.', not ' '. If we look at the code
of locale.py, revision 55038, lines 157-161, the inserted spaces are later
deleted again:

        while seps:
            sp = formatted.find(' ')
            if sp == -1: break
            formatted = formatted[:sp] + formatted[sp+1:]
            seps -= 1

This code is only called if numbers are formated as floating point, but not for
integers. The following works:

>>> locale.setlocale(locale.LC_ALL, 'de_AT.utf8')
'de_AT.utf8'
>>> locale.format('%d',1234.5678, grouping=True, monetary=True)
'1 234'

The reason for the space removal is explained in an earlier version of
locale.py, e.g. 42120:

  # If the number was formatted for a specific width, then it
  # might have been filled with spaces to the left or right. If
  # so, kill as much spaces as there where separators.
  # Leading zeroes as fillers are not yet dealt with, as it is
  # not clear how they should interact with grouping.

But I don't know the why and how this code is necessary. Can anybody shed some
light on this issue?

Best Regards, Roman



More information about the Python-list mailing list