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

Code before:
    Py_DECREF(ktharray);

    if (order != NULL) {
        Py_XDECREF(PyArray_DESCR(self));
        ((PyArrayObject_fields *)self)->descr = saved;
    }
    if (val < 0) {
        return NULL;
    }
    Py_RETURN_NONE;
}


static PyObject *
array_argsort(PyArrayObject *self,
        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_UNDEFINED;
    int stable = -1;
    int descending = -1;
    int nanfirst = -1;
    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_UNDEFINED) {
        // keywords only if sortkind not passed
        sortkind = 0;
        sortkind |= (stable > 0)? NPY_SORT_STABLE: 0;
        sortkind |= (descending > 0)? NPY_SORT_DESCENDING: 0;
        sortkind |= (nanfirst > 0)? NPY_SORT_NANFIRST: 0;
    }
    else {
        // Check that no keywords are used
        int keywords_used = 0;
        keywords_used |= (stable != -1);
        keywords_used |= (descending != -1);

Review comment (suggestion):
This doesn't need the optional bool converter, since the default is well defined in both cases.  The optional one is just for when `None`/not passed has a special meaning.
(Which is the case for `stable`, because it needs to distinguish not passed for the error.)

I would also be happy to just delete the NaN thing here, but either way. I have been drifting away from wanting it much.  And I think if we have it then `nan_placement="first"` might be clearer than a boolean thing in Python.

(Anyway, it doesn't really matter of course as it is all commented out anyway.)

Code after:
        ((PyArrayObject_fields *)self)->descr = saved;
    }
    if (val < 0) {
        return NULL;
    }
    Py_RETURN_NONE;
}


static PyObject *
array_argsort(PyArrayObject *self,
        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_UNDEFINED;
    int stable = -1;
    int descending = -1;
    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,
            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;
        }
    }