changeset 587:964cd2ec6f94 trunk

parse_decimal() now returns Decimals not floats, API change (#178)
author fschwarz
date Mon, 06 Aug 2012 20:19:20 +0000
parents 46410022772a
children acdb8f9c9ce6
files ChangeLog babel/numbers.py babel/tests/numbers.py
diffstat 3 files changed, 19 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -45,6 +45,7 @@
  * fix format_decimal() with small Decimal values (#214, patch from George Lund)
  * fix handling of messages containing '\\n' (#198)
  * handle irregular multi-line msgstr (no "" as first line) gracefully (#171)
+ * parse_decimal() now returns Decimals not floats, API change (#178)
 
 
 Version 0.9.6
--- a/babel/numbers.py
+++ b/babel/numbers.py
@@ -23,7 +23,7 @@
 # TODO:
 #  Padding and rounding increments in pattern:
 #  - http://www.unicode.org/reports/tr35/ (Appendix G.6)
-from decimal import Decimal
+from decimal import Decimal, InvalidOperation
 import math
 import re
 
@@ -281,12 +281,12 @@
         raise NumberFormatError('%r is not a valid number' % string)
 
 def parse_decimal(string, locale=LC_NUMERIC):
-    """Parse localized decimal string into a float.
+    """Parse localized decimal string into a decimal.
     
     >>> parse_decimal('1,099.98', locale='en_US')
-    1099.98
+    Decimal('1099.98')
     >>> parse_decimal('1.099,98', locale='de')
-    1099.98
+    Decimal('1099.98')
     
     When the given string cannot be parsed, an exception is raised:
     
@@ -298,15 +298,15 @@
     :param string: the string to parse
     :param locale: the `Locale` object or locale identifier
     :return: the parsed decimal number
-    :rtype: `float`
+    :rtype: `Decimal`
     :raise `NumberFormatError`: if the string can not be converted to a
                                 decimal number
     """
     locale = Locale.parse(locale)
     try:
-        return float(string.replace(get_group_symbol(locale), '')
+        return Decimal(string.replace(get_group_symbol(locale), '')
                            .replace(get_decimal_symbol(locale), '.'))
-    except ValueError:
+    except InvalidOperation:
         raise NumberFormatError('%r is not a valid decimal number' % string)
 
 
--- a/babel/tests/numbers.py
+++ b/babel/tests/numbers.py
@@ -162,11 +162,22 @@
         self.assertEqual(Decimal('0.2'), numbers.bankersround(Decimal('0.15'), ndigits=1))
 
 
+class NumberParsingTestCase(unittest.TestCase):
+    def test_can_parse_decimals(self):
+        self.assertEqual(Decimal('1099.98'), 
+            numbers.parse_decimal('1,099.98', locale='en_US'))
+        self.assertEqual(Decimal('1099.98'), 
+            numbers.parse_decimal('1.099,98', locale='de'))
+        self.assertRaises(numbers.NumberFormatError, 
+                          lambda: numbers.parse_decimal('2,109,998', locale='de'))
+
+
 def suite():
     suite = unittest.TestSuite()
     suite.addTest(doctest.DocTestSuite(numbers))
     suite.addTest(unittest.makeSuite(FormatDecimalTestCase))
     suite.addTest(unittest.makeSuite(BankersRoundTestCase))
+    suite.addTest(unittest.makeSuite(NumberParsingTestCase))
     return suite
 
 if __name__ == '__main__':
Copyright (C) 2012-2017 Edgewall Software