* Check a set of args for the `__array_ufunc__` method. If more than one of * the input arguments implements `__array_ufunc__`, they are tried in the * order: subclasses before superclasses, otherwise left to right. The first * (non-None) routine returning something other than `NotImplemented` * determines the result. If all of the `__array_ufunc__` operations return * `NotImplemented` (or a
| 211 | * result of the operation, if any. If *result is NULL, there is no override. |
| 212 | */ |
| 213 | NPY_NO_EXPORT int |
| 214 | PyUFunc_CheckOverride(PyUFuncObject *ufunc, char *method, |
| 215 | PyObject *in_args, PyObject *out_args, PyObject *wheremask_obj, |
| 216 | PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames, |
| 217 | PyObject **result) |
| 218 | { |
| 219 | int status; |
| 220 | |
| 221 | int num_override_args; |
| 222 | PyObject *with_override[NPY_MAXARGS]; |
| 223 | PyObject *array_ufunc_methods[NPY_MAXARGS]; |
| 224 | |
| 225 | PyObject *method_name = NULL; |
| 226 | PyObject *normal_kwds = NULL; |
| 227 | |
| 228 | PyObject *override_args = NULL; |
| 229 | |
| 230 | /* |
| 231 | * Check inputs for overrides |
| 232 | */ |
| 233 | num_override_args = get_array_ufunc_overrides( |
| 234 | in_args, out_args, wheremask_obj, with_override, array_ufunc_methods); |
| 235 | if (num_override_args == -1) { |
| 236 | goto fail; |
| 237 | } |
| 238 | /* No overrides, bail out.*/ |
| 239 | if (num_override_args == 0) { |
| 240 | *result = NULL; |
| 241 | return 0; |
| 242 | } |
| 243 | |
| 244 | /* |
| 245 | * Normalize ufunc arguments, note that any input and output arguments |
| 246 | * have already been stored in `in_args` and `out_args`. |
| 247 | */ |
| 248 | normal_kwds = PyDict_New(); |
| 249 | if (normal_kwds == NULL) { |
| 250 | goto fail; |
| 251 | } |
| 252 | if (initialize_normal_kwds(out_args, |
| 253 | args, len_args, kwnames, normal_kwds) < 0) { |
| 254 | goto fail; |
| 255 | } |
| 256 | |
| 257 | /* |
| 258 | * Reduce-like methods can pass keyword arguments also by position, |
| 259 | * in which case the additional positional arguments have to be copied |
| 260 | * into the keyword argument dictionary. The `__call__` and `__outer__` |
| 261 | * method have to normalize sig and signature. |
| 262 | */ |
| 263 | |
| 264 | /* ufunc.__call__ */ |
| 265 | if (strcmp(method, "__call__") == 0) { |
| 266 | status = normalize_signature_keyword(normal_kwds); |
| 267 | } |
| 268 | /* ufunc.reduce */ |
| 269 | else if (strcmp(method, "reduce") == 0) { |
| 270 | static const char *keywords[] = { |
no test coverage detected