Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 28 additions & 3 deletions babel/numbers.py
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ def format_currency(number, currency, format=None, locale=LC_NUMERIC,
return pattern.apply(number, locale, currency=currency, force_frac=frac)


def format_percent(number, format=None, locale=LC_NUMERIC):
def format_percent(number, format=None, locale=LC_NUMERIC, scale=None):
"""Return formatted percent value for a specific locale.

>>> format_percent(0.34, locale='en_US')
Expand All @@ -347,20 +347,44 @@ def format_percent(number, format=None, locale=LC_NUMERIC):
>>> format_percent(25.1234, locale='sv_SE')
u'2\\xa0512\\xa0%'

You can set the percent precision changing the scale
>>> format_percent(0.345, locale='en_US', scale=2)
u'34.50%'

The format pattern can also be specified explicitly:

>>> format_percent(25.1234, u'#,##0\u2030', locale='en_US')
u'25,123\u2030'

The format pattern with percent or per mille symbol change the precision:

>>> format_percent(0.346, locale='en_US')
u'35%'

>>> format_percent(0.346, u'#,###.##%', locale='en_US')
u'34.6%'

In this case is considered the precision by format and not the param scale.

:param number: the percent number to format
:param format:
:param locale: the `Locale` object or locale identifier
:param scale: the number to change the percent precision
"""
if scale and isinstance(scale, int):
frac = (scale, scale)
else:
frac = None

locale = Locale.parse(locale)
if not format:
format = locale.percent_formats.get(format)
else:
# if the format was setted is disconsidered any scale value
# to use the format scale
frac = None
pattern = parse_pattern(format)
return pattern.apply(number, locale)
return pattern.apply(number, locale, force_frac=frac)


def format_scientific(number, format=None, locale=LC_NUMERIC):
Expand Down Expand Up @@ -617,7 +641,8 @@ def apply(self, value, locale, currency=None, force_frac=None):
retval = retval.replace(u'¤¤¤',
get_currency_name(currency, value, locale))
retval = retval.replace(u'¤¤', currency.upper())
retval = retval.replace(u'¤', get_currency_symbol(currency, locale))
retval = retval.replace(
u'¤', get_currency_symbol(currency, locale))
return retval

#
Expand Down
14 changes: 14 additions & 0 deletions tests/test_numbers.py
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,20 @@ def test_format_percent():
== u'2\xa0512\xa0%')
assert (numbers.format_percent(25.1234, u'#,##0\u2030', locale='en_US')
== u'25,123\u2030')
assert numbers.format_percent(0.346, locale='en_US', scale=1) == u'34.6%'
assert numbers.format_percent(0.346, locale='en_US', scale=2) == u'34.60%'
assert numbers.format_percent(0.3465, locale='en_US', scale=2) == u'34.65%'
# this assertion verify that the scale format is greater than
# the input scale
assert numbers.format_percent(
0.34654, format='#,###.##%', locale='en_US', scale=3) == u'34.65%'
assert numbers.format_percent(
0.346, format='#,###.##%', locale='en_US', scale=3) == u'34.6%'
# this assertion is to validate if the format_percent
# is not broken if the scale input has a wrong type
assert numbers.format_percent(0.3465, locale='en_US', scale='a') == u'35%'
# validate bas percent format
assert numbers.format_percent(0.3465, locale='cs_CZ', scale=2) == u'34,65\xa0%'


def test_scientific_exponent_displayed_as_integer():
Expand Down