Skip to content

Commit 1cf93a7

Browse files
Garvit Khatribitdancer
authored andcommitted
bpo-10379: add 'monetary' to format_string, deprecate format
Add the 'monetary' parameter to format_string so that all uses of format can be converted to format_string. Adjust the documentation accordingly, and add a deprecation warning when format is used.
1 parent c8fa45b commit 1cf93a7

File tree

6 files changed

+82
-53
lines changed

6 files changed

+82
-53
lines changed

Doc/library/locale.rst

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ The :mod:`locale` module defines the following exception and functions:
352352
sequence of strings.
353353

354354

355-
.. function:: format(format, val, grouping=False, monetary=False)
355+
.. function:: format_string(format, val, grouping=False, monetary=False)
356356

357357
Formats a number *val* according to the current :const:`LC_NUMERIC` setting.
358358
The format follows the conventions of the ``%`` operator. For floating point
@@ -362,14 +362,22 @@ The :mod:`locale` module defines the following exception and functions:
362362
If *monetary* is true, the conversion uses monetary thousands separator and
363363
grouping strings.
364364

365-
Please note that this function will only work for exactly one %char specifier.
366-
For whole format strings, use :func:`format_string`.
365+
Processes formatting specifiers as in ``format % val``, but takes the current
366+
locale settings into account.
367367

368+
.. versionchanged:: 3.7
369+
The *monetary* keyword parameter was added.
368370

369-
.. function:: format_string(format, val, grouping=False)
370371

371-
Processes formatting specifiers as in ``format % val``, but takes the current
372-
locale settings into account.
372+
.. function:: format(format, val, grouping=False, monetary=False)
373+
374+
Please note that this function works like format_string but will only work
375+
for exactly one %char specifier.
376+
377+
For whole format strings, use :func:`format_string`.
378+
379+
.. deprecated:: 3.7
380+
Use :meth:`format_string` instead
373381

374382

375383
.. function:: currency(val, symbol=True, grouping=False, international=False)

Doc/whatsnew/3.7.rst

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -76,16 +76,14 @@ Other Language Changes
7676
======================
7777

7878
* More than 255 arguments can now be passed to a function, and a function can
79-
now have more than 255 parameters.
80-
(Contributed by Serhiy Storchaka in :issue:`12844` and :issue:`18896`.)
79+
now have more than 255 parameters. (Contributed by Serhiy Storchaka in
80+
:issue:`12844` and :issue:`18896`.)
8181

8282
* :meth:`bytes.fromhex` and :meth:`bytearray.fromhex` now ignore all ASCII
83-
whitespace, not only spaces.
84-
(Contributed by Robert Xiao in :issue:`28927`.)
83+
whitespace, not only spaces. (Contributed by Robert Xiao in :issue:`28927`.)
8584

8685
* :exc:`ImportError` now displays module name and module ``__file__`` path when
87-
``from ... import ...`` fails.
88-
(Contributed by Matthias Bussonnier in :issue:`29546`.)
86+
``from ... import ...`` fails. (Contributed by Matthias Bussonnier in :issue:`29546`.)
8987

9088

9189
New Modules
@@ -97,25 +95,32 @@ New Modules
9795
Improved Modules
9896
================
9997

98+
locale
99+
------
100+
101+
Added another argument *monetary* in :meth:`format_string` of :mod:`locale`.
102+
If *monetary* is true, the conversion uses monetary thousands separator and
103+
grouping strings. (Contributed by Garvit in :issue:`10379`.)
104+
100105
os
101106
--
102107

103-
Added support for :class:`bytes` paths in :func:`~os.fwalk`.
104-
(Contributed by Serhiy Storchaka in :issue:`28682`.)
108+
Added support for :class:`bytes` paths in :func:`~os.fwalk`. (Contributed by
109+
Serhiy Storchaka in :issue:`28682`.)
105110

106111
unittest.mock
107112
-------------
108113

