This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Currency not correct for all locales
Type: behavior Stage: resolved
Components: Library (Lib) Versions: Python 3.7
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: GiftZwergrapper, eric.smith, lemburg
Priority: normal Keywords:

Created on 2020-10-26 13:33 by GiftZwergrapper, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (5)
msg379662 - (view) Author: Stefan Völkl (GiftZwergrapper) Date: 2020-10-26 13:33
I found that the currency formatting does not work correctly for all locales. For example:

{{{
import locale

amount = 24.99
locale.setlocale(locale.LC_ALL, 'it_IT.UTF-8')

price = locale.currency(amount)

print(price)
}}}

returns "€ 24,99".
It should return "24,99 €", just like noted at http://publications.europa.eu/code/it/it-370303.htm
under "Posizione del simbolo (€) negli importi in cifre".
msg379664 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2020-10-26 13:48
What does locale.localeconv() return?

>>> locale.localeconv()
{'int_curr_symbol': '', 'currency_symbol': '', 'mon_decimal_point': '', 'mon_thousands_sep': '', 'mon_grouping': [], 'positive_sign': '', 'negative_sign': '', 'int_frac_digits': 127, 'frac_digits': 127, 'p_cs_precedes': 127, 'p_sep_by_space': 127, 'n_cs_precedes': 127, 'n_sep_by_space': 127, 'p_sign_posn': 127, 'n_sign_posn': 127, 'decimal_point': '.', 'thousands_sep': '', 'grouping': []}
>>>

In particular, the values of p_cs_precedes and n_cs_precedes.
msg379665 - (view) Author: Stefan Völkl (GiftZwergrapper) Date: 2020-10-26 13:58
>>> locale.localeconv()
{'int_curr_symbol': 'EUR ', 'currency_symbol': '€', 'mon_decimal_point': ',', 'mon_thousands_sep': '.', 'mon_grouping': [3, 3, 0], 'positive_sign': '', 'negative_sign': '-', 'int_frac_digits': 2, 'frac_digits': 2, 'p_cs_precedes': 1, 'p_sep_by_space': 1, 'n_cs_precedes': 1, 'n_sep_by_space': 1, 'p_sign_posn': 1, 'n_sign_posn': 1, 'decimal_point': ',', 'thousands_sep': '.', 'grouping': [3, 3, 0]}
msg379666 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2020-10-26 14:07
p_cs_precedes == 1 means "the currency_symbol or int_curr_symbol strings should precede the value of a monetary amount", per https://www.gnu.org/software/libc/manual/html_node/Currency-Symbol.html (I couldn't find a more authoritative source, but I think this is okay).

So it looks like Python is following the rules correctly. I don't know how you'd adjust the locale values.
msg379681 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2020-10-26 18:58
And just to show that python is doing the right thing, if the locale is set up correctly, I'll show the following hack:

>>> import locale
>>> locale.setlocale(locale.LC_ALL, 'en_US')
'en_US'
>>> locale.currency(24.99)
'$24.99'
>>> locale._override_localeconv["p_cs_precedes"] = 0
>>> locale.currency(24.99)
'24.99$'

Notice the change from '$24.99' to '24.99$' when I change p_cs_precedes to 0.

WARNING: you really, really shouldn't use _override_localeconv. It looks like it exists just for testing, but I'm using it here to show that currency formatting does respect p_cs_precedes.

On the other hand, I've often wanted to build up a locale programmatically and then use it, so maybe we should support that use case.
History
Date User Action Args
2022-04-11 14:59:37adminsetgithub: 86322
2020-10-29 12:04:50eric.smithsetstatus: open -> closed
resolution: not a bug
stage: resolved
2020-10-26 18:58:45eric.smithsetmessages: + msg379681
2020-10-26 14:07:05eric.smithsetmessages: + msg379666
2020-10-26 13:58:51GiftZwergrappersetmessages: + msg379665
2020-10-26 13:48:49eric.smithsetnosy: + eric.smith
messages: + msg379664
2020-10-26 13:33:05GiftZwergrappercreate