[Python-checkins] cpython: Raise InvalidOperation if exponents of zeros are clamped during exact

stefan.krah python-checkins at python.org
Thu Apr 5 16:27:26 CEST 2012


http://hg.python.org/cpython/rev/0f9d79998c79
changeset:   76120:0f9d79998c79
parent:      76116:2c514c382a2a
user:        Stefan Krah <skrah at bytereef.org>
date:        Thu Apr 05 15:21:58 2012 +0200
summary:
  Raise InvalidOperation if exponents of zeros are clamped during exact
conversion in the Decimal constructor. Exact here refers to the
representation and not to the value (clamping does not change the value).

files:
  Lib/test/test_decimal.py           |  24 ++++++++++++++++++
  Modules/_decimal/_decimal.c        |   4 +-
  Modules/_decimal/tests/deccheck.py |   1 +
  3 files changed, 27 insertions(+), 2 deletions(-)


diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py
--- a/Lib/test/test_decimal.py
+++ b/Lib/test/test_decimal.py
@@ -4953,6 +4953,30 @@
         self.assertRaises(ValueError, get_fmt, 12345, invalid_dot, 'g')
         self.assertRaises(ValueError, get_fmt, 12345, invalid_sep, 'g')
 
+    def test_exact_conversion(self):
+        Decimal = C.Decimal
+        localcontext = C.localcontext
+        InvalidOperation = C.InvalidOperation
+
+        with localcontext() as c:
+
+            c.traps[InvalidOperation] = True
+
+            # Clamped
+            x = "0e%d" % sys.maxsize
+            self.assertRaises(InvalidOperation, Decimal, x)
+
+            x = "0e%d" % (-sys.maxsize-1)
+            self.assertRaises(InvalidOperation, Decimal, x)
+
+            # Overflow
+            x = "1e%d" % sys.maxsize
+            self.assertRaises(InvalidOperation, Decimal, x)
+
+            # Underflow
+            x = "1e%d" % (-sys.maxsize-1)
+            self.assertRaises(InvalidOperation, Decimal, x)
+
 
 all_tests = [
   CExplicitConstructionTest, PyExplicitConstructionTest,
diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c
--- a/Modules/_decimal/_decimal.c
+++ b/Modules/_decimal/_decimal.c
@@ -1935,7 +1935,7 @@
     mpd_maxcontext(&maxctx);
 
     mpd_qset_string(MPD(dec), s, &maxctx, &status);
-    if (status & (MPD_Inexact|MPD_Rounded)) {
+    if (status & (MPD_Inexact|MPD_Rounded|MPD_Clamped)) {
         /* we want exact results */
         mpd_seterror(MPD(dec), MPD_Invalid_operation, &status);
     }
@@ -2139,7 +2139,7 @@
         return NULL;
     }
 
-    if (status & (MPD_Inexact|MPD_Rounded)) {
+    if (status & (MPD_Inexact|MPD_Rounded|MPD_Clamped)) {
         /* we want exact results */
         mpd_seterror(MPD(dec), MPD_Invalid_operation, &status);
     }
diff --git a/Modules/_decimal/tests/deccheck.py b/Modules/_decimal/tests/deccheck.py
--- a/Modules/_decimal/tests/deccheck.py
+++ b/Modules/_decimal/tests/deccheck.py
@@ -302,6 +302,7 @@
     dec = maxcontext.create_decimal(value)
     if maxcontext.flags[P.Inexact] or \
        maxcontext.flags[P.Rounded] or \
+       maxcontext.flags[P.Clamped] or \
        maxcontext.flags[P.InvalidOperation]:
         return context.p._raise_error(P.InvalidOperation)
     if maxcontext.flags[P.FloatOperation]:

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list