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

Code before:
        PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
{
    int axis = -1;
    PyObject *res;
    PyObject *order = NULL;
    PyArray_Descr *saved = NULL;
    PyArray_Descr *newd;
    NPY_SORTKIND sortkind = NPY_SORT_USEFLAGS;
    int stable = -1;
    int descending = -1;
    int nanfirst = -1;
    NPY_SORTFLAGS flags = 0;
    NPY_PREPARE_ARGPARSER;

    if (npy_parse_arguments("argsort", args, len_args, kwnames,
            "|axis", &PyArray_AxisConverter, &axis,
            "|kind", &PyArray_SortkindConverter, &sortkind,
            "|order", NULL, &order,
            "$stable", &PyArray_OptionalBoolConverter, &stable,
            "$descending", &PyArray_OptionalBoolConverter, &descending,
            "$nanfirst", &PyArray_OptionalBoolConverter, &nanfirst,
            NULL, NULL, NULL) < 0) {
        return NULL;
    }

    if (sortkind == NPY_SORT_USEFLAGS) {
        stable = (stable > 0)? NPY_SORT_STABLE: 0;
        descending = (descending > 0)? NPY_SORT_DESCENDING: 0;
        nanfirst = (nanfirst > 0)? NPY_SORT_NANFIRST: 0;
        flags = stable | descending | nanfirst;
    }
    else {
        // Check that no keywords are used
        int keywords_used = (stable != -1) | (descending != -1) | (nanfirst != -1);
        if (keywords_used) {
            PyErr_SetString(PyExc_ValueError,
                    "`kind` and keyword parameters can't be provided at "
                    "the same time. Use only one of them.");
            return NULL;
        }
        // remap sortkind to flags, NPY_HEAPSORT is effectively mapped to NPY_QUICKSORT.
        switch (sortkind) {
            case NPY_STABLESORT:
                flags = NPY_SORT_STABLE;
                break;
            case NPY_HEAPSORT:
            case NPY_QUICKSORT:
            default:
                flags = 0;
        }
    }

Review comment (refactor):
It may be worth splitting out this sortkind checking into a separate function, since it is duplicated between sort and argsort. Something like
```
int get_sort_flags(NPY_SORTKIND sortkind, int stable, int descending, int nanfirst)
```
where the return argument is flags (or -1 if an error occurred. (Maybe better with `flags` passed in?)

Code after:

    if (npy_parse_arguments("argsort", args, len_args, kwnames,
            "|axis", &PyArray_AxisConverter, &axis,
            "|kind", &PyArray_SortkindConverter, &sortkind,
            "|order", NULL, &order,
            "$stable", &PyArray_OptionalBoolConverter, &stable,
//            "$descending", &PyArray_OptionalBoolConverter, &descending,
            NULL, NULL, NULL) < 0) {
        return NULL;
    }

    if (sortkind == _NPY_SORT_UNDEFINED) {
        // keywords only if sortkind not passed
        sortkind = 0;
        sortkind |= (stable > 0)? NPY_SORT_STABLE: 0;
        sortkind |= (descending > 0)? NPY_SORT_DESCENDING: 0;
    }
    else {
        // Check that no keywords are used
        int keywords_used = 0;
        keywords_used |= (stable != -1);
        keywords_used |= (descending != -1);
        if (keywords_used) {
            PyErr_SetString(PyExc_ValueError,
                    "`kind` and keyword parameters can't be provided at "
                    "the same time. Use only one of them.");
            return NULL;
        }
    }

    // Reorder field names if required.
    order = (order != Py_None)? order: NULL;
    if (order != NULL) {
        PyObject *new_name;
        PyObject *_numpy_internal;
        saved = PyArray_DESCR(self);
        if (!PyDataType_HASFIELDS(saved)) {
            PyErr_SetString(PyExc_ValueError, "Cannot specify "
                            "order when the array has no fields.");
            return NULL;
        }
        _numpy_internal = PyImport_ImportModule("numpy._core._internal");
        if (_numpy_internal == NULL) {
            return NULL;
        }
        new_name = PyObject_CallMethod(_numpy_internal, "_newnames",
                                       "OO", saved, order);
        Py_DECREF(_numpy_internal);
        if (new_name == NULL) {
            return NULL;
        }