Skip to content
Snippets Groups Projects
Commit bbbfa0724f5f authored by Cédric Krier's avatar Cédric Krier
Browse files

bpo-34311: Add locale.localize (GH-15275)

* Add method localize to the locale module
* Update the documentation of the locale module
parent 7a8e21a7103a
No related branches found
No related tags found
No related merge requests found
...@@ -427,6 +427,14 @@ ...@@ -427,6 +427,14 @@
.. versionadded:: 3.5 .. versionadded:: 3.5
.. function:: localize(string, grouping=False, monetary=False)
Converts a normalized number string into a formatted string following the
:const:`LC_NUMERIC` settings.
.. versionadded:: 3.10
.. function:: atof(string) .. function:: atof(string)
Converts a string to a floating point number, following the :const:`LC_NUMERIC` Converts a string to a floating point number, following the :const:`LC_NUMERIC`
......
...@@ -185,4 +185,10 @@ ...@@ -185,4 +185,10 @@
formatted = percent % ((value,) + additional) formatted = percent % ((value,) + additional)
else: else:
formatted = percent % value formatted = percent % value
if percent[-1] in 'eEfFgGdiu':
formatted = _localize(formatted, grouping, monetary)
return formatted
# Transform formatted as locale number according to the locale settings
def _localize(formatted, grouping=False, monetary=False):
# floats and decimal ints need special action! # floats and decimal ints need special action!
...@@ -188,5 +194,5 @@ ...@@ -188,5 +194,5 @@
# floats and decimal ints need special action! # floats and decimal ints need special action!
if percent[-1] in 'eEfFgG': if '.' in formatted:
seps = 0 seps = 0
parts = formatted.split('.') parts = formatted.split('.')
if grouping: if grouping:
...@@ -196,7 +202,7 @@ ...@@ -196,7 +202,7 @@
formatted = decimal_point.join(parts) formatted = decimal_point.join(parts)
if seps: if seps:
formatted = _strip_padding(formatted, seps) formatted = _strip_padding(formatted, seps)
elif percent[-1] in 'diu': else:
seps = 0 seps = 0
if grouping: if grouping:
formatted, seps = _group(formatted, monetary=monetary) formatted, seps = _group(formatted, monetary=monetary)
...@@ -267,7 +273,7 @@ ...@@ -267,7 +273,7 @@
raise ValueError("Currency formatting is not possible using " raise ValueError("Currency formatting is not possible using "
"the 'C' locale.") "the 'C' locale.")
s = _format('%%.%if' % digits, abs(val), grouping, monetary=True) s = _localize(f'{abs(val):.{digits}f}', grouping, monetary=True)
# '<' and '>' are markers if the sign must be inserted between symbol and value # '<' and '>' are markers if the sign must be inserted between symbol and value
s = '<' + s + '>' s = '<' + s + '>'
...@@ -323,6 +329,10 @@ ...@@ -323,6 +329,10 @@
string = string.replace(dd, '.') string = string.replace(dd, '.')
return string return string
def localize(string, grouping=False, monetary=False):
"""Parses a string as locale number according to the locale settings."""
return _localize(string, grouping, monetary)
def atof(string, func=float): def atof(string, func=float):
"Parses a string as a float according to the locale settings." "Parses a string as a float according to the locale settings."
return func(delocalize(string)) return func(delocalize(string))
......
from decimal import Decimal
from test.support import verbose, is_android from test.support import verbose, is_android
from test.support.warnings_helper import check_warnings from test.support.warnings_helper import check_warnings
import unittest import unittest
...@@ -636,5 +637,32 @@ ...@@ -636,5 +637,32 @@
self._test_atoi('50 000', 50000) self._test_atoi('50 000', 50000)
class BaseLocalizeTest(BaseLocalizedTest):
def _test_localize(self, value, out, grouping=False):
self.assertEqual(locale.localize(value, grouping=grouping), out)
class TestEnUSLocalize(EnUSCookedTest, BaseLocalizeTest):
def test_localize(self):
self._test_localize('50000.00', '50000.00')
self._test_localize(
'{0:.16f}'.format(Decimal('1.15')), '1.1500000000000000')
class TestCLocalize(CCookedTest, BaseLocalizeTest):
def test_localize(self):
self._test_localize('50000.00', '50000.00')
class TestfrFRLocalize(FrFRCookedTest, BaseLocalizeTest):
def test_localize(self):
self._test_localize('50000.00', '50000,00')
self._test_localize('50000.00', '50 000,00', grouping=True)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
Provide a locale.localize() function, which converts a normalized number string
into a locale format.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment