| 1153 | |
| 1154 | |
| 1155 | NPY_NO_EXPORT PyObject * |
| 1156 | array_ufunc(PyArrayObject *NPY_UNUSED(self), PyObject *args, PyObject *kwds) |
| 1157 | { |
| 1158 | PyObject *ufunc, *method_name, *normal_args, *ufunc_method; |
| 1159 | PyObject *result = NULL; |
| 1160 | int has_override; |
| 1161 | |
| 1162 | assert(PyTuple_CheckExact(args)); |
| 1163 | assert(kwds == NULL || PyDict_CheckExact(kwds)); |
| 1164 | |
| 1165 | if (PyTuple_GET_SIZE(args) < 2) { |
| 1166 | PyErr_SetString(PyExc_TypeError, |
| 1167 | "__array_ufunc__ requires at least 2 arguments"); |
| 1168 | return NULL; |
| 1169 | } |
| 1170 | normal_args = PyTuple_GetSlice(args, 2, PyTuple_GET_SIZE(args)); |
| 1171 | if (normal_args == NULL) { |
| 1172 | return NULL; |
| 1173 | } |
| 1174 | /* ndarray cannot handle overrides itself */ |
| 1175 | has_override = any_array_ufunc_overrides(normal_args, kwds); |
| 1176 | if (has_override < 0) { |
| 1177 | goto cleanup; |
| 1178 | } |
| 1179 | else if (has_override) { |
| 1180 | result = Py_NotImplemented; |
| 1181 | Py_INCREF(Py_NotImplemented); |
| 1182 | goto cleanup; |
| 1183 | } |
| 1184 | |
| 1185 | ufunc = PyTuple_GET_ITEM(args, 0); |
| 1186 | method_name = PyTuple_GET_ITEM(args, 1); |
| 1187 | /* |
| 1188 | * TODO(?): call into UFunc code at a later point, since here arguments are |
| 1189 | * already normalized and we do not have to look for __array_ufunc__ again. |
| 1190 | */ |
| 1191 | ufunc_method = PyObject_GetAttr(ufunc, method_name); |
| 1192 | if (ufunc_method == NULL) { |
| 1193 | goto cleanup; |
| 1194 | } |
| 1195 | result = PyObject_Call(ufunc_method, normal_args, kwds); |
| 1196 | Py_DECREF(ufunc_method); |
| 1197 | |
| 1198 | cleanup: |
| 1199 | Py_DECREF(normal_args); |
| 1200 | /* no need to DECREF borrowed references ufunc and method_name */ |
| 1201 | return result; |
| 1202 | } |
| 1203 | |
| 1204 | static PyObject * |
| 1205 | array_function(PyArrayObject *NPY_UNUSED(self), PyObject *c_args, PyObject *c_kwds) |
nothing calls this directly
no test coverage detected