From 9a4ff437d156b3cc9c942473141eafcee79f9d75 Mon Sep 17 00:00:00 2001 From: Stefan Krah Date: Sun, 16 Dec 2012 21:10:35 +0100 Subject: [PATCH] Issue #15783: Support None default values in the Context() constructor. --- Lib/test/test_decimal.py | 21 ++++++++++++ Modules/_decimal/_decimal.c | 67 +++++++++++++++++++------------------ 2 files changed, 56 insertions(+), 32 deletions(-) diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py index 0dddc4ba6bb..e13870965a9 100644 --- a/Lib/test/test_decimal.py +++ b/Lib/test/test_decimal.py @@ -2718,6 +2718,27 @@ class PyPythonAPItests(PythonAPItests): class ContextAPItests(unittest.TestCase): + def test_none_args(self): + Context = self.decimal.Context + InvalidOperation = self.decimal.InvalidOperation + DivisionByZero = self.decimal.DivisionByZero + Overflow = self.decimal.Overflow + ROUND_HALF_EVEN = self.decimal.ROUND_HALF_EVEN + + c1 = Context() + c2 = Context(prec=None, rounding=None, Emax=None, Emin=None, + capitals=None, clamp=None, flags=None, traps=None) + for c in [c1, c2]: + self.assertEqual(c.prec, 28) + self.assertEqual(c.rounding, ROUND_HALF_EVEN) + self.assertEqual(c.Emax, 999999) + self.assertEqual(c.Emin, -999999) + self.assertEqual(c.capitals, 1) + self.assertEqual(c.clamp, 0) + assert_signals(self, c, 'flags', []) + assert_signals(self, c, 'traps', [InvalidOperation, DivisionByZero, + Overflow]) + def test_pickle(self): Context = self.decimal.Context diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index 3490cd2a451..4fb99985777 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -1241,50 +1241,53 @@ context_init(PyObject *self, PyObject *args, PyObject *kwds) "prec", "rounding", "Emin", "Emax", "capitals", "clamp", "flags", "traps", NULL }; - PyObject *rounding = NULL; - PyObject *traps = NULL; - PyObject *status = NULL; - mpd_context_t *ctx, t; - int capitals = 1; + PyObject *prec = Py_None; + PyObject *rounding = Py_None; + PyObject *emin = Py_None; + PyObject *emax = Py_None; + PyObject *capitals = Py_None; + PyObject *clamp = Py_None; + PyObject *status = Py_None; + PyObject *traps = Py_None; int ret; assert(PyTuple_Check(args)); - ctx = CTX(self); - t = *ctx; if (!PyArg_ParseTupleAndKeywords( args, kwds, - "|nOnniiOO", kwlist, - &t.prec, &rounding, &t.emin, &t.emax, &capitals, &t.clamp, - &status, &traps + "|OOOOOOOO", kwlist, + &prec, &rounding, &emin, &emax, &capitals, &clamp, &status, &traps )) { return -1; } - if (rounding != NULL) { - t.round = getround(rounding); - if (t.round < 0) { + + if (prec != Py_None && context_setprec(self, prec, NULL) < 0) { + return -1; + } + if (emin != Py_None && context_setemin(self, emin, NULL) < 0) { + return -1; + } + if (emax != Py_None && context_setemax(self, emax, NULL) < 0) { + return -1; + } + if (capitals != Py_None && context_setcapitals(self, capitals, NULL) < 0) { + return -1; + } + if (clamp != Py_None && context_setclamp(self, clamp, NULL) < 0) { + return -1; + } + + if (rounding != Py_None) { + int x = getround(rounding); + if (x < 0) { return -1; } + if (!mpd_qsetround(CTX(self), x)) { + return type_error_int(invalid_rounding_err); + } } - if (!mpd_qsetprec(ctx, t.prec) || - !mpd_qsetemin(ctx, t.emin) || - !mpd_qsetemax(ctx, t.emax) || - !mpd_qsetclamp(ctx, t.clamp)) { - return value_error_int("invalid context"); - } - if (!mpd_qsetround(ctx, t.round) || - !mpd_qsettraps(ctx, t.traps) || - !mpd_qsetstatus(ctx, t.status)) { - return type_error_int("invalid context"); - } - - if (capitals != 0 && capitals != 1) { - return value_error_int("invalid context"); - } - CtxCaps(self) = capitals; - - if (traps != NULL) { + if (traps != Py_None) { if (PyList_Check(traps)) { ret = context_settraps_list(self, traps); } @@ -1300,7 +1303,7 @@ context_init(PyObject *self, PyObject *args, PyObject *kwds) return ret; } } - if (status != NULL) { + if (status != Py_None) { if (PyList_Check(status)) { ret = context_setstatus_list(self, status); }