109114
The :const:`~unittest.mock.sentinel` attributes now preserve their identity
110-
when they are :mod:`copied <copy>` or :mod:`pickled <pickle>`.
111-
(Contributed by Serhiy Storchaka in :issue:`20804`.)
115+
when they are :mod:`copied <copy>` or :mod:`pickled <pickle>`. (Contributed by
116+
Serhiy Storchaka in :issue:`20804`.)
112117

113118
xmlrpc.server
114119
-------------
115120

116121
:meth:`register_function` of :class:`xmlrpc.server.SimpleXMLRPCDispatcher` and
117-
its subclasses can be used as a decorator.
118-
(Contributed by Xiang Zhang in :issue:`7769`.)
122+
its subclasses can be used as a decorator. (Contributed by Xiang Zhang in
123+
:issue:`7769`.)
119124

120125
urllib.parse
121126
------------
@@ -130,13 +135,13 @@ Optimizations
130135

131136
* Added two new opcodes: ``LOAD_METHOD`` and ``CALL_METHOD`` to avoid
132137
instantiation of bound method objects for method calls, which results
133-
in method calls being faster up to 20%.
134-
(Contributed by Yury Selivanov and INADA Naoki in :issue:`26110`.)
138+
in method calls being faster up to 20%. (Contributed by Yury Selivanov and
139+
INADA Naoki in :issue:`26110`.)
135140

136141
* Fast implementation from standard C library is now used for functions
137142
:func:`~math.tgamma`, :func:`~math.lgamma`, :func:`~math.erf` and
138-
:func:`~math.erfc` in the :mod:`math` module.
139-
(Contributed by Serhiy Storchaka in :issue:`26121`.)
143+
:func:`~math.erfc` in the :mod:`math` module. (Contributed by Serhiy
144+
Storchaka in :issue:`26121`.)
140145

141146

142147
Build and C API Changes
@@ -154,8 +159,8 @@ Build and C API Changes
154159
``char *``. (Contributed by Serhiy Storchaka in :issue:`28761`.)
155160

156161
* The result of :c:func:`PyUnicode_AsUTF8AndSize` and :c:func:`PyUnicode_AsUTF8`
157-
is now of type ``const char *`` rather of ``char *``.
158-
(Contributed by Serhiy Storchaka in :issue:`28769`.)
162+
is now of type ``const char *`` rather of ``char *``. (Contributed by Serhiy
163+
Storchaka in :issue:`28769`.)
159164

160165
* Added functions :c:func:`PySlice_Unpack` and :c:func:`PySlice_AdjustIndices`.
161166
(Contributed by Serhiy Storchaka in :issue:`27867`.)
@@ -169,6 +174,9 @@ Deprecated
169174
``0x03050400`` and ``0x03060000`` (not including) or ``0x03060100`` or
170175
higher. (Contributed by Serhiy Storchaka in :issue:`27867`.)
171176

177+
- Deprecated :meth:`format` from :mod:`locale`, use the :meth:`format_string`
178+
instead. (Contributed by Garvit in :issue:`10379`.)
179+
172180
- Methods
173181
:meth:`MetaPathFinder.find_module() <importlib.abc.MetaPathFinder.find_module>`
174182
(replaced by
@@ -181,8 +189,8 @@ Deprecated
181189
by Matthias Bussonnier in :issue:`29576`)
182190

183191
- Using non-integer value for selecting a plural form in :mod:`gettext` is
184-
now deprecated. It never correctly worked.
185-
(Contributed by Serhiy Storchaka in :issue:`28692`.)
192+
now deprecated. It never correctly worked. (Contributed by Serhiy Storchaka
193+
in :issue:`28692`.)
186194

187195

188196
Changes in the C API
@@ -229,8 +237,8 @@ Changes in the Python API
229237

230238
* A format string argument for :meth:`string.Formatter.format`
231239
is now :ref:`positional-only <positional-only_parameter>`.
232-
Passing it as a keyword argument was deprecated in Python 3.5.
233-
(Contributed by Serhiy Storchaka in :issue:`29193`.)
240+
Passing it as a keyword argument was deprecated in Python 3.5. (Contributed
241+
by Serhiy Storchaka in :issue:`29193`.)
234242

235243
* Attributes :attr:`~http.cookies.Morsel.key`,
236244
:attr:`~http.cookies.Morsel.value` and
@@ -244,8 +252,8 @@ Changes in the Python API
244252
``ClassDef`` AST nodes now have a new ``docstring`` field.
245253
The first statement in their body is not considered as a docstring
246254
anymore. ``co_firstlineno`` and ``co_lnotab`` of code object for class
247-
and module are affected by this change.
248-
(Contributed by INADA Naoki and Eugene Toder in :issue:`29463`.)
255+
and module are affected by this change. (Contributed by INADA Naoki and
256+
Eugene Toder in :issue:`29463`.)
249257

250258
* The *mode* argument of :func:`os.makedirs` no longer affects the file
251259
permission bits of newly-created intermediate-level directories.

Lib/locale.py

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import collections
1818
from builtins import str as _builtin_str
1919
import functools
20+
import warnings
2021

2122
# Try importing the _locale module.
2223
#
@@ -180,19 +181,6 @@ def _strip_padding(s, amount):
180181
_percent_re = re.compile(r'%(?:\((?P<key>.*?)\))?'
181182
r'(?P<modifiers>[-#0-9 +*.hlL]*?)[eEfFgGdiouxXcrs%]')
182183

183-
def format(percent, value, grouping=False, monetary=False, *additional):
184-
"""Returns the locale-aware substitution of a %? specifier
185-
(percent).
186-
187-
additional is for format strings which contain one or more
188-
'*' modifiers."""
189-
# this is only for one-percent-specifier strings and this should be checked
190-
match = _percent_re.match(percent)
191-
if not match or len(match.group())!= len(percent):
192-
raise ValueError(("format() must be given exactly one %%char "
193-
"format specifier, %s not valid") % repr(percent))
194-
return _format(percent, value, grouping, monetary, *additional)
195-
196184
def _format(percent, value, grouping=False, monetary=False, *additional):
197185
if additional:
198186
formatted = percent % ((value,) + additional)
@@ -217,10 +205,13 @@ def _format(percent, value, grouping=False, monetary=False, *additional):
217205
formatted = _strip_padding(formatted, seps)
218206
return formatted
219207

220-
def format_string(f, val, grouping=False):
208+
def format_string(f, val, grouping=False, monetary=False):
221209
"""Formats a string in the same way that the % formatting would use,
222210
but takes the current locale into account.
223-
Grouping is applied if the third parameter is true."""
211+
212+
Grouping is applied if the third parameter is true.
213+
Conversion uses monetary thousands separator and grouping strings if
214+
forth parameter monetary is true."""
224215
percents = list(_percent_re.finditer(f))
225216
new_f = _percent_re.sub('%s', f)
226217

@@ -230,7 +221,7 @@ def format_string(f, val, grouping=False):
230221
if perc.group()[-1]=='%':
231222
new_val.append('%')
232223
else:
233-
new_val.append(format(perc.group(), val, grouping))
224+
new_val.append(_format(perc.group(), val, grouping, monetary))
234225
else:
235226
if not isinstance(val, tuple):
236227
val = (val,)
@@ -244,13 +235,27 @@ def format_string(f, val, grouping=False):
244235
new_val.append(_format(perc.group(),
245236
val[i],
246237
grouping,
247-
False,
238+
monetary,
248239
*val[i+1:i+1+starcount]))
249240
i += (1 + starcount)
250241
val = tuple(new_val)
251242

252243
return new_f % val
253244

245+
def format(percent, value, grouping=False, monetary=False, *additional):
246+
"""Deprecated, use format_string instead."""
247+
warnings.warn(
248+
"This method will be removed in a future version of Python."
249+
"Use 'locale.format_string()' instead.",
250+
DeprecationWarning, stacklevel=2
251+
)
252+
253+
match = _percent_re.match(percent)
254+
if not match or len(match.group())!= len(percent):
255+
raise ValueError(("format() must be given exactly one %%char "
256+
"format specifier, %s not valid") % repr(percent))
257+
return _format(percent, value, grouping, monetary, *additional)
258+
254259
def currency(val, symbol=True, grouping=False, international=False):
255260
"""Formats val according to the currency settings
256261
in the current locale."""
@@ -262,7 +267,7 @@ def currency(val, symbol=True, grouping=False, international=False):
262267
raise ValueError("Currency formatting is not possible using "
263268
"the 'C' locale.")
264269

265-
s = format('%%.%if' % digits, abs(val), grouping, monetary=True)
270+
s = _format('%%.%if' % digits, abs(val), grouping, monetary=True)
266271
# '<' and '>' are markers if the sign must be inserted between symbol and value
267272
s = '<' + s + '>'
268273

@@ -298,7 +303,7 @@ def currency(val, symbol=True, grouping=False, international=False):
298303

299304
def str(val):
300305
"""Convert float to string, taking the locale into account."""
301-
return format("%.12g", val)
306+
return _format("%.12g", val)
302307

303308
def delocalize(string):
304309
"Parses a string as a normalized number according to the locale settings."
@@ -327,7 +332,7 @@ def atoi(string):
327332
def _test():
328333
setlocale(LC_ALL, "")
329334
#do grouping
330-
s1 = format("%d", 123456789,1)
335+
s1 = format_string("%d", 123456789,1)
331336
print(s1, "is", atoi(s1))
332337
#standard formatting
333338
s1 = str(3.14)

Lib/test/test_locale.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import locale
44
import sys
55
import codecs
6+
import warnings
67

78
class BaseLocalizedTest(unittest.TestCase):
89
#
@@ -197,6 +198,10 @@ def test_padding(self):
197198
self._test_format("%+10.f", -4200, grouping=0, out='-4200'.rjust(10))
198199
self._test_format("%-10.f", 4200, grouping=0, out='4200'.ljust(10))
199200

201+
def test_format_deprecation(self):
202+
with self.assertWarns(DeprecationWarning):
203+
locale.format("%-10.f", 4200, grouping=True)
204+
200205
def test_complex_formatting(self):
201206
# Spaces in formatting string
202207
self._test_format_string("One million is %i", 1000000, grouping=1,

Lib/test/test_types.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -381,16 +381,16 @@ def test_float__format__locale(self):
381381

382382
for i in range(-10, 10):
383383
x = 1234567890.0 * (10.0 ** i)
384-
self.assertEqual(locale.format('%g', x, grouping=True), format(x, 'n'))
385-
self.assertEqual(locale.format('%.10g', x, grouping=True), format(x, '.10n'))
384+
self.assertEqual(locale.format_string('%g', x, grouping=True), format(x, 'n'))
385+
self.assertEqual(locale.format_string('%.10g', x, grouping=True), format(x, '.10n'))
386386

387387
@run_with_locale('LC_NUMERIC', 'en_US.UTF8')
388388
def test_int__format__locale(self):
389389
# test locale support for __format__ code 'n' for integers
390390

391391
x = 123456789012345678901234567890
392392
for i in range(0, 30):
393-
self.assertEqual(locale.format('%d', x, grouping=True), format(x, 'n'))
393+
self.assertEqual(locale.format_string('%d', x, grouping=True), format(x, 'n'))
394394

395395
# move to the next integer to test
396396
x = x // 10

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,9 @@ Library
397397
- bpo-29534: Fixed different behaviour of Decimal.from_float()
398398
for _decimal and _pydecimal. Thanks Andrew Nester.
399399

400+
- bpo-10379: locale.format_string now supports the 'monetary' keyword argument,
401+
and locale.format is deprecated.
402+
400403
- Issue #28556: Various updates to typing module: typing.Counter, typing.ChainMap,
401404
improved ABC caching, etc. Original PRs by Jelle Zijlstra, Ivan Levkivskyi,
402405
Manuel Krebber, and Łukasz Langa.

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy