* Create a new ArrayMethod (internal version). * * @param name A name for the individual method, may be NULL. * @param spec A filled context object to pass generic information about * the method (such as usually needing the API, and the DTypes). * Unused fields must be NULL. * @param slots Slots with the correct pair of IDs and (function) pointers. * @param private Some slots
| 418 | * @returns A new (bound) ArrayMethod object. |
| 419 | */ |
| 420 | NPY_NO_EXPORT PyBoundArrayMethodObject * |
| 421 | PyArrayMethod_FromSpec_int(PyArrayMethod_Spec *spec, int private) |
| 422 | { |
| 423 | int nargs = spec->nin + spec->nout; |
| 424 | |
| 425 | if (spec->name == NULL) { |
| 426 | spec->name = "<unknown>"; |
| 427 | } |
| 428 | |
| 429 | if (validate_spec(spec) < 0) { |
| 430 | return NULL; |
| 431 | } |
| 432 | |
| 433 | PyBoundArrayMethodObject *res; |
| 434 | res = PyObject_New(PyBoundArrayMethodObject, &PyBoundArrayMethod_Type); |
| 435 | if (res == NULL) { |
| 436 | return NULL; |
| 437 | } |
| 438 | res->method = NULL; |
| 439 | |
| 440 | res->dtypes = PyMem_Malloc(sizeof(PyArray_DTypeMeta *) * nargs); |
| 441 | if (res->dtypes == NULL) { |
| 442 | Py_DECREF(res); |
| 443 | PyErr_NoMemory(); |
| 444 | return NULL; |
| 445 | } |
| 446 | for (int i = 0; i < nargs ; i++) { |
| 447 | Py_XINCREF(spec->dtypes[i]); |
| 448 | res->dtypes[i] = spec->dtypes[i]; |
| 449 | } |
| 450 | |
| 451 | res->method = PyObject_New(PyArrayMethodObject, &PyArrayMethod_Type); |
| 452 | if (res->method == NULL) { |
| 453 | Py_DECREF(res); |
| 454 | PyErr_NoMemory(); |
| 455 | return NULL; |
| 456 | } |
| 457 | memset((char *)(res->method) + sizeof(PyObject), 0, |
| 458 | sizeof(PyArrayMethodObject) - sizeof(PyObject)); |
| 459 | |
| 460 | res->method->nin = spec->nin; |
| 461 | res->method->nout = spec->nout; |
| 462 | res->method->flags = spec->flags; |
| 463 | res->method->casting = spec->casting; |
| 464 | if (fill_arraymethod_from_slots(res, spec, private) < 0) { |
| 465 | Py_DECREF(res); |
| 466 | return NULL; |
| 467 | } |
| 468 | |
| 469 | Py_ssize_t length = strlen(spec->name); |
| 470 | res->method->name = PyMem_Malloc(length + 1); |
| 471 | if (res->method->name == NULL) { |
| 472 | Py_DECREF(res); |
| 473 | PyErr_NoMemory(); |
| 474 | return NULL; |
| 475 | } |
| 476 | strcpy(res->method->name, spec->name); |
| 477 |
no test coverage detected