| 2921 | " int: The number of occurrences of the substring."; |
| 2922 | |
| 2923 | static PyObject *Str_like_count(PyObject *self, PyObject *const *args, Py_ssize_t positional_args_count, |
| 2924 | PyObject *args_names_tuple) { |
| 2925 | // Fast path variables |
| 2926 | PyObject *haystack_obj = NULL; |
| 2927 | PyObject *needle_obj = NULL; |
| 2928 | PyObject *start_obj = NULL; |
| 2929 | PyObject *end_obj = NULL; |
| 2930 | PyObject *allowoverlap_obj = NULL; |
| 2931 | |
| 2932 | int const is_member = self != NULL && PyObject_TypeCheck(self, &StrType); |
| 2933 | |
| 2934 | // Fast argument validation |
| 2935 | Py_ssize_t const args_names_count = args_names_tuple ? PyTuple_Size(args_names_tuple) : 0; |
| 2936 | Py_ssize_t const total_args = positional_args_count + args_names_count; |
| 2937 | Py_ssize_t const expected_min = is_member ? 1 : 2; // needle is required |
| 2938 | Py_ssize_t const expected_max = expected_min + 3; // + start + end + allowoverlap |
| 2939 | |
| 2940 | if (total_args < expected_min || total_args > expected_max) { |
| 2941 | PyErr_SetString(PyExc_TypeError, "Invalid number of arguments"); |
| 2942 | return NULL; |
| 2943 | } |
| 2944 | |
| 2945 | if (positional_args_count > expected_max) { |
| 2946 | PyErr_SetString(PyExc_TypeError, "Too many positional arguments"); |
| 2947 | return NULL; |
| 2948 | } |
| 2949 | |
| 2950 | // Fast positional argument extraction |
| 2951 | if (is_member) { |
| 2952 | haystack_obj = self; |
| 2953 | if (positional_args_count >= 1) needle_obj = args[0]; |
| 2954 | if (positional_args_count >= 2) start_obj = args[1]; |
| 2955 | if (positional_args_count >= 3) end_obj = args[2]; |
| 2956 | if (positional_args_count >= 4) allowoverlap_obj = args[3]; |
| 2957 | } |
| 2958 | else { |
| 2959 | if (positional_args_count >= 1) haystack_obj = args[0]; |
| 2960 | if (positional_args_count >= 2) needle_obj = args[1]; |
| 2961 | if (positional_args_count >= 3) start_obj = args[2]; |
| 2962 | if (positional_args_count >= 4) end_obj = args[3]; |
| 2963 | if (positional_args_count >= 5) allowoverlap_obj = args[4]; |
| 2964 | } |
| 2965 | |
| 2966 | // Fast keyword argument parsing |
| 2967 | if (args_names_count > 0) { |
| 2968 | for (Py_ssize_t i = 0; i < args_names_count; ++i) { |
| 2969 | PyObject *const key = PyTuple_GetItem(args_names_tuple, i); |
| 2970 | PyObject *const value = args[positional_args_count + i]; |
| 2971 | |
| 2972 | if (PyUnicode_CompareWithASCIIString(key, "start") == 0) { |
| 2973 | if (start_obj) { |
| 2974 | PyErr_SetString(PyExc_TypeError, "start specified twice"); |
| 2975 | return NULL; |
| 2976 | } |
| 2977 | start_obj = value; |
| 2978 | } |
| 2979 | else if (PyUnicode_CompareWithASCIIString(key, "end") == 0) { |
| 2980 | if (end_obj) { |
nothing calls this directly
no test coverage detected
searching dependent graphs…