Repository: numpy/numpy
File: numpy/_core/src/umath/dispatching.cpp (C++)

Code before:
    PyObject *info = PyTuple_Pack(2, dtypes, bmeth->method);
    Py_DECREF(bmeth);
    Py_DECREF(dtypes);
    if (info == NULL) {
        return -1;
    }
    return PyUFunc_AddLoop((PyUFuncObject *)ufunc, info, 0);
}


/*UFUNC_API
 * Add multiple loops to ufuncs from ArrayMethod specs. This also
 * handles the registration of sort and argsort methods for dtypes
 * from ArrayMethod specs.
 */
NPY_NO_EXPORT int
PyUFunc_AddLoopsFromSpecs(PyUFunc_LoopSlot *slots)
{
    PyUFunc_LoopSlot *slot;
    for (slot = slots; slot->name != NULL; slot++) {
        PyObject *ufunc = npy_import("numpy", slot->name);
        if (ufunc == NULL) {
            return -1;
        }

        if (npy_cache_import_runtime("numpy", "sort", &npy_runtime_imports._sort) < 0 ||
            npy_cache_import_runtime("numpy", "argsort", &npy_runtime_imports._argsort) < 0) {
            Py_DECREF(ufunc);
            return -1;
        }

        if (ufunc == npy_runtime_imports._sort) {
            PyArray_DTypeMeta *dtype = slot->spec->dtypes[0];

            PyBoundArrayMethodObject *sort_meth = PyArrayMethod_FromSpec_int(slot->spec, 0);
            if (sort_meth == NULL) {
                PyErr_Format(PyExc_TypeError, "Failed to create sort method for %R", dtype);
                return -1;
            }

            NPY_DT_SLOTS(dtype)->sort_meth = sort_meth->method;
            Py_INCREF(sort_meth->method);
            Py_DECREF(sort_meth);
        }
        else if (ufunc == npy_runtime_imports._argsort) {
            PyArray_DTypeMeta *dtype = slot->spec->dtypes[0];

            PyBoundArrayMethodObject *argsort_meth = PyArrayMethod_FromSpec_int(slot->spec, 0);
            if (argsort_meth == NULL) {
                PyErr_Format(PyExc_TypeError, "Failed to create argsort method for %R", dtype);
                return -1;

Review comment (suggestion):
Weird that this did not work. It looks good, though it should be outside the loop, and the object should not have an underscore (at least, that seems to be the habit, to just use the name).

Code after:
    PyObject *info = PyTuple_Pack(2, dtypes, bmeth->method);
    Py_DECREF(bmeth);
    Py_DECREF(dtypes);
    if (info == NULL) {
        return -1;
    }
    return PyUFunc_AddLoop((PyUFuncObject *)ufunc, info, 0);
}


/*UFUNC_API
 * Add multiple loops to ufuncs from ArrayMethod specs. This also
 * handles the registration of sort and argsort methods for dtypes
 * from ArrayMethod specs.
 */
NPY_NO_EXPORT int
PyUFunc_AddLoopsFromSpecs(PyUFunc_LoopSlot *slots)
{
    if (npy_cache_import_runtime(
            "numpy", "sort", &npy_runtime_imports.sort) < 0) {
        return -1;
    }
    if (npy_cache_import_runtime(
            "numpy", "argsort", &npy_runtime_imports.argsort) < 0) {
        return -1;
    }

    PyUFunc_LoopSlot *slot;
    for (slot = slots; slot->name != NULL; slot++) {
        PyObject *ufunc = npy_import("numpy", slot->name);
        if (ufunc == NULL) {
            return -1;
        }

        if (ufunc == npy_runtime_imports.sort) {
            Py_DECREF(ufunc);

            PyArray_DTypeMeta *dtype = slot->spec->dtypes[0];
            PyBoundArrayMethodObject *sort_meth = PyArrayMethod_FromSpec_int(slot->spec, 0);
            if (sort_meth == NULL) {
                return -1;
            }

            NPY_DT_SLOTS(dtype)->sort_meth = sort_meth->method;
            Py_INCREF(sort_meth->method);
            Py_DECREF(sort_meth);
        }
        else if (ufunc == npy_runtime_imports.argsort) {
            Py_DECREF(ufunc);

            PyArray_DTypeMeta *dtype = slot->spec->dtypes[0];