Skip to content

Commit d8f65a1

Browse files
committed
gh-100239: expose sq_repeat helpers for BINARY_OP_EXTEND
1 parent a00b24e commit d8f65a1

File tree

9 files changed

+59
-45
lines changed

9 files changed

+59
-45
lines changed

Include/internal/pycore_bytesobject.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,11 @@ _PyBytes_ReverseFind(const char *haystack, Py_ssize_t len_haystack,
6262
//
6363
// Export for 'array' shared extension.
6464
PyAPI_FUNC(void)
65-
_PyBytes_Repeat(char* dest, Py_ssize_t len_dest,
65+
_PyBytes_RepeatBuffer(char* dest, Py_ssize_t len_dest,
6666
const char* src, Py_ssize_t len_src);
6767

68+
PyAPI_FUNC(PyObject *) _PyBytes_Repeat(PyObject *self, Py_ssize_t n);
69+
6870
/* _PyBytesObject_SIZE gives the basic size of a bytes object; any memory allocation
6971
for a bytes object of length n should request PyBytesObject_SIZE + n bytes.
7072

Include/internal/pycore_tuple.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ PyAPI_FUNC(PyObject *)_PyTuple_FromStackRefStealOnSuccess(const union _PyStackRe
2929
PyAPI_FUNC(PyObject *)_PyTuple_FromArraySteal(PyObject *const *, Py_ssize_t);
3030
PyAPI_FUNC(PyObject *) _PyTuple_BinarySlice(PyObject *, PyObject *, PyObject *);
3131
PyAPI_FUNC(PyObject *) _PyTuple_Concat(PyObject *, PyObject *);
32+
PyAPI_FUNC(PyObject *) _PyTuple_Repeat(PyObject *self, Py_ssize_t n);
3233

3334
PyAPI_FUNC(PyObject *) _PyTuple_FromPair(PyObject *, PyObject *);
3435
PyAPI_FUNC(PyObject *) _PyTuple_FromPairSteal(PyObject *, PyObject *);

Include/internal/pycore_unicodeobject.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ extern PyObject* _PyUnicode_ResizeCompact(
3333
Py_ssize_t length);
3434
extern PyObject* _PyUnicode_GetEmpty(void);
3535
PyAPI_FUNC(PyObject*) _PyUnicode_BinarySlice(PyObject *, PyObject *, PyObject *);
36+
PyAPI_FUNC(PyObject *) _PyUnicode_Repeat(PyObject *str, Py_ssize_t len);
3637

3738

3839
/* Generic helper macro to convert characters of different types.

Modules/arraymodule.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
#endif
99

1010
#include "Python.h"
11-
#include "pycore_bytesobject.h" // _PyBytes_Repeat
11+
#include "pycore_bytesobject.h" // _PyBytes_RepeatBuffer
1212
#include "pycore_call.h" // _PyObject_CallMethod()
1313
#include "pycore_ceval.h" // _PyEval_GetBuiltin()
1414
#include "pycore_floatobject.h" // _PY_FLOAT_BIG_ENDIAN
@@ -1148,7 +1148,7 @@ array_repeat(PyObject *op, Py_ssize_t n)
11481148

11491149
const Py_ssize_t oldbytes = array_length * a->ob_descr->itemsize;
11501150
const Py_ssize_t newbytes = oldbytes * n;
1151-
_PyBytes_Repeat(np->ob_item, newbytes, a->ob_item, oldbytes);
1151+
_PyBytes_RepeatBuffer(np->ob_item, newbytes, a->ob_item, oldbytes);
11521152

11531153
return (PyObject *)np;
11541154
}
@@ -1305,7 +1305,7 @@ array_inplace_repeat(PyObject *op, Py_ssize_t n)
13051305
if (array_resize(self, n * array_size) == -1)
13061306
return NULL;
13071307

1308-
_PyBytes_Repeat(self->ob_item, n*size, self->ob_item, size);
1308+
_PyBytes_RepeatBuffer(self->ob_item, n*size, self->ob_item, size);
13091309
}
13101310
return Py_NewRef(self);
13111311
}

Objects/bytearrayobject.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ bytearray_repeat_lock_held(PyObject *op, Py_ssize_t count)
402402
PyByteArrayObject* result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size);
403403
const char* buf = PyByteArray_AS_STRING(self);
404404
if (result != NULL && size != 0) {
405-
_PyBytes_Repeat(result->ob_bytes, size, buf, mysize);
405+
_PyBytes_RepeatBuffer(result->ob_bytes, size, buf, mysize);
406406
}
407407
return (PyObject *)result;
408408
}
@@ -439,7 +439,7 @@ bytearray_irepeat_lock_held(PyObject *op, Py_ssize_t count)
439439
}
440440

441441
char* buf = PyByteArray_AS_STRING(self);
442-
_PyBytes_Repeat(buf, size, buf, mysize);
442+
_PyBytes_RepeatBuffer(buf, size, buf, mysize);
443443

444444
return Py_NewRef(self);
445445
}

Objects/bytesobject.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#include "Python.h"
44
#include "pycore_abstract.h" // _PyIndex_Check()
55
#include "pycore_bytes_methods.h" // _Py_bytes_startswith()
6-
#include "pycore_bytesobject.h" // _PyBytes_Find(), _PyBytes_Repeat()
6+
#include "pycore_bytesobject.h" // _PyBytes_Find(), _PyBytes_RepeatBuffer()
77
#include "pycore_call.h" // _PyObject_CallNoArgs()
88
#include "pycore_ceval.h" // _PyEval_GetBuiltin()
99
#include "pycore_format.h" // F_LJUST
@@ -1581,8 +1581,8 @@ _PyBytes_Concat(PyObject *a, PyObject *b)
15811581
return result;
15821582
}
15831583

1584-
static PyObject *
1585-
bytes_repeat(PyObject *self, Py_ssize_t n)
1584+
PyObject *
1585+
_PyBytes_Repeat(PyObject *self, Py_ssize_t n)
15861586
{
15871587
PyBytesObject *a = _PyBytes_CAST(self);
15881588
if (n < 0)
@@ -1613,7 +1613,7 @@ bytes_repeat(PyObject *self, Py_ssize_t n)
16131613
set_ob_shash(op, -1);
16141614
op->ob_sval[size] = '\0';
16151615

1616-
_PyBytes_Repeat(op->ob_sval, size, a->ob_sval, Py_SIZE(a));
1616+
_PyBytes_RepeatBuffer(op->ob_sval, size, a->ob_sval, Py_SIZE(a));
16171617

16181618
return (PyObject *) op;
16191619
}
@@ -1805,7 +1805,7 @@ bytes_buffer_getbuffer(PyObject *op, Py_buffer *view, int flags)
18051805
static PySequenceMethods bytes_as_sequence = {
18061806
bytes_length, /*sq_length*/
18071807
_PyBytes_Concat, /*sq_concat*/
1808-
bytes_repeat, /*sq_repeat*/
1808+
_PyBytes_Repeat, /*sq_repeat*/
18091809
bytes_item, /*sq_item*/
18101810
0, /*sq_slice*/
18111811
0, /*sq_ass_item*/
@@ -3555,7 +3555,7 @@ bytes_iter(PyObject *seq)
35553555

35563556

35573557
void
3558-
_PyBytes_Repeat(char* dest, Py_ssize_t len_dest,
3558+
_PyBytes_RepeatBuffer(char* dest, Py_ssize_t len_dest,
35593559
const char* src, Py_ssize_t len_src)
35603560
{
35613561
if (len_dest == 0) {

Objects/tupleobject.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -594,8 +594,8 @@ _PyTuple_Concat(PyObject *aa, PyObject *bb)
594594
return (PyObject *)np;
595595
}
596596

597-
static PyObject *
598-
tuple_repeat(PyObject *self, Py_ssize_t n)
597+
PyObject *
598+
_PyTuple_Repeat(PyObject *self, Py_ssize_t n)
599599
{
600600
PyTupleObject *a = _PyTuple_CAST(self);
601601
const Py_ssize_t input_size = Py_SIZE(a);
@@ -865,7 +865,7 @@ tuple_subtype_new(PyTypeObject *type, PyObject *iterable)
865865
static PySequenceMethods tuple_as_sequence = {
866866
tuple_length, /* sq_length */
867867
_PyTuple_Concat, /* sq_concat */
868-
tuple_repeat, /* sq_repeat */
868+
_PyTuple_Repeat, /* sq_repeat */
869869
tuple_item, /* sq_item */
870870
0, /* sq_slice */
871871
0, /* sq_ass_item */

Objects/unicodeobject.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
4141
#include "Python.h"
4242
#include "pycore_abstract.h" // _PyIndex_Check()
4343
#include "pycore_bytes_methods.h" // _Py_bytes_lower()
44-
#include "pycore_bytesobject.h" // _PyBytes_Repeat()
44+
#include "pycore_bytesobject.h" // _PyBytes_RepeatBuffer()
4545
#include "pycore_ceval.h" // _PyEval_GetBuiltin()
4646
#include "pycore_codecs.h" // _PyCodec_Lookup()
4747
#include "pycore_critical_section.h" // Py_*_CRITICAL_SECTION_SEQUENCE_FAST
@@ -12494,8 +12494,8 @@ unicode_rstrip_impl(PyObject *self, PyObject *chars)
1249412494
}
1249512495

1249612496

12497-
static PyObject*
12498-
unicode_repeat(PyObject *str, Py_ssize_t len)
12497+
PyObject *
12498+
_PyUnicode_Repeat(PyObject *str, Py_ssize_t len)
1249912499
{
1250012500
PyObject *u;
1250112501
Py_ssize_t nchars, n;
@@ -12540,7 +12540,7 @@ unicode_repeat(PyObject *str, Py_ssize_t len)
1254012540
else {
1254112541
Py_ssize_t char_size = PyUnicode_KIND(str);
1254212542
char *to = (char *) PyUnicode_DATA(u);
12543-
_PyBytes_Repeat(to, nchars * char_size, PyUnicode_DATA(str),
12543+
_PyBytes_RepeatBuffer(to, nchars * char_size, PyUnicode_DATA(str),
1254412544
PyUnicode_GET_LENGTH(str) * char_size);
1254512545
}
1254612546

@@ -13726,7 +13726,7 @@ static PyNumberMethods unicode_as_number = {
1372613726
static PySequenceMethods unicode_as_sequence = {
1372713727
unicode_length, /* sq_length */
1372813728
PyUnicode_Concat, /* sq_concat */
13729-
unicode_repeat, /* sq_repeat */
13729+
_PyUnicode_Repeat, /* sq_repeat */
1373013730
unicode_getitem, /* sq_item */
1373113731
0, /* sq_slice */
1373213732
0, /* sq_ass_item */

Python/specialize.c

Lines changed: 35 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2122,54 +2122,64 @@ is_compactlong(PyObject *v)
21222122
_PyLong_IsCompact((PyLongObject *)v);
21232123
}
21242124

2125-
/* sequence * int helpers: bypass PyNumber_Multiply dispatch overhead
2126-
by calling sq_repeat directly with PyLong_AsSsize_t. */
2127-
2128-
static inline PyObject *
2129-
seq_int_multiply(PyObject *seq, PyObject *n,
2130-
ssizeargfunc repeat)
2125+
static PyObject *
2126+
str_int_multiply(PyObject *lhs, PyObject *rhs)
21312127
{
2132-
Py_ssize_t count = PyLong_AsSsize_t(n);
2128+
Py_ssize_t count = PyLong_AsSsize_t(rhs);
21332129
if (count == -1 && PyErr_Occurred()) {
21342130
return NULL;
21352131
}
2136-
return repeat(seq, count);
2137-
}
2138-
2139-
static PyObject *
2140-
str_int_multiply(PyObject *lhs, PyObject *rhs)
2141-
{
2142-
return seq_int_multiply(lhs, rhs, PyUnicode_Type.tp_as_sequence->sq_repeat);
2132+
return _PyUnicode_Repeat(lhs, count);
21432133
}
21442134

21452135
static PyObject *
21462136
int_str_multiply(PyObject *lhs, PyObject *rhs)
21472137
{
2148-
return seq_int_multiply(rhs, lhs, PyUnicode_Type.tp_as_sequence->sq_repeat);
2138+
Py_ssize_t count = PyLong_AsSsize_t(lhs);
2139+
if (count == -1 && PyErr_Occurred()) {
2140+
return NULL;
2141+
}
2142+
return _PyUnicode_Repeat(rhs, count);
21492143
}
21502144

21512145
static PyObject *
21522146
bytes_int_multiply(PyObject *lhs, PyObject *rhs)
21532147
{
2154-
return seq_int_multiply(lhs, rhs, PyBytes_Type.tp_as_sequence->sq_repeat);
2148+
Py_ssize_t count = PyLong_AsSsize_t(rhs);
2149+
if (count == -1 && PyErr_Occurred()) {
2150+
return NULL;
2151+
}
2152+
return _PyBytes_Repeat(lhs, count);
21552153
}
21562154

21572155
static PyObject *
21582156
int_bytes_multiply(PyObject *lhs, PyObject *rhs)
21592157
{
2160-
return seq_int_multiply(rhs, lhs, PyBytes_Type.tp_as_sequence->sq_repeat);
2158+
Py_ssize_t count = PyLong_AsSsize_t(lhs);
2159+
if (count == -1 && PyErr_Occurred()) {
2160+
return NULL;
2161+
}
2162+
return _PyBytes_Repeat(rhs, count);
21612163
}
21622164

21632165
static PyObject *
21642166
tuple_int_multiply(PyObject *lhs, PyObject *rhs)
21652167
{
2166-
return seq_int_multiply(lhs, rhs, PyTuple_Type.tp_as_sequence->sq_repeat);
2168+
Py_ssize_t count = PyLong_AsSsize_t(rhs);
2169+
if (count == -1 && PyErr_Occurred()) {
2170+
return NULL;
2171+
}
2172+
return _PyTuple_Repeat(lhs, count);
21672173
}
21682174

21692175
static PyObject *
21702176
int_tuple_multiply(PyObject *lhs, PyObject *rhs)
21712177
{
2172-
return seq_int_multiply(rhs, lhs, PyTuple_Type.tp_as_sequence->sq_repeat);
2178+
Py_ssize_t count = PyLong_AsSsize_t(lhs);
2179+
if (count == -1 && PyErr_Occurred()) {
2180+
return NULL;
2181+
}
2182+
return _PyTuple_Repeat(rhs, count);
21732183
}
21742184

21752185
static int
@@ -2290,8 +2300,8 @@ static _PyBinaryOpSpecializationDescr binaryop_extend_descrs[] = {
22902300
to be a freshly allocated object. */
22912301
{NB_ADD, NULL, _PyTuple_Concat, &PyTuple_Type, 0, &PyTuple_Type, &PyTuple_Type},
22922302

2293-
/* str * int / int * str: call unicode_repeat directly.
2294-
unicode_repeat returns the original when n == 1. */
2303+
/* str * int / int * str: call _PyUnicode_Repeat directly.
2304+
_PyUnicode_Repeat returns the original when n == 1. */
22952305
{NB_MULTIPLY, NULL, str_int_multiply, &PyUnicode_Type, 0, &PyUnicode_Type, &PyLong_Type},
22962306
{NB_MULTIPLY, NULL, int_str_multiply, &PyUnicode_Type, 0, &PyLong_Type, &PyUnicode_Type},
22972307
{NB_INPLACE_MULTIPLY, NULL, str_int_multiply, &PyUnicode_Type, 0, &PyUnicode_Type, &PyLong_Type},
@@ -2302,15 +2312,15 @@ static _PyBinaryOpSpecializationDescr binaryop_extend_descrs[] = {
23022312
{NB_ADD, NULL, _PyBytes_Concat, &PyBytes_Type, 0, &PyBytes_Type, &PyBytes_Type},
23032313
{NB_INPLACE_ADD, NULL, _PyBytes_Concat, &PyBytes_Type, 0, &PyBytes_Type, &PyBytes_Type},
23042314

2305-
/* bytes * int / int * bytes: call bytes_repeat directly.
2306-
bytes_repeat returns the original when n == 1. */
2315+
/* bytes * int / int * bytes: call _PyBytes_Repeat directly.
2316+
_PyBytes_Repeat returns the original when n == 1. */
23072317
{NB_MULTIPLY, NULL, bytes_int_multiply, &PyBytes_Type, 0, &PyBytes_Type, &PyLong_Type},
23082318
{NB_MULTIPLY, NULL, int_bytes_multiply, &PyBytes_Type, 0, &PyLong_Type, &PyBytes_Type},
23092319
{NB_INPLACE_MULTIPLY, NULL, bytes_int_multiply, &PyBytes_Type, 0, &PyBytes_Type, &PyLong_Type},
23102320
{NB_INPLACE_MULTIPLY, NULL, int_bytes_multiply, &PyBytes_Type, 0, &PyLong_Type, &PyBytes_Type},
23112321

2312-
/* tuple * int / int * tuple: call tuple_repeat directly.
2313-
tuple_repeat returns the original when n == 1. */
2322+
/* tuple * int / int * tuple: call _PyTuple_Repeat directly.
2323+
_PyTuple_Repeat returns the original when n == 1. */
23142324
{NB_MULTIPLY, NULL, tuple_int_multiply, &PyTuple_Type, 0, &PyTuple_Type, &PyLong_Type},
23152325
{NB_MULTIPLY, NULL, int_tuple_multiply, &PyTuple_Type, 0, &PyLong_Type, &PyTuple_Type},
23162326
{NB_INPLACE_MULTIPLY, NULL, tuple_int_multiply, &PyTuple_Type, 0, &PyTuple_Type, &PyLong_Type},

0 commit comments

Comments
 (0)