]> git.ipfire.org Git - thirdparty/babel.git/commitdiff
add a `suggestions` attribute to `NumberFormatError` 590/head
authorChangaco <changaco@changaco.oy.lc>
Sun, 17 Jun 2018 07:55:02 +0000 (09:55 +0200)
committerChangaco <changaco@changaco.oy.lc>
Sun, 17 Jun 2018 08:46:54 +0000 (10:46 +0200)
babel/numbers.py
docs/api/numbers.rst
tests/test_numbers.py

index b0cfe65e7389789b95cd1e95c4234841543251ff..d3d2238366b1db2fc50c5f9b636f3ec73348a5b8 100644 (file)
@@ -634,6 +634,11 @@ def format_scientific(
 class NumberFormatError(ValueError):
     """Exception raised when a string cannot be parsed into a number."""
 
+    def __init__(self, message, suggestions=None):
+        super(NumberFormatError, self).__init__(message)
+        #: a list of properly formatted numbers derived from the invalid input
+        self.suggestions = suggestions
+
 
 def parse_number(string, locale=LC_NUMERIC):
     """Parse localized number string into an integer.
@@ -706,16 +711,16 @@ def parse_decimal(string, locale=LC_NUMERIC, strict=False):
                 parsed_alt = decimal.Decimal(string.replace(decimal_symbol, '')
                                                    .replace(group_symbol, '.'))
             except decimal.InvalidOperation:
-                raise NumberFormatError(
+                raise NumberFormatError((
                     "%r is not a properly formatted decimal number. Did you mean %r?" %
                     (string, proper)
-                )
+                ), suggestions=[proper])
             else:
                 proper_alt = format_decimal(parsed_alt, locale=locale, decimal_quantization=False)
-                raise NumberFormatError(
+                raise NumberFormatError((
                     "%r is not a properly formatted decimal number. Did you mean %r? Or maybe %r?" %
                     (string, proper, proper_alt)
-                )
+                ), suggestions=[proper, proper_alt])
     return parsed
 
 
index 758cebaf320e3a94559fbead89db0fae865e8fd3..f9b0833a238005c0bc2c45dca19ee3da206dda75 100644 (file)
@@ -30,6 +30,7 @@ Exceptions
 ----------
 
 .. autoexception:: NumberFormatError
+    :members:
 
 Data Access
 -----------
index b9dcb72783344fed997ff3af3567069f96503e79..9c3896ce5c982d3a9ebb0fe4f8c58d2a945e111b 100644 (file)
@@ -167,17 +167,21 @@ class NumberParsingTestCase(unittest.TestCase):
 
     def test_parse_decimal_strict_mode(self):
         # Numbers with a misplaced grouping symbol should be rejected
-        with self.assertRaises(numbers.NumberFormatError):
+        with self.assertRaises(numbers.NumberFormatError) as info:
             numbers.parse_decimal('11.11', locale='de', strict=True)
+        assert info.exception.suggestions == ['1.111', '11,11']
         # Numbers with two misplaced grouping symbols should be rejected
-        with self.assertRaises(numbers.NumberFormatError):
+        with self.assertRaises(numbers.NumberFormatError) as info:
             numbers.parse_decimal('80.00.00', locale='de', strict=True)
+        assert info.exception.suggestions == ['800.000']
         # Partially grouped numbers should be rejected
-        with self.assertRaises(numbers.NumberFormatError):
+        with self.assertRaises(numbers.NumberFormatError) as info:
             numbers.parse_decimal('2000,000', locale='en_US', strict=True)
+        assert info.exception.suggestions == ['2,000,000', '2,000']
         # Numbers with duplicate grouping symbols should be rejected
-        with self.assertRaises(numbers.NumberFormatError):
+        with self.assertRaises(numbers.NumberFormatError) as info:
             numbers.parse_decimal('0,,000', locale='en_US', strict=True)
+        assert info.exception.suggestions == ['0']
         # Properly formatted numbers should be accepted
         assert str(numbers.parse_decimal('1.001', locale='de', strict=True)) == '1001'
         # Trailing zeroes should be accepted