| 1448 | "If alphabet is provided, each byte is mapped to alphabet[b % len(alphabet)]."; |
| 1449 | |
| 1450 | static PyObject *module_random(PyObject *self, PyObject *const *args, Py_ssize_t positional_args_count, |
| 1451 | PyObject *args_names_tuple) { |
| 1452 | (void)self; |
| 1453 | if (positional_args_count < 1 || positional_args_count > 2) { |
| 1454 | PyErr_SetString(PyExc_TypeError, "random() expects 1 or 2 positional arguments"); |
| 1455 | return NULL; |
| 1456 | } |
| 1457 | PyObject *length_obj = args[0]; |
| 1458 | PyObject *nonce_obj = positional_args_count > 1 ? args[1] : NULL; |
| 1459 | PyObject *alphabet_obj = NULL; |
| 1460 | |
| 1461 | if (args_names_tuple) { |
| 1462 | Py_ssize_t kw_count = PyTuple_GET_SIZE(args_names_tuple); |
| 1463 | for (Py_ssize_t i = 0; i < kw_count; ++i) { |
| 1464 | PyObject *key = PyTuple_GET_ITEM(args_names_tuple, i); |
| 1465 | PyObject *value = args[positional_args_count + i]; |
| 1466 | if (PyUnicode_CompareWithASCIIString(key, "nonce") == 0 && !nonce_obj) nonce_obj = value; |
| 1467 | else if (PyUnicode_CompareWithASCIIString(key, "alphabet") == 0 && !alphabet_obj) |
| 1468 | alphabet_obj = value; |
| 1469 | else { |
| 1470 | PyErr_Format(PyExc_TypeError, "unexpected keyword argument: %S", key); |
| 1471 | return NULL; |
| 1472 | } |
| 1473 | } |
| 1474 | } |
| 1475 | |
| 1476 | if (!PyLong_Check(length_obj)) { |
| 1477 | PyErr_SetString(PyExc_TypeError, "length must be an integer"); |
| 1478 | return NULL; |
| 1479 | } |
| 1480 | Py_ssize_t signed_length = PyLong_AsSsize_t(length_obj); |
| 1481 | if (signed_length == -1 && PyErr_Occurred()) return NULL; |
| 1482 | if (signed_length < 0) { |
| 1483 | PyErr_SetString(PyExc_ValueError, "length must be non-negative"); |
| 1484 | return NULL; |
| 1485 | } |
| 1486 | sz_size_t length = (sz_size_t)signed_length; |
| 1487 | |
| 1488 | sz_u64_t nonce = 0; |
| 1489 | if (nonce_obj) { |
| 1490 | if (!PyLong_Check(nonce_obj)) { |
| 1491 | PyErr_SetString(PyExc_TypeError, "nonce must be an integer"); |
| 1492 | return NULL; |
| 1493 | } |
| 1494 | nonce = PyLong_AsUnsignedLongLong(nonce_obj); |
| 1495 | if (PyErr_Occurred()) return NULL; |
| 1496 | } |
| 1497 | |
| 1498 | PyObject *bytes_obj = PyBytes_FromStringAndSize(NULL, (Py_ssize_t)length); |
| 1499 | if (!bytes_obj) { |
| 1500 | PyErr_SetString(PyExc_MemoryError, "Unable to allocate random bytes"); |
| 1501 | return NULL; |
| 1502 | } |
| 1503 | if (length > 0) { |
| 1504 | sz_ptr_t buffer = (sz_ptr_t)PyBytes_AS_STRING(bytes_obj); |
| 1505 | sz_fill_random(buffer, length, nonce); |
| 1506 | } |
| 1507 |
nothing calls this directly
no test coverage detected
searching dependent graphs…