diff --git a/babel/numbers.py b/babel/numbers.py index a5d30ef26..fbe3b8013 100644 --- a/babel/numbers.py +++ b/babel/numbers.py @@ -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') @@ -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): @@ -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 # diff --git a/tests/test_numbers.py b/tests/test_numbers.py index 2593cc017..3aee3371e 100644 --- a/tests/test_numbers.py +++ b/tests/test_numbers.py @@ -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():