Commit bb23cde8 authored by Stefan Krah's avatar Stefan Krah

Merge.

parents dbe4e622 e677e003
......@@ -4953,6 +4953,78 @@ 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)
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 = [
CExplicitConstructionTest, PyExplicitConstructionTest,
......
......@@ -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);
}
......@@ -2385,8 +2385,8 @@ dectuple_as_str(PyObject *dectuple)
}
/* coefficient */
digits = sequence_as_tuple(PyTuple_GET_ITEM(dectuple, 1),
PyExc_ValueError, "coefficient must be a tuple of digits");
digits = sequence_as_tuple(PyTuple_GET_ITEM(dectuple, 1), PyExc_ValueError,
"coefficient must be a tuple of digits");
if (digits == NULL) {
goto error;
}
......@@ -2435,8 +2435,8 @@ dectuple_as_str(PyObject *dectuple)
if (sign_special[1] == '\0') {
/* not a special number */
*cp++ = 'E';
n = snprintf(cp, MPD_EXPDIGITS+1, "%" PRI_mpd_ssize_t, exp);
if (n < 0 || n >= MPD_EXPDIGITS+1) {
n = snprintf(cp, MPD_EXPDIGITS+2, "%" PRI_mpd_ssize_t, exp);
if (n < 0 || n >= MPD_EXPDIGITS+2) {
PyErr_SetString(PyExc_RuntimeError,
"internal error in dec_sequence_as_str");
goto error;
......@@ -4215,7 +4215,7 @@ dec_hash(PyObject *v)
mpd_uint_t p_data[1] = {2305843009213693951ULL};
mpd_t p = {MPD_POS|MPD_STATIC|MPD_CONST_DATA, 0, 19, 1, 1, p_data};
/* 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,
0, 19, 1, 1, inv10_p_data};
#elif defined(CONFIG_32) && _PyHASH_BITS == 31
......@@ -4934,7 +4934,7 @@ ctx_copy_decimal(PyObject *context, PyObject *v)
PyObject *result;
CONVERT_OP_RAISE(&result, v, context);
return result;
return result;
}
static PyObject *
......
......@@ -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]:
......
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