| 5000 | " Str: A new string with leading characters removed."; |
| 5001 | |
| 5002 | static PyObject *Str_like_lstrip(PyObject *self, PyObject *const *args, Py_ssize_t positional_args_count, |
| 5003 | PyObject *args_names_tuple) { |
| 5004 | // Check arguments |
| 5005 | int is_member = self != NULL && PyObject_TypeCheck(self, &StrType); |
| 5006 | Py_ssize_t expected_min_args = !is_member; |
| 5007 | Py_ssize_t expected_max_args = !is_member + 1; |
| 5008 | if (positional_args_count < expected_min_args || positional_args_count > expected_max_args) { |
| 5009 | PyErr_SetString(PyExc_TypeError, "lstrip() takes at most 1 argument"); |
| 5010 | return NULL; |
| 5011 | } |
| 5012 | |
| 5013 | PyObject *text_obj = is_member ? self : args[0]; |
| 5014 | PyObject *chars_obj = positional_args_count > !is_member ? args[!is_member] : NULL; |
| 5015 | |
| 5016 | if (args_names_tuple) { |
| 5017 | Py_ssize_t args_names_count = PyTuple_GET_SIZE(args_names_tuple); |
| 5018 | for (Py_ssize_t i = 0; i < args_names_count; ++i) { |
| 5019 | PyObject *key = PyTuple_GET_ITEM(args_names_tuple, i); |
| 5020 | PyObject *value = args[positional_args_count + i]; |
| 5021 | if (PyUnicode_CompareWithASCIIString(key, "chars") == 0 && !chars_obj) { chars_obj = value; } |
| 5022 | else if (PyErr_Format(PyExc_TypeError, "Got an unexpected keyword argument '%U'", key)) |
| 5023 | return NULL; |
| 5024 | } |
| 5025 | } |
| 5026 | |
| 5027 | sz_string_view_t text; |
| 5028 | sz_string_view_t chars; |
| 5029 | |
| 5030 | // Validate and convert text |
| 5031 | if (!sz_py_export_string_like(text_obj, &text.start, &text.length)) { |
| 5032 | wrap_current_exception("The text argument must be string-like"); |
| 5033 | return NULL; |
| 5034 | } |
| 5035 | |
| 5036 | // Default to whitespace if chars is not provided |
| 5037 | char const *default_chars = " \t\n\r\f\v"; |
| 5038 | if (chars_obj) { |
| 5039 | if (!sz_py_export_string_like(chars_obj, &chars.start, &chars.length)) { |
| 5040 | wrap_current_exception("The chars argument must be string-like"); |
| 5041 | return NULL; |
| 5042 | } |
| 5043 | } |
| 5044 | else { |
| 5045 | chars.start = default_chars; |
| 5046 | chars.length = 6; |
| 5047 | } |
| 5048 | |
| 5049 | // Create byteset from chars |
| 5050 | sz_byteset_t set; |
| 5051 | sz_byteset_init(&set); |
| 5052 | for (sz_size_t i = 0; i < chars.length; ++i) sz_byteset_add(&set, chars.start[i]); |
| 5053 | sz_byteset_invert(&set); |
| 5054 | |
| 5055 | // Find first character NOT in the set (i.e., not to be stripped) |
| 5056 | sz_cptr_t new_start = sz_find_byteset(text.start, text.length, &set); |
| 5057 | if (!new_start) { |
| 5058 | // Return empty string |
| 5059 | Str *result = (Str *)StrType.tp_alloc(&StrType, 0); |
nothing calls this directly
no test coverage detected
searching dependent graphs…