mirror of
https://github.com/python/cpython.git
synced 2025-10-06 23:21:06 +00:00
gh-117431: Adapt bytes and bytearray .find() and friends to Argument Clinic (#117502)
This change gives a significant speedup, as the METH_FASTCALL calling convention is now used. The following bytes and bytearray methods are adapted: - count() - find() - index() - rfind() - rindex() Co-authored-by: Inada Naoki <songofacandy@gmail.com>
This commit is contained in:
parent
49fc1414b5
commit
deb921f851
8 changed files with 709 additions and 170 deletions
|
@ -453,31 +453,21 @@ stringlib_parse_args_finds().
|
|||
*/
|
||||
|
||||
Py_LOCAL_INLINE(int)
|
||||
parse_args_finds_byte(const char *function_name, PyObject *args,
|
||||
PyObject **subobj, char *byte,
|
||||
Py_ssize_t *start, Py_ssize_t *end)
|
||||
parse_args_finds_byte(const char *function_name, PyObject **subobj, char *byte)
|
||||
{
|
||||
PyObject *tmp_subobj;
|
||||
Py_ssize_t ival;
|
||||
|
||||
if(!stringlib_parse_args_finds(function_name, args, &tmp_subobj,
|
||||
start, end))
|
||||
return 0;
|
||||
|
||||
if (PyObject_CheckBuffer(tmp_subobj)) {
|
||||
*subobj = tmp_subobj;
|
||||
if (PyObject_CheckBuffer(*subobj)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!_PyIndex_Check(tmp_subobj)) {
|
||||
if (!_PyIndex_Check(*subobj)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"argument should be integer or bytes-like object, "
|
||||
"not '%.200s'",
|
||||
Py_TYPE(tmp_subobj)->tp_name);
|
||||
Py_TYPE(*subobj)->tp_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ival = PyNumber_AsSsize_t(tmp_subobj, NULL);
|
||||
Py_ssize_t ival = PyNumber_AsSsize_t(*subobj, NULL);
|
||||
if (ival == -1 && PyErr_Occurred()) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -508,19 +498,19 @@ parse_args_finds_byte(const char *function_name, PyObject *args,
|
|||
|
||||
Py_LOCAL_INLINE(Py_ssize_t)
|
||||
find_internal(const char *str, Py_ssize_t len,
|
||||
const char *function_name, PyObject *args, int dir)
|
||||
const char *function_name, PyObject *subobj,
|
||||
Py_ssize_t start, Py_ssize_t end,
|
||||
int dir)
|
||||
{
|
||||
PyObject *subobj;
|
||||
char byte;
|
||||
Py_buffer subbuf;
|
||||
const char *sub;
|
||||
Py_ssize_t sub_len;
|
||||
Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
|
||||
Py_ssize_t res;
|
||||
|
||||
if (!parse_args_finds_byte(function_name, args,
|
||||
&subobj, &byte, &start, &end))
|
||||
if (!parse_args_finds_byte(function_name, &subobj, &byte)) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (subobj) {
|
||||
if (PyObject_GetBuffer(subobj, &subbuf, PyBUF_SIMPLE) != 0)
|
||||
|
@ -566,37 +556,21 @@ find_internal(const char *str, Py_ssize_t len,
|
|||
return res;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR_shared(_Py_find__doc__,
|
||||
"B.find(sub[, start[, end]]) -> int\n\
|
||||
\n\
|
||||
Return the lowest index in B where subsection sub is found,\n\
|
||||
such that sub is contained within B[start,end]. Optional\n\
|
||||
arguments start and end are interpreted as in slice notation.\n\
|
||||
\n\
|
||||
Return -1 on failure.");
|
||||
|
||||
PyObject *
|
||||
_Py_bytes_find(const char *str, Py_ssize_t len, PyObject *args)
|
||||
_Py_bytes_find(const char *str, Py_ssize_t len, PyObject *sub,
|
||||
Py_ssize_t start, Py_ssize_t end)
|
||||
{
|
||||
Py_ssize_t result = find_internal(str, len, "find", args, +1);
|
||||
Py_ssize_t result = find_internal(str, len, "find", sub, start, end, +1);
|
||||
if (result == -2)
|
||||
return NULL;
|
||||
return PyLong_FromSsize_t(result);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR_shared(_Py_index__doc__,
|
||||
"B.index(sub[, start[, end]]) -> int\n\
|
||||
\n\
|
||||
Return the lowest index in B where subsection sub is found,\n\
|
||||
such that sub is contained within B[start,end]. Optional\n\
|
||||
arguments start and end are interpreted as in slice notation.\n\
|
||||
\n\
|
||||
Raises ValueError when the subsection is not found.");
|
||||
|
||||
PyObject *
|
||||
_Py_bytes_index(const char *str, Py_ssize_t len, PyObject *args)
|
||||
_Py_bytes_index(const char *str, Py_ssize_t len, PyObject *sub,
|
||||
Py_ssize_t start, Py_ssize_t end)
|
||||
{
|
||||
Py_ssize_t result = find_internal(str, len, "index", args, +1);
|
||||
Py_ssize_t result = find_internal(str, len, "index", sub, start, end, +1);
|
||||
if (result == -2)
|
||||
return NULL;
|
||||
if (result == -1) {
|
||||
|
@ -607,37 +581,21 @@ _Py_bytes_index(const char *str, Py_ssize_t len, PyObject *args)
|
|||
return PyLong_FromSsize_t(result);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR_shared(_Py_rfind__doc__,
|
||||
"B.rfind(sub[, start[, end]]) -> int\n\
|
||||
\n\
|
||||
Return the highest index in B where subsection sub is found,\n\
|
||||
such that sub is contained within B[start,end]. Optional\n\
|
||||
arguments start and end are interpreted as in slice notation.\n\
|
||||
\n\
|
||||
Return -1 on failure.");
|
||||
|
||||
PyObject *
|
||||
_Py_bytes_rfind(const char *str, Py_ssize_t len, PyObject *args)
|
||||
_Py_bytes_rfind(const char *str, Py_ssize_t len, PyObject *sub,
|
||||
Py_ssize_t start, Py_ssize_t end)
|
||||
{
|
||||
Py_ssize_t result = find_internal(str, len, "rfind", args, -1);
|
||||
Py_ssize_t result = find_internal(str, len, "rfind", sub, start, end, -1);
|
||||
if (result == -2)
|
||||
return NULL;
|
||||
return PyLong_FromSsize_t(result);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR_shared(_Py_rindex__doc__,
|
||||
"B.rindex(sub[, start[, end]]) -> int\n\
|
||||
\n\
|
||||
Return the highest index in B where subsection sub is found,\n\
|
||||
such that sub is contained within B[start,end]. Optional\n\
|
||||
arguments start and end are interpreted as in slice notation.\n\
|
||||
\n\
|
||||
Raise ValueError when the subsection is not found.");
|
||||
|
||||
PyObject *
|
||||
_Py_bytes_rindex(const char *str, Py_ssize_t len, PyObject *args)
|
||||
_Py_bytes_rindex(const char *str, Py_ssize_t len, PyObject *sub,
|
||||
Py_ssize_t start, Py_ssize_t end)
|
||||
{
|
||||
Py_ssize_t result = find_internal(str, len, "rindex", args, -1);
|
||||
Py_ssize_t result = find_internal(str, len, "rindex", sub, start, end, -1);
|
||||
if (result == -2)
|
||||
return NULL;
|
||||
if (result == -1) {
|
||||
|
@ -648,28 +606,20 @@ _Py_bytes_rindex(const char *str, Py_ssize_t len, PyObject *args)
|
|||
return PyLong_FromSsize_t(result);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR_shared(_Py_count__doc__,
|
||||
"B.count(sub[, start[, end]]) -> int\n\
|
||||
\n\
|
||||
Return the number of non-overlapping occurrences of subsection sub in\n\
|
||||
bytes B[start:end]. Optional arguments start and end are interpreted\n\
|
||||
as in slice notation.");
|
||||
|
||||
PyObject *
|
||||
_Py_bytes_count(const char *str, Py_ssize_t len, PyObject *args)
|
||||
_Py_bytes_count(const char *str, Py_ssize_t len, PyObject *sub_obj,
|
||||
Py_ssize_t start, Py_ssize_t end)
|
||||
{
|
||||
PyObject *sub_obj;
|
||||
const char *sub;
|
||||
Py_ssize_t sub_len;
|
||||
char byte;
|
||||
Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
|
||||
|
||||
Py_buffer vsub;
|
||||
PyObject *count_obj;
|
||||
|
||||
if (!parse_args_finds_byte("count", args,
|
||||
&sub_obj, &byte, &start, &end))
|
||||
if (!parse_args_finds_byte("count", &sub_obj, &byte)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (sub_obj) {
|
||||
if (PyObject_GetBuffer(sub_obj, &vsub, PyBUF_SIMPLE) != 0)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue