| 1253 | " >>> def hash(text, seed=0, /) -> int: ..."; |
| 1254 | |
| 1255 | static PyObject *Str_like_hash(PyObject *self, PyObject *const *args, Py_ssize_t positional_args_count, |
| 1256 | PyObject *args_names_tuple) { |
| 1257 | // Fast path variables |
| 1258 | PyObject *text_obj = NULL; |
| 1259 | PyObject *seed_obj = NULL; |
| 1260 | sz_string_view_t text; |
| 1261 | sz_u64_t seed = 0; |
| 1262 | |
| 1263 | // Check if this is a method call on a Str instance |
| 1264 | int const is_member = self != NULL && PyObject_TypeCheck(self, &StrType); |
| 1265 | |
| 1266 | // Fast argument validation |
| 1267 | Py_ssize_t const args_names_count = args_names_tuple ? PyTuple_Size(args_names_tuple) : 0; |
| 1268 | Py_ssize_t const total_args = positional_args_count + args_names_count; |
| 1269 | Py_ssize_t const expected_min = is_member ? 0 : 1; |
| 1270 | Py_ssize_t const expected_max = expected_min + 1; |
| 1271 | |
| 1272 | if (total_args < expected_min || total_args > expected_max) { |
| 1273 | PyErr_SetString(PyExc_TypeError, is_member ? "hash() takes 0 or 1 positional arguments" |
| 1274 | : "hash() takes 1 or 2 positional arguments"); |
| 1275 | return NULL; |
| 1276 | } |
| 1277 | |
| 1278 | if (positional_args_count > expected_max) { |
| 1279 | PyErr_SetString(PyExc_TypeError, "Too many positional arguments"); |
| 1280 | return NULL; |
| 1281 | } |
| 1282 | |
| 1283 | // Fast positional argument extraction |
| 1284 | if (is_member) { |
| 1285 | text_obj = self; |
| 1286 | if (positional_args_count >= 1) seed_obj = args[0]; |
| 1287 | } |
| 1288 | else { |
| 1289 | if (positional_args_count >= 1) text_obj = args[0]; |
| 1290 | if (positional_args_count >= 2) seed_obj = args[1]; |
| 1291 | } |
| 1292 | |
| 1293 | // Fast keyword argument parsing |
| 1294 | if (args_names_count > 0) { |
| 1295 | for (Py_ssize_t i = 0; i < args_names_count; ++i) { |
| 1296 | PyObject *const key = PyTuple_GetItem(args_names_tuple, i); |
| 1297 | PyObject *const value = args[positional_args_count + i]; |
| 1298 | |
| 1299 | if (PyUnicode_CompareWithASCIIString(key, "seed") == 0) { |
| 1300 | if (seed_obj) { |
| 1301 | PyErr_SetString(PyExc_TypeError, "seed specified twice"); |
| 1302 | return NULL; |
| 1303 | } |
| 1304 | seed_obj = value; |
| 1305 | } |
| 1306 | else { |
| 1307 | PyErr_Format(PyExc_TypeError, "unexpected keyword argument: %S", key); |
| 1308 | return NULL; |
| 1309 | } |
| 1310 | } |
| 1311 | } |
| 1312 |
nothing calls this directly
no test coverage detected
searching dependent graphs…