diff --git a/Doc/library/locale.rst b/Doc/library/locale.rst index 7a8e21a7103a01660b4737a3b98d9571aced8fd9_RG9jL2xpYnJhcnkvbG9jYWxlLnJzdA==..bbbfa0724f5f18544264d7ca576efadfb9c32815_RG9jL2xpYnJhcnkvbG9jYWxlLnJzdA== 100644 --- a/Doc/library/locale.rst +++ b/Doc/library/locale.rst @@ -427,6 +427,14 @@ .. 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) Converts a string to a floating point number, following the :const:`LC_NUMERIC` diff --git a/Lib/locale.py b/Lib/locale.py index 7a8e21a7103a01660b4737a3b98d9571aced8fd9_TGliL2xvY2FsZS5weQ==..bbbfa0724f5f18544264d7ca576efadfb9c32815_TGliL2xvY2FsZS5weQ== 100644 --- a/Lib/locale.py +++ b/Lib/locale.py @@ -185,4 +185,10 @@ formatted = percent % ((value,) + additional) else: 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! @@ -188,5 +194,5 @@ # floats and decimal ints need special action! - if percent[-1] in 'eEfFgG': + if '.' in formatted: seps = 0 parts = formatted.split('.') if grouping: @@ -196,7 +202,7 @@ formatted = decimal_point.join(parts) if seps: formatted = _strip_padding(formatted, seps) - elif percent[-1] in 'diu': + else: seps = 0 if grouping: formatted, seps = _group(formatted, monetary=monetary) @@ -267,7 +273,7 @@ raise ValueError("Currency formatting is not possible using " "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 s = '<' + s + '>' @@ -323,6 +329,10 @@ string = string.replace(dd, '.') 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): "Parses a string as a float according to the locale settings." return func(delocalize(string)) diff --git a/Lib/test/test_locale.py b/Lib/test/test_locale.py index 7a8e21a7103a01660b4737a3b98d9571aced8fd9_TGliL3Rlc3QvdGVzdF9sb2NhbGUucHk=..bbbfa0724f5f18544264d7ca576efadfb9c32815_TGliL3Rlc3QvdGVzdF9sb2NhbGUucHk= 100644 --- a/Lib/test/test_locale.py +++ b/Lib/test/test_locale.py @@ -1,3 +1,4 @@ +from decimal import Decimal from test.support import verbose, is_android from test.support.warnings_helper import check_warnings import unittest @@ -636,5 +637,32 @@ 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__': unittest.main() diff --git a/Misc/NEWS.d/next/Library/2019-08-14-13-19-50.bpo-33731.9esS0d.rst b/Misc/NEWS.d/next/Library/2019-08-14-13-19-50.bpo-33731.9esS0d.rst new file mode 100644 index 0000000000000000000000000000000000000000..bbbfa0724f5f18544264d7ca576efadfb9c32815_TWlzYy9ORVdTLmQvbmV4dC9MaWJyYXJ5LzIwMTktMDgtMTQtMTMtMTktNTAuYnBvLTMzNzMxLjllc1MwZC5yc3Q= --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-08-14-13-19-50.bpo-33731.9esS0d.rst @@ -0,0 +1,2 @@ +Provide a locale.localize() function, which converts a normalized number string +into a locale format.