* @brief Returns the tuple permuting a `Strs` object into a sorted order. */
| 6359 | * @brief Returns the tuple permuting a `Strs` object into a sorted order. |
| 6360 | */ |
| 6361 | static PyObject *Strs_argsort(Strs *self, PyObject *const *args, Py_ssize_t positional_args_count, |
| 6362 | PyObject *args_names_tuple) { |
| 6363 | PyObject *reverse_obj = NULL; // Default is not reversed |
| 6364 | |
| 6365 | // Check for positional arguments |
| 6366 | if (positional_args_count > 1) { |
| 6367 | PyErr_SetString(PyExc_TypeError, "order() takes at most 1 positional argument"); |
| 6368 | return NULL; |
| 6369 | } |
| 6370 | else if (positional_args_count == 1) { reverse_obj = args[0]; } |
| 6371 | |
| 6372 | // Check for keyword arguments |
| 6373 | if (args_names_tuple) { |
| 6374 | Py_ssize_t args_names_count = PyTuple_GET_SIZE(args_names_tuple); |
| 6375 | for (Py_ssize_t i = 0; i < args_names_count; ++i) { |
| 6376 | PyObject *key = PyTuple_GET_ITEM(args_names_tuple, i); |
| 6377 | PyObject *value = args[positional_args_count + i]; |
| 6378 | if (PyUnicode_CompareWithASCIIString(key, "reverse") == 0 && !reverse_obj) { reverse_obj = value; } |
| 6379 | else if (PyErr_Format(PyExc_TypeError, "Got an unexpected keyword argument '%U'", key)) { return NULL; } |
| 6380 | } |
| 6381 | } |
| 6382 | |
| 6383 | sz_bool_t reverse = 0; // Default is False |
| 6384 | if (reverse_obj) { |
| 6385 | if (!PyBool_Check(reverse_obj)) { |
| 6386 | PyErr_SetString(PyExc_TypeError, "The reverse must be a boolean"); |
| 6387 | return NULL; |
| 6388 | } |
| 6389 | reverse = PyObject_IsTrue(reverse_obj); |
| 6390 | } |
| 6391 | |
| 6392 | sz_size_t const count = Strs_len(self); |
| 6393 | sz_sorted_idx_t *order = (sz_sorted_idx_t *)malloc(sizeof(sz_sorted_idx_t) * count); |
| 6394 | if (!order) { |
| 6395 | PyErr_Format(PyExc_MemoryError, "Unable to allocate memory for the sorting operation"); |
| 6396 | return NULL; |
| 6397 | } |
| 6398 | |
| 6399 | // Call our sorting algorithm |
| 6400 | sz_sequence_t sequence; |
| 6401 | sz_fill(&sequence, sizeof(sequence), 0); |
| 6402 | sequence.count = count; |
| 6403 | sequence.handle = self; |
| 6404 | sequence.get_start = Strs_get_start_; |
| 6405 | sequence.get_length = Strs_get_length_; |
| 6406 | sz_status_t status = sz_sequence_argsort(&sequence, NULL, order); |
| 6407 | sz_unused_(status); |
| 6408 | |
| 6409 | // Apply the sorting algorithm here, considering the `reverse` value |
| 6410 | if (reverse) reverse_offsets(order, count); |
| 6411 | |
| 6412 | // Here, instead of applying the order, we want to return the copy of the |
| 6413 | // order as a NumPy array of 64-bit unsigned integers. |
| 6414 | // |
| 6415 | // npy_intp numpy_size = count; |
| 6416 | // PyObject *array = PyArray_SimpleNew(1, &numpy_size, NPY_UINT64); |
| 6417 | // if (!array) { |
| 6418 | // PyErr_SetString(PyExc_RuntimeError, "Failed to create a NumPy array"); |
nothing calls this directly
no test coverage detected
searching dependent graphs…