[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