From 0774e9b9f57197380c796d36353344cb95ed07bf Mon Sep 17 00:00:00 2001 From: Stefan Krah Date: Thu, 5 Apr 2012 15:21:58 +0200 Subject: [PATCH] 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). --- 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 index 694b959e2187..90f401554981 100644 --- a/Lib/test/test_decimal.py +++ b/Lib/test/test_decimal.py @@ -4953,6 +4953,30 @@ class CWhitebox(unittest.TestCase): 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 index 32e336b4fff3..ad3c3df3184c 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -1935,7 +1935,7 @@ PyDecType_FromCStringExact(PyTypeObject *type, const char *s, 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 @@ PyDecType_FromLongExact(PyTypeObject *type, const PyObject *pylong, 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 index aefbed67af46..c8da4d02b737 100644 --- a/Modules/_decimal/tests/deccheck.py +++ b/Modules/_decimal/tests/deccheck.py @@ -302,6 +302,7 @@ def RestrictedDecimal(value): 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]: -- 2.47.3