summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Wieser <wieser.eric@gmail.com>2020-01-06 18:57:47 +0000
committerEric Wieser <wieser.eric@gmail.com>2020-01-14 15:06:52 +0000
commite2921434a07c22714bbf242be5389c3056449863 (patch)
treed0272d304ff0cde77a1953d4ec46d82a8b0af453
parentfbd807f5c5587407847f1aa54e6dada79bb90c35 (diff)
downloadnumpy-e2921434a07c22714bbf242be5389c3056449863.tar.gz
BUG: Use PyDict_GetItemWithError() instead of PyDict_GetItem()
This means we no longer interpret `MemoryError` or `KeyboardInterrupt` as `keyword arg not provided`, for instance. This function is python 3 only, hence this was difficult to do in older versions of numpy. Inspired by https://bugs.python.org/issue35459
-rw-r--r--numpy/core/include/numpy/npy_3kcompat.h16
-rw-r--r--numpy/core/src/common/ufunc_override.c5
-rw-r--r--numpy/core/src/multiarray/common.c5
-rw-r--r--numpy/core/src/multiarray/compiled_base.c25
-rw-r--r--numpy/core/src/multiarray/ctors.c47
-rw-r--r--numpy/core/src/multiarray/descriptor.c84
-rw-r--r--numpy/core/src/multiarray/mapping.c7
-rw-r--r--numpy/core/src/multiarray/methods.c6
-rw-r--r--numpy/core/src/multiarray/multiarraymodule.c24
-rw-r--r--numpy/core/src/multiarray/number.c7
-rw-r--r--numpy/core/src/umath/extobj.c8
-rw-r--r--numpy/core/src/umath/override.c71
-rw-r--r--numpy/core/src/umath/ufunc_object.c64
-rw-r--r--numpy/core/src/umath/ufunc_type_resolution.c21
-rw-r--r--numpy/f2py/src/fortranobject.c7
15 files changed, 307 insertions, 90 deletions
diff --git a/numpy/core/include/numpy/npy_3kcompat.h b/numpy/core/include/numpy/npy_3kcompat.h
index dbb5bd506..efe196c84 100644
--- a/numpy/core/include/numpy/npy_3kcompat.h
+++ b/numpy/core/include/numpy/npy_3kcompat.h
@@ -72,6 +72,22 @@ static NPY_INLINE int PyInt_Check(PyObject *op) {
} while (0)
#endif
+/* introduced in https://github.com/python/cpython/commit/a24107b04c1277e3c1105f98aff5bfa3a98b33a0 */
+#if PY_VERSION_HEX < 0x030800A3
+ static NPY_INLINE PyObject *
+ _PyDict_GetItemStringWithError(PyObject *v, const char *key)
+ {
+ PyObject *kv, *rv;
+ kv = PyUnicode_FromString(key);
+ if (kv == NULL) {
+ return NULL;
+ }
+ rv = PyDict_GetItemWithError(v, kv);
+ Py_DECREF(kv);
+ return rv;
+ }
+#endif
+
/*
* PyString -> PyBytes
*/
diff --git a/numpy/core/src/common/ufunc_override.c b/numpy/core/src/common/ufunc_override.c
index 3f699bcdd..d510f185a 100644
--- a/numpy/core/src/common/ufunc_override.c
+++ b/numpy/core/src/common/ufunc_override.c
@@ -94,8 +94,11 @@ PyUFuncOverride_GetOutObjects(PyObject *kwds, PyObject **out_kwd_obj, PyObject *
return -1;
}
/* borrowed reference */
- *out_kwd_obj = PyDict_GetItemString(kwds, "out");
+ *out_kwd_obj = _PyDict_GetItemStringWithError(kwds, "out");
if (*out_kwd_obj == NULL) {
+ if (PyErr_Occurred()) {
+ return -1;
+ }
Py_INCREF(Py_None);
*out_kwd_obj = Py_None;
return 0;
diff --git a/numpy/core/src/multiarray/common.c b/numpy/core/src/multiarray/common.c
index 3ec151368..39916a14d 100644
--- a/numpy/core/src/multiarray/common.c
+++ b/numpy/core/src/multiarray/common.c
@@ -317,7 +317,10 @@ PyArray_DTypeFromObjectHelper(PyObject *obj, int maxdims,
if (PyDict_Check(ip)) {
PyObject *typestr;
PyObject *tmp = NULL;
- typestr = PyDict_GetItemString(ip, "typestr");
+ typestr = _PyDict_GetItemStringWithError(ip, "typestr");
+ if (typestr == NULL && PyErr_Occurred()) {
+ goto fail;
+ }
/* Allow unicode type strings */
if (typestr && PyUnicode_Check(typestr)) {
tmp = PyUnicode_AsASCIIString(typestr);
diff --git a/numpy/core/src/multiarray/compiled_base.c b/numpy/core/src/multiarray/compiled_base.c
index d4b9edd57..59f5e0e25 100644
--- a/numpy/core/src/multiarray/compiled_base.c
+++ b/numpy/core/src/multiarray/compiled_base.c
@@ -1242,8 +1242,14 @@ arr_unravel_index(PyObject *self, PyObject *args, PyObject *kwds)
*/
if (kwds) {
PyObject *dims_item, *shape_item;
- dims_item = PyDict_GetItemString(kwds, "dims");
- shape_item = PyDict_GetItemString(kwds, "shape");
+ dims_item = _PyDict_GetItemStringWithError(kwds, "dims");
+ if (dims_item == NULL && PyErr_Occurred()){
+ return NULL;
+ }
+ shape_item = _PyDict_GetItemStringWithError(kwds, "shape");
+ if (shape_item == NULL && PyErr_Occurred()){
+ return NULL;
+ }
if (dims_item != NULL && shape_item == NULL) {
if (DEPRECATE("'shape' argument should be"
" used instead of 'dims'") < 0) {
@@ -1429,19 +1435,28 @@ arr_add_docstring(PyObject *NPY_UNUSED(dummy), PyObject *args)
if (PyGetSetDescr_TypePtr == NULL) {
/* Get "subdescr" */
- myobj = PyDict_GetItemString(tp_dict, "fields");
+ myobj = _PyDict_GetItemStringWithError(tp_dict, "fields");
+ if (myobj == NULL && PyErr_Occurred()) {
+ return NULL;
+ }
if (myobj != NULL) {
PyGetSetDescr_TypePtr = Py_TYPE(myobj);
}
}
if (PyMemberDescr_TypePtr == NULL) {
- myobj = PyDict_GetItemString(tp_dict, "alignment");
+ myobj = _PyDict_GetItemStringWithError(tp_dict, "alignment");
+ if (myobj == NULL && PyErr_Occurred()) {
+ return NULL;
+ }
if (myobj != NULL) {
PyMemberDescr_TypePtr = Py_TYPE(myobj);
}
}
if (PyMethodDescr_TypePtr == NULL) {
- myobj = PyDict_GetItemString(tp_dict, "newbyteorder");
+ myobj = _PyDict_GetItemStringWithError(tp_dict, "newbyteorder");
+ if (myobj == NULL && PyErr_Occurred()) {
+ return NULL;
+ }
if (myobj != NULL) {
PyMethodDescr_TypePtr = Py_TYPE(myobj);
}
diff --git a/numpy/core/src/multiarray/ctors.c b/numpy/core/src/multiarray/ctors.c
index 07e269b57..b30e24496 100644
--- a/numpy/core/src/multiarray/ctors.c
+++ b/numpy/core/src/multiarray/ctors.c
@@ -824,7 +824,11 @@ discover_dimensions(PyObject *obj, int *maxndim, npy_intp *d, int check_it,
int nd = -1;
if (PyDict_Check(e)) {
PyObject *new;
- new = PyDict_GetItemString(e, "shape");
+ new = _PyDict_GetItemStringWithError(e, "shape");
+ if (new == NULL && PyErr_Occurred()) {
+ Py_DECREF(e);
+ return -1;
+ }
if (new && PyTuple_Check(new)) {
nd = PyTuple_GET_SIZE(new);
if (nd < *maxndim) {
@@ -2403,11 +2407,13 @@ PyArray_FromInterface(PyObject *origin)
}
/* Get type string from interface specification */
- attr = PyDict_GetItemString(iface, "typestr");
+ attr = _PyDict_GetItemStringWithError(iface, "typestr");
if (attr == NULL) {
Py_DECREF(iface);
- PyErr_SetString(PyExc_ValueError,
- "Missing __array_interface__ typestr");
+ if (!PyErr_Occurred()) {
+ PyErr_SetString(PyExc_ValueError,
+ "Missing __array_interface__ typestr");
+ }
return NULL;
}
@@ -2439,7 +2445,10 @@ PyArray_FromInterface(PyObject *origin)
* the 'descr' attribute.
*/
if (dtype->type_num == NPY_VOID) {
- PyObject *descr = PyDict_GetItemString(iface, "descr");
+ PyObject *descr = _PyDict_GetItemStringWithError(iface, "descr");
+ if (descr == NULL && PyErr_Occurred()) {
+ goto fail;
+ }
PyArray_Descr *new_dtype = NULL;
if (descr != NULL && !_is_default_descr(descr, attr) &&
@@ -2453,10 +2462,17 @@ PyArray_FromInterface(PyObject *origin)
Py_DECREF(attr); /* Pairs with the unicode handling above */
/* Get shape tuple from interface specification */
- attr = PyDict_GetItemString(iface, "shape");
+ attr = _PyDict_GetItemStringWithError(iface, "shape");
if (attr == NULL) {
+ if (PyErr_Occurred()) {
+ return NULL;
+ }
/* Shape must be specified when 'data' is specified */
- if (PyDict_GetItemString(iface, "data") != NULL) {
+ PyObject *data = _PyDict_GetItemStringWithError(iface, "data");
+ if (data == NULL && PyErr_Occurred()) {
+ return NULL;
+ }
+ else if (data != NULL) {
Py_DECREF(iface);
PyErr_SetString(PyExc_ValueError,
"Missing __array_interface__ shape");
@@ -2487,7 +2503,10 @@ PyArray_FromInterface(PyObject *origin)
}
/* Get data buffer from interface specification */
- attr = PyDict_GetItemString(iface, "data");
+ attr = _PyDict_GetItemStringWithError(iface, "data");
+ if (attr == NULL && PyErr_Occurred()){
+ return NULL;
+ }
/* Case for data access through pointer */
if (attr && PyTuple_Check(attr)) {
@@ -2551,8 +2570,11 @@ PyArray_FromInterface(PyObject *origin)
_dealloc_cached_buffer_info(base);
/* Get offset number from interface specification */
- attr = PyDict_GetItemString(iface, "offset");
- if (attr) {
+ attr = _PyDict_GetItemStringWithError(iface, "offset");
+ if (attr == NULL && PyErr_Occurred()) {
+ goto fail;
+ }
+ else if (attr) {
npy_longlong num = PyLong_AsLongLong(attr);
if (error_converting(num)) {
PyErr_SetString(PyExc_TypeError,
@@ -2587,7 +2609,10 @@ PyArray_FromInterface(PyObject *origin)
goto fail;
}
}
- attr = PyDict_GetItemString(iface, "strides");
+ attr = _PyDict_GetItemStringWithError(iface, "strides");
+ if (attr == NULL && PyErr_Occurred()){
+ return NULL;
+ }
if (attr != NULL && attr != Py_None) {
if (!PyTuple_Check(attr)) {
PyErr_SetString(PyExc_TypeError,
diff --git a/numpy/core/src/multiarray/descriptor.c b/numpy/core/src/multiarray/descriptor.c
index da3babc33..ea40064ab 100644
--- a/numpy/core/src/multiarray/descriptor.c
+++ b/numpy/core/src/multiarray/descriptor.c
@@ -509,15 +509,20 @@ _convert_from_array_descr(PyObject *obj, int align)
_report_generic_error();
goto fail;
}
- if ((PyDict_GetItem(fields, name) != NULL)
+ if ((PyDict_GetItemWithError(fields, name) != NULL)
|| (title
&& PyBaseString_Check(title)
- && (PyDict_GetItem(fields, title) != NULL))) {
+ && (PyDict_GetItemWithError(fields, title) != NULL))) {
PyErr_Format(PyExc_ValueError,
"field %R occurs more than once", name);
Py_DECREF(conv);
goto fail;
}
+ else if (PyErr_Occurred()) {
+ /* Dict lookup crashed */
+ Py_DECREF(conv);
+ goto fail;
+ }
dtypeflags |= (conv->flags & NPY_FROM_FIELDS);
if (align) {
int _align = conv->alignment;
@@ -545,7 +550,11 @@ _convert_from_array_descr(PyObject *obj, int align)
goto fail;
}
if (PyBaseString_Check(title)) {
- if (PyDict_GetItem(fields, title) != NULL) {
+ PyObject *existing = PyDict_GetItemWithError(fields, title);
+ if (existing == NULL && PyErr_Occurred()) {
+ goto fail;
+ }
+ if (existing != NULL) {
PyErr_SetString(PyExc_ValueError,
"title already used as a name or title.");
Py_DECREF(tup);
@@ -786,8 +795,12 @@ _validate_union_object_dtype(PyArray_Descr *new, PyArray_Descr *conv)
if (name == NULL) {
return -1;
}
- tup = PyDict_GetItem(conv->fields, name);
+ tup = PyDict_GetItemWithError(conv->fields, name);
if (tup == NULL) {
+ if (!PyErr_Occurred()) {
+ /* fields was missing the name it claimed to contain */
+ PyErr_BadInternalCall();
+ }
return -1;
}
dtype = (PyArray_Descr *)PyTuple_GET_ITEM(tup, 0);
@@ -909,8 +922,12 @@ _validate_object_field_overlap(PyArray_Descr *dtype)
if (key == NULL) {
return -1;
}
- tup = PyDict_GetItem(fields, key);
+ tup = PyDict_GetItemWithError(fields, key);
if (tup == NULL) {
+ if (!PyErr_Occurred()) {
+ /* fields was missing the name it claimed to contain */
+ PyErr_BadInternalCall();
+ }
return -1;
}
if (!PyArg_ParseTuple(tup, "Oi|O", &fld_dtype, &fld_offset, &title)) {
@@ -925,8 +942,12 @@ _validate_object_field_overlap(PyArray_Descr *dtype)
if (key == NULL) {
return -1;
}
- tup = PyDict_GetItem(fields, key);
+ tup = PyDict_GetItemWithError(fields, key);
if (tup == NULL) {
+ if (!PyErr_Occurred()) {
+ /* fields was missing the name it claimed to contain */
+ PyErr_BadInternalCall();
+ }
return -1;
}
if (!PyArg_ParseTuple(tup, "Oi|O", &fld2_dtype,
@@ -1178,17 +1199,22 @@ _convert_from_dict(PyObject *obj, int align)
}
/* Insert into dictionary */
- if (PyDict_GetItem(fields, name) != NULL) {
+ if (PyDict_GetItemWithError(fields, name) != NULL) {
PyErr_SetString(PyExc_ValueError,
"name already used as a name or title");
Py_DECREF(tup);
goto fail;
}
+ else if (PyErr_Occurred()) {
+ /* MemoryError during dict lookup */
+ Py_DECREF(tup);
+ goto fail;
+ }
PyDict_SetItem(fields, name, tup);
Py_DECREF(name);
if (len == 3) {
if (PyBaseString_Check(title)) {
- if (PyDict_GetItem(fields, title) != NULL) {
+ if (PyDict_GetItemWithError(fields, title) != NULL) {
PyErr_SetString(PyExc_ValueError,
"title already used as a name or title.");
Py_DECREF(tup);
@@ -1614,8 +1640,11 @@ _convert_from_str(PyObject *obj, int align)
if (typeDict == NULL) {
goto fail;
}
- PyObject *item = PyDict_GetItem(typeDict, obj);
+ PyObject *item = PyDict_GetItemWithError(typeDict, obj);
if (item == NULL) {
+ if (PyErr_Occurred()) {
+ return NULL;
+ }
goto fail;
}
@@ -2106,7 +2135,16 @@ arraydescr_names_set(PyArray_Descr *self, PyObject *val)
int ret;
key = PyTuple_GET_ITEM(self->names, i);
/* Borrowed references to item and new_key */
- item = PyDict_GetItem(self->fields, key);
+ item = PyDict_GetItemWithError(self->fields, key);
+ if (item == NULL) {
+ if (!PyErr_Occurred()) {
+ /* fields was missing the name it claimed to contain */
+ PyErr_BadInternalCall();
+ }
+ Py_DECREF(new_names);
+ Py_DECREF(new_fields);
+ return -1;
+ }
new_key = PyTuple_GET_ITEM(new_names, i);
/* Check for duplicates */
ret = PyDict_Contains(new_fields, new_key);
@@ -2554,8 +2592,12 @@ arraydescr_setstate(PyArray_Descr *self, PyObject *args)
if (fields != Py_None) {
PyObject *key, *list;
key = PyInt_FromLong(-1);
- list = PyDict_GetItem(fields, key);
+ list = PyDict_GetItemWithError(fields, key);
if (!list) {
+ if (!PyErr_Occurred()) {
+ /* fields was missing the name it claimed to contain */
+ PyErr_BadInternalCall();
+ }
return NULL;
}
Py_INCREF(list);
@@ -2726,8 +2768,12 @@ arraydescr_setstate(PyArray_Descr *self, PyObject *args)
for (i = 0; i < PyTuple_GET_SIZE(names); ++i) {
name = PyTuple_GET_ITEM(names, i);
- field = PyDict_GetItem(fields, name);
+ field = PyDict_GetItemWithError(fields, name);
if (!field) {
+ if (!PyErr_Occurred()) {
+ /* fields was missing the name it claimed to contain */
+ PyErr_BadInternalCall();
+ }
return NULL;
}
@@ -3212,10 +3258,12 @@ _check_has_fields(PyArray_Descr *self)
static PyObject *
_subscript_by_name(PyArray_Descr *self, PyObject *op)
{
- PyObject *obj = PyDict_GetItem(self->fields, op);
+ PyObject *obj = PyDict_GetItemWithError(self->fields, op);
if (obj == NULL) {
- PyErr_Format(PyExc_KeyError,
- "Field named %R not found.", op);
+ if (!PyErr_Occurred()) {
+ PyErr_Format(PyExc_KeyError,
+ "Field named %R not found.", op);
+ }
return NULL;
}
PyObject *descr = PyTuple_GET_ITEM(obj, 0);
@@ -3292,9 +3340,11 @@ arraydescr_field_subset_view(PyArray_Descr *self, PyObject *ind)
*/
PyTuple_SET_ITEM(names, i, name);
- tup = PyDict_GetItem(self->fields, name);
+ tup = PyDict_GetItemWithError(self->fields, name);
if (tup == NULL) {
- PyErr_SetObject(PyExc_KeyError, name);
+ if (!PyErr_Occurred()) {
+ PyErr_SetObject(PyExc_KeyError, name);
+ }
goto fail;
}
diff --git a/numpy/core/src/multiarray/mapping.c b/numpy/core/src/multiarray/mapping.c
index 3efb3cb9d..4122d27ad 100644
--- a/numpy/core/src/multiarray/mapping.c
+++ b/numpy/core/src/multiarray/mapping.c
@@ -1404,8 +1404,11 @@ _get_field_view(PyArrayObject *arr, PyObject *ind, PyArrayObject **view)
npy_intp offset;
/* get the field offset and dtype */
- tup = PyDict_GetItem(PyArray_DESCR(arr)->fields, ind);
- if (tup == NULL){
+ tup = PyDict_GetItemWithError(PyArray_DESCR(arr)->fields, ind);
+ if (tup == NULL && PyErr_Occurred()) {
+ return 0;
+ }
+ else if (tup == NULL){
PyObject *errmsg = PyUString_FromString("no field of name ");
PyUString_Concat(&errmsg, ind);
PyErr_SetObject(PyExc_ValueError, errmsg);
diff --git a/numpy/core/src/multiarray/methods.c b/numpy/core/src/multiarray/methods.c
index 83c993425..7b9aa4794 100644
--- a/numpy/core/src/multiarray/methods.c
+++ b/numpy/core/src/multiarray/methods.c
@@ -64,7 +64,11 @@ get_forwarding_ndarray_method(const char *name)
if (module_methods == NULL) {
return NULL;
}
- callable = PyDict_GetItemString(PyModule_GetDict(module_methods), name);
+ callable = _PyDict_GetItemStringWithError(PyModule_GetDict(module_methods), name);
+ if (callable == NULL && PyErr_Occurred()) {
+ Py_DECREF(module_methods);
+ return NULL;
+ }
if (callable == NULL) {
Py_DECREF(module_methods);
PyErr_Format(PyExc_RuntimeError,
diff --git a/numpy/core/src/multiarray/multiarraymodule.c b/numpy/core/src/multiarray/multiarraymodule.c
index b1b9c0051..af0cef15b 100644
--- a/numpy/core/src/multiarray/multiarraymodule.c
+++ b/numpy/core/src/multiarray/multiarraymodule.c
@@ -1601,7 +1601,10 @@ _array_fromobject(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *kws)
dtype_obj = PyTuple_GET_ITEM(args, 1);
}
else if (kws) {
- dtype_obj = PyDict_GetItem(kws, npy_ma_str_dtype);
+ dtype_obj = PyDict_GetItemWithError(kws, npy_ma_str_dtype);
+ if (dtype_obj == NULL && PyErr_Occurred()) {
+ return NULL;
+ }
if (dtype_obj == NULL) {
dtype_obj = Py_None;
}
@@ -1618,7 +1621,10 @@ _array_fromobject(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *kws)
else {
/* fast path for copy=False rest default (np.asarray) */
PyObject * copy_obj, * order_obj, *ndmin_obj;
- copy_obj = PyDict_GetItem(kws, npy_ma_str_copy);
+ copy_obj = PyDict_GetItemWithError(kws, npy_ma_str_copy);
+ if (copy_obj == NULL && PyErr_Occurred()) {
+ return NULL;
+ }
if (copy_obj != Py_False) {
goto full_path;
}
@@ -1627,14 +1633,20 @@ _array_fromobject(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *kws)
/* order does not matter for contiguous 1d arrays */
if (PyArray_NDIM((PyArrayObject*)op) > 1 ||
!PyArray_IS_C_CONTIGUOUS((PyArrayObject*)op)) {
- order_obj = PyDict_GetItem(kws, npy_ma_str_order);
- if (order_obj != Py_None && order_obj != NULL) {
+ order_obj = PyDict_GetItemWithError(kws, npy_ma_str_order);
+ if (order_obj == NULL && PyErr_Occurred()) {
+ return NULL;
+ }
+ else if (order_obj != Py_None && order_obj != NULL) {
goto full_path;
}
}
- ndmin_obj = PyDict_GetItem(kws, npy_ma_str_ndmin);
- if (ndmin_obj) {
+ ndmin_obj = PyDict_GetItemWithError(kws, npy_ma_str_ndmin);
+ if (ndmin_obj == NULL && PyErr_Occurred()) {
+ return NULL;
+ }
+ else if (ndmin_obj) {
long t = PyLong_AsLong(ndmin_obj);
if (error_converting(t)) {
goto clean_type;
diff --git a/numpy/core/src/multiarray/number.c b/numpy/core/src/multiarray/number.c
index 8cdc502d6..21471a80a 100644
--- a/numpy/core/src/multiarray/number.c
+++ b/numpy/core/src/multiarray/number.c
@@ -57,8 +57,11 @@ array_inplace_power(PyArrayObject *a1, PyObject *o2, PyObject *NPY_UNUSED(modulo
*/
/* FIXME - macro contains a return */
-#define SET(op) temp = PyDict_GetItemString(dict, #op); \
- if (temp != NULL) { \
+#define SET(op) temp = _PyDict_GetItemStringWithError(dict, #op); \
+ if (temp == NULL && PyErr_Occurred()) { \
+ return -1; \
+ } \
+ else if (temp != NULL) { \
if (!(PyCallable_Check(temp))) { \
return -1; \
} \
diff --git a/numpy/core/src/umath/extobj.c b/numpy/core/src/umath/extobj.c
index aea1815e8..3404a0c6a 100644
--- a/numpy/core/src/umath/extobj.c
+++ b/numpy/core/src/umath/extobj.c
@@ -165,7 +165,7 @@ get_global_ext_obj(void)
if (thedict == NULL) {
thedict = PyEval_GetBuiltins();
}
- ref = PyDict_GetItem(thedict, npy_um_str_pyvals_name);
+ ref = PyDict_GetItemWithError(thedict, npy_um_str_pyvals_name);
#if USE_USE_DEFAULTS==1
}
#endif
@@ -290,6 +290,9 @@ _check_ufunc_fperr(int errmask, PyObject *extobj, const char *ufunc_name) {
/* Get error object globals */
if (extobj == NULL) {
extobj = get_global_ext_obj();
+ if (extobj == NULL && PyErr_Occurred()) {
+ return -1;
+ }
}
if (_extract_pyvals(extobj, ufunc_name,
NULL, NULL, &errobj) < 0) {
@@ -311,6 +314,9 @@ _get_bufsize_errmask(PyObject * extobj, const char *ufunc_name,
/* Get the buffersize and errormask */
if (extobj == NULL) {
extobj = get_global_ext_obj();
+ if (extobj == NULL && PyErr_Occurred()) {
+ return -1;
+ }
}
if (_extract_pyvals(extobj, ufunc_name,
buffersize, errormask, NULL) < 0) {
diff --git a/numpy/core/src/umath/override.c b/numpy/core/src/umath/override.c
index 43bed425c..bf6e5a698 100644
--- a/numpy/core/src/umath/override.c
+++ b/numpy/core/src/umath/override.c
@@ -112,9 +112,16 @@ fail:
static int
normalize_signature_keyword(PyObject *normal_kwds)
{
- PyObject* obj = PyDict_GetItemString(normal_kwds, "sig");
+ PyObject *obj = _PyDict_GetItemStringWithError(normal_kwds, "sig");
+ if (obj == NULL && PyErr_Occurred()){
+ return -1;
+ }
if (obj != NULL) {
- if (PyDict_GetItemString(normal_kwds, "signature")) {
+ PyObject *sig = _PyDict_GetItemStringWithError(normal_kwds, "signature");
+ if (sig == NULL && PyErr_Occurred()) {
+ return -1;
+ }
+ if (sig) {
PyErr_SetString(PyExc_TypeError,
"cannot specify both 'sig' and 'signature'");
return -1;
@@ -165,11 +172,17 @@ normalize___call___args(PyUFuncObject *ufunc, PyObject *args,
/* If we have more args than nin, they must be the output variables.*/
if (nargs > nin) {
- if(nkwds > 0 && PyDict_GetItemString(*normal_kwds, "out")) {
- PyErr_Format(PyExc_TypeError,
- "argument given by name ('out') and position "
- "(%"NPY_INTP_FMT")", nin);
- return -1;
+ if (nkwds > 0) {
+ PyObject *out_kwd = _PyDict_GetItemStringWithError(*normal_kwds, "out");
+ if (out_kwd == NULL && PyErr_Occurred()) {
+ return -1;
+ }
+ else if (out_kwd) {
+ PyErr_Format(PyExc_TypeError,
+ "argument given by name ('out') and position "
+ "(%"NPY_INTP_FMT")", nin);
+ return -1;
+ }
}
for (i = nin; i < nargs; i++) {
not_all_none = (PyTuple_GET_ITEM(args, i) != Py_None);
@@ -204,11 +217,20 @@ normalize___call___args(PyUFuncObject *ufunc, PyObject *args,
}
}
/* gufuncs accept either 'axes' or 'axis', but not both */
- if (nkwds >= 2 && (PyDict_GetItemString(*normal_kwds, "axis") &&
- PyDict_GetItemString(*normal_kwds, "axes"))) {
- PyErr_SetString(PyExc_TypeError,
- "cannot specify both 'axis' and 'axes'");
- return -1;
+ if (nkwds >= 2) {
+ PyObject *axis_kwd = _PyDict_GetItemStringWithError(*normal_kwds, "axis");
+ if (axis_kwd == NULL && PyErr_Occurred()) {
+ return -1;
+ }
+ PyObject *axes_kwd = _PyDict_GetItemStringWithError(*normal_kwds, "axes");
+ if (axes_kwd == NULL && PyErr_Occurred()) {
+ return -1;
+ }
+ if (axis_kwd && axes_kwd) {
+ PyErr_SetString(PyExc_TypeError,
+ "cannot specify both 'axis' and 'axes'");
+ return -1;
+ }
}
/* finally, ufuncs accept 'sig' or 'signature' normalize to 'signature' */
return nkwds == 0 ? 0 : normalize_signature_keyword(*normal_kwds);
@@ -243,7 +265,11 @@ normalize_reduce_args(PyUFuncObject *ufunc, PyObject *args,
}
for (i = 1; i < nargs; i++) {
- if (PyDict_GetItemString(*normal_kwds, kwlist[i])) {
+ PyObject *kwd = _PyDict_GetItemStringWithError(*normal_kwds, kwlist[i]);
+ if (kwd == NULL && PyErr_Occurred()) {
+ return -1;
+ }
+ else if (kwd) {
PyErr_Format(PyExc_TypeError,
"argument given by name ('%s') and position "
"(%"NPY_INTP_FMT")", kwlist[i], i);
@@ -293,7 +319,11 @@ normalize_accumulate_args(PyUFuncObject *ufunc, PyObject *args,
}
for (i = 1; i < nargs; i++) {
- if (PyDict_GetItemString(*normal_kwds, kwlist[i])) {
+ PyObject *kwd = _PyDict_GetItemStringWithError(*normal_kwds, kwlist[i]);
+ if (kwd == NULL && PyErr_Occurred()) {
+ return -1;
+ }
+ else if (kwd) {
PyErr_Format(PyExc_TypeError,
"argument given by name ('%s') and position "
"(%"NPY_INTP_FMT")", kwlist[i], i);
@@ -341,7 +371,11 @@ normalize_reduceat_args(PyUFuncObject *ufunc, PyObject *args,
}
for (i = 2; i < nargs; i++) {
- if (PyDict_GetItemString(*normal_kwds, kwlist[i])) {
+ PyObject *kwd = _PyDict_GetItemStringWithError(*normal_kwds, kwlist[i]);
+ if (kwd == NULL && PyErr_Occurred()) {
+ return -1;
+ }
+ else if (kwd) {
PyErr_Format(PyExc_TypeError,
"argument given by name ('%s') and position "
"(%"NPY_INTP_FMT")", kwlist[i], i);
@@ -469,8 +503,11 @@ PyUFunc_CheckOverride(PyUFuncObject *ufunc, char *method,
/* ensure out is always a tuple */
normal_kwds = PyDict_Copy(kwds);
- out = PyDict_GetItemString(normal_kwds, "out");
- if (out != NULL) {
+ out = _PyDict_GetItemStringWithError(normal_kwds, "out");
+ if (out == NULL && PyErr_Occurred()) {
+ goto fail;
+ }
+ else if (out) {
int nout = ufunc->nout;
if (PyTuple_CheckExact(out)) {
diff --git a/numpy/core/src/umath/ufunc_object.c b/numpy/core/src/umath/ufunc_object.c
index fdbe8f2ad..db2842542 100644
--- a/numpy/core/src/umath/ufunc_object.c
+++ b/numpy/core/src/umath/ufunc_object.c
@@ -324,7 +324,7 @@ _find_array_prepare(ufunc_full_args args,
NPY_NO_EXPORT int
set_matmul_flags(PyObject *d)
{
- PyObject *matmul = PyDict_GetItemString(d, "matmul");
+ PyObject *matmul = _PyDict_GetItemStringWithError(d, "matmul");
if (matmul == NULL) {
return -1;
}
@@ -397,7 +397,7 @@ _ufunc_setup_flags(PyUFuncObject *ufunc, npy_uint32 op_in_flags,
* A NULL is placed in output_wrap for outputs that
* should just have PyArray_Return called.
*/
-static void
+static int
_find_array_wrap(ufunc_full_args args, PyObject *kwds,
PyObject **output_wrap, int nin, int nout)
{
@@ -409,9 +409,12 @@ _find_array_wrap(ufunc_full_args args, PyObject *kwds,
* If a 'subok' parameter is passed and isn't True, don't wrap but put None
* into slots with out arguments which means return the out argument
*/
- if (kwds != NULL && (obj = PyDict_GetItem(kwds,
- npy_um_str_subok)) != NULL) {
- if (obj != Py_True) {
+ if (kwds != NULL) {
+ obj = PyDict_GetItemWithError(kwds, npy_um_str_subok);
+ if (obj == NULL && PyErr_Occurred()) {
+ return -1;
+ }
+ else if (obj != NULL && obj != Py_True) {
/* skip search for wrap members */
goto handle_out;
}
@@ -450,7 +453,7 @@ handle_out:
}
Py_XDECREF(wrap);
- return;
+ return 0;
}
@@ -1928,7 +1931,15 @@ make_full_arg_tuple(
}
/* Look for output keyword arguments */
- out_kwd = kwds ? PyDict_GetItem(kwds, npy_um_str_out) : NULL;
+ if (kwds) {
+ out_kwd = PyDict_GetItemWithError(kwds, npy_um_str_out);
+ if (out_kwd == NULL && PyErr_Occurred()) {
+ goto fail;
+ }
+ }
+ else {
+ out_kwd = NULL;
+ }
if (out_kwd != NULL) {
assert(nargs == nin);
@@ -3296,9 +3307,12 @@ get_binary_op_function(PyUFuncObject *ufunc, int *otype,
if (key == NULL) {
return -1;
}
- obj = PyDict_GetItem(ufunc->userloops, key);
+ obj = PyDict_GetItemWithError(ufunc->userloops, key);
Py_DECREF(key);
- if (obj != NULL) {
+ if (obj == NULL && PyErr_Occurred()) {
+ return -1;
+ }
+ else if (obj != NULL) {
funcdata = (PyUFunc_Loop1d *)NpyCapsule_AsVoidPtr(obj);
while (funcdata != NULL) {
int *types = funcdata->arg_types;
@@ -4426,8 +4440,11 @@ PyUFunc_GenericReduction(PyUFuncObject *ufunc, PyObject *args,
}
/* if there is a tuple of 1 for `out` in kwds, unpack it */
if (kwds != NULL) {
- PyObject *out_obj = PyDict_GetItem(kwds, npy_um_str_out);
- if (out_obj != NULL && PyTuple_CheckExact(out_obj)) {
+ PyObject *out_obj = PyDict_GetItemWithError(kwds, npy_um_str_out);
+ if (out_obj == NULL && PyErr_Occurred()){
+ return NULL;
+ }
+ else if (out_obj != NULL && PyTuple_CheckExact(out_obj)) {
if (PyTuple_GET_SIZE(out_obj) != 1) {
PyErr_SetString(PyExc_ValueError,
"The 'out' tuple must have exactly one entry");
@@ -4719,7 +4736,9 @@ ufunc_generic_call(PyUFuncObject *ufunc, PyObject *args, PyObject *kwds)
if (make_full_arg_tuple(&full_args, ufunc->nin, ufunc->nout, args, kwds) < 0) {
goto fail;
}
- _find_array_wrap(full_args, kwds, wraparr, ufunc->nin, ufunc->nout);
+ if (_find_array_wrap(full_args, kwds, wraparr, ufunc->nin, ufunc->nout) < 0) {
+ goto fail;
+ }
/* wrap outputs */
for (i = 0; i < ufunc->nout; i++) {
@@ -4781,8 +4800,11 @@ ufunc_geterr(PyObject *NPY_UNUSED(dummy), PyObject *args)
if (thedict == NULL) {
thedict = PyEval_GetBuiltins();
}
- res = PyDict_GetItem(thedict, npy_um_str_pyvals_name);
- if (res != NULL) {
+ res = PyDict_GetItemWithError(thedict, npy_um_str_pyvals_name);
+ if (res == NULL && PyErr_Occurred()) {
+ return NULL;
+ }
+ else if (res != NULL) {
Py_INCREF(res);
return res;
}
@@ -5127,8 +5149,11 @@ PyUFunc_RegisterLoopForDescr(PyUFuncObject *ufunc,
function, arg_typenums, data);
if (result == 0) {
- cobj = PyDict_GetItem(ufunc->userloops, key);
- if (cobj == NULL) {
+ cobj = PyDict_GetItemWithError(ufunc->userloops, key);
+ if (cobj == NULL && PyErr_Occurred()) {
+ result = -1;
+ }
+ else if (cobj == NULL) {
PyErr_SetString(PyExc_KeyError,
"userloop for user dtype not found");
result = -1;
@@ -5232,9 +5257,12 @@ PyUFunc_RegisterLoopForType(PyUFuncObject *ufunc,
funcdata->nargs = 0;
/* Get entry for this user-defined type*/
- cobj = PyDict_GetItem(ufunc->userloops, key);
+ cobj = PyDict_GetItemWithError(ufunc->userloops, key);
+ if (cobj == NULL && PyErr_Occurred()) {
+ return 0;
+ }
/* If it's not there, then make one and return. */
- if (cobj == NULL) {
+ else if (cobj == NULL) {
cobj = NpyCapsule_FromVoidPtr((void *)funcdata, _loop1d_list_free);
if (cobj == NULL) {
goto fail;
diff --git a/numpy/core/src/umath/ufunc_type_resolution.c b/numpy/core/src/umath/ufunc_type_resolution.c
index 0e71305b6..2534ff78a 100644
--- a/numpy/core/src/umath/ufunc_type_resolution.c
+++ b/numpy/core/src/umath/ufunc_type_resolution.c
@@ -1379,9 +1379,12 @@ find_userloop(PyUFuncObject *ufunc,
if (key == NULL) {
return -1;
}
- obj = PyDict_GetItem(ufunc->userloops, key);
+ obj = PyDict_GetItemWithError(ufunc->userloops, key);
Py_DECREF(key);
- if (obj == NULL) {
+ if (obj == NULL && PyErr_Occurred()){
+ return -1;
+ }
+ else if (obj == NULL) {
continue;
}
for (funcdata = (PyUFunc_Loop1d *)NpyCapsule_AsVoidPtr(obj);
@@ -1784,9 +1787,12 @@ linear_search_userloop_type_resolver(PyUFuncObject *self,
if (key == NULL) {
return -1;
}
- obj = PyDict_GetItem(self->userloops, key);
+ obj = PyDict_GetItemWithError(self->userloops, key);
Py_DECREF(key);
- if (obj == NULL) {
+ if (obj == NULL && PyErr_Occurred()){
+ return -1;
+ }
+ else if (obj == NULL) {
continue;
}
for (funcdata = (PyUFunc_Loop1d *)NpyCapsule_AsVoidPtr(obj);
@@ -1848,9 +1854,12 @@ type_tuple_userloop_type_resolver(PyUFuncObject *self,
if (key == NULL) {
return -1;
}
- obj = PyDict_GetItem(self->userloops, key);
+ obj = PyDict_GetItemWithError(self->userloops, key);
Py_DECREF(key);
- if (obj == NULL) {
+ if (obj == NULL && PyErr_Occurred()){
+ return -1;
+ }
+ else if (obj == NULL) {
continue;
}
diff --git a/numpy/f2py/src/fortranobject.c b/numpy/f2py/src/fortranobject.c
index 8ec5b510f..644339218 100644
--- a/numpy/f2py/src/fortranobject.c
+++ b/numpy/f2py/src/fortranobject.c
@@ -260,8 +260,11 @@ static PyObject *
fortran_getattr(PyFortranObject *fp, char *name) {
int i,j,k,flag;
if (fp->dict != NULL) {
- PyObject *v = PyDict_GetItemString(fp->dict, name);
- if (v != NULL) {
+ PyObject *v = _PyDict_GetItemStringWithError(fp->dict, name);
+ if (v == NULL && PyErr_Occurred()) {
+ return NULL;
+ }
+ else if (v != NULL) {
Py_INCREF(v);
return v;
}