| 6445 | } |
| 6446 | |
| 6447 | static PyObject *Strs_sample(Strs *self, PyObject *const *args, Py_ssize_t positional_args_count, |
| 6448 | PyObject *args_names_tuple) { |
| 6449 | PyObject *sample_size_obj = NULL; |
| 6450 | PyObject *seed_obj = NULL; |
| 6451 | |
| 6452 | // Check for positional arguments |
| 6453 | if (positional_args_count > 1) { |
| 6454 | PyErr_SetString(PyExc_TypeError, "sample() takes 1 positional argument and 1 keyword argument"); |
| 6455 | return NULL; |
| 6456 | } |
| 6457 | else if (positional_args_count == 1) { sample_size_obj = args[0]; } |
| 6458 | |
| 6459 | // Parse keyword arguments |
| 6460 | if (args_names_tuple) { |
| 6461 | Py_ssize_t args_names_count = PyTuple_GET_SIZE(args_names_tuple); |
| 6462 | for (Py_ssize_t i = 0; i < args_names_count; ++i) { |
| 6463 | PyObject *key = PyTuple_GET_ITEM(args_names_tuple, i); |
| 6464 | PyObject *value = args[positional_args_count + i]; |
| 6465 | if (PyUnicode_CompareWithASCIIString(key, "seed") == 0 && !seed_obj) { seed_obj = value; } |
| 6466 | else if (PyErr_Format(PyExc_TypeError, "Got an unexpected keyword argument '%U'", key)) { return NULL; } |
| 6467 | } |
| 6468 | } |
| 6469 | |
| 6470 | // Translate the seed and the sample size to C types |
| 6471 | sz_size_t sample_size = 0; |
| 6472 | if (sample_size_obj) { |
| 6473 | if (!PyLong_Check(sample_size_obj)) { |
| 6474 | PyErr_SetString(PyExc_TypeError, "The sample size must be an integer"); |
| 6475 | return NULL; |
| 6476 | } |
| 6477 | sample_size = PyLong_AsSize_t(sample_size_obj); |
| 6478 | } |
| 6479 | unsigned int seed = (unsigned int)time(NULL); // Default seed |
| 6480 | if (seed_obj) { |
| 6481 | if (!PyLong_Check(seed_obj)) { |
| 6482 | PyErr_SetString(PyExc_TypeError, "The seed must be an integer"); |
| 6483 | return NULL; |
| 6484 | } |
| 6485 | seed = PyLong_AsUnsignedLong(seed_obj); |
| 6486 | } |
| 6487 | |
| 6488 | // Create a new `Strs` object |
| 6489 | Strs *result = (Strs *)StrsType.tp_alloc(&StrsType, 0); |
| 6490 | if (result == NULL && PyErr_NoMemory()) return NULL; |
| 6491 | |
| 6492 | // Initialize the memory allocator with default malloc wrapper |
| 6493 | sz_memory_allocator_init_default(&result->data.fragmented.allocator); |
| 6494 | |
| 6495 | result->layout = STRS_FRAGMENTED; |
| 6496 | result->data.fragmented.count = 0; |
| 6497 | result->data.fragmented.spans = NULL; |
| 6498 | result->data.fragmented.parent = NULL; |
| 6499 | if (sample_size == 0) { return (PyObject *)result; } |
| 6500 | |
| 6501 | // Now create a new Strs object with the sampled strings |
| 6502 | sz_string_view_t *result_spans = malloc(sample_size * sizeof(sz_string_view_t)); |
| 6503 | if (!result_spans) { |
| 6504 | PyErr_SetString(PyExc_MemoryError, "Failed to allocate memory for the sample"); |
nothing calls this directly
no test coverage detected
searching dependent graphs…