]> git.ipfire.org Git - thirdparty/babel.git/commitdiff
parse_decimal(): assume spaces are equivalent to non-breaking spaces when not in...
authorAarni Koskela <akx@iki.fi>
Mon, 27 May 2019 11:32:48 +0000 (14:32 +0300)
committerAarni Koskela <akx@iki.fi>
Mon, 27 May 2019 11:42:00 +0000 (14:42 +0300)
Fixes #637

babel/numbers.py
tests/test_numbers.py

index e5650dd52627793dcead2ab74b2cfd597578dbb8..3dcd73099c3fc16fb95cf5e56ea92389790b48a1 100644 (file)
@@ -673,6 +673,8 @@ def parse_decimal(string, locale=LC_NUMERIC, strict=False):
     Decimal('1099.98')
     >>> parse_decimal('1.099,98', locale='de')
     Decimal('1099.98')
+    >>> parse_decimal('12 345,123', locale='ru')
+    Decimal('12345.123')
 
     When the given string cannot be parsed, an exception is raised:
 
@@ -704,6 +706,15 @@ def parse_decimal(string, locale=LC_NUMERIC, strict=False):
     locale = Locale.parse(locale)
     group_symbol = get_group_symbol(locale)
     decimal_symbol = get_decimal_symbol(locale)
+
+    if not strict and (
+        group_symbol == u'\xa0' and  # if the grouping symbol is U+00A0 NO-BREAK SPACE,
+        group_symbol not in string and  # and the string to be parsed does not contain it,
+        ' ' in string  # but it does contain a space instead,
+    ):
+        # ... it's reasonable to assume it is taking the place of the grouping symbol.
+        string = string.replace(' ', group_symbol)
+
     try:
         parsed = decimal.Decimal(string.replace(group_symbol, '')
                                        .replace(decimal_symbol, '.'))
index 99aa96b7e9f6d599a312f962999dd37adc159af9..27649f841f830e6eb99a12867be10cb1a013c310 100644 (file)
@@ -679,3 +679,14 @@ def test_numberpattern_repr():
 def test_parse_static_pattern():
     assert numbers.parse_pattern('Kun')  # in the So locale in CLDR 30
     # TODO: static patterns might not be correctly `apply()`ed at present
+
+
+def test_parse_decimal_nbsp_heuristics():
+    # Re https://github.com/python-babel/babel/issues/637 –
+    #    for locales (of which there are many) that use U+00A0 as the group
+    #    separator in numbers, it's reasonable to assume that input strings
+    #    with plain spaces actually should have U+00A0s instead.
+    #    This heuristic is only applied when strict=False.
+    n = decimal.Decimal("12345.123")
+    assert numbers.parse_decimal("12 345.123", locale="fi") == n
+    assert numbers.parse_decimal(numbers.format_decimal(n, locale="fi"), locale="fi") == n