summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTravis Oliphant <oliphant@enthought.com>2006-04-18 18:00:09 +0000
committerTravis Oliphant <oliphant@enthought.com>2006-04-18 18:00:09 +0000
commitae43872a80811507385bb4175a550d5d40d6eece (patch)
treece0cfbdbffb6ec4b0e45d1677ed08dd320a0be16
parent5d5d80f54e09b5bb220c3e92a5703ab3cdc53ab5 (diff)
downloadnumpy-ae43872a80811507385bb4175a550d5d40d6eece.tar.gz
Changed error look-up to use per-thread global variable.
-rw-r--r--numpy/core/numeric.py77
-rw-r--r--numpy/core/src/ufuncobject.c90
-rw-r--r--numpy/core/src/umathmodule.c.src6
3 files changed, 101 insertions, 72 deletions
diff --git a/numpy/core/numeric.py b/numpy/core/numeric.py
index 8bab9008b..ad19f5b99 100644
--- a/numpy/core/numeric.py
+++ b/numpy/core/numeric.py
@@ -374,7 +374,7 @@ def ones(shape, dtype=int_, order='C'):
return a
def identity(n,dtype=int_):
- """identity(n) returns the identity matrix of shape n x n.
+ """identity(n) returns the identity 2-d array of shape n x n.
"""
a = array([1]+n*[0],dtype=dtype)
b = empty((n,n),dtype=dtype)
@@ -394,36 +394,6 @@ def allclose (a, b, rtol=1.e-5, atol=1.e-8):
d = less(absolute(x-y), atol + rtol * absolute(y))
return d.ravel().all()
-def _setpyvals(lst, frame, where=0):
- if not isinstance(lst, list) or len(lst) != 3:
- raise ValueError, "Invalid pyvalues (length 3 list needed)."
-
- try:
- wh = where.lower()[0]
- except (AttributeError, TypeError, IndexError):
- wh = None
-
- if where==0 or wh == 'l':
- frame.f_locals[UFUNC_PYVALS_NAME] = lst
- elif where == 1 or wh == 'g':
- frame.f_globals[UFUNC_PYVALS_NAME] = lst
- elif where == 2 or wh == 'b':
- frame.f_builtins[UFUNC_PYVALS_NAME] = lst
-
- umath.update_use_defaults()
- return
-
-def _getpyvals(frame):
- try:
- return frame.f_locals[UFUNC_PYVALS_NAME]
- except KeyError:
- try:
- return frame.f_globals[UFUNC_PYVALS_NAME]
- except KeyError:
- try:
- return frame.f_builtins[UFUNC_PYVALS_NAME]
- except KeyError:
- return [UFUNC_BUFSIZE_DEFAULT, ERR_DEFAULT, None]
_errdict = {"ignore":ERR_IGNORE,
"warn":ERR_WARN,
@@ -436,21 +406,21 @@ for key in _errdict.keys():
del key
def seterr(divide="ignore", over="ignore", under="ignore",
- invalid="ignore", where=0):
+ invalid="ignore"):
+
maskvalue = ((_errdict[divide] << SHIFT_DIVIDEBYZERO) +
(_errdict[over] << SHIFT_OVERFLOW ) +
(_errdict[under] << SHIFT_UNDERFLOW) +
(_errdict[invalid] << SHIFT_INVALID))
- frame = sys._getframe().f_back
- pyvals = _getpyvals(frame)
- pyvals[1] = maskvalue
- _setpyvals(pyvals, frame, where)
+ pyvals = umath.geterrlist()
+ old = pyvals[:]
+ pyvals[1] = maskvalue
+ umath.seterrlist(pyvals)
+ return old
def geterr():
- frame = sys._getframe().f_back
- maskvalue = _getpyvals(frame)[1]
-
+ maskvalue = umath.geterrlist()[1]
mask = 3
res = {}
val = (maskvalue >> SHIFT_DIVIDEBYZERO) & mask
@@ -463,37 +433,34 @@ def geterr():
res['invalid'] = _errdict_rev[val]
return res
-def setbufsize(size, where=0):
+def setbufsize(size):
if size > 10e6:
raise ValueError, "Very big buffers.. %s" % size
- frame = sys._getframe().f_back
- pyvals = _getpyvals(frame)
+ pyvals = umath.geterrlist()
+ old = pyvals[:]
pyvals[0] = size
- _setpyvals(pyvals, frame, where)
+ umath.seterrlist(pyvals)
+ return old
def getbufsize():
- frame = sys._getframe().f_back
- return _getpyvals(frame)[0]
+ return umath.geterrlist()[0]
-def seterrcall(func, where=0):
+def seterrcall(func):
if not callable(func):
raise ValueError, "Only callable can be used as callback"
- frame = sys._getframe().f_back
- pyvals = _getpyvals(frame)
+ pyvals = umath.geterrlist()
+ old = pyvals[:]
pyvals[2] = func
- _setpyvals(pyvals, frame, where)
+ umath.seterrlist(pyvals)
+ return old
def geterrcall():
- frame = sys._getframe().f_back
- return _getpyvals(frame)[2]
+ return umath.geterrlist()[2]
def _setdef():
- frame = sys._getframe()
defval = [UFUNC_BUFSIZE_DEFAULT, ERR_DEFAULT, None]
- frame.f_globals[UFUNC_PYVALS_NAME] = defval
- frame.f_builtins[UFUNC_PYVALS_NAME] = defval
- umath.update_use_defaults()
+ umath.seterrlist(defval)
# set the default values
_setdef()
diff --git a/numpy/core/src/ufuncobject.c b/numpy/core/src/ufuncobject.c
index d1afb0467..ee2314ca1 100644
--- a/numpy/core/src/ufuncobject.c
+++ b/numpy/core/src/ufuncobject.c
@@ -698,6 +698,7 @@ select_types(PyUFuncObject *self, int *arg_types,
}
static int PyUFunc_USEDEFAULTS=0;
+static PyObject *PyUFunc_PYVALS_NAME=NULL;
/*UFUNC_API*/
static int
@@ -706,22 +707,26 @@ PyUFunc_GetPyValues(char *name, int *bufsize, int *errmask, PyObject **errobj)
PyObject *thedict;
PyObject *ref=NULL;
PyObject *retval;
- static PyObject *thestring=NULL;
if (!PyUFunc_USEDEFAULTS) {
- if (thestring == NULL) {
- thestring = PyString_InternFromString(UFUNC_PYVALS_NAME);
+ if (PyUFunc_PYVALS_NAME == NULL) {
+ PyUFunc_PYVALS_NAME = PyString_InternFromString(UFUNC_PYVALS_NAME);
}
- thedict = PyEval_GetLocals();
- ref = PyDict_GetItem(thedict, thestring);
- if (ref == NULL) {
- thedict = PyEval_GetGlobals();
- ref = PyDict_GetItem(thedict, thestring);
- }
- if (ref == NULL) {
+ thedict = PyThreadState_GetDict();
+ if (thedict == NULL) {
thedict = PyEval_GetBuiltins();
- ref = PyDict_GetItem(thedict, thestring);
}
+ ref = PyDict_GetItem(thedict, PyUFunc_PYVALS_NAME);
+/* thedict = PyEval_GetLocals(); */
+/* ref = PyDict_GetItem(thedict, thestring); */
+/* if (ref == NULL) { */
+/* thedict = PyEval_GetGlobals(); */
+/* ref = PyDict_GetItem(thedict, thestring); */
+/* } */
+/* if (ref == NULL) { */
+/* thedict = PyEval_GetBuiltins(); */
+/* ref = PyDict_GetItem(thedict, thestring); */
+/* } */
}
if (ref == NULL) {
*errmask = UFUNC_ERR_DEFAULT;
@@ -2743,26 +2748,81 @@ ufunc_generic_call(PyUFuncObject *self, PyObject *args)
}
static PyObject *
-ufunc_update_use_defaults(PyObject *dummy, PyObject *args)
+ufunc_geterr(PyObject *dummy, PyObject *args)
+{
+ PyObject *thedict;
+ PyObject *res;
+
+ if (!PyArg_ParseTuple(args, "")) return NULL;
+
+ if (PyUFunc_PYVALS_NAME == NULL) {
+ PyUFunc_PYVALS_NAME = PyString_InternFromString(UFUNC_PYVALS_NAME);
+ }
+ thedict = PyThreadState_GetDict();
+ if (thedict == NULL) {
+ thedict = PyEval_GetBuiltins();
+ }
+ res = PyDict_GetItem(thedict, PyUFunc_PYVALS_NAME);
+ if (res != NULL) {
+ Py_INCREF(res);
+ return res;
+ }
+ /* Construct list of defaults */
+ res = PyList_New(3);
+ if (res == NULL) return NULL;
+ PyList_SET_ITEM(res, 0, PyInt_FromLong(PyArray_BUFSIZE));
+ PyList_SET_ITEM(res, 1, PyInt_FromLong(UFUNC_ERR_DEFAULT));
+ PyList_SET_ITEM(res, 2, Py_None); Py_INCREF(Py_None);
+ return res;
+}
+
+static int
+ufunc_update_use_defaults(void)
{
PyObject *errobj;
int errmask, bufsize;
- if (!PyArg_ParseTuple(args, "")) return NULL;
-
PyUFunc_USEDEFAULTS = 0;
- if (PyUFunc_GetPyValues("test", &bufsize, &errmask, &errobj) < 0) return NULL;
+ if (PyUFunc_GetPyValues("test", &bufsize, &errmask, &errobj) < 0) return -1;
if ((errmask == UFUNC_ERR_DEFAULT) && \
(bufsize == PyArray_BUFSIZE) && \
(PyTuple_GET_ITEM(errobj, 1) == Py_None)) {
PyUFunc_USEDEFAULTS = 1;
}
+ return 0;
+}
+
+static PyObject *
+ufunc_seterr(PyObject *dummy, PyObject *args)
+{
+ PyObject *thedict;
+ int res;
+ PyObject *val;
+
+ if (!PyArg_ParseTuple(args, "O!", &PyList_Type, &val)) return NULL;
+ if (PyList_GET_SIZE(val) < 3) {
+ PyErr_SetString(PyExc_ValueError,
+ "Error object Must be a list of length 3");
+ return NULL;
+ }
+ if (PyUFunc_PYVALS_NAME == NULL) {
+ PyUFunc_PYVALS_NAME = PyString_InternFromString(UFUNC_PYVALS_NAME);
+ }
+ thedict = PyThreadState_GetDict();
+ if (thedict == NULL) {
+ thedict = PyEval_GetBuiltins();
+ }
+ res = PyDict_SetItem(thedict, PyUFunc_PYVALS_NAME, val);
+ if (res < 0) return NULL;
+ if (ufunc_update_use_defaults() < 0) return NULL;
Py_INCREF(Py_None);
return Py_None;
}
+
+
static PyUFuncGenericFunction pyfunc_functions[] = {PyUFunc_On_Om};
static char
diff --git a/numpy/core/src/umathmodule.c.src b/numpy/core/src/umathmodule.c.src
index b35597447..461671818 100644
--- a/numpy/core/src/umathmodule.c.src
+++ b/numpy/core/src/umathmodule.c.src
@@ -2262,8 +2262,10 @@ InitOtherOperators(PyObject *dictionary) {
static struct PyMethodDef methods[] = {
{"frompyfunc", (PyCFunction) ufunc_frompyfunc,
METH_VARARGS | METH_KEYWORDS, doc_frompyfunc},
- {"update_use_defaults", (PyCFunction) ufunc_update_use_defaults,
- METH_VARARGS , NULL},
+ {"seterrlist", (PyCFunction) ufunc_seterr,
+ METH_VARARGS, NULL},
+ {"geterrlist", (PyCFunction) ufunc_geterr,
+ METH_VARARGS, NULL},
{NULL, NULL, 0} /* sentinel */
};