diff options
author | Changaco <changaco@changaco.oy.lc> | 2018-06-17 09:55:02 +0200 |
---|---|---|
committer | Changaco <changaco@changaco.oy.lc> | 2018-06-17 10:46:54 +0200 |
commit | b5f6f362440faf862ea887a4157252874c59d910 (patch) | |
tree | 8daae8a99bea528785698c2c228dbc88546582fa | |
parent | 6bf8745f6a913af71357583e8e97116fcfd444ca (diff) | |
download | babel-b5f6f362440faf862ea887a4157252874c59d910.tar.gz |
add a `suggestions` attribute to `NumberFormatError`
-rw-r--r-- | babel/numbers.py | 13 | ||||
-rw-r--r-- | docs/api/numbers.rst | 1 | ||||
-rw-r--r-- | tests/test_numbers.py | 12 |
3 files changed, 18 insertions, 8 deletions
diff --git a/babel/numbers.py b/babel/numbers.py index b0cfe65..d3d2238 100644 --- a/babel/numbers.py +++ b/babel/numbers.py @@ -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 diff --git a/docs/api/numbers.rst b/docs/api/numbers.rst index 758ceba..f9b0833 100644 --- a/docs/api/numbers.rst +++ b/docs/api/numbers.rst @@ -30,6 +30,7 @@ Exceptions ---------- .. autoexception:: NumberFormatError + :members: Data Access ----------- diff --git a/tests/test_numbers.py b/tests/test_numbers.py index b9dcb72..9c3896c 100644 --- a/tests/test_numbers.py +++ b/tests/test_numbers.py @@ -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 |