diff options
author | Eric Wieser <wieser.eric@gmail.com> | 2020-01-06 18:57:47 +0000 |
---|---|---|
committer | Eric Wieser <wieser.eric@gmail.com> | 2020-01-14 15:06:52 +0000 |
commit | e2921434a07c22714bbf242be5389c3056449863 (patch) | |
tree | d0272d304ff0cde77a1953d4ec46d82a8b0af453 | |
parent | fbd807f5c5587407847f1aa54e6dada79bb90c35 (diff) | |
download | numpy-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.h | 16 | ||||
-rw-r--r-- | numpy/core/src/common/ufunc_override.c | 5 | ||||
-rw-r--r-- | numpy/core/src/multiarray/common.c | 5 | ||||
-rw-r--r-- | numpy/core/src/multiarray/compiled_base.c | 25 | ||||
-rw-r--r-- | numpy/core/src/multiarray/ctors.c | 47 | ||||
-rw-r--r-- | numpy/core/src/multiarray/descriptor.c | 84 | ||||
-rw-r--r-- | numpy/core/src/multiarray/mapping.c | 7 | ||||
-rw-r--r-- | numpy/core/src/multiarray/methods.c | 6 | ||||
-rw-r--r-- | numpy/core/src/multiarray/multiarraymodule.c | 24 | ||||
-rw-r--r-- | numpy/core/src/multiarray/number.c | 7 | ||||
-rw-r--r-- | numpy/core/src/umath/extobj.c | 8 | ||||
-rw-r--r-- | numpy/core/src/umath/override.c | 71 | ||||
-rw-r--r-- | numpy/core/src/umath/ufunc_object.c | 64 | ||||
-rw-r--r-- | numpy/core/src/umath/ufunc_type_resolution.c | 21 | ||||
-rw-r--r-- | numpy/f2py/src/fortranobject.c | 7 |
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; } |