[Python-checkins] r46188 - sandbox/trunk/decimal-c/_decimal.c sandbox/trunk/decimal-c/decimal.py

jack.diederich python-checkins at python.org
Wed May 24 18:24:34 CEST 2006


Author: jack.diederich
Date: Wed May 24 18:24:33 2006
New Revision: 46188

Modified:
   sandbox/trunk/decimal-c/_decimal.c
   sandbox/trunk/decimal-c/decimal.py
Log:
* added more context methods

Modified: sandbox/trunk/decimal-c/_decimal.c
==============================================================================
--- sandbox/trunk/decimal-c/_decimal.c	(original)
+++ sandbox/trunk/decimal-c/_decimal.c	Wed May 24 18:24:33 2006
@@ -20,6 +20,7 @@
 
 #define ISFLAGSET(f, b) (((f) >> b) & 1)
 #define SETFLAG(f, b) (f |= (1 << b))
+#define UNSETFLAG(f, b) (f &= (0 << b))
 
 /* Checks */
 
@@ -58,9 +59,11 @@
 #define ROUND_HALF_UP   4
 #define ROUND_FLOOR     5
 #define ROUND_CEILING   6
+#define VALID_ROUND(x) ((x) <= ROUND_CEILING && (x) >= ROUND_DOWN)
 
 #define ALWAYS_ROUND    0
 #define NEVER_ROUND     16
+#define VALID_ROUND_DEC(x) ((x) == ALWAYS_ROUND || (x) == NEVER_ROUND)
 
 /* Context signals */
 
@@ -2961,6 +2964,122 @@
     return res;
 }
 
+static PyObject *
+context_ignore_flags(contextobject *self, PyObject *args)
+{
+    PyObject *flag, *ret_flags;
+    Py_ssize_t i, j;
+
+    /* NB, unlike regard_flags this doesn't accept a sequence as the
+       first element and regard_flags returns a list-ized version of
+       its arguments instead of None
+    */
+
+    if (ret_flags == NULL)
+        return NULL;
+    for (i = 0; i < PyTuple_GET_SIZE(args); i++) {
+        flag = PyTuple_GET_ITEM(args, i);
+        for (j = 0; j < NUMSIGNALS; j++) {
+            if (errors[j] == flag) {
+                SETFLAG(self->ignored, j);
+                Py_INCREF(flag);
+                PyList_SET_ITEM(ret_flags, i, flag);
+                break;
+            }
+        }
+        if (j == NUMSIGNALS) {
+            Py_DECREF(ret_flags);
+            PyErr_SetString(PyExc_ValueError, "arguments must be valid flags");
+            return NULL;
+        }
+    }
+    return ret_flags;
+}
+
+static PyObject *
+context_ignore_all_flags(contextobject *self)
+{
+    PyObject *allflags, *flag;
+    int i = 0;
+
+    allflags = PyTuple_New(NUMSIGNALS);
+    if (allflags == NULL)
+        return NULL;
+        
+    for (i = 0; i < NUMSIGNALS; i++) {
+        flag = errors[i];
+        Py_INCREF(flag);
+        PyTuple_SET_ITEM(allflags, i, flag);
+    }
+    return context_ignore_flags(self, allflags);
+}
+
+static PyObject *
+context_regard_flags(contextobject *self, PyObject *args)
+{
+    PyObject *flag, *flags;
+    Py_ssize_t i, j;
+
+    /* regard_flags allows a list of flags as the first arg */
+    flags = PyTuple_GET_ITEM(args, 0);
+    if (PyTuple_GET_SIZE(args) != 1 && !PySequence_Check(flags))
+        flags = args;
+
+    for (i = 0; i < PySequence_Size(flags); i++) {
+        flag = PySequence_GetItem(flags, i);
+        for (j = 0; j < NUMSIGNALS; j++) {
+            if (flag == errors[j]) {
+                UNSETFLAG(self->ignored, j);
+                break;
+            }
+        }
+        if (j == NUMSIGNALS) {
+            PyErr_SetString(PyExc_ValueError, "arguments must be valid flags");
+            return NULL;
+        }
+    }
+    Py_RETURN_NONE;
+}
+
+static PyObject *
+context_set_rounding_decision(contextobject *self, PyObject *args)
+{
+    int old_dec, new_dec;
+    PyObject *ret;
+
+    if (!PyArg_ParseTuple(args, "i:_set_rounding_decision", &new_dec))
+        return NULL;
+    if (!VALID_ROUND_DEC(new_dec)) {
+        PyErr_SetString(PyExc_ValueError, "value is not a valid rounding decision");
+        return NULL;
+    }
+        
+    old_dec = self->rounding_dec;
+    self->rounding_dec = new_dec;
+    ret = PyLong_FromLong((long)old_dec);
+    if (ret == NULL)
+        return NULL;
+    return ret;
+}
+static PyObject *
+context_set_rounding(contextobject *self, PyObject *args)
+{
+    int old_round, new_round;
+    PyObject *ret;
+
+    if (!PyArg_ParseTuple(args, "i:_set_rounding", &new_round))
+        return NULL;
+    if (!VALID_ROUND(new_round)) {
+        PyErr_SetString(PyExc_ValueError, "value is not a valid rounding");
+        return NULL;
+    }
+    old_round = self->rounding;
+    self->rounding = new_round;
+    ret = PyLong_FromLong((long)old_round);
+    if (ret == NULL)
+        return NULL;
+    return ret;
+}
 
 static PyMethodDef context_methods[] = {
     {"clear_flags",     (PyCFunction)context_clear_flags,
@@ -2973,8 +3092,7 @@
      METH_NOARGS},
     {"Etop",            (PyCFunction)context_Etop,
      METH_NOARGS},
-    {"abs",             (PyCFunction)context_abs,
-     METH_O},
+    {"abs",             (PyCFunction)context_abs,     METH_O},
     {"add",             (PyCFunction)context_add,
      METH_VARARGS},
     {"compare",         (PyCFunction)context_compare,
@@ -3017,6 +3135,16 @@
      METH_O},
     {"to_sci_string",   (PyCFunction)context_to_sci_string,
      METH_O},
+    {"_ignore_all_flags", (PyCFunction)context_ignore_all_flags,
+     METH_NOARGS},
+    {"_ignore_flags", (PyCFunction)context_ignore_flags,
+     METH_VARARGS},
+    {"_regard_flags", (PyCFunction)context_regard_flags,
+     METH_VARARGS},
+    {"_set_rounding_decision", (PyCFunction)context_set_rounding_decision,
+     METH_VARARGS},
+    {"_set_rounding", (PyCFunction)context_set_rounding,
+     METH_VARARGS},
     {"__copy__",        (PyCFunction)context_copy,
      METH_NOARGS},
     {"_shallow_copy",   (PyCFunction)context_copy,

Modified: sandbox/trunk/decimal-c/decimal.py
==============================================================================
--- sandbox/trunk/decimal-c/decimal.py	(original)
+++ sandbox/trunk/decimal-c/decimal.py	Wed May 24 18:24:33 2006
@@ -370,9 +370,6 @@
 #     """
 
 # # List of public traps and flags
-# _signals = [Clamped, DivisionByZero, Inexact, Overflow, Rounded,
-#            Underflow, InvalidOperation, Subnormal]
-
 # # Map conditions (per the spec) to signals
 # _condition_map = {ConversionSyntax:InvalidOperation,
 #                   DivisionImpossible:InvalidOperation,
@@ -2185,64 +2182,6 @@
         #self._ignored_flags = []
         raise error, explanation
 
-    def _ignore_all_flags(self):
-        """Ignore all flags, if they are raised"""
-        return self._ignore_flags(*_signals)
-
-    def _ignore_flags(self, *flags):
-        """Ignore the flags, if they are raised"""
-        # Do not mutate-- This way, copies of a context leave the original
-        # alone.
-        self._ignored_flags = (self._ignored_flags + list(flags))
-        return list(flags)
-
-    def _regard_flags(self, *flags):
-        """Stop ignoring the flags, if they are raised"""
-        if flags and isinstance(flags[0], (tuple,list)):
-            flags = flags[0]
-        for flag in flags:
-            self._ignored_flags.remove(flag)
-
-    def _set_rounding_decision(self, type):
-        """Sets the rounding decision.
-
-        Sets the rounding decision, and returns the current (previous)
-        rounding decision.  Often used like:
-
-        context = context._shallow_copy()
-        # That so you don't change the calling context
-        # if an error occurs in the middle (say DivisionImpossible is raised).
-
-        rounding = context._set_rounding_decision(NEVER_ROUND)
-        instance = instance / Decimal(2)
-        context._set_rounding_decision(rounding)
-
-        This will make it not round for that operation.
-        """
-
-        rounding = self._rounding_decision
-        self._rounding_decision = type
-        return rounding
-
-    def _set_rounding(self, type):
-        """Sets the rounding type.
-
-        Sets the rounding type, and returns the current (previous)
-        rounding type.  Often used like:
-
-        context = context.copy()
-        # so you don't change the calling context
-        # if an error occurs in the middle.
-        rounding = context._set_rounding(ROUND_UP)
-        val = self.__sub__(other, context=context)
-        context._set_rounding(rounding)
-
-        This will make it round up for that operation.
-        """
-        rounding = self.rounding
-        self.rounding= type
-        return rounding
-
 ## TO HERE
 
     def create_decimal(self, num='0'):
@@ -2719,9 +2658,6 @@
 from _decimal import BasicContext, ExtendedContext, \
      DefaultContext
 
-BasicContext._ignore_flags = Context._ignore_flags
-
-
 class _WorkRep(object):
     __slots__ = ('sign','int','exp')
     # sign: 0 or 1


More information about the Python-checkins mailing list