Repository: numpy/numpy
File: numpy/_core/src/multiarray/item_selection.c (C)

Code before:
static PyArray_SortFunc* const generic_sort_table[] = {npy_quicksort,
                                                       npy_heapsort,
                                                       npy_timsort};

/*NUMPY_API
 * Sort an array in-place with extended parameters
 */
NPY_NO_EXPORT int
PyArray_SortEx(PyArrayObject *op, int axis, NPY_SORTFLAGS flags)
{
    PyArray_SortFunc **sort_table = NULL;
    PyArray_SortFunc *sort = NULL;

    if (check_and_adjust_axis(&axis, PyArray_NDIM(op)) < 0) {
        return -1;
    }

    if (PyArray_FailUnlessWriteable(op, "sort array") < 0) {
        return -1;
    }

    sort_table = PyDataType_GetArrFuncs(PyArray_DESCR(op))->sort;
    switch (flags) {
        case NPY_SORT_STABLE:
            sort = sort_table[NPY_STABLESORT];
            break;
        default:
            sort = sort_table[NPY_QUICKSORT];
    }

    // Look for appropriate generic function if no type specific version
    if (sort == NULL) {
        if (!PyDataType_GetArrFuncs(PyArray_DESCR(op))->compare) {
            PyErr_SetString(PyExc_TypeError,
                            "type does not have compare function");
            return -1;
        }
        switch (flags) {
            case NPY_SORT_STABLE:
                sort = generic_sort_table[NPY_STABLESORT];
                break;
            default:
                sort = generic_sort_table[NPY_QUICKSORT];
        }
    }

    if (sort == NULL) {
        PyErr_SetString(PyExc_TypeError,
                        "no current sort function meets the requirements");
        return -1;
    }

Review comment (bug):
Hmm, we should make sure that any iteration is correct.... Here, if people pass in `NPY_SORT_STABLE | NPY_SORT_DESCENDING`, they get `quicksort`, which is neither stable nor descending... For now, just have the default be `NULL`? (so one falls through to the generic function, and from there to an error; may need to adjust error messages so that it is clear what was wrong).

Code after:
static PyArray_SortFunc* const generic_sort_table[] = {npy_quicksort,
                                                       npy_heapsort,
                                                       npy_timsort};

/*NUMPY_API
 * Sort an array in-place with extended parameters
 */
NPY_NO_EXPORT int
PyArray_Sort(PyArrayObject *op, int axis, NPY_SORTKIND flags)
{
    PyArray_SortFunc **sort_table = NULL;
    PyArray_SortFunc *sort = NULL;

    if (check_and_adjust_axis(&axis, PyArray_NDIM(op)) < 0) {
        return -1;
    }

    if (PyArray_FailUnlessWriteable(op, "sort array") < 0) {
        return -1;
    }

    // Zero the NPY_HEAPSORT bit, maps NPY_HEAPSORT to NPY_QUICKSORT
    flags &= ~_NPY_SORT_HEAPSORT;

    sort_table = PyDataType_GetArrFuncs(PyArray_DESCR(op))->sort;
    switch (flags) {
        case NPY_SORT_DEFAULT:
            sort = sort_table[NPY_QUICKSORT];
            break;
        case NPY_SORT_STABLE:
            sort = sort_table[NPY_STABLESORT];
            break;
        default:
            break;
    }

    // Look for appropriate generic function if no type specific version
    if (sort == NULL) {
        if (!PyDataType_GetArrFuncs(PyArray_DESCR(op))->compare) {
            PyErr_SetString(PyExc_TypeError,
                            "type does not have compare function");
            return -1;
        }
        switch (flags) {
            case NPY_SORT_DEFAULT:
                sort = generic_sort_table[NPY_QUICKSORT];
                break;
            case NPY_SORT_STABLE:
                sort = generic_sort_table[NPY_STABLESORT];
                break;
            default: