diff options
-rw-r--r-- | numpy/core/src/common/binop_override.h | 2 | ||||
-rw-r--r-- | numpy/core/src/common/get_attr_string.h | 61 | ||||
-rw-r--r-- | numpy/core/src/common/ufunc_override.c | 2 | ||||
-rw-r--r-- | numpy/core/src/multiarray/arrayfunction_override.c | 2 | ||||
-rw-r--r-- | numpy/core/src/multiarray/ctors.c | 6 | ||||
-rw-r--r-- | numpy/core/src/multiarray/multiarraymodule.c | 27 | ||||
-rw-r--r-- | numpy/core/src/multiarray/multiarraymodule.h | 5 | ||||
-rw-r--r-- | numpy/core/src/umath/ufunc_object.h | 1 | ||||
-rw-r--r-- | numpy/core/src/umath/umathmodule.c | 5 |
9 files changed, 63 insertions, 48 deletions
diff --git a/numpy/core/src/common/binop_override.h b/numpy/core/src/common/binop_override.h index 61bc05ef3..ec3d04679 100644 --- a/numpy/core/src/common/binop_override.h +++ b/numpy/core/src/common/binop_override.h @@ -128,7 +128,7 @@ binop_should_defer(PyObject *self, PyObject *other, int inplace) * Classes with __array_ufunc__ are living in the future, and only need to * check whether __array_ufunc__ equals None. */ - attr = PyArray_LookupSpecial(other, "__array_ufunc__"); + attr = PyArray_LookupSpecial(other, npy_um_str_array_ufunc); if (attr != NULL) { defer = !inplace && (attr == Py_None); Py_DECREF(attr); diff --git a/numpy/core/src/common/get_attr_string.h b/numpy/core/src/common/get_attr_string.h index 3b23b2e66..a3e5d5ec8 100644 --- a/numpy/core/src/common/get_attr_string.h +++ b/numpy/core/src/common/get_attr_string.h @@ -1,6 +1,9 @@ #ifndef NUMPY_CORE_SRC_COMMON_GET_ATTR_STRING_H_ #define NUMPY_CORE_SRC_COMMON_GET_ATTR_STRING_H_ +#include <Python.h> +#include "ufunc_object.h" + static NPY_INLINE npy_bool _is_basic_python_type(PyTypeObject *tp) { @@ -33,43 +36,6 @@ _is_basic_python_type(PyTypeObject *tp) ); } -/* - * Stripped down version of PyObject_GetAttrString(obj, name) that does not - * raise PyExc_AttributeError. - * - * This allows it to avoid creating then discarding exception objects when - * performing lookups on objects without any attributes. - * - * Returns attribute value on success, NULL without an exception set if - * there is no such attribute, and NULL with an exception on failure. - */ -static NPY_INLINE PyObject * -maybe_get_attr(PyObject *obj, char const *name) -{ - PyTypeObject *tp = Py_TYPE(obj); - PyObject *res = (PyObject *)NULL; - - /* Attribute referenced by (char *)name */ - if (tp->tp_getattr != NULL) { - res = (*tp->tp_getattr)(obj, (char *)name); - if (res == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_Clear(); - } - } - /* Attribute referenced by (PyObject *)name */ - else if (tp->tp_getattro != NULL) { - PyObject *w = PyUnicode_InternFromString(name); - if (w == NULL) { - return (PyObject *)NULL; - } - res = (*tp->tp_getattro)(obj, w); - Py_DECREF(w); - if (res == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_Clear(); - } - } - return res; -} /* * Lookup a special method, following the python approach of looking up @@ -81,7 +47,7 @@ maybe_get_attr(PyObject *obj, char const *name) * In future, could be made more like _Py_LookupSpecial */ static NPY_INLINE PyObject * -PyArray_LookupSpecial(PyObject *obj, char const *name) +PyArray_LookupSpecial(PyObject *obj, PyObject *name_unicode) { PyTypeObject *tp = Py_TYPE(obj); @@ -89,9 +55,16 @@ PyArray_LookupSpecial(PyObject *obj, char const *name) if (_is_basic_python_type(tp)) { return NULL; } - return maybe_get_attr((PyObject *)tp, name); + PyObject *res = PyObject_GetAttr((PyObject *)tp, name_unicode); + + if (res == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + } + + return res; } + /* * PyArray_LookupSpecial_OnInstance: * @@ -101,7 +74,7 @@ PyArray_LookupSpecial(PyObject *obj, char const *name) * Kept for backwards compatibility. In future, we should deprecate this. */ static NPY_INLINE PyObject * -PyArray_LookupSpecial_OnInstance(PyObject *obj, char const *name) +PyArray_LookupSpecial_OnInstance(PyObject *obj, PyObject *name_unicode) { PyTypeObject *tp = Py_TYPE(obj); @@ -110,7 +83,13 @@ PyArray_LookupSpecial_OnInstance(PyObject *obj, char const *name) return NULL; } - return maybe_get_attr(obj, name); + PyObject *res = PyObject_GetAttr(obj, name_unicode); + + if (res == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + } + + return res; } #endif /* NUMPY_CORE_SRC_COMMON_GET_ATTR_STRING_H_ */ diff --git a/numpy/core/src/common/ufunc_override.c b/numpy/core/src/common/ufunc_override.c index d510f185a..2c3dc5cb3 100644 --- a/numpy/core/src/common/ufunc_override.c +++ b/numpy/core/src/common/ufunc_override.c @@ -34,7 +34,7 @@ PyUFuncOverride_GetNonDefaultArrayUfunc(PyObject *obj) * Does the class define __array_ufunc__? (Note that LookupSpecial has fast * return for basic python types, so no need to worry about those here) */ - cls_array_ufunc = PyArray_LookupSpecial(obj, "__array_ufunc__"); + cls_array_ufunc = PyArray_LookupSpecial(obj, npy_um_str_array_ufunc); if (cls_array_ufunc == NULL) { if (PyErr_Occurred()) { PyErr_Clear(); /* TODO[gh-14801]: propagate crashes during attribute access? */ diff --git a/numpy/core/src/multiarray/arrayfunction_override.c b/numpy/core/src/multiarray/arrayfunction_override.c index 4800ed360..af53d7821 100644 --- a/numpy/core/src/multiarray/arrayfunction_override.c +++ b/numpy/core/src/multiarray/arrayfunction_override.c @@ -37,7 +37,7 @@ get_array_function(PyObject *obj) return ndarray_array_function; } - PyObject *array_function = PyArray_LookupSpecial(obj, "__array_function__"); + PyObject *array_function = PyArray_LookupSpecial(obj, npy_ma_str_array_function); if (array_function == NULL && PyErr_Occurred()) { PyErr_Clear(); /* TODO[gh-14801]: propagate crashes during attribute access? */ } diff --git a/numpy/core/src/multiarray/ctors.c b/numpy/core/src/multiarray/ctors.c index 0f1b0d99b..f72ba11cd 100644 --- a/numpy/core/src/multiarray/ctors.c +++ b/numpy/core/src/multiarray/ctors.c @@ -2109,7 +2109,7 @@ PyArray_FromStructInterface(PyObject *input) PyObject *attr; char endian = NPY_NATBYTE; - attr = PyArray_LookupSpecial_OnInstance(input, "__array_struct__"); + attr = PyArray_LookupSpecial_OnInstance(input, npy_ma_str_array_struct); if (attr == NULL) { if (PyErr_Occurred()) { return NULL; @@ -2233,7 +2233,7 @@ PyArray_FromInterface(PyObject *origin) npy_intp dims[NPY_MAXDIMS], strides[NPY_MAXDIMS]; int dataflags = NPY_ARRAY_BEHAVED; - iface = PyArray_LookupSpecial_OnInstance(origin, "__array_interface__"); + iface = PyArray_LookupSpecial_OnInstance(origin, npy_ma_str_array_interface); if (iface == NULL) { if (PyErr_Occurred()) { @@ -2514,7 +2514,7 @@ PyArray_FromArrayAttr_int( PyObject *new; PyObject *array_meth; - array_meth = PyArray_LookupSpecial_OnInstance(op, "__array__"); + array_meth = PyArray_LookupSpecial_OnInstance(op, npy_ma_str_array); if (array_meth == NULL) { if (PyErr_Occurred()) { return NULL; diff --git a/numpy/core/src/multiarray/multiarraymodule.c b/numpy/core/src/multiarray/multiarraymodule.c index 97ed0ba2a..0ce092780 100644 --- a/numpy/core/src/multiarray/multiarraymodule.c +++ b/numpy/core/src/multiarray/multiarraymodule.c @@ -128,7 +128,7 @@ PyArray_GetPriority(PyObject *obj, double default_) return NPY_SCALAR_PRIORITY; } - ret = PyArray_LookupSpecial_OnInstance(obj, "__array_priority__"); + ret = PyArray_LookupSpecial_OnInstance(obj, npy_ma_str_array_priority); if (ret == NULL) { if (PyErr_Occurred()) { /* TODO[gh-14801]: propagate crashes during attribute access? */ @@ -4665,6 +4665,11 @@ set_flaginfo(PyObject *d) return; } +NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_array = NULL; +NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_array_function = NULL; +NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_array_struct = NULL; +NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_array_interface = NULL; +NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_array_priority = NULL; NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_array_wrap = NULL; NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_array_finalize = NULL; NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_implementation = NULL; @@ -4676,6 +4681,26 @@ NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_numpy = NULL; static int intern_strings(void) { + npy_ma_str_array = PyUnicode_InternFromString("__array__"); + if (npy_ma_str_array == NULL) { + return -1; + } + npy_ma_str_array_function = PyUnicode_InternFromString("__array_function__"); + if (npy_ma_str_array_function == NULL) { + return -1; + } + npy_ma_str_array_struct = PyUnicode_InternFromString("__array_struct__"); + if (npy_ma_str_array_struct == NULL) { + return -1; + } + npy_ma_str_array_priority = PyUnicode_InternFromString("__array_priority__"); + if (npy_ma_str_array_priority == NULL) { + return -1; + } + npy_ma_str_array_interface = PyUnicode_InternFromString("__array_interface__"); + if (npy_ma_str_array_interface == NULL) { + return -1; + } npy_ma_str_array_wrap = PyUnicode_InternFromString("__array_wrap__"); if (npy_ma_str_array_wrap == NULL) { return -1; diff --git a/numpy/core/src/multiarray/multiarraymodule.h b/numpy/core/src/multiarray/multiarraymodule.h index 640940d2a..70205dfd2 100644 --- a/numpy/core/src/multiarray/multiarraymodule.h +++ b/numpy/core/src/multiarray/multiarraymodule.h @@ -1,6 +1,11 @@ #ifndef NUMPY_CORE_SRC_MULTIARRAY_MULTIARRAYMODULE_H_ #define NUMPY_CORE_SRC_MULTIARRAY_MULTIARRAYMODULE_H_ +NPY_VISIBILITY_HIDDEN extern PyObject * npy_ma_str_array; +NPY_VISIBILITY_HIDDEN extern PyObject * npy_ma_str_array_function; +NPY_VISIBILITY_HIDDEN extern PyObject * npy_ma_str_array_struct; +NPY_VISIBILITY_HIDDEN extern PyObject * npy_ma_str_array_priority; +NPY_VISIBILITY_HIDDEN extern PyObject * npy_ma_str_array_interface; NPY_VISIBILITY_HIDDEN extern PyObject * npy_ma_str_array_wrap; NPY_VISIBILITY_HIDDEN extern PyObject * npy_ma_str_array_finalize; NPY_VISIBILITY_HIDDEN extern PyObject * npy_ma_str_implementation; diff --git a/numpy/core/src/umath/ufunc_object.h b/numpy/core/src/umath/ufunc_object.h index 6d4fed7c0..32af6c58e 100644 --- a/numpy/core/src/umath/ufunc_object.h +++ b/numpy/core/src/umath/ufunc_object.h @@ -13,6 +13,7 @@ NPY_NO_EXPORT const char* ufunc_get_name_cstr(PyUFuncObject *ufunc); /* strings from umathmodule.c that are interned on umath import */ +NPY_VISIBILITY_HIDDEN extern PyObject *npy_um_str_array_ufunc; NPY_VISIBILITY_HIDDEN extern PyObject *npy_um_str_array_prepare; NPY_VISIBILITY_HIDDEN extern PyObject *npy_um_str_array_wrap; NPY_VISIBILITY_HIDDEN extern PyObject *npy_um_str_pyvals_name; diff --git a/numpy/core/src/umath/umathmodule.c b/numpy/core/src/umath/umathmodule.c index e9b84df06..49328d19e 100644 --- a/numpy/core/src/umath/umathmodule.c +++ b/numpy/core/src/umath/umathmodule.c @@ -213,6 +213,7 @@ add_newdoc_ufunc(PyObject *NPY_UNUSED(dummy), PyObject *args) ***************************************************************************** */ +NPY_VISIBILITY_HIDDEN PyObject *npy_um_str_array_ufunc = NULL; NPY_VISIBILITY_HIDDEN PyObject *npy_um_str_array_prepare = NULL; NPY_VISIBILITY_HIDDEN PyObject *npy_um_str_array_wrap = NULL; NPY_VISIBILITY_HIDDEN PyObject *npy_um_str_pyvals_name = NULL; @@ -221,6 +222,10 @@ NPY_VISIBILITY_HIDDEN PyObject *npy_um_str_pyvals_name = NULL; static int intern_strings(void) { + npy_um_str_array_ufunc = PyUnicode_InternFromString("__array_ufunc__"); + if (npy_um_str_array_ufunc == NULL) { + return -1; + } npy_um_str_array_prepare = PyUnicode_InternFromString("__array_prepare__"); if (npy_um_str_array_prepare == NULL) { return -1; |