summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChangaco <changaco@changaco.oy.lc>2018-06-17 09:55:02 +0200
committerChangaco <changaco@changaco.oy.lc>2018-06-17 10:46:54 +0200
commitb5f6f362440faf862ea887a4157252874c59d910 (patch)
tree8daae8a99bea528785698c2c228dbc88546582fa
parent6bf8745f6a913af71357583e8e97116fcfd444ca (diff)
downloadbabel-b5f6f362440faf862ea887a4157252874c59d910.tar.gz
add a `suggestions` attribute to `NumberFormatError`
-rw-r--r--babel/numbers.py13
-rw-r--r--docs/api/numbers.rst1
-rw-r--r--tests/test_numbers.py12
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