summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--numpy/core/src/common/binop_override.h2
-rw-r--r--numpy/core/src/common/get_attr_string.h61
-rw-r--r--numpy/core/src/common/ufunc_override.c2
-rw-r--r--numpy/core/src/multiarray/arrayfunction_override.c2
-rw-r--r--numpy/core/src/multiarray/ctors.c6
-rw-r--r--numpy/core/src/multiarray/multiarraymodule.c27
-rw-r--r--numpy/core/src/multiarray/multiarraymodule.h5
-rw-r--r--numpy/core/src/umath/ufunc_object.h1
-rw-r--r--numpy/core/src/umath/umathmodule.c5
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;