Commit bb23cde8 authored by Stefan Krah's avatar Stefan Krah

Merge.

parents dbe4e622 e677e003
...@@ -4953,6 +4953,78 @@ class CWhitebox(unittest.TestCase): ...@@ -4953,6 +4953,78 @@ class CWhitebox(unittest.TestCase):
self.assertRaises(ValueError, get_fmt, 12345, invalid_dot, 'g') self.assertRaises(ValueError, get_fmt, 12345, invalid_dot, 'g')
self.assertRaises(ValueError, get_fmt, 12345, invalid_sep, '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)
def test_from_tuple(self):
Decimal = C.Decimal
localcontext = C.localcontext
InvalidOperation = C.InvalidOperation
Overflow = C.Overflow
Underflow = C.Underflow
with localcontext() as c:
c.traps[InvalidOperation] = True
c.traps[Overflow] = True
c.traps[Underflow] = True
# SSIZE_MAX
x = (1, (), sys.maxsize)
self.assertEqual(str(c.create_decimal(x)), '-0E+999999')
self.assertRaises(InvalidOperation, Decimal, x)
x = (1, (0, 1, 2), sys.maxsize)
self.assertRaises(Overflow, c.create_decimal, x)
self.assertRaises(InvalidOperation, Decimal, x)
# SSIZE_MIN
x = (1, (), -sys.maxsize-1)
self.assertEqual(str(c.create_decimal(x)), '-0E-1000026')
self.assertRaises(InvalidOperation, Decimal, x)
x = (1, (0, 1, 2), -sys.maxsize-1)
self.assertRaises(Underflow, c.create_decimal, x)
self.assertRaises(InvalidOperation, Decimal, x)
# OverflowError
x = (1, (), sys.maxsize+1)
self.assertRaises(OverflowError, c.create_decimal, x)
self.assertRaises(OverflowError, Decimal, x)
x = (1, (), -sys.maxsize-2)
self.assertRaises(OverflowError, c.create_decimal, x)
self.assertRaises(OverflowError, Decimal, x)
# Specials
x = (1, (), "N")
self.assertEqual(str(Decimal(x)), '-sNaN')
x = (1, (0,), "N")
self.assertEqual(str(Decimal(x)), '-sNaN')
x = (1, (0, 1), "N")
self.assertEqual(str(Decimal(x)), '-sNaN1')
all_tests = [ all_tests = [
CExplicitConstructionTest, PyExplicitConstructionTest, CExplicitConstructionTest, PyExplicitConstructionTest,
......
...@@ -1935,7 +1935,7 @@ PyDecType_FromCStringExact(PyTypeObject *type, const char *s, ...@@ -1935,7 +1935,7 @@ PyDecType_FromCStringExact(PyTypeObject *type, const char *s,
mpd_maxcontext(&maxctx); mpd_maxcontext(&maxctx);
mpd_qset_string(MPD(dec), s, &maxctx, &status); 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 */ /* we want exact results */
mpd_seterror(MPD(dec), MPD_Invalid_operation, &status); mpd_seterror(MPD(dec), MPD_Invalid_operation, &status);
} }
...@@ -2139,7 +2139,7 @@ PyDecType_FromLongExact(PyTypeObject *type, const PyObject *pylong, ...@@ -2139,7 +2139,7 @@ PyDecType_FromLongExact(PyTypeObject *type, const PyObject *pylong,
return NULL; return NULL;
} }
if (status & (MPD_Inexact|MPD_Rounded)) { if (status & (MPD_Inexact|MPD_Rounded|MPD_Clamped)) {
/* we want exact results */ /* we want exact results */
mpd_seterror(MPD(dec), MPD_Invalid_operation, &status); mpd_seterror(MPD(dec), MPD_Invalid_operation, &status);
} }
...@@ -2385,8 +2385,8 @@ dectuple_as_str(PyObject *dectuple) ...@@ -2385,8 +2385,8 @@ dectuple_as_str(PyObject *dectuple)
} }
/* coefficient */ /* coefficient */
digits = sequence_as_tuple(PyTuple_GET_ITEM(dectuple, 1), digits = sequence_as_tuple(PyTuple_GET_ITEM(dectuple, 1), PyExc_ValueError,
PyExc_ValueError, "coefficient must be a tuple of digits"); "coefficient must be a tuple of digits");
if (digits == NULL) { if (digits == NULL) {
goto error; goto error;
} }
...@@ -2435,8 +2435,8 @@ dectuple_as_str(PyObject *dectuple) ...@@ -2435,8 +2435,8 @@ dectuple_as_str(PyObject *dectuple)
if (sign_special[1] == '\0') { if (sign_special[1] == '\0') {
/* not a special number */ /* not a special number */
*cp++ = 'E'; *cp++ = 'E';
n = snprintf(cp, MPD_EXPDIGITS+1, "%" PRI_mpd_ssize_t, exp); n = snprintf(cp, MPD_EXPDIGITS+2, "%" PRI_mpd_ssize_t, exp);
if (n < 0 || n >= MPD_EXPDIGITS+1) { if (n < 0 || n >= MPD_EXPDIGITS+2) {
PyErr_SetString(PyExc_RuntimeError, PyErr_SetString(PyExc_RuntimeError,
"internal error in dec_sequence_as_str"); "internal error in dec_sequence_as_str");
goto error; goto error;
...@@ -4215,7 +4215,7 @@ dec_hash(PyObject *v) ...@@ -4215,7 +4215,7 @@ dec_hash(PyObject *v)
mpd_uint_t p_data[1] = {2305843009213693951ULL}; mpd_uint_t p_data[1] = {2305843009213693951ULL};
mpd_t p = {MPD_POS|MPD_STATIC|MPD_CONST_DATA, 0, 19, 1, 1, p_data}; mpd_t p = {MPD_POS|MPD_STATIC|MPD_CONST_DATA, 0, 19, 1, 1, p_data};
/* Inverse of 10 modulo p */ /* Inverse of 10 modulo p */
mpd_uint_t inv10_p_data[2] = {2075258708292324556ULL}; mpd_uint_t inv10_p_data[1] = {2075258708292324556ULL};
mpd_t inv10_p = {MPD_POS|MPD_STATIC|MPD_CONST_DATA, mpd_t inv10_p = {MPD_POS|MPD_STATIC|MPD_CONST_DATA,
0, 19, 1, 1, inv10_p_data}; 0, 19, 1, 1, inv10_p_data};
#elif defined(CONFIG_32) && _PyHASH_BITS == 31 #elif defined(CONFIG_32) && _PyHASH_BITS == 31
...@@ -4934,7 +4934,7 @@ ctx_copy_decimal(PyObject *context, PyObject *v) ...@@ -4934,7 +4934,7 @@ ctx_copy_decimal(PyObject *context, PyObject *v)
PyObject *result; PyObject *result;
CONVERT_OP_RAISE(&result, v, context); CONVERT_OP_RAISE(&result, v, context);
return result; return result;
} }
static PyObject * static PyObject *
......
...@@ -302,6 +302,7 @@ def RestrictedDecimal(value): ...@@ -302,6 +302,7 @@ def RestrictedDecimal(value):
dec = maxcontext.create_decimal(value) dec = maxcontext.create_decimal(value)
if maxcontext.flags[P.Inexact] or \ if maxcontext.flags[P.Inexact] or \
maxcontext.flags[P.Rounded] or \ maxcontext.flags[P.Rounded] or \
maxcontext.flags[P.Clamped] or \
maxcontext.flags[P.InvalidOperation]: maxcontext.flags[P.InvalidOperation]:
return context.p._raise_error(P.InvalidOperation) return context.p._raise_error(P.InvalidOperation)
if maxcontext.flags[P.FloatOperation]: if maxcontext.flags[P.FloatOperation]:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment