Coverage Report

Created: 2025-10-10 06:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cpython/Objects/bytearrayobject.c
Line
Count
Source
1
/* PyByteArray (bytearray) implementation */
2
3
#include "Python.h"
4
#include "pycore_abstract.h"      // _PyIndex_Check()
5
#include "pycore_bytes_methods.h"
6
#include "pycore_bytesobject.h"
7
#include "pycore_ceval.h"         // _PyEval_GetBuiltin()
8
#include "pycore_critical_section.h"
9
#include "pycore_object.h"        // _PyObject_GC_UNTRACK()
10
#include "pycore_strhex.h"        // _Py_strhex_with_sep()
11
#include "pycore_long.h"          // _PyLong_FromUnsignedChar()
12
#include "pycore_pyatomic_ft_wrappers.h"
13
#include "bytesobject.h"
14
15
/*[clinic input]
16
class bytearray "PyByteArrayObject *" "&PyByteArray_Type"
17
[clinic start generated code]*/
18
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=5535b77c37a119e0]*/
19
20
/* For PyByteArray_AS_STRING(). */
21
char _PyByteArray_empty_string[] = "";
22
23
/* Helpers */
24
25
static int
26
_getbytevalue(PyObject* arg, int *value)
27
653k
{
28
653k
    int overflow;
29
653k
    long face_value = PyLong_AsLongAndOverflow(arg, &overflow);
30
31
653k
    if (face_value == -1 && PyErr_Occurred()) {
32
0
        *value = -1;
33
0
        return 0;
34
0
    }
35
653k
    if (face_value < 0 || face_value >= 256) {
36
        /* this includes an overflow in converting to C long */
37
0
        PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
38
0
        *value = -1;
39
0
        return 0;
40
0
    }
41
42
653k
    *value = face_value;
43
653k
    return 1;
44
653k
}
45
46
static int
47
bytearray_getbuffer_lock_held(PyObject *self, Py_buffer *view, int flags)
48
1.09M
{
49
1.09M
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(self);
50
1.09M
    PyByteArrayObject *obj = _PyByteArray_CAST(self);
51
1.09M
    if (view == NULL) {
52
0
        PyErr_SetString(PyExc_BufferError,
53
0
            "bytearray_getbuffer: view==NULL argument is obsolete");
54
0
        return -1;
55
0
    }
56
57
1.09M
    void *ptr = (void *) PyByteArray_AS_STRING(obj);
58
1.09M
    if (PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags) < 0) {
59
0
        return -1;
60
0
    }
61
1.09M
    obj->ob_exports++;
62
1.09M
    return 0;
63
1.09M
}
64
65
static int
66
bytearray_getbuffer(PyObject *self, Py_buffer *view, int flags)
67
1.09M
{
68
1.09M
    int ret;
69
1.09M
    Py_BEGIN_CRITICAL_SECTION(self);
70
1.09M
    ret = bytearray_getbuffer_lock_held(self, view, flags);
71
1.09M
    Py_END_CRITICAL_SECTION();
72
1.09M
    return ret;
73
1.09M
}
74
75
static void
76
bytearray_releasebuffer(PyObject *self, Py_buffer *view)
77
1.09M
{
78
1.09M
    Py_BEGIN_CRITICAL_SECTION(self);
79
1.09M
    PyByteArrayObject *obj = _PyByteArray_CAST(self);
80
1.09M
    obj->ob_exports--;
81
1.09M
    assert(obj->ob_exports >= 0);
82
1.09M
    Py_END_CRITICAL_SECTION();
83
1.09M
}
84
85
static int
86
_canresize(PyByteArrayObject *self)
87
6.06M
{
88
6.06M
    if (self->ob_exports > 0) {
89
0
        PyErr_SetString(PyExc_BufferError,
90
0
                "Existing exports of data: object cannot be re-sized");
91
0
        return 0;
92
0
    }
93
6.06M
    return 1;
94
6.06M
}
95
96
#include "clinic/bytearrayobject.c.h"
97
98
/* Direct API functions */
99
100
PyObject *
101
PyByteArray_FromObject(PyObject *input)
102
0
{
103
0
    return PyObject_CallOneArg((PyObject *)&PyByteArray_Type, input);
104
0
}
105
106
static PyObject *
107
_PyByteArray_FromBufferObject(PyObject *obj)
108
0
{
109
0
    PyObject *result;
110
0
    Py_buffer view;
111
112
0
    if (PyObject_GetBuffer(obj, &view, PyBUF_FULL_RO) < 0) {
113
0
        return NULL;
114
0
    }
115
0
    result = PyByteArray_FromStringAndSize(NULL, view.len);
116
0
    if (result != NULL &&
117
0
        PyBuffer_ToContiguous(PyByteArray_AS_STRING(result),
118
0
                              &view, view.len, 'C') < 0)
119
0
    {
120
0
        Py_CLEAR(result);
121
0
    }
122
0
    PyBuffer_Release(&view);
123
0
    return result;
124
0
}
125
126
PyObject *
127
PyByteArray_FromStringAndSize(const char *bytes, Py_ssize_t size)
128
2.83k
{
129
2.83k
    PyByteArrayObject *new;
130
2.83k
    Py_ssize_t alloc;
131
132
2.83k
    if (size < 0) {
133
0
        PyErr_SetString(PyExc_SystemError,
134
0
            "Negative size passed to PyByteArray_FromStringAndSize");
135
0
        return NULL;
136
0
    }
137
138
    /* Prevent buffer overflow when setting alloc to size+1. */
139
2.83k
    if (size == PY_SSIZE_T_MAX) {
140
0
        return PyErr_NoMemory();
141
0
    }
142
143
2.83k
    new = PyObject_New(PyByteArrayObject, &PyByteArray_Type);
144
2.83k
    if (new == NULL)
145
0
        return NULL;
146
147
2.83k
    if (size == 0) {
148
0
        new->ob_bytes = NULL;
149
0
        alloc = 0;
150
0
    }
151
2.83k
    else {
152
2.83k
        alloc = size + 1;
153
2.83k
        new->ob_bytes = PyMem_Malloc(alloc);
154
2.83k
        if (new->ob_bytes == NULL) {
155
0
            Py_DECREF(new);
156
0
            return PyErr_NoMemory();
157
0
        }
158
2.83k
        if (bytes != NULL && size > 0)
159
1.24k
            memcpy(new->ob_bytes, bytes, size);
160
2.83k
        new->ob_bytes[size] = '\0';  /* Trailing null byte */
161
2.83k
    }
162
2.83k
    Py_SET_SIZE(new, size);
163
2.83k
    new->ob_alloc = alloc;
164
2.83k
    new->ob_start = new->ob_bytes;
165
2.83k
    new->ob_exports = 0;
166
167
2.83k
    return (PyObject *)new;
168
2.83k
}
169
170
Py_ssize_t
171
PyByteArray_Size(PyObject *self)
172
0
{
173
0
    assert(self != NULL);
174
0
    assert(PyByteArray_Check(self));
175
176
0
    return PyByteArray_GET_SIZE(self);
177
0
}
178
179
char  *
180
PyByteArray_AsString(PyObject *self)
181
0
{
182
0
    assert(self != NULL);
183
0
    assert(PyByteArray_Check(self));
184
185
0
    return PyByteArray_AS_STRING(self);
186
0
}
187
188
static int
189
bytearray_resize_lock_held(PyObject *self, Py_ssize_t requested_size)
190
6.19M
{
191
6.19M
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(self);
192
6.19M
    void *sval;
193
6.19M
    PyByteArrayObject *obj = ((PyByteArrayObject *)self);
194
    /* All computations are done unsigned to avoid integer overflows
195
       (see issue #22335). */
196
6.19M
    size_t alloc = (size_t) obj->ob_alloc;
197
6.19M
    size_t logical_offset = (size_t) (obj->ob_start - obj->ob_bytes);
198
6.19M
    size_t size = (size_t) requested_size;
199
200
6.19M
    assert(self != NULL);
201
6.19M
    assert(PyByteArray_Check(self));
202
6.19M
    assert(logical_offset <= alloc);
203
204
6.19M
    if (requested_size < 0) {
205
0
        PyErr_Format(PyExc_ValueError,
206
0
            "Can only resize to positive sizes, got %zd", requested_size);
207
0
        return -1;
208
0
    }
209
210
6.19M
    if (requested_size == Py_SIZE(self)) {
211
129k
        return 0;
212
129k
    }
213
6.06M
    if (!_canresize(obj)) {
214
0
        return -1;
215
0
    }
216
217
6.06M
    if (size + logical_offset + 1 <= alloc) {
218
        /* Current buffer is large enough to host the requested size,
219
           decide on a strategy. */
220
4.18M
        if (size < alloc / 2) {
221
            /* Major downsize; resize down to exact size */
222
0
            alloc = size + 1;
223
0
        }
224
4.18M
        else {
225
            /* Minor downsize; quick exit */
226
4.18M
            Py_SET_SIZE(self, size);
227
4.18M
            PyByteArray_AS_STRING(self)[size] = '\0'; /* Trailing null */
228
4.18M
            return 0;
229
4.18M
        }
230
4.18M
    }
231
1.88M
    else {
232
        /* Need growing, decide on a strategy */
233
1.88M
        if (size <= alloc * 1.125) {
234
            /* Moderate upsize; overallocate similar to list_resize() */
235
760k
            alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
236
760k
        }
237
1.12M
        else {
238
            /* Major upsize; resize up to exact size */
239
1.12M
            alloc = size + 1;
240
1.12M
        }
241
1.88M
    }
242
1.88M
    if (alloc > PY_SSIZE_T_MAX) {
243
0
        PyErr_NoMemory();
244
0
        return -1;
245
0
    }
246
247
1.88M
    if (logical_offset > 0) {
248
0
        sval = PyMem_Malloc(alloc);
249
0
        if (sval == NULL) {
250
0
            PyErr_NoMemory();
251
0
            return -1;
252
0
        }
253
0
        memcpy(sval, PyByteArray_AS_STRING(self),
254
0
               Py_MIN((size_t)requested_size, (size_t)Py_SIZE(self)));
255
0
        PyMem_Free(obj->ob_bytes);
256
0
    }
257
1.88M
    else {
258
1.88M
        sval = PyMem_Realloc(obj->ob_bytes, alloc);
259
1.88M
        if (sval == NULL) {
260
0
            PyErr_NoMemory();
261
0
            return -1;
262
0
        }
263
1.88M
    }
264
265
1.88M
    obj->ob_bytes = obj->ob_start = sval;
266
1.88M
    Py_SET_SIZE(self, size);
267
1.88M
    FT_ATOMIC_STORE_SSIZE_RELAXED(obj->ob_alloc, alloc);
268
1.88M
    obj->ob_bytes[size] = '\0'; /* Trailing null byte */
269
270
1.88M
    return 0;
271
1.88M
}
272
273
int
274
PyByteArray_Resize(PyObject *self, Py_ssize_t requested_size)
275
623k
{
276
623k
    int ret;
277
623k
    Py_BEGIN_CRITICAL_SECTION(self);
278
623k
    ret = bytearray_resize_lock_held(self, requested_size);
279
623k
    Py_END_CRITICAL_SECTION();
280
623k
    return ret;
281
623k
}
282
283
PyObject *
284
PyByteArray_Concat(PyObject *a, PyObject *b)
285
0
{
286
0
    Py_buffer va, vb;
287
0
    PyByteArrayObject *result = NULL;
288
289
0
    va.len = -1;
290
0
    vb.len = -1;
291
0
    if (PyObject_GetBuffer(a, &va, PyBUF_SIMPLE) != 0 ||
292
0
        PyObject_GetBuffer(b, &vb, PyBUF_SIMPLE) != 0) {
293
0
            PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
294
0
                         Py_TYPE(b)->tp_name, Py_TYPE(a)->tp_name);
295
0
            goto done;
296
0
    }
297
298
0
    if (va.len > PY_SSIZE_T_MAX - vb.len) {
299
0
        PyErr_NoMemory();
300
0
        goto done;
301
0
    }
302
303
0
    result = (PyByteArrayObject *) \
304
0
        PyByteArray_FromStringAndSize(NULL, va.len + vb.len);
305
    // result->ob_bytes is NULL if result is an empty bytearray:
306
    // if va.len + vb.len equals zero.
307
0
    if (result != NULL && result->ob_bytes != NULL) {
308
0
        memcpy(result->ob_bytes, va.buf, va.len);
309
0
        memcpy(result->ob_bytes + va.len, vb.buf, vb.len);
310
0
    }
311
312
0
  done:
313
0
    if (va.len != -1)
314
0
        PyBuffer_Release(&va);
315
0
    if (vb.len != -1)
316
0
        PyBuffer_Release(&vb);
317
0
    return (PyObject *)result;
318
0
}
319
320
/* Functions stuffed into the type object */
321
322
static Py_ssize_t
323
bytearray_length(PyObject *op)
324
544
{
325
544
    return PyByteArray_GET_SIZE(op);
326
544
}
327
328
static PyObject *
329
bytearray_iconcat_lock_held(PyObject *op, PyObject *other)
330
20
{
331
20
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
332
20
    PyByteArrayObject *self = _PyByteArray_CAST(op);
333
334
20
    Py_buffer vo;
335
20
    if (PyObject_GetBuffer(other, &vo, PyBUF_SIMPLE) != 0) {
336
0
        PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
337
0
                     Py_TYPE(other)->tp_name, Py_TYPE(self)->tp_name);
338
0
        return NULL;
339
0
    }
340
341
20
    Py_ssize_t size = Py_SIZE(self);
342
20
    if (size > PY_SSIZE_T_MAX - vo.len) {
343
0
        PyBuffer_Release(&vo);
344
0
        return PyErr_NoMemory();
345
0
    }
346
347
20
    if (bytearray_resize_lock_held((PyObject *)self, size + vo.len) < 0) {
348
0
        PyBuffer_Release(&vo);
349
0
        return NULL;
350
0
    }
351
352
20
    memcpy(PyByteArray_AS_STRING(self) + size, vo.buf, vo.len);
353
20
    PyBuffer_Release(&vo);
354
20
    return Py_NewRef(self);
355
20
}
356
357
static PyObject *
358
bytearray_iconcat(PyObject *op, PyObject *other)
359
20
{
360
20
    PyObject *ret;
361
20
    Py_BEGIN_CRITICAL_SECTION(op);
362
20
    ret = bytearray_iconcat_lock_held(op, other);
363
20
    Py_END_CRITICAL_SECTION();
364
20
    return ret;
365
20
}
366
367
static PyObject *
368
bytearray_repeat_lock_held(PyObject *op, Py_ssize_t count)
369
0
{
370
0
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
371
0
    PyByteArrayObject *self = _PyByteArray_CAST(op);
372
0
    if (count < 0) {
373
0
        count = 0;
374
0
    }
375
0
    const Py_ssize_t mysize = Py_SIZE(self);
376
0
    if (count > 0 && mysize > PY_SSIZE_T_MAX / count) {
377
0
        return PyErr_NoMemory();
378
0
    }
379
0
    Py_ssize_t size = mysize * count;
380
381
0
    PyByteArrayObject* result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size);
382
0
    const char* buf = PyByteArray_AS_STRING(self);
383
0
    if (result != NULL && size != 0) {
384
0
        _PyBytes_Repeat(result->ob_bytes, size, buf, mysize);
385
0
    }
386
0
    return (PyObject *)result;
387
0
}
388
389
static PyObject *
390
bytearray_repeat(PyObject *op, Py_ssize_t count)
391
0
{
392
0
    PyObject *ret;
393
0
    Py_BEGIN_CRITICAL_SECTION(op);
394
0
    ret = bytearray_repeat_lock_held(op, count);
395
0
    Py_END_CRITICAL_SECTION();
396
0
    return ret;
397
0
}
398
399
static PyObject *
400
bytearray_irepeat_lock_held(PyObject *op, Py_ssize_t count)
401
0
{
402
0
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
403
0
    PyByteArrayObject *self = _PyByteArray_CAST(op);
404
0
    if (count < 0) {
405
0
        count = 0;
406
0
    }
407
0
    else if (count == 1) {
408
0
        return Py_NewRef(self);
409
0
    }
410
411
0
    const Py_ssize_t mysize = Py_SIZE(self);
412
0
    if (count > 0 && mysize > PY_SSIZE_T_MAX / count) {
413
0
        return PyErr_NoMemory();
414
0
    }
415
0
    const Py_ssize_t size = mysize * count;
416
0
    if (bytearray_resize_lock_held((PyObject *)self, size) < 0) {
417
0
        return NULL;
418
0
    }
419
420
0
    char* buf = PyByteArray_AS_STRING(self);
421
0
    _PyBytes_Repeat(buf, size, buf, mysize);
422
423
0
    return Py_NewRef(self);
424
0
}
425
426
static PyObject *
427
bytearray_irepeat(PyObject *op, Py_ssize_t count)
428
0
{
429
0
    PyObject *ret;
430
0
    Py_BEGIN_CRITICAL_SECTION(op);
431
0
    ret = bytearray_irepeat_lock_held(op, count);
432
0
    Py_END_CRITICAL_SECTION();
433
0
    return ret;
434
0
}
435
436
static PyObject *
437
bytearray_getitem_lock_held(PyObject *op, Py_ssize_t i)
438
0
{
439
0
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
440
0
    PyByteArrayObject *self = _PyByteArray_CAST(op);
441
0
    if (i < 0 || i >= Py_SIZE(self)) {
442
0
        PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
443
0
        return NULL;
444
0
    }
445
0
    return _PyLong_FromUnsignedChar((unsigned char)(self->ob_start[i]));
446
0
}
447
448
static PyObject *
449
bytearray_getitem(PyObject *op, Py_ssize_t i)
450
0
{
451
0
    PyObject *ret;
452
0
    Py_BEGIN_CRITICAL_SECTION(op);
453
0
    ret = bytearray_getitem_lock_held(op, i);
454
0
    Py_END_CRITICAL_SECTION();
455
0
    return ret;
456
0
}
457
458
static PyObject *
459
bytearray_subscript_lock_held(PyObject *op, PyObject *index)
460
1.39k
{
461
1.39k
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
462
1.39k
    PyByteArrayObject *self = _PyByteArray_CAST(op);
463
1.39k
    if (_PyIndex_Check(index)) {
464
0
        Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
465
466
0
        if (i == -1 && PyErr_Occurred())
467
0
            return NULL;
468
469
0
        if (i < 0)
470
0
            i += PyByteArray_GET_SIZE(self);
471
472
0
        if (i < 0 || i >= Py_SIZE(self)) {
473
0
            PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
474
0
            return NULL;
475
0
        }
476
0
        return _PyLong_FromUnsignedChar((unsigned char)(self->ob_start[i]));
477
0
    }
478
1.39k
    else if (PySlice_Check(index)) {
479
1.39k
        Py_ssize_t start, stop, step, slicelength, i;
480
1.39k
        size_t cur;
481
1.39k
        if (PySlice_Unpack(index, &start, &stop, &step) < 0) {
482
0
            return NULL;
483
0
        }
484
1.39k
        slicelength = PySlice_AdjustIndices(PyByteArray_GET_SIZE(self),
485
1.39k
                                            &start, &stop, step);
486
487
1.39k
        if (slicelength <= 0)
488
0
            return PyByteArray_FromStringAndSize("", 0);
489
1.39k
        else if (step == 1) {
490
1.24k
            return PyByteArray_FromStringAndSize(
491
1.24k
                PyByteArray_AS_STRING(self) + start, slicelength);
492
1.24k
        }
493
144
        else {
494
144
            char *source_buf = PyByteArray_AS_STRING(self);
495
144
            char *result_buf;
496
144
            PyObject *result;
497
498
144
            result = PyByteArray_FromStringAndSize(NULL, slicelength);
499
144
            if (result == NULL)
500
0
                return NULL;
501
502
144
            result_buf = PyByteArray_AS_STRING(result);
503
40.0k
            for (cur = start, i = 0; i < slicelength;
504
39.9k
                 cur += step, i++) {
505
39.9k
                     result_buf[i] = source_buf[cur];
506
39.9k
            }
507
144
            return result;
508
144
        }
509
1.39k
    }
510
0
    else {
511
0
        PyErr_Format(PyExc_TypeError,
512
0
                     "bytearray indices must be integers or slices, not %.200s",
513
0
                     Py_TYPE(index)->tp_name);
514
0
        return NULL;
515
0
    }
516
1.39k
}
517
518
static PyObject *
519
bytearray_subscript(PyObject *op, PyObject *index)
520
1.39k
{
521
1.39k
    PyObject *ret;
522
1.39k
    Py_BEGIN_CRITICAL_SECTION(op);
523
1.39k
    ret = bytearray_subscript_lock_held(op, index);
524
1.39k
    Py_END_CRITICAL_SECTION();
525
1.39k
    return ret;
526
527
1.39k
}
528
529
static int
530
bytearray_setslice_linear(PyByteArrayObject *self,
531
                          Py_ssize_t lo, Py_ssize_t hi,
532
                          char *bytes, Py_ssize_t bytes_len)
533
9.13M
{
534
9.13M
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(self);
535
9.13M
    Py_ssize_t avail = hi - lo;
536
9.13M
    char *buf = PyByteArray_AS_STRING(self);
537
9.13M
    Py_ssize_t growth = bytes_len - avail;
538
9.13M
    int res = 0;
539
9.13M
    assert(avail >= 0);
540
541
9.13M
    if (growth < 0) {
542
0
        if (!_canresize(self))
543
0
            return -1;
544
545
0
        if (lo == 0) {
546
            /* Shrink the buffer by advancing its logical start */
547
0
            self->ob_start -= growth;
548
            /*
549
              0   lo               hi             old_size
550
              |   |<----avail----->|<-----tail------>|
551
              |      |<-bytes_len->|<-----tail------>|
552
              0    new_lo         new_hi          new_size
553
            */
554
0
        }
555
0
        else {
556
            /*
557
              0   lo               hi               old_size
558
              |   |<----avail----->|<-----tomove------>|
559
              |   |<-bytes_len->|<-----tomove------>|
560
              0   lo         new_hi              new_size
561
            */
562
0
            memmove(buf + lo + bytes_len, buf + hi,
563
0
                    Py_SIZE(self) - hi);
564
0
        }
565
0
        if (bytearray_resize_lock_held((PyObject *)self,
566
0
                               Py_SIZE(self) + growth) < 0) {
567
            /* Issue #19578: Handling the memory allocation failure here is
568
               tricky here because the bytearray object has already been
569
               modified. Depending on growth and lo, the behaviour is
570
               different.
571
572
               If growth < 0 and lo != 0, the operation is completed, but a
573
               MemoryError is still raised and the memory block is not
574
               shrunk. Otherwise, the bytearray is restored in its previous
575
               state and a MemoryError is raised. */
576
0
            if (lo == 0) {
577
0
                self->ob_start += growth;
578
0
                return -1;
579
0
            }
580
            /* memmove() removed bytes, the bytearray object cannot be
581
               restored in its previous state. */
582
0
            Py_SET_SIZE(self, Py_SIZE(self) + growth);
583
0
            res = -1;
584
0
        }
585
0
        buf = PyByteArray_AS_STRING(self);
586
0
    }
587
9.13M
    else if (growth > 0) {
588
4.92M
        if (Py_SIZE(self) > (Py_ssize_t)PY_SSIZE_T_MAX - growth) {
589
0
            PyErr_NoMemory();
590
0
            return -1;
591
0
        }
592
593
4.92M
        if (bytearray_resize_lock_held((PyObject *)self,
594
4.92M
                               Py_SIZE(self) + growth) < 0) {
595
0
            return -1;
596
0
        }
597
4.92M
        buf = PyByteArray_AS_STRING(self);
598
        /* Make the place for the additional bytes */
599
        /*
600
          0   lo        hi               old_size
601
          |   |<-avail->|<-----tomove------>|
602
          |   |<---bytes_len-->|<-----tomove------>|
603
          0   lo            new_hi              new_size
604
         */
605
4.92M
        memmove(buf + lo + bytes_len, buf + hi,
606
4.92M
                Py_SIZE(self) - lo - bytes_len);
607
4.92M
    }
608
609
9.13M
    if (bytes_len > 0)
610
4.92M
        memcpy(buf + lo, bytes, bytes_len);
611
9.13M
    return res;
612
9.13M
}
613
614
static int
615
bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
616
               PyObject *values)
617
9.13M
{
618
9.13M
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(self);
619
9.13M
    Py_ssize_t needed;
620
9.13M
    void *bytes;
621
9.13M
    Py_buffer vbytes;
622
9.13M
    int res = 0;
623
624
9.13M
    vbytes.len = -1;
625
9.13M
    if (values == (PyObject *)self) {
626
        /* Make a copy and call this function recursively */
627
0
        int err;
628
0
        values = PyByteArray_FromStringAndSize(PyByteArray_AS_STRING(values),
629
0
                                               PyByteArray_GET_SIZE(values));
630
0
        if (values == NULL)
631
0
            return -1;
632
0
        err = bytearray_setslice(self, lo, hi, values);
633
0
        Py_DECREF(values);
634
0
        return err;
635
0
    }
636
9.13M
    if (values == NULL) {
637
        /* del b[lo:hi] */
638
0
        bytes = NULL;
639
0
        needed = 0;
640
0
    }
641
9.13M
    else {
642
9.13M
        if (PyObject_GetBuffer(values, &vbytes, PyBUF_SIMPLE) != 0) {
643
0
            PyErr_Format(PyExc_TypeError,
644
0
                         "can't set bytearray slice from %.100s",
645
0
                         Py_TYPE(values)->tp_name);
646
0
            return -1;
647
0
        }
648
9.13M
        needed = vbytes.len;
649
9.13M
        bytes = vbytes.buf;
650
9.13M
    }
651
652
9.13M
    if (lo < 0)
653
0
        lo = 0;
654
9.13M
    if (hi < lo)
655
0
        hi = lo;
656
9.13M
    if (hi > Py_SIZE(self))
657
0
        hi = Py_SIZE(self);
658
659
9.13M
    res = bytearray_setslice_linear(self, lo, hi, bytes, needed);
660
9.13M
    if (vbytes.len != -1)
661
9.13M
        PyBuffer_Release(&vbytes);
662
9.13M
    return res;
663
9.13M
}
664
665
static int
666
bytearray_setitem_lock_held(PyObject *op, Py_ssize_t i, PyObject *value)
667
0
{
668
0
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
669
0
    PyByteArrayObject *self = _PyByteArray_CAST(op);
670
671
    // GH-91153: We need to do this *before* the size check, in case value has a
672
    // nasty __index__ method that changes the size of the bytearray:
673
0
    int ival = -1;
674
0
    if (value && !_getbytevalue(value, &ival)) {
675
0
        return -1;
676
0
    }
677
678
0
    if (i < 0) {
679
0
        i += Py_SIZE(self);
680
0
    }
681
682
0
    if (i < 0 || i >= Py_SIZE(self)) {
683
0
        PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
684
0
        return -1;
685
0
    }
686
687
0
    if (value == NULL) {
688
0
        return bytearray_setslice(self, i, i+1, NULL);
689
0
    }
690
691
0
    assert(0 <= ival && ival < 256);
692
0
    PyByteArray_AS_STRING(self)[i] = ival;
693
0
    return 0;
694
0
}
695
696
static int
697
bytearray_setitem(PyObject *op, Py_ssize_t i, PyObject *value)
698
0
{
699
0
    int ret;
700
0
    Py_BEGIN_CRITICAL_SECTION(op);
701
0
    ret = bytearray_setitem_lock_held(op, i, value);
702
0
    Py_END_CRITICAL_SECTION();
703
0
    return ret;
704
0
}
705
706
static int
707
bytearray_ass_subscript_lock_held(PyObject *op, PyObject *index, PyObject *values)
708
8.76k
{
709
8.76k
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
710
8.76k
    PyByteArrayObject *self = _PyByteArray_CAST(op);
711
8.76k
    Py_ssize_t start, stop, step, slicelen;
712
    // Do not store a reference to the internal buffer since
713
    // index.__index__() or _getbytevalue() may alter 'self'.
714
    // See https://github.com/python/cpython/issues/91153.
715
716
8.76k
    if (_PyIndex_Check(index)) {
717
8.76k
        Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
718
719
8.76k
        if (i == -1 && PyErr_Occurred()) {
720
0
            return -1;
721
0
        }
722
723
8.76k
        int ival = -1;
724
725
        // GH-91153: We need to do this *before* the size check, in case values
726
        // has a nasty __index__ method that changes the size of the bytearray:
727
8.76k
        if (values && !_getbytevalue(values, &ival)) {
728
0
            return -1;
729
0
        }
730
731
8.76k
        if (i < 0) {
732
0
            i += PyByteArray_GET_SIZE(self);
733
0
        }
734
735
8.76k
        if (i < 0 || i >= Py_SIZE(self)) {
736
4
            PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
737
4
            return -1;
738
4
        }
739
740
8.75k
        if (values == NULL) {
741
            /* Fall through to slice assignment */
742
0
            start = i;
743
0
            stop = i + 1;
744
0
            step = 1;
745
0
            slicelen = 1;
746
0
        }
747
8.75k
        else {
748
8.75k
            assert(0 <= ival && ival < 256);
749
8.75k
            PyByteArray_AS_STRING(self)[i] = (char)ival;
750
8.75k
            return 0;
751
8.75k
        }
752
8.75k
    }
753
0
    else if (PySlice_Check(index)) {
754
0
        if (PySlice_Unpack(index, &start, &stop, &step) < 0) {
755
0
            return -1;
756
0
        }
757
0
        slicelen = PySlice_AdjustIndices(PyByteArray_GET_SIZE(self), &start,
758
0
                                         &stop, step);
759
0
    }
760
0
    else {
761
0
        PyErr_Format(PyExc_TypeError,
762
0
                     "bytearray indices must be integers or slices, not %.200s",
763
0
                      Py_TYPE(index)->tp_name);
764
0
        return -1;
765
0
    }
766
767
0
    char *bytes;
768
0
    Py_ssize_t needed;
769
0
    if (values == NULL) {
770
0
        bytes = NULL;
771
0
        needed = 0;
772
0
    }
773
0
    else if (values == (PyObject *)self || !PyByteArray_Check(values)) {
774
0
        int err;
775
0
        if (PyNumber_Check(values) || PyUnicode_Check(values)) {
776
0
            PyErr_SetString(PyExc_TypeError,
777
0
                            "can assign only bytes, buffers, or iterables "
778
0
                            "of ints in range(0, 256)");
779
0
            return -1;
780
0
        }
781
        /* Make a copy and call this function recursively */
782
0
        values = PyByteArray_FromObject(values);
783
0
        if (values == NULL)
784
0
            return -1;
785
0
        err = bytearray_ass_subscript_lock_held((PyObject*)self, index, values);
786
0
        Py_DECREF(values);
787
0
        return err;
788
0
    }
789
0
    else {
790
0
        assert(PyByteArray_Check(values));
791
0
        bytes = PyByteArray_AS_STRING(values);
792
0
        needed = Py_SIZE(values);
793
0
    }
794
795
    /* Make sure b[5:2] = ... inserts before 5, not before 2. */
796
0
    if ((step < 0 && start < stop) ||
797
0
        (step > 0 && start > stop))
798
0
    {
799
0
        stop = start;
800
0
    }
801
802
0
    if (step == 1) {
803
0
        return bytearray_setslice_linear(self, start, stop, bytes, needed);
804
0
    }
805
0
    else {
806
0
        if (needed == 0) {
807
            /* Delete slice */
808
0
            size_t cur;
809
0
            Py_ssize_t i;
810
0
            char *buf = PyByteArray_AS_STRING(self);
811
812
0
            if (!_canresize(self))
813
0
                return -1;
814
815
0
            if (slicelen == 0)
816
                /* Nothing to do here. */
817
0
                return 0;
818
819
0
            if (step < 0) {
820
0
                stop = start + 1;
821
0
                start = stop + step * (slicelen - 1) - 1;
822
0
                step = -step;
823
0
            }
824
0
            for (cur = start, i = 0;
825
0
                 i < slicelen; cur += step, i++) {
826
0
                Py_ssize_t lim = step - 1;
827
828
0
                if (cur + step >= (size_t)PyByteArray_GET_SIZE(self))
829
0
                    lim = PyByteArray_GET_SIZE(self) - cur - 1;
830
831
0
                memmove(buf + cur - i,
832
0
                        buf + cur + 1, lim);
833
0
            }
834
            /* Move the tail of the bytes, in one chunk */
835
0
            cur = start + (size_t)slicelen*step;
836
0
            if (cur < (size_t)PyByteArray_GET_SIZE(self)) {
837
0
                memmove(buf + cur - slicelen,
838
0
                        buf + cur,
839
0
                        PyByteArray_GET_SIZE(self) - cur);
840
0
            }
841
0
            if (bytearray_resize_lock_held((PyObject *)self,
842
0
                               PyByteArray_GET_SIZE(self) - slicelen) < 0)
843
0
                return -1;
844
845
0
            return 0;
846
0
        }
847
0
        else {
848
            /* Assign slice */
849
0
            Py_ssize_t i;
850
0
            size_t cur;
851
0
            char *buf = PyByteArray_AS_STRING(self);
852
853
0
            if (needed != slicelen) {
854
0
                PyErr_Format(PyExc_ValueError,
855
0
                             "attempt to assign bytes of size %zd "
856
0
                             "to extended slice of size %zd",
857
0
                             needed, slicelen);
858
0
                return -1;
859
0
            }
860
0
            for (cur = start, i = 0; i < slicelen; cur += step, i++)
861
0
                buf[cur] = bytes[i];
862
0
            return 0;
863
0
        }
864
0
    }
865
0
}
866
867
static int
868
bytearray_ass_subscript(PyObject *op, PyObject *index, PyObject *values)
869
8.76k
{
870
8.76k
    int ret;
871
8.76k
    if (values != NULL && PyByteArray_Check(values)) {
872
0
        Py_BEGIN_CRITICAL_SECTION2(op, values);
873
0
        ret = bytearray_ass_subscript_lock_held(op, index, values);
874
0
        Py_END_CRITICAL_SECTION2();
875
0
    }
876
8.76k
    else {
877
8.76k
        Py_BEGIN_CRITICAL_SECTION(op);
878
8.76k
        ret = bytearray_ass_subscript_lock_held(op, index, values);
879
8.76k
        Py_END_CRITICAL_SECTION();
880
8.76k
    }
881
8.76k
    return ret;
882
8.76k
}
883
884
/*[clinic input]
885
bytearray.__init__
886
887
    source as arg: object = NULL
888
    encoding: str = NULL
889
    errors: str = NULL
890
891
[clinic start generated code]*/
892
893
static int
894
bytearray___init___impl(PyByteArrayObject *self, PyObject *arg,
895
                        const char *encoding, const char *errors)
896
/*[clinic end generated code: output=4ce1304649c2f8b3 input=1141a7122eefd7b9]*/
897
1.09M
{
898
1.09M
    Py_ssize_t count;
899
1.09M
    PyObject *it;
900
1.09M
    PyObject *(*iternext)(PyObject *);
901
902
1.09M
    if (Py_SIZE(self) != 0) {
903
        /* Empty previous contents (yes, do this first of all!) */
904
0
        if (PyByteArray_Resize((PyObject *)self, 0) < 0)
905
0
            return -1;
906
0
    }
907
908
    /* Make a quick exit if no first argument */
909
1.09M
    if (arg == NULL) {
910
471k
        if (encoding != NULL || errors != NULL) {
911
0
            PyErr_SetString(PyExc_TypeError,
912
0
                            encoding != NULL ?
913
0
                            "encoding without a string argument" :
914
0
                            "errors without a string argument");
915
0
            return -1;
916
0
        }
917
471k
        return 0;
918
471k
    }
919
920
623k
    if (PyUnicode_Check(arg)) {
921
        /* Encode via the codec registry */
922
0
        PyObject *encoded, *new;
923
0
        if (encoding == NULL) {
924
0
            PyErr_SetString(PyExc_TypeError,
925
0
                            "string argument without an encoding");
926
0
            return -1;
927
0
        }
928
0
        encoded = PyUnicode_AsEncodedString(arg, encoding, errors);
929
0
        if (encoded == NULL)
930
0
            return -1;
931
0
        assert(PyBytes_Check(encoded));
932
0
        new = bytearray_iconcat((PyObject*)self, encoded);
933
0
        Py_DECREF(encoded);
934
0
        if (new == NULL)
935
0
            return -1;
936
0
        Py_DECREF(new);
937
0
        return 0;
938
0
    }
939
940
    /* If it's not unicode, there can't be encoding or errors */
941
623k
    if (encoding != NULL || errors != NULL) {
942
0
        PyErr_SetString(PyExc_TypeError,
943
0
                        encoding != NULL ?
944
0
                        "encoding without a string argument" :
945
0
                        "errors without a string argument");
946
0
        return -1;
947
0
    }
948
949
    /* Is it an int? */
950
623k
    if (_PyIndex_Check(arg)) {
951
406
        count = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
952
406
        if (count == -1 && PyErr_Occurred()) {
953
0
            if (!PyErr_ExceptionMatches(PyExc_TypeError))
954
0
                return -1;
955
0
            PyErr_Clear();  /* fall through */
956
0
        }
957
406
        else {
958
406
            if (count < 0) {
959
0
                PyErr_SetString(PyExc_ValueError, "negative count");
960
0
                return -1;
961
0
            }
962
406
            if (count > 0) {
963
406
                if (PyByteArray_Resize((PyObject *)self, count))
964
0
                    return -1;
965
406
                memset(PyByteArray_AS_STRING(self), 0, count);
966
406
            }
967
406
            return 0;
968
406
        }
969
406
    }
970
971
    /* Use the buffer API */
972
623k
    if (PyObject_CheckBuffer(arg)) {
973
623k
        Py_ssize_t size;
974
623k
        Py_buffer view;
975
623k
        if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0)
976
0
            return -1;
977
623k
        size = view.len;
978
623k
        if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
979
623k
        if (PyBuffer_ToContiguous(PyByteArray_AS_STRING(self),
980
623k
            &view, size, 'C') < 0)
981
0
            goto fail;
982
623k
        PyBuffer_Release(&view);
983
623k
        return 0;
984
0
    fail:
985
0
        PyBuffer_Release(&view);
986
0
        return -1;
987
623k
    }
988
989
0
    if (PyList_CheckExact(arg) || PyTuple_CheckExact(arg)) {
990
0
        Py_ssize_t size = PySequence_Fast_GET_SIZE(arg);
991
0
        if (PyByteArray_Resize((PyObject *)self, size) < 0) {
992
0
            return -1;
993
0
        }
994
0
        PyObject **items = PySequence_Fast_ITEMS(arg);
995
0
        char *s = PyByteArray_AS_STRING(self);
996
0
        for (Py_ssize_t i = 0; i < size; i++) {
997
0
            int value;
998
0
            if (!PyLong_CheckExact(items[i])) {
999
                /* Resize to 0 and go through slowpath */
1000
0
                if (Py_SIZE(self) != 0) {
1001
0
                   if (PyByteArray_Resize((PyObject *)self, 0) < 0) {
1002
0
                       return -1;
1003
0
                   }
1004
0
                }
1005
0
                goto slowpath;
1006
0
            }
1007
0
            int rc = _getbytevalue(items[i], &value);
1008
0
            if (!rc) {
1009
0
                return -1;
1010
0
            }
1011
0
            s[i] = value;
1012
0
        }
1013
0
        return 0;
1014
0
    }
1015
0
slowpath:
1016
    /* Get the iterator */
1017
0
    it = PyObject_GetIter(arg);
1018
0
    if (it == NULL) {
1019
0
        if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1020
0
            PyErr_Format(PyExc_TypeError,
1021
0
                         "cannot convert '%.200s' object to bytearray",
1022
0
                         Py_TYPE(arg)->tp_name);
1023
0
        }
1024
0
        return -1;
1025
0
    }
1026
0
    iternext = *Py_TYPE(it)->tp_iternext;
1027
1028
    /* Run the iterator to exhaustion */
1029
0
    for (;;) {
1030
0
        PyObject *item;
1031
0
        int rc, value;
1032
1033
        /* Get the next item */
1034
0
        item = iternext(it);
1035
0
        if (item == NULL) {
1036
0
            if (PyErr_Occurred()) {
1037
0
                if (!PyErr_ExceptionMatches(PyExc_StopIteration))
1038
0
                    goto error;
1039
0
                PyErr_Clear();
1040
0
            }
1041
0
            break;
1042
0
        }
1043
1044
        /* Interpret it as an int (__index__) */
1045
0
        rc = _getbytevalue(item, &value);
1046
0
        Py_DECREF(item);
1047
0
        if (!rc)
1048
0
            goto error;
1049
1050
        /* Append the byte */
1051
0
        if (Py_SIZE(self) + 1 < self->ob_alloc) {
1052
0
            Py_SET_SIZE(self, Py_SIZE(self) + 1);
1053
0
            PyByteArray_AS_STRING(self)[Py_SIZE(self)] = '\0';
1054
0
        }
1055
0
        else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0)
1056
0
            goto error;
1057
0
        PyByteArray_AS_STRING(self)[Py_SIZE(self)-1] = value;
1058
0
    }
1059
1060
    /* Clean up and return success */
1061
0
    Py_DECREF(it);
1062
0
    return 0;
1063
1064
0
 error:
1065
    /* Error handling when it != NULL */
1066
0
    Py_DECREF(it);
1067
0
    return -1;
1068
0
}
1069
1070
static PyObject *
1071
bytearray_repr_lock_held(PyObject *op)
1072
0
{
1073
0
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
1074
0
    const char *className = _PyType_Name(Py_TYPE(op));
1075
0
    PyObject *bytes_repr = _Py_bytes_repr(PyByteArray_AS_STRING(op),
1076
0
                                          PyByteArray_GET_SIZE(op), 1,
1077
0
                                          "bytearray");
1078
0
    if (bytes_repr == NULL) {
1079
0
        return NULL;
1080
0
    }
1081
0
    PyObject *res = PyUnicode_FromFormat("%s(%U)", className, bytes_repr);
1082
0
    Py_DECREF(bytes_repr);
1083
0
    return res;
1084
0
}
1085
1086
static PyObject *
1087
bytearray_repr(PyObject *op)
1088
0
{
1089
0
    PyObject *ret;
1090
0
    Py_BEGIN_CRITICAL_SECTION(op);
1091
0
    ret = bytearray_repr_lock_held(op);
1092
0
    Py_END_CRITICAL_SECTION();
1093
0
    return ret;
1094
0
}
1095
1096
static PyObject *
1097
bytearray_str(PyObject *op)
1098
0
{
1099
0
    if (_Py_GetConfig()->bytes_warning) {
1100
0
        if (PyErr_WarnEx(PyExc_BytesWarning,
1101
0
                         "str() on a bytearray instance", 1)) {
1102
0
                return NULL;
1103
0
        }
1104
0
    }
1105
0
    return bytearray_repr(op);
1106
0
}
1107
1108
static PyObject *
1109
bytearray_richcompare(PyObject *self, PyObject *other, int op)
1110
0
{
1111
0
    Py_ssize_t self_size, other_size;
1112
0
    Py_buffer self_bytes, other_bytes;
1113
0
    int cmp;
1114
1115
0
    if (!PyObject_CheckBuffer(self) || !PyObject_CheckBuffer(other)) {
1116
0
        if (PyUnicode_Check(self) || PyUnicode_Check(other)) {
1117
0
            if (_Py_GetConfig()->bytes_warning && (op == Py_EQ || op == Py_NE)) {
1118
0
                if (PyErr_WarnEx(PyExc_BytesWarning,
1119
0
                                "Comparison between bytearray and string", 1))
1120
0
                    return NULL;
1121
0
            }
1122
0
        }
1123
0
        Py_RETURN_NOTIMPLEMENTED;
1124
0
    }
1125
1126
    /* Bytearrays can be compared to anything that supports the buffer API. */
1127
0
    if (PyObject_GetBuffer(self, &self_bytes, PyBUF_SIMPLE) != 0) {
1128
0
        PyErr_Clear();
1129
0
        Py_RETURN_NOTIMPLEMENTED;
1130
0
    }
1131
0
    self_size = self_bytes.len;
1132
1133
0
    if (PyObject_GetBuffer(other, &other_bytes, PyBUF_SIMPLE) != 0) {
1134
0
        PyErr_Clear();
1135
0
        PyBuffer_Release(&self_bytes);
1136
0
        Py_RETURN_NOTIMPLEMENTED;
1137
0
    }
1138
0
    other_size = other_bytes.len;
1139
1140
0
    if (self_size != other_size && (op == Py_EQ || op == Py_NE)) {
1141
        /* Shortcut: if the lengths differ, the objects differ */
1142
0
        PyBuffer_Release(&self_bytes);
1143
0
        PyBuffer_Release(&other_bytes);
1144
0
        return PyBool_FromLong((op == Py_NE));
1145
0
    }
1146
0
    else {
1147
0
        cmp = memcmp(self_bytes.buf, other_bytes.buf,
1148
0
                     Py_MIN(self_size, other_size));
1149
        /* In ISO C, memcmp() guarantees to use unsigned bytes! */
1150
1151
0
        PyBuffer_Release(&self_bytes);
1152
0
        PyBuffer_Release(&other_bytes);
1153
1154
0
        if (cmp != 0) {
1155
0
            Py_RETURN_RICHCOMPARE(cmp, 0, op);
1156
0
        }
1157
1158
0
        Py_RETURN_RICHCOMPARE(self_size, other_size, op);
1159
0
    }
1160
1161
0
}
1162
1163
static void
1164
bytearray_dealloc(PyObject *op)
1165
1.09M
{
1166
1.09M
    PyByteArrayObject *self = _PyByteArray_CAST(op);
1167
1.09M
    if (self->ob_exports > 0) {
1168
0
        PyErr_SetString(PyExc_SystemError,
1169
0
                        "deallocated bytearray object has exported buffers");
1170
0
        PyErr_Print();
1171
0
    }
1172
1.09M
    if (self->ob_bytes != 0) {
1173
1.08M
        PyMem_Free(self->ob_bytes);
1174
1.08M
    }
1175
1.09M
    Py_TYPE(self)->tp_free((PyObject *)self);
1176
1.09M
}
1177
1178
1179
/* -------------------------------------------------------------------- */
1180
/* Methods */
1181
1182
#define STRINGLIB_IS_UNICODE 0
1183
0
#define FASTSEARCH fastsearch
1184
0
#define STRINGLIB(F) stringlib_##F
1185
0
#define STRINGLIB_CHAR char
1186
0
#define STRINGLIB_SIZEOF_CHAR 1
1187
0
#define STRINGLIB_LEN PyByteArray_GET_SIZE
1188
0
#define STRINGLIB_STR PyByteArray_AS_STRING
1189
0
#define STRINGLIB_NEW PyByteArray_FromStringAndSize
1190
0
#define STRINGLIB_ISSPACE Py_ISSPACE
1191
0
#define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r'))
1192
#define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact
1193
0
#define STRINGLIB_FAST_MEMCHR memchr
1194
#define STRINGLIB_MUTABLE 1
1195
1196
#include "stringlib/fastsearch.h"
1197
#include "stringlib/count.h"
1198
#include "stringlib/find.h"
1199
#include "stringlib/join.h"
1200
#include "stringlib/partition.h"
1201
#include "stringlib/split.h"
1202
#include "stringlib/ctype.h"
1203
#include "stringlib/transmogrify.h"
1204
1205
1206
/*[clinic input]
1207
@permit_long_summary
1208
@critical_section
1209
@text_signature "($self, sub[, start[, end]], /)"
1210
bytearray.find
1211
1212
    sub: object
1213
    start: slice_index(accept={int, NoneType}, c_default='0') = None
1214
         Optional start position. Default: start of the bytes.
1215
    end: slice_index(accept={int, NoneType}, c_default='PY_SSIZE_T_MAX') = None
1216
         Optional stop position. Default: end of the bytes.
1217
    /
1218
1219
Return the lowest index in B where subsection 'sub' is found, such that 'sub' is contained within B[start:end].
1220
1221
Return -1 on failure.
1222
[clinic start generated code]*/
1223
1224
static PyObject *
1225
bytearray_find_impl(PyByteArrayObject *self, PyObject *sub, Py_ssize_t start,
1226
                    Py_ssize_t end)
1227
/*[clinic end generated code: output=413e1cab2ae87da0 input=df3aa94840d893a7]*/
1228
1.71k
{
1229
1.71k
    return _Py_bytes_find(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1230
1.71k
                          sub, start, end);
1231
1.71k
}
1232
1233
/*[clinic input]
1234
@permit_long_summary
1235
@critical_section
1236
bytearray.count = bytearray.find
1237
1238
Return the number of non-overlapping occurrences of subsection 'sub' in bytes B[start:end].
1239
[clinic start generated code]*/
1240
1241
static PyObject *
1242
bytearray_count_impl(PyByteArrayObject *self, PyObject *sub,
1243
                     Py_ssize_t start, Py_ssize_t end)
1244
/*[clinic end generated code: output=a21ee2692e4f1233 input=e8fcdca8272857e0]*/
1245
0
{
1246
0
    return _Py_bytes_count(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1247
0
                           sub, start, end);
1248
0
}
1249
1250
/*[clinic input]
1251
bytearray.clear
1252
1253
Remove all items from the bytearray.
1254
[clinic start generated code]*/
1255
1256
static PyObject *
1257
bytearray_clear_impl(PyByteArrayObject *self)
1258
/*[clinic end generated code: output=85c2fe6aede0956c input=ed6edae9de447ac4]*/
1259
0
{
1260
0
    if (PyByteArray_Resize((PyObject *)self, 0) < 0)
1261
0
        return NULL;
1262
0
    Py_RETURN_NONE;
1263
0
}
1264
1265
/*[clinic input]
1266
@critical_section
1267
bytearray.copy
1268
1269
Return a copy of B.
1270
[clinic start generated code]*/
1271
1272
static PyObject *
1273
bytearray_copy_impl(PyByteArrayObject *self)
1274
/*[clinic end generated code: output=68cfbcfed484c132 input=b96f8b01f73851ad]*/
1275
0
{
1276
0
    return PyByteArray_FromStringAndSize(PyByteArray_AS_STRING((PyObject *)self),
1277
0
                                         PyByteArray_GET_SIZE(self));
1278
0
}
1279
1280
/*[clinic input]
1281
@permit_long_summary
1282
@critical_section
1283
bytearray.index = bytearray.find
1284
1285
Return the lowest index in B where subsection 'sub' is found, such that 'sub' is contained within B[start:end].
1286
1287
Raise ValueError if the subsection is not found.
1288
[clinic start generated code]*/
1289
1290
static PyObject *
1291
bytearray_index_impl(PyByteArrayObject *self, PyObject *sub,
1292
                     Py_ssize_t start, Py_ssize_t end)
1293
/*[clinic end generated code: output=067a1e78efc672a7 input=c37f177cfee19fe4]*/
1294
0
{
1295
0
    return _Py_bytes_index(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1296
0
                           sub, start, end);
1297
0
}
1298
1299
/*[clinic input]
1300
@permit_long_summary
1301
@critical_section
1302
bytearray.rfind = bytearray.find
1303
1304
Return the highest index in B where subsection 'sub' is found, such that 'sub' is contained within B[start:end].
1305
1306
Return -1 on failure.
1307
[clinic start generated code]*/
1308
1309
static PyObject *
1310
bytearray_rfind_impl(PyByteArrayObject *self, PyObject *sub,
1311
                     Py_ssize_t start, Py_ssize_t end)
1312
/*[clinic end generated code: output=51bf886f932b283c input=1265b11c437d2750]*/
1313
0
{
1314
0
    return _Py_bytes_rfind(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1315
0
                           sub, start, end);
1316
0
}
1317
1318
/*[clinic input]
1319
@permit_long_summary
1320
@critical_section
1321
bytearray.rindex = bytearray.find
1322
1323
Return the highest index in B where subsection 'sub' is found, such that 'sub' is contained within B[start:end].
1324
1325
Raise ValueError if the subsection is not found.
1326
[clinic start generated code]*/
1327
1328
static PyObject *
1329
bytearray_rindex_impl(PyByteArrayObject *self, PyObject *sub,
1330
                      Py_ssize_t start, Py_ssize_t end)
1331
/*[clinic end generated code: output=38e1cf66bafb08b9 input=7d198b3d6b0a62ce]*/
1332
0
{
1333
0
    return _Py_bytes_rindex(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1334
0
                            sub, start, end);
1335
0
}
1336
1337
static int
1338
bytearray_contains(PyObject *self, PyObject *arg)
1339
0
{
1340
0
    int ret;
1341
0
    Py_BEGIN_CRITICAL_SECTION(self);
1342
0
    ret = _Py_bytes_contains(PyByteArray_AS_STRING(self),
1343
0
                             PyByteArray_GET_SIZE(self),
1344
0
                             arg);
1345
0
    Py_END_CRITICAL_SECTION();
1346
0
    return ret;
1347
0
}
1348
1349
/*[clinic input]
1350
@permit_long_summary
1351
@critical_section
1352
@text_signature "($self, prefix[, start[, end]], /)"
1353
bytearray.startswith
1354
1355
    prefix as subobj: object
1356
        A bytes or a tuple of bytes to try.
1357
    start: slice_index(accept={int, NoneType}, c_default='0') = None
1358
        Optional start position. Default: start of the bytearray.
1359
    end: slice_index(accept={int, NoneType}, c_default='PY_SSIZE_T_MAX') = None
1360
        Optional stop position. Default: end of the bytearray.
1361
    /
1362
1363
Return True if the bytearray starts with the specified prefix, False otherwise.
1364
[clinic start generated code]*/
1365
1366
static PyObject *
1367
bytearray_startswith_impl(PyByteArrayObject *self, PyObject *subobj,
1368
                          Py_ssize_t start, Py_ssize_t end)
1369
/*[clinic end generated code: output=a3d9b6d44d3662a6 input=93f9ffee684f109a]*/
1370
0
{
1371
0
    return _Py_bytes_startswith(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1372
0
                                subobj, start, end);
1373
0
}
1374
1375
/*[clinic input]
1376
@permit_long_summary
1377
@critical_section
1378
@text_signature "($self, suffix[, start[, end]], /)"
1379
bytearray.endswith
1380
1381
    suffix as subobj: object
1382
        A bytes or a tuple of bytes to try.
1383
    start: slice_index(accept={int, NoneType}, c_default='0') = None
1384
         Optional start position. Default: start of the bytearray.
1385
    end: slice_index(accept={int, NoneType}, c_default='PY_SSIZE_T_MAX') = None
1386
         Optional stop position. Default: end of the bytearray.
1387
    /
1388
1389
Return True if the bytearray ends with the specified suffix, False otherwise.
1390
[clinic start generated code]*/
1391
1392
static PyObject *
1393
bytearray_endswith_impl(PyByteArrayObject *self, PyObject *subobj,
1394
                        Py_ssize_t start, Py_ssize_t end)
1395
/*[clinic end generated code: output=e75ea8c227954caa input=d158b030a11d0b06]*/
1396
0
{
1397
0
    return _Py_bytes_endswith(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1398
0
                              subobj, start, end);
1399
0
}
1400
1401
/*[clinic input]
1402
@critical_section
1403
bytearray.removeprefix as bytearray_removeprefix
1404
1405
    prefix: Py_buffer
1406
    /
1407
1408
Return a bytearray with the given prefix string removed if present.
1409
1410
If the bytearray starts with the prefix string, return
1411
bytearray[len(prefix):].  Otherwise, return a copy of the original
1412
bytearray.
1413
[clinic start generated code]*/
1414
1415
static PyObject *
1416
bytearray_removeprefix_impl(PyByteArrayObject *self, Py_buffer *prefix)
1417
/*[clinic end generated code: output=6cabc585e7f502e0 input=4323ba6d275fe7a8]*/
1418
0
{
1419
0
    const char *self_start = PyByteArray_AS_STRING(self);
1420
0
    Py_ssize_t self_len = PyByteArray_GET_SIZE(self);
1421
0
    const char *prefix_start = prefix->buf;
1422
0
    Py_ssize_t prefix_len = prefix->len;
1423
1424
0
    if (self_len >= prefix_len
1425
0
        && memcmp(self_start, prefix_start, prefix_len) == 0)
1426
0
    {
1427
0
        return PyByteArray_FromStringAndSize(self_start + prefix_len,
1428
0
                                             self_len - prefix_len);
1429
0
    }
1430
1431
0
    return PyByteArray_FromStringAndSize(self_start, self_len);
1432
0
}
1433
1434
/*[clinic input]
1435
@critical_section
1436
bytearray.removesuffix as bytearray_removesuffix
1437
1438
    suffix: Py_buffer
1439
    /
1440
1441
Return a bytearray with the given suffix string removed if present.
1442
1443
If the bytearray ends with the suffix string and that suffix is not
1444
empty, return bytearray[:-len(suffix)].  Otherwise, return a copy of
1445
the original bytearray.
1446
[clinic start generated code]*/
1447
1448
static PyObject *
1449
bytearray_removesuffix_impl(PyByteArrayObject *self, Py_buffer *suffix)
1450
/*[clinic end generated code: output=2bc8cfb79de793d3 input=f71ba2e1a40c47dd]*/
1451
0
{
1452
0
    const char *self_start = PyByteArray_AS_STRING(self);
1453
0
    Py_ssize_t self_len = PyByteArray_GET_SIZE(self);
1454
0
    const char *suffix_start = suffix->buf;
1455
0
    Py_ssize_t suffix_len = suffix->len;
1456
1457
0
    if (self_len >= suffix_len
1458
0
        && memcmp(self_start + self_len - suffix_len,
1459
0
                  suffix_start, suffix_len) == 0)
1460
0
    {
1461
0
        return PyByteArray_FromStringAndSize(self_start,
1462
0
                                             self_len - suffix_len);
1463
0
    }
1464
1465
0
    return PyByteArray_FromStringAndSize(self_start, self_len);
1466
0
}
1467
1468
1469
/*[clinic input]
1470
bytearray.resize
1471
    size: Py_ssize_t
1472
        New size to resize to..
1473
    /
1474
Resize the internal buffer of bytearray to len.
1475
[clinic start generated code]*/
1476
1477
static PyObject *
1478
bytearray_resize_impl(PyByteArrayObject *self, Py_ssize_t size)
1479
/*[clinic end generated code: output=f73524922990b2d9 input=75fd4d17c4aa47d3]*/
1480
0
{
1481
0
    Py_ssize_t start_size = PyByteArray_GET_SIZE(self);
1482
0
    int result = PyByteArray_Resize((PyObject *)self, size);
1483
0
    if (result < 0) {
1484
0
        return NULL;
1485
0
    }
1486
    // Set new bytes to null bytes
1487
0
    if (size > start_size) {
1488
0
        memset(PyByteArray_AS_STRING(self) + start_size, 0, size - start_size);
1489
0
    }
1490
0
    Py_RETURN_NONE;
1491
0
}
1492
1493
1494
/*[clinic input]
1495
@critical_section
1496
bytearray.translate
1497
1498
    table: object
1499
        Translation table, which must be a bytes object of length 256.
1500
    /
1501
    delete as deletechars: object(c_default="NULL") = b''
1502
1503
Return a copy with each character mapped by the given translation table.
1504
1505
All characters occurring in the optional argument delete are removed.
1506
The remaining characters are mapped through the given translation table.
1507
[clinic start generated code]*/
1508
1509
static PyObject *
1510
bytearray_translate_impl(PyByteArrayObject *self, PyObject *table,
1511
                         PyObject *deletechars)
1512
/*[clinic end generated code: output=b6a8f01c2a74e446 input=cd6fa93ca04e05bc]*/
1513
144
{
1514
144
    char *input, *output;
1515
144
    const char *table_chars;
1516
144
    Py_ssize_t i, c;
1517
144
    PyObject *input_obj = (PyObject*)self;
1518
144
    const char *output_start;
1519
144
    Py_ssize_t inlen;
1520
144
    PyObject *result = NULL;
1521
144
    int trans_table[256];
1522
144
    Py_buffer vtable, vdel;
1523
1524
144
    if (table == Py_None) {
1525
0
        table_chars = NULL;
1526
0
        table = NULL;
1527
144
    } else if (PyObject_GetBuffer(table, &vtable, PyBUF_SIMPLE) != 0) {
1528
0
        return NULL;
1529
144
    } else {
1530
144
        if (vtable.len != 256) {
1531
0
            PyErr_SetString(PyExc_ValueError,
1532
0
                            "translation table must be 256 characters long");
1533
0
            PyBuffer_Release(&vtable);
1534
0
            return NULL;
1535
0
        }
1536
144
        table_chars = (const char*)vtable.buf;
1537
144
    }
1538
1539
144
    if (deletechars != NULL) {
1540
0
        if (PyObject_GetBuffer(deletechars, &vdel, PyBUF_SIMPLE) != 0) {
1541
0
            if (table != NULL)
1542
0
                PyBuffer_Release(&vtable);
1543
0
            return NULL;
1544
0
        }
1545
0
    }
1546
144
    else {
1547
144
        vdel.buf = NULL;
1548
144
        vdel.len = 0;
1549
144
    }
1550
1551
144
    inlen = PyByteArray_GET_SIZE(input_obj);
1552
144
    result = PyByteArray_FromStringAndSize((char *)NULL, inlen);
1553
144
    if (result == NULL)
1554
0
        goto done;
1555
144
    output_start = output = PyByteArray_AS_STRING(result);
1556
144
    input = PyByteArray_AS_STRING(input_obj);
1557
1558
144
    if (vdel.len == 0 && table_chars != NULL) {
1559
        /* If no deletions are required, use faster code */
1560
40.0k
        for (i = inlen; --i >= 0; ) {
1561
39.9k
            c = Py_CHARMASK(*input++);
1562
39.9k
            *output++ = table_chars[c];
1563
39.9k
        }
1564
144
        goto done;
1565
144
    }
1566
1567
0
    if (table_chars == NULL) {
1568
0
        for (i = 0; i < 256; i++)
1569
0
            trans_table[i] = Py_CHARMASK(i);
1570
0
    } else {
1571
0
        for (i = 0; i < 256; i++)
1572
0
            trans_table[i] = Py_CHARMASK(table_chars[i]);
1573
0
    }
1574
1575
0
    for (i = 0; i < vdel.len; i++)
1576
0
        trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1;
1577
1578
0
    for (i = inlen; --i >= 0; ) {
1579
0
        c = Py_CHARMASK(*input++);
1580
0
        if (trans_table[c] != -1)
1581
0
            *output++ = (char)trans_table[c];
1582
0
    }
1583
    /* Fix the size of the resulting bytearray */
1584
0
    if (inlen > 0)
1585
0
        if (PyByteArray_Resize(result, output - output_start) < 0) {
1586
0
            Py_CLEAR(result);
1587
0
            goto done;
1588
0
        }
1589
1590
144
done:
1591
144
    if (table != NULL)
1592
144
        PyBuffer_Release(&vtable);
1593
144
    if (deletechars != NULL)
1594
0
        PyBuffer_Release(&vdel);
1595
144
    return result;
1596
0
}
1597
1598
1599
/*[clinic input]
1600
1601
@permit_long_summary
1602
@permit_long_docstring_body
1603
@staticmethod
1604
bytearray.maketrans
1605
1606
    frm: Py_buffer
1607
    to: Py_buffer
1608
    /
1609
1610
Return a translation table usable for the bytes or bytearray translate method.
1611
1612
The returned table will be one where each byte in frm is mapped to the byte at
1613
the same position in to.
1614
1615
The bytes objects frm and to must be of the same length.
1616
[clinic start generated code]*/
1617
1618
static PyObject *
1619
bytearray_maketrans_impl(Py_buffer *frm, Py_buffer *to)
1620
/*[clinic end generated code: output=1df267d99f56b15e input=1146b43a592eca13]*/
1621
0
{
1622
0
    return _Py_bytes_maketrans(frm, to);
1623
0
}
1624
1625
1626
/*[clinic input]
1627
@permit_long_docstring_body
1628
@critical_section
1629
bytearray.replace
1630
1631
    old: Py_buffer
1632
    new: Py_buffer
1633
    count: Py_ssize_t = -1
1634
        Maximum number of occurrences to replace.
1635
        -1 (the default value) means replace all occurrences.
1636
    /
1637
1638
Return a copy with all occurrences of substring old replaced by new.
1639
1640
If the optional argument count is given, only the first count occurrences are
1641
replaced.
1642
[clinic start generated code]*/
1643
1644
static PyObject *
1645
bytearray_replace_impl(PyByteArrayObject *self, Py_buffer *old,
1646
                       Py_buffer *new, Py_ssize_t count)
1647
/*[clinic end generated code: output=d39884c4dc59412a input=66afec32f4e095e0]*/
1648
0
{
1649
0
    return stringlib_replace((PyObject *)self,
1650
0
                             (const char *)old->buf, old->len,
1651
0
                             (const char *)new->buf, new->len, count);
1652
0
}
1653
1654
/*[clinic input]
1655
@permit_long_summary
1656
@critical_section
1657
bytearray.split
1658
1659
    sep: object = None
1660
        The delimiter according which to split the bytearray.
1661
        None (the default value) means split on ASCII whitespace characters
1662
        (space, tab, return, newline, formfeed, vertical tab).
1663
    maxsplit: Py_ssize_t = -1
1664
        Maximum number of splits to do.
1665
        -1 (the default value) means no limit.
1666
1667
Return a list of the sections in the bytearray, using sep as the delimiter.
1668
[clinic start generated code]*/
1669
1670
static PyObject *
1671
bytearray_split_impl(PyByteArrayObject *self, PyObject *sep,
1672
                     Py_ssize_t maxsplit)
1673
/*[clinic end generated code: output=833e2cf385d9a04d input=dd9f6e2910cc3a34]*/
1674
0
{
1675
0
    Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
1676
0
    const char *s = PyByteArray_AS_STRING(self), *sub;
1677
0
    PyObject *list;
1678
0
    Py_buffer vsub;
1679
1680
0
    if (maxsplit < 0)
1681
0
        maxsplit = PY_SSIZE_T_MAX;
1682
1683
0
    if (sep == Py_None)
1684
0
        return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
1685
1686
0
    if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0)
1687
0
        return NULL;
1688
0
    sub = vsub.buf;
1689
0
    n = vsub.len;
1690
1691
0
    list = stringlib_split(
1692
0
        (PyObject*) self, s, len, sub, n, maxsplit
1693
0
        );
1694
0
    PyBuffer_Release(&vsub);
1695
0
    return list;
1696
0
}
1697
1698
/*[clinic input]
1699
@permit_long_docstring_body
1700
@critical_section
1701
bytearray.partition
1702
1703
    sep: object
1704
    /
1705
1706
Partition the bytearray into three parts using the given separator.
1707
1708
This will search for the separator sep in the bytearray. If the separator is
1709
found, returns a 3-tuple containing the part before the separator, the
1710
separator itself, and the part after it as new bytearray objects.
1711
1712
If the separator is not found, returns a 3-tuple containing the copy of the
1713
original bytearray object and two empty bytearray objects.
1714
[clinic start generated code]*/
1715
1716
static PyObject *
1717
bytearray_partition_impl(PyByteArrayObject *self, PyObject *sep)
1718
/*[clinic end generated code: output=b5fa1e03f10cfccb input=b87276af883f39d9]*/
1719
0
{
1720
0
    PyObject *bytesep, *result;
1721
1722
0
    bytesep = _PyByteArray_FromBufferObject(sep);
1723
0
    if (! bytesep)
1724
0
        return NULL;
1725
1726
0
    result = stringlib_partition(
1727
0
            (PyObject*) self,
1728
0
            PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1729
0
            bytesep,
1730
0
            PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
1731
0
            );
1732
1733
0
    Py_DECREF(bytesep);
1734
0
    return result;
1735
0
}
1736
1737
/*[clinic input]
1738
@permit_long_docstring_body
1739
@critical_section
1740
bytearray.rpartition
1741
1742
    sep: object
1743
    /
1744
1745
Partition the bytearray into three parts using the given separator.
1746
1747
This will search for the separator sep in the bytearray, starting at the end.
1748
If the separator is found, returns a 3-tuple containing the part before the
1749
separator, the separator itself, and the part after it as new bytearray
1750
objects.
1751
1752
If the separator is not found, returns a 3-tuple containing two empty bytearray
1753
objects and the copy of the original bytearray object.
1754
[clinic start generated code]*/
1755
1756
static PyObject *
1757
bytearray_rpartition_impl(PyByteArrayObject *self, PyObject *sep)
1758
/*[clinic end generated code: output=0186ce7b1ef61289 input=5bdcfc4c333bcfab]*/
1759
0
{
1760
0
    PyObject *bytesep, *result;
1761
1762
0
    bytesep = _PyByteArray_FromBufferObject(sep);
1763
0
    if (! bytesep)
1764
0
        return NULL;
1765
1766
0
    result = stringlib_rpartition(
1767
0
            (PyObject*) self,
1768
0
            PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1769
0
            bytesep,
1770
0
            PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
1771
0
            );
1772
1773
0
    Py_DECREF(bytesep);
1774
0
    return result;
1775
0
}
1776
1777
/*[clinic input]
1778
@permit_long_summary
1779
@permit_long_docstring_body
1780
@critical_section
1781
bytearray.rsplit = bytearray.split
1782
1783
Return a list of the sections in the bytearray, using sep as the delimiter.
1784
1785
Splitting is done starting at the end of the bytearray and working to the front.
1786
[clinic start generated code]*/
1787
1788
static PyObject *
1789
bytearray_rsplit_impl(PyByteArrayObject *self, PyObject *sep,
1790
                      Py_ssize_t maxsplit)
1791
/*[clinic end generated code: output=a55e0b5a03cb6190 input=60e9abf305128ff4]*/
1792
0
{
1793
0
    Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
1794
0
    const char *s = PyByteArray_AS_STRING(self), *sub;
1795
0
    PyObject *list;
1796
0
    Py_buffer vsub;
1797
1798
0
    if (maxsplit < 0)
1799
0
        maxsplit = PY_SSIZE_T_MAX;
1800
1801
0
    if (sep == Py_None)
1802
0
        return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
1803
1804
0
    if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0)
1805
0
        return NULL;
1806
0
    sub = vsub.buf;
1807
0
    n = vsub.len;
1808
1809
0
    list = stringlib_rsplit(
1810
0
        (PyObject*) self, s, len, sub, n, maxsplit
1811
0
        );
1812
0
    PyBuffer_Release(&vsub);
1813
0
    return list;
1814
0
}
1815
1816
/*[clinic input]
1817
@critical_section
1818
bytearray.reverse
1819
1820
Reverse the order of the values in B in place.
1821
[clinic start generated code]*/
1822
1823
static PyObject *
1824
bytearray_reverse_impl(PyByteArrayObject *self)
1825
/*[clinic end generated code: output=9f7616f29ab309d3 input=2f3d5ce3180ffc53]*/
1826
0
{
1827
0
    char swap, *head, *tail;
1828
0
    Py_ssize_t i, j, n = Py_SIZE(self);
1829
1830
0
    j = n / 2;
1831
0
    head = PyByteArray_AS_STRING(self);
1832
0
    tail = head + n - 1;
1833
0
    for (i = 0; i < j; i++) {
1834
0
        swap = *head;
1835
0
        *head++ = *tail;
1836
0
        *tail-- = swap;
1837
0
    }
1838
1839
0
    Py_RETURN_NONE;
1840
0
}
1841
1842
1843
/*[python input]
1844
class bytesvalue_converter(CConverter):
1845
    type = 'int'
1846
    converter = '_getbytevalue'
1847
[python start generated code]*/
1848
/*[python end generated code: output=da39a3ee5e6b4b0d input=29c2e7c26c212812]*/
1849
1850
1851
/*[clinic input]
1852
@critical_section
1853
bytearray.insert
1854
1855
    index: Py_ssize_t
1856
        The index where the value is to be inserted.
1857
    item: bytesvalue
1858
        The item to be inserted.
1859
    /
1860
1861
Insert a single item into the bytearray before the given index.
1862
[clinic start generated code]*/
1863
1864
static PyObject *
1865
bytearray_insert_impl(PyByteArrayObject *self, Py_ssize_t index, int item)
1866
/*[clinic end generated code: output=76c775a70e7b07b7 input=b3e14ede546dd8cc]*/
1867
0
{
1868
0
    Py_ssize_t n = Py_SIZE(self);
1869
0
    char *buf;
1870
1871
0
    if (n == PY_SSIZE_T_MAX) {
1872
0
        PyErr_SetString(PyExc_OverflowError,
1873
0
                        "cannot add more objects to bytearray");
1874
0
        return NULL;
1875
0
    }
1876
0
    if (bytearray_resize_lock_held((PyObject *)self, n + 1) < 0)
1877
0
        return NULL;
1878
0
    buf = PyByteArray_AS_STRING(self);
1879
1880
0
    if (index < 0) {
1881
0
        index += n;
1882
0
        if (index < 0)
1883
0
            index = 0;
1884
0
    }
1885
0
    if (index > n)
1886
0
        index = n;
1887
0
    memmove(buf + index + 1, buf + index, n - index);
1888
0
    buf[index] = item;
1889
1890
0
    Py_RETURN_NONE;
1891
0
}
1892
1893
static PyObject *
1894
bytearray_isalnum(PyObject *self, PyObject *Py_UNUSED(ignored))
1895
0
{
1896
0
    PyObject *ret;
1897
0
    Py_BEGIN_CRITICAL_SECTION(self);
1898
0
    ret = stringlib_isalnum(self, NULL);
1899
0
    Py_END_CRITICAL_SECTION();
1900
0
    return ret;
1901
0
}
1902
1903
static PyObject *
1904
bytearray_isalpha(PyObject *self, PyObject *Py_UNUSED(ignored))
1905
0
{
1906
0
    PyObject *ret;
1907
0
    Py_BEGIN_CRITICAL_SECTION(self);
1908
0
    ret = stringlib_isalpha(self, NULL);
1909
0
    Py_END_CRITICAL_SECTION();
1910
0
    return ret;
1911
0
}
1912
1913
static PyObject *
1914
bytearray_isascii(PyObject *self, PyObject *Py_UNUSED(ignored))
1915
0
{
1916
0
    PyObject *ret;
1917
0
    Py_BEGIN_CRITICAL_SECTION(self);
1918
0
    ret = stringlib_isascii(self, NULL);
1919
0
    Py_END_CRITICAL_SECTION();
1920
0
    return ret;
1921
0
}
1922
1923
static PyObject *
1924
bytearray_isdigit(PyObject *self, PyObject *Py_UNUSED(ignored))
1925
0
{
1926
0
    PyObject *ret;
1927
0
    Py_BEGIN_CRITICAL_SECTION(self);
1928
0
    ret = stringlib_isdigit(self, NULL);
1929
0
    Py_END_CRITICAL_SECTION();
1930
0
    return ret;
1931
0
}
1932
1933
static PyObject *
1934
bytearray_islower(PyObject *self, PyObject *Py_UNUSED(ignored))
1935
0
{
1936
0
    PyObject *ret;
1937
0
    Py_BEGIN_CRITICAL_SECTION(self);
1938
0
    ret = stringlib_islower(self, NULL);
1939
0
    Py_END_CRITICAL_SECTION();
1940
0
    return ret;
1941
0
}
1942
1943
static PyObject *
1944
bytearray_isspace(PyObject *self, PyObject *Py_UNUSED(ignored))
1945
0
{
1946
0
    PyObject *ret;
1947
0
    Py_BEGIN_CRITICAL_SECTION(self);
1948
0
    ret = stringlib_isspace(self, NULL);
1949
0
    Py_END_CRITICAL_SECTION();
1950
0
    return ret;
1951
0
}
1952
1953
static PyObject *
1954
bytearray_istitle(PyObject *self, PyObject *Py_UNUSED(ignored))
1955
0
{
1956
0
    PyObject *ret;
1957
0
    Py_BEGIN_CRITICAL_SECTION(self);
1958
0
    ret = stringlib_istitle(self, NULL);
1959
0
    Py_END_CRITICAL_SECTION();
1960
0
    return ret;
1961
0
}
1962
1963
static PyObject *
1964
bytearray_isupper(PyObject *self, PyObject *Py_UNUSED(ignored))
1965
0
{
1966
0
    PyObject *ret;
1967
0
    Py_BEGIN_CRITICAL_SECTION(self);
1968
0
    ret = stringlib_isupper(self, NULL);
1969
0
    Py_END_CRITICAL_SECTION();
1970
0
    return ret;
1971
0
}
1972
1973
/*[clinic input]
1974
@critical_section
1975
bytearray.append
1976
1977
    item: bytesvalue
1978
        The item to be appended.
1979
    /
1980
1981
Append a single item to the end of the bytearray.
1982
[clinic start generated code]*/
1983
1984
static PyObject *
1985
bytearray_append_impl(PyByteArrayObject *self, int item)
1986
/*[clinic end generated code: output=a154e19ed1886cb6 input=a874689bac8bd352]*/
1987
644k
{
1988
644k
    Py_ssize_t n = Py_SIZE(self);
1989
1990
644k
    if (n == PY_SSIZE_T_MAX) {
1991
0
        PyErr_SetString(PyExc_OverflowError,
1992
0
                        "cannot add more objects to bytearray");
1993
0
        return NULL;
1994
0
    }
1995
644k
    if (bytearray_resize_lock_held((PyObject *)self, n + 1) < 0)
1996
0
        return NULL;
1997
1998
644k
    PyByteArray_AS_STRING(self)[n] = item;
1999
2000
644k
    Py_RETURN_NONE;
2001
644k
}
2002
2003
static PyObject *
2004
bytearray_capitalize(PyObject *self, PyObject *Py_UNUSED(ignored))
2005
0
{
2006
0
    PyObject *ret;
2007
0
    Py_BEGIN_CRITICAL_SECTION(self);
2008
0
    ret = stringlib_capitalize(self, NULL);
2009
0
    Py_END_CRITICAL_SECTION();
2010
0
    return ret;
2011
0
}
2012
2013
static PyObject *
2014
bytearray_center(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
2015
0
{
2016
0
    PyObject *ret;
2017
0
    Py_BEGIN_CRITICAL_SECTION(self);
2018
0
    ret = stringlib_center(self, args, nargs);
2019
0
    Py_END_CRITICAL_SECTION();
2020
0
    return ret;
2021
0
}
2022
2023
static PyObject *
2024
bytearray_expandtabs(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
2025
0
{
2026
0
    PyObject *ret;
2027
0
    Py_BEGIN_CRITICAL_SECTION(self);
2028
0
    ret = stringlib_expandtabs(self, args, nargs, kwnames);
2029
0
    Py_END_CRITICAL_SECTION();
2030
0
    return ret;
2031
0
}
2032
2033
/*[clinic input]
2034
@permit_long_summary
2035
@critical_section
2036
bytearray.extend
2037
2038
    iterable_of_ints: object
2039
        The iterable of items to append.
2040
    /
2041
2042
Append all the items from the iterator or sequence to the end of the bytearray.
2043
[clinic start generated code]*/
2044
2045
static PyObject *
2046
bytearray_extend_impl(PyByteArrayObject *self, PyObject *iterable_of_ints)
2047
/*[clinic end generated code: output=2f25e0ce72b98748 input=aeed44b025146632]*/
2048
9.13M
{
2049
9.13M
    PyObject *it, *item, *bytearray_obj;
2050
9.13M
    Py_ssize_t buf_size = 0, len = 0;
2051
9.13M
    int value;
2052
9.13M
    char *buf;
2053
2054
    /* bytearray_setslice code only accepts something supporting PEP 3118. */
2055
9.13M
    if (PyObject_CheckBuffer(iterable_of_ints)) {
2056
9.13M
        if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), iterable_of_ints) == -1)
2057
0
            return NULL;
2058
2059
9.13M
        Py_RETURN_NONE;
2060
9.13M
    }
2061
2062
0
    it = PyObject_GetIter(iterable_of_ints);
2063
0
    if (it == NULL) {
2064
0
        if (PyErr_ExceptionMatches(PyExc_TypeError)) {
2065
0
            PyErr_Format(PyExc_TypeError,
2066
0
                         "can't extend bytearray with %.100s",
2067
0
                         Py_TYPE(iterable_of_ints)->tp_name);
2068
0
        }
2069
0
        return NULL;
2070
0
    }
2071
2072
    /* Try to determine the length of the argument. 32 is arbitrary. */
2073
0
    buf_size = PyObject_LengthHint(iterable_of_ints, 32);
2074
0
    if (buf_size == -1) {
2075
0
        Py_DECREF(it);
2076
0
        return NULL;
2077
0
    }
2078
2079
0
    bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
2080
0
    if (bytearray_obj == NULL) {
2081
0
        Py_DECREF(it);
2082
0
        return NULL;
2083
0
    }
2084
0
    buf = PyByteArray_AS_STRING(bytearray_obj);
2085
2086
0
    while ((item = PyIter_Next(it)) != NULL) {
2087
0
        if (! _getbytevalue(item, &value)) {
2088
0
            if (PyErr_ExceptionMatches(PyExc_TypeError) && PyUnicode_Check(iterable_of_ints)) {
2089
0
                PyErr_Format(PyExc_TypeError,
2090
0
                             "expected iterable of integers; got: 'str'");
2091
0
            }
2092
0
            Py_DECREF(item);
2093
0
            Py_DECREF(it);
2094
0
            Py_DECREF(bytearray_obj);
2095
0
            return NULL;
2096
0
        }
2097
0
        buf[len++] = value;
2098
0
        Py_DECREF(item);
2099
2100
0
        if (len >= buf_size) {
2101
0
            Py_ssize_t addition;
2102
0
            if (len == PY_SSIZE_T_MAX) {
2103
0
                Py_DECREF(it);
2104
0
                Py_DECREF(bytearray_obj);
2105
0
                return PyErr_NoMemory();
2106
0
            }
2107
0
            addition = len >> 1;
2108
0
            if (addition > PY_SSIZE_T_MAX - len - 1)
2109
0
                buf_size = PY_SSIZE_T_MAX;
2110
0
            else
2111
0
                buf_size = len + addition + 1;
2112
0
            if (bytearray_resize_lock_held((PyObject *)bytearray_obj, buf_size) < 0) {
2113
0
                Py_DECREF(it);
2114
0
                Py_DECREF(bytearray_obj);
2115
0
                return NULL;
2116
0
            }
2117
            /* Recompute the `buf' pointer, since the resizing operation may
2118
               have invalidated it. */
2119
0
            buf = PyByteArray_AS_STRING(bytearray_obj);
2120
0
        }
2121
0
    }
2122
0
    Py_DECREF(it);
2123
2124
0
    if (PyErr_Occurred()) {
2125
0
        Py_DECREF(bytearray_obj);
2126
0
        return NULL;
2127
0
    }
2128
2129
    /* Resize down to exact size. */
2130
0
    if (bytearray_resize_lock_held((PyObject *)bytearray_obj, len) < 0) {
2131
0
        Py_DECREF(bytearray_obj);
2132
0
        return NULL;
2133
0
    }
2134
2135
0
    if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1) {
2136
0
        Py_DECREF(bytearray_obj);
2137
0
        return NULL;
2138
0
    }
2139
0
    Py_DECREF(bytearray_obj);
2140
2141
0
    assert(!PyErr_Occurred());
2142
0
    Py_RETURN_NONE;
2143
0
}
2144
2145
/*[clinic input]
2146
@critical_section
2147
bytearray.pop
2148
2149
    index: Py_ssize_t = -1
2150
        The index from where to remove the item.
2151
        -1 (the default value) means remove the last item.
2152
    /
2153
2154
Remove and return a single item from B.
2155
2156
If no index argument is given, will pop the last item.
2157
[clinic start generated code]*/
2158
2159
static PyObject *
2160
bytearray_pop_impl(PyByteArrayObject *self, Py_ssize_t index)
2161
/*[clinic end generated code: output=e0ccd401f8021da8 input=fc0fd8de4f97661c]*/
2162
0
{
2163
0
    int value;
2164
0
    Py_ssize_t n = Py_SIZE(self);
2165
0
    char *buf;
2166
2167
0
    if (n == 0) {
2168
0
        PyErr_SetString(PyExc_IndexError,
2169
0
                        "pop from empty bytearray");
2170
0
        return NULL;
2171
0
    }
2172
0
    if (index < 0)
2173
0
        index += Py_SIZE(self);
2174
0
    if (index < 0 || index >= Py_SIZE(self)) {
2175
0
        PyErr_SetString(PyExc_IndexError, "pop index out of range");
2176
0
        return NULL;
2177
0
    }
2178
0
    if (!_canresize(self))
2179
0
        return NULL;
2180
2181
0
    buf = PyByteArray_AS_STRING(self);
2182
0
    value = buf[index];
2183
0
    memmove(buf + index, buf + index + 1, n - index);
2184
0
    if (bytearray_resize_lock_held((PyObject *)self, n - 1) < 0)
2185
0
        return NULL;
2186
2187
0
    return _PyLong_FromUnsignedChar((unsigned char)value);
2188
0
}
2189
2190
/*[clinic input]
2191
@critical_section
2192
bytearray.remove
2193
2194
    value: bytesvalue
2195
        The value to remove.
2196
    /
2197
2198
Remove the first occurrence of a value in the bytearray.
2199
[clinic start generated code]*/
2200
2201
static PyObject *
2202
bytearray_remove_impl(PyByteArrayObject *self, int value)
2203
/*[clinic end generated code: output=d659e37866709c13 input=797588bc77f86afb]*/
2204
0
{
2205
0
    Py_ssize_t where, n = Py_SIZE(self);
2206
0
    char *buf = PyByteArray_AS_STRING(self);
2207
2208
0
    where = stringlib_find_char(buf, n, value);
2209
0
    if (where < 0) {
2210
0
        PyErr_SetString(PyExc_ValueError, "value not found in bytearray");
2211
0
        return NULL;
2212
0
    }
2213
0
    if (!_canresize(self))
2214
0
        return NULL;
2215
2216
0
    memmove(buf + where, buf + where + 1, n - where);
2217
0
    if (bytearray_resize_lock_held((PyObject *)self, n - 1) < 0)
2218
0
        return NULL;
2219
2220
0
    Py_RETURN_NONE;
2221
0
}
2222
2223
0
#define LEFTSTRIP 0
2224
0
#define RIGHTSTRIP 1
2225
0
#define BOTHSTRIP 2
2226
2227
static PyObject*
2228
bytearray_strip_impl_helper(PyByteArrayObject* self, PyObject* bytes, int striptype)
2229
0
{
2230
0
    Py_ssize_t mysize, byteslen;
2231
0
    const char* myptr;
2232
0
    const char* bytesptr;
2233
0
    Py_buffer vbytes;
2234
2235
0
    if (bytes == Py_None) {
2236
0
        bytesptr = "\t\n\r\f\v ";
2237
0
        byteslen = 6;
2238
0
    }
2239
0
    else {
2240
0
        if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0)
2241
0
            return NULL;
2242
0
        bytesptr = (const char*)vbytes.buf;
2243
0
        byteslen = vbytes.len;
2244
0
    }
2245
0
    myptr = PyByteArray_AS_STRING(self);
2246
0
    mysize = Py_SIZE(self);
2247
2248
0
    Py_ssize_t left = 0;
2249
0
    if (striptype != RIGHTSTRIP) {
2250
0
        while (left < mysize && memchr(bytesptr, (unsigned char)myptr[left], byteslen))
2251
0
            left++;
2252
0
    }
2253
0
    Py_ssize_t right = mysize;
2254
0
    if (striptype != LEFTSTRIP) {
2255
0
        do {
2256
0
            right--;
2257
0
        } while (right >= left && memchr(bytesptr, (unsigned char)myptr[right], byteslen));
2258
0
        right++;
2259
0
    }
2260
0
    if (bytes != Py_None)
2261
0
        PyBuffer_Release(&vbytes);
2262
0
    return PyByteArray_FromStringAndSize(myptr + left, right - left);
2263
0
}
2264
2265
/*[clinic input]
2266
@permit_long_docstring_body
2267
@critical_section
2268
bytearray.strip
2269
2270
    bytes: object = None
2271
    /
2272
2273
Strip leading and trailing bytes contained in the argument.
2274
2275
If the argument is omitted or None, strip leading and trailing ASCII whitespace.
2276
[clinic start generated code]*/
2277
2278
static PyObject *
2279
bytearray_strip_impl(PyByteArrayObject *self, PyObject *bytes)
2280
/*[clinic end generated code: output=760412661a34ad5a input=6acaf88b2ec9daa7]*/
2281
0
{
2282
0
    return bytearray_strip_impl_helper(self, bytes, BOTHSTRIP);
2283
0
}
2284
2285
static PyObject *
2286
bytearray_swapcase(PyObject *self, PyObject *Py_UNUSED(ignored))
2287
0
{
2288
0
    PyObject *ret;
2289
0
    Py_BEGIN_CRITICAL_SECTION(self);
2290
0
    ret = stringlib_swapcase(self, NULL);
2291
0
    Py_END_CRITICAL_SECTION();
2292
0
    return ret;
2293
0
}
2294
2295
static PyObject *
2296
bytearray_title(PyObject *self, PyObject *Py_UNUSED(ignored))
2297
0
{
2298
0
    PyObject *ret;
2299
0
    Py_BEGIN_CRITICAL_SECTION(self);
2300
0
    ret = stringlib_title(self, NULL);
2301
0
    Py_END_CRITICAL_SECTION();
2302
0
    return ret;
2303
0
}
2304
2305
static PyObject *
2306
bytearray_upper(PyObject *self, PyObject *Py_UNUSED(ignored))
2307
0
{
2308
0
    PyObject *ret;
2309
0
    Py_BEGIN_CRITICAL_SECTION(self);
2310
0
    ret = stringlib_upper(self, NULL);
2311
0
    Py_END_CRITICAL_SECTION();
2312
0
    return ret;
2313
0
}
2314
2315
static PyObject *
2316
bytearray_lower(PyObject *self, PyObject *Py_UNUSED(ignored))
2317
0
{
2318
0
    PyObject *ret;
2319
0
    Py_BEGIN_CRITICAL_SECTION(self);
2320
0
    ret = stringlib_lower(self, NULL);
2321
0
    Py_END_CRITICAL_SECTION();
2322
0
    return ret;
2323
0
}
2324
2325
static PyObject *
2326
bytearray_zfill(PyObject *self, PyObject *arg)
2327
0
{
2328
0
    PyObject *ret;
2329
0
    Py_BEGIN_CRITICAL_SECTION(self);
2330
0
    ret = stringlib_zfill(self, arg);
2331
0
    Py_END_CRITICAL_SECTION();
2332
0
    return ret;
2333
0
}
2334
2335
/*[clinic input]
2336
@critical_section
2337
bytearray.lstrip
2338
2339
    bytes: object = None
2340
    /
2341
2342
Strip leading bytes contained in the argument.
2343
2344
If the argument is omitted or None, strip leading ASCII whitespace.
2345
[clinic start generated code]*/
2346
2347
static PyObject *
2348
bytearray_lstrip_impl(PyByteArrayObject *self, PyObject *bytes)
2349
/*[clinic end generated code: output=d005c9d0ab909e66 input=ed86e00eb2023625]*/
2350
0
{
2351
0
    return bytearray_strip_impl_helper(self, bytes, LEFTSTRIP);
2352
0
}
2353
2354
/*[clinic input]
2355
@critical_section
2356
bytearray.rstrip
2357
2358
    bytes: object = None
2359
    /
2360
2361
Strip trailing bytes contained in the argument.
2362
2363
If the argument is omitted or None, strip trailing ASCII whitespace.
2364
[clinic start generated code]*/
2365
2366
static PyObject *
2367
bytearray_rstrip_impl(PyByteArrayObject *self, PyObject *bytes)
2368
/*[clinic end generated code: output=030e2fbd2f7276bd input=d9ca66cf20fe7649]*/
2369
0
{
2370
0
    return bytearray_strip_impl_helper(self, bytes, RIGHTSTRIP);
2371
0
}
2372
2373
/*[clinic input]
2374
@critical_section
2375
bytearray.decode
2376
2377
    encoding: str(c_default="NULL") = 'utf-8'
2378
        The encoding with which to decode the bytearray.
2379
    errors: str(c_default="NULL") = 'strict'
2380
        The error handling scheme to use for the handling of decoding errors.
2381
        The default is 'strict' meaning that decoding errors raise a
2382
        UnicodeDecodeError. Other possible values are 'ignore' and 'replace'
2383
        as well as any other name registered with codecs.register_error that
2384
        can handle UnicodeDecodeErrors.
2385
2386
Decode the bytearray using the codec registered for encoding.
2387
[clinic start generated code]*/
2388
2389
static PyObject *
2390
bytearray_decode_impl(PyByteArrayObject *self, const char *encoding,
2391
                      const char *errors)
2392
/*[clinic end generated code: output=f57d43f4a00b42c5 input=86c303ee376b8453]*/
2393
587k
{
2394
587k
    if (encoding == NULL)
2395
0
        encoding = PyUnicode_GetDefaultEncoding();
2396
587k
    return PyUnicode_FromEncodedObject((PyObject*)self, encoding, errors);
2397
587k
}
2398
2399
PyDoc_STRVAR(alloc_doc,
2400
"B.__alloc__() -> int\n\
2401
\n\
2402
Return the number of bytes actually allocated.");
2403
2404
static PyObject *
2405
bytearray_alloc(PyObject *op, PyObject *Py_UNUSED(ignored))
2406
0
{
2407
0
    PyByteArrayObject *self = _PyByteArray_CAST(op);
2408
0
    return PyLong_FromSsize_t(FT_ATOMIC_LOAD_SSIZE_RELAXED(self->ob_alloc));
2409
0
}
2410
2411
/*[clinic input]
2412
@critical_section
2413
bytearray.join
2414
2415
    iterable_of_bytes: object
2416
    /
2417
2418
Concatenate any number of bytes/bytearray objects.
2419
2420
The bytearray whose method is called is inserted in between each pair.
2421
2422
The result is returned as a new bytearray object.
2423
[clinic start generated code]*/
2424
2425
static PyObject *
2426
bytearray_join_impl(PyByteArrayObject *self, PyObject *iterable_of_bytes)
2427
/*[clinic end generated code: output=0ced382b5846a7ee input=49627e07ca31ca26]*/
2428
0
{
2429
0
    PyObject *ret;
2430
0
    self->ob_exports++; // this protects `self` from being cleared/resized if `iterable_of_bytes` is a custom iterator
2431
0
    ret = stringlib_bytes_join((PyObject*)self, iterable_of_bytes);
2432
0
    self->ob_exports--; // unexport `self`
2433
0
    return ret;
2434
0
}
2435
2436
static PyObject *
2437
bytearray_ljust(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
2438
0
{
2439
0
    PyObject *ret;
2440
0
    Py_BEGIN_CRITICAL_SECTION(self);
2441
0
    ret = stringlib_ljust(self, args, nargs);
2442
0
    Py_END_CRITICAL_SECTION();
2443
0
    return ret;
2444
0
}
2445
2446
static PyObject *
2447
bytearray_rjust(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
2448
0
{
2449
0
    PyObject *ret;
2450
0
    Py_BEGIN_CRITICAL_SECTION(self);
2451
0
    ret = stringlib_rjust(self, args, nargs);
2452
0
    Py_END_CRITICAL_SECTION();
2453
0
    return ret;
2454
0
}
2455
2456
/*[clinic input]
2457
@permit_long_summary
2458
@permit_long_docstring_body
2459
@critical_section
2460
bytearray.splitlines
2461
2462
    keepends: bool = False
2463
2464
Return a list of the lines in the bytearray, breaking at line boundaries.
2465
2466
Line breaks are not included in the resulting list unless keepends is given and
2467
true.
2468
[clinic start generated code]*/
2469
2470
static PyObject *
2471
bytearray_splitlines_impl(PyByteArrayObject *self, int keepends)
2472
/*[clinic end generated code: output=4223c94b895f6ad9 input=21bc3f02bf1be832]*/
2473
0
{
2474
0
    return stringlib_splitlines(
2475
0
        (PyObject*) self, PyByteArray_AS_STRING(self),
2476
0
        PyByteArray_GET_SIZE(self), keepends
2477
0
        );
2478
0
}
2479
2480
/*[clinic input]
2481
@classmethod
2482
bytearray.fromhex
2483
2484
    string: object
2485
    /
2486
2487
Create a bytearray object from a string of hexadecimal numbers.
2488
2489
Spaces between two numbers are accepted.
2490
Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef')
2491
[clinic start generated code]*/
2492
2493
static PyObject *
2494
bytearray_fromhex_impl(PyTypeObject *type, PyObject *string)
2495
/*[clinic end generated code: output=8f0f0b6d30fb3ba0 input=7e314e5b2d7ab484]*/
2496
0
{
2497
0
    PyObject *result = _PyBytes_FromHex(string, type == &PyByteArray_Type);
2498
0
    if (type != &PyByteArray_Type && result != NULL) {
2499
0
        Py_SETREF(result, PyObject_CallOneArg((PyObject *)type, result));
2500
0
    }
2501
0
    return result;
2502
0
}
2503
2504
/*[clinic input]
2505
@critical_section
2506
bytearray.hex
2507
2508
    sep: object = NULL
2509
        An optional single character or byte to separate hex bytes.
2510
    bytes_per_sep: int = 1
2511
        How many bytes between separators.  Positive values count from the
2512
        right, negative values count from the left.
2513
2514
Create a string of hexadecimal numbers from a bytearray object.
2515
2516
Example:
2517
>>> value = bytearray([0xb9, 0x01, 0xef])
2518
>>> value.hex()
2519
'b901ef'
2520
>>> value.hex(':')
2521
'b9:01:ef'
2522
>>> value.hex(':', 2)
2523
'b9:01ef'
2524
>>> value.hex(':', -2)
2525
'b901:ef'
2526
[clinic start generated code]*/
2527
2528
static PyObject *
2529
bytearray_hex_impl(PyByteArrayObject *self, PyObject *sep, int bytes_per_sep)
2530
/*[clinic end generated code: output=29c4e5ef72c565a0 input=7784107de7048873]*/
2531
0
{
2532
0
    char* argbuf = PyByteArray_AS_STRING(self);
2533
0
    Py_ssize_t arglen = PyByteArray_GET_SIZE(self);
2534
0
    return _Py_strhex_with_sep(argbuf, arglen, sep, bytes_per_sep);
2535
0
}
2536
2537
static PyObject *
2538
_common_reduce(PyByteArrayObject *self, int proto)
2539
0
{
2540
0
    PyObject *state;
2541
0
    const char *buf;
2542
2543
0
    state = _PyObject_GetState((PyObject *)self);
2544
0
    if (state == NULL) {
2545
0
        return NULL;
2546
0
    }
2547
2548
0
    if (!Py_SIZE(self)) {
2549
0
        return Py_BuildValue("(O()N)", Py_TYPE(self), state);
2550
0
    }
2551
0
    buf = PyByteArray_AS_STRING(self);
2552
0
    if (proto < 3) {
2553
        /* use str based reduction for backwards compatibility with Python 2.x */
2554
0
        PyObject *latin1 = PyUnicode_DecodeLatin1(buf, Py_SIZE(self), NULL);
2555
0
        return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", state);
2556
0
    }
2557
0
    else {
2558
        /* use more efficient byte based reduction */
2559
0
        return Py_BuildValue("(O(y#)N)", Py_TYPE(self), buf, Py_SIZE(self), state);
2560
0
    }
2561
0
}
2562
2563
/*[clinic input]
2564
@critical_section
2565
bytearray.__reduce__ as bytearray_reduce
2566
2567
Return state information for pickling.
2568
[clinic start generated code]*/
2569
2570
static PyObject *
2571
bytearray_reduce_impl(PyByteArrayObject *self)
2572
/*[clinic end generated code: output=52bf304086464cab input=0fac78e4b7d84dd2]*/
2573
0
{
2574
0
    return _common_reduce(self, 2);
2575
0
}
2576
2577
/*[clinic input]
2578
@critical_section
2579
bytearray.__reduce_ex__ as bytearray_reduce_ex
2580
2581
    proto: int = 0
2582
    /
2583
2584
Return state information for pickling.
2585
[clinic start generated code]*/
2586
2587
static PyObject *
2588
bytearray_reduce_ex_impl(PyByteArrayObject *self, int proto)
2589
/*[clinic end generated code: output=52eac33377197520 input=751718f477033a29]*/
2590
0
{
2591
0
    return _common_reduce(self, proto);
2592
0
}
2593
2594
/*[clinic input]
2595
bytearray.__sizeof__ as bytearray_sizeof
2596
2597
Returns the size of the bytearray object in memory, in bytes.
2598
[clinic start generated code]*/
2599
2600
static PyObject *
2601
bytearray_sizeof_impl(PyByteArrayObject *self)
2602
/*[clinic end generated code: output=738abdd17951c427 input=e27320fd98a4bc5a]*/
2603
0
{
2604
0
    size_t res = _PyObject_SIZE(Py_TYPE(self));
2605
0
    res += (size_t)FT_ATOMIC_LOAD_SSIZE_RELAXED(self->ob_alloc) * sizeof(char);
2606
0
    return PyLong_FromSize_t(res);
2607
0
}
2608
2609
static PySequenceMethods bytearray_as_sequence = {
2610
    bytearray_length,                       /* sq_length */
2611
    PyByteArray_Concat,                     /* sq_concat */
2612
    bytearray_repeat,                       /* sq_repeat */
2613
    bytearray_getitem,                      /* sq_item */
2614
    0,                                      /* sq_slice */
2615
    bytearray_setitem,                      /* sq_ass_item */
2616
    0,                                      /* sq_ass_slice */
2617
    bytearray_contains,                     /* sq_contains */
2618
    bytearray_iconcat,                      /* sq_inplace_concat */
2619
    bytearray_irepeat,                      /* sq_inplace_repeat */
2620
};
2621
2622
static PyMappingMethods bytearray_as_mapping = {
2623
    bytearray_length,
2624
    bytearray_subscript,
2625
    bytearray_ass_subscript,
2626
};
2627
2628
static PyBufferProcs bytearray_as_buffer = {
2629
    bytearray_getbuffer,
2630
    bytearray_releasebuffer,
2631
};
2632
2633
static PyMethodDef bytearray_methods[] = {
2634
    {"__alloc__", bytearray_alloc, METH_NOARGS, alloc_doc},
2635
    BYTEARRAY_REDUCE_METHODDEF
2636
    BYTEARRAY_REDUCE_EX_METHODDEF
2637
    BYTEARRAY_SIZEOF_METHODDEF
2638
    BYTEARRAY_APPEND_METHODDEF
2639
    {"capitalize", bytearray_capitalize, METH_NOARGS, _Py_capitalize__doc__},
2640
    {"center", _PyCFunction_CAST(bytearray_center), METH_FASTCALL,
2641
    stringlib_center__doc__},
2642
    BYTEARRAY_CLEAR_METHODDEF
2643
    BYTEARRAY_COPY_METHODDEF
2644
    BYTEARRAY_COUNT_METHODDEF
2645
    BYTEARRAY_DECODE_METHODDEF
2646
    BYTEARRAY_ENDSWITH_METHODDEF
2647
    {"expandtabs", _PyCFunction_CAST(bytearray_expandtabs),
2648
    METH_FASTCALL|METH_KEYWORDS, stringlib_expandtabs__doc__},
2649
    BYTEARRAY_EXTEND_METHODDEF
2650
    BYTEARRAY_FIND_METHODDEF
2651
    BYTEARRAY_FROMHEX_METHODDEF
2652
    BYTEARRAY_HEX_METHODDEF
2653
    BYTEARRAY_INDEX_METHODDEF
2654
    BYTEARRAY_INSERT_METHODDEF
2655
    {"isalnum", bytearray_isalnum, METH_NOARGS, _Py_isalnum__doc__},
2656
    {"isalpha", bytearray_isalpha, METH_NOARGS, _Py_isalpha__doc__},
2657
    {"isascii", bytearray_isascii, METH_NOARGS, _Py_isascii__doc__},
2658
    {"isdigit", bytearray_isdigit, METH_NOARGS, _Py_isdigit__doc__},
2659
    {"islower", bytearray_islower, METH_NOARGS, _Py_islower__doc__},
2660
    {"isspace", bytearray_isspace, METH_NOARGS, _Py_isspace__doc__},
2661
    {"istitle", bytearray_istitle, METH_NOARGS, _Py_istitle__doc__},
2662
    {"isupper", bytearray_isupper, METH_NOARGS, _Py_isupper__doc__},
2663
    BYTEARRAY_JOIN_METHODDEF
2664
    {"ljust", _PyCFunction_CAST(bytearray_ljust), METH_FASTCALL,
2665
    stringlib_ljust__doc__},
2666
    {"lower", bytearray_lower, METH_NOARGS, _Py_lower__doc__},
2667
    BYTEARRAY_LSTRIP_METHODDEF
2668
    BYTEARRAY_MAKETRANS_METHODDEF
2669
    BYTEARRAY_PARTITION_METHODDEF
2670
    BYTEARRAY_POP_METHODDEF
2671
    BYTEARRAY_REMOVE_METHODDEF
2672
    BYTEARRAY_REPLACE_METHODDEF
2673
    BYTEARRAY_REMOVEPREFIX_METHODDEF
2674
    BYTEARRAY_REMOVESUFFIX_METHODDEF
2675
    BYTEARRAY_RESIZE_METHODDEF
2676
    BYTEARRAY_REVERSE_METHODDEF
2677
    BYTEARRAY_RFIND_METHODDEF
2678
    BYTEARRAY_RINDEX_METHODDEF
2679
    {"rjust", _PyCFunction_CAST(bytearray_rjust), METH_FASTCALL,
2680
    stringlib_rjust__doc__},
2681
    BYTEARRAY_RPARTITION_METHODDEF
2682
    BYTEARRAY_RSPLIT_METHODDEF
2683
    BYTEARRAY_RSTRIP_METHODDEF
2684
    BYTEARRAY_SPLIT_METHODDEF
2685
    BYTEARRAY_SPLITLINES_METHODDEF
2686
    BYTEARRAY_STARTSWITH_METHODDEF
2687
    BYTEARRAY_STRIP_METHODDEF
2688
    {"swapcase", bytearray_swapcase, METH_NOARGS, _Py_swapcase__doc__},
2689
    {"title", bytearray_title, METH_NOARGS, _Py_title__doc__},
2690
    BYTEARRAY_TRANSLATE_METHODDEF
2691
    {"upper", bytearray_upper, METH_NOARGS, _Py_upper__doc__},
2692
    {"zfill", bytearray_zfill, METH_O, stringlib_zfill__doc__},
2693
    {NULL}
2694
};
2695
2696
static PyObject *
2697
bytearray_mod_lock_held(PyObject *v, PyObject *w)
2698
0
{
2699
0
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(v);
2700
0
    if (!PyByteArray_Check(v))
2701
0
        Py_RETURN_NOTIMPLEMENTED;
2702
0
    return _PyBytes_FormatEx(PyByteArray_AS_STRING(v), PyByteArray_GET_SIZE(v), w, 1);
2703
0
}
2704
2705
static PyObject *
2706
bytearray_mod(PyObject *v, PyObject *w)
2707
0
{
2708
0
    PyObject *ret;
2709
0
    if (PyByteArray_Check(w)) {
2710
0
        Py_BEGIN_CRITICAL_SECTION2(v, w);
2711
0
        ret = bytearray_mod_lock_held(v, w);
2712
0
        Py_END_CRITICAL_SECTION2();
2713
0
    }
2714
0
    else {
2715
0
        Py_BEGIN_CRITICAL_SECTION(v);
2716
0
        ret = bytearray_mod_lock_held(v, w);
2717
0
        Py_END_CRITICAL_SECTION();
2718
0
    }
2719
0
    return ret;
2720
0
}
2721
2722
static PyNumberMethods bytearray_as_number = {
2723
    0,              /*nb_add*/
2724
    0,              /*nb_subtract*/
2725
    0,              /*nb_multiply*/
2726
    bytearray_mod,  /*nb_remainder*/
2727
};
2728
2729
PyDoc_STRVAR(bytearray_doc,
2730
"bytearray(iterable_of_ints) -> bytearray\n\
2731
bytearray(string, encoding[, errors]) -> bytearray\n\
2732
bytearray(bytes_or_buffer) -> mutable copy of bytes_or_buffer\n\
2733
bytearray(int) -> bytes array of size given by the parameter initialized with null bytes\n\
2734
bytearray() -> empty bytes array\n\
2735
\n\
2736
Construct a mutable bytearray object from:\n\
2737
  - an iterable yielding integers in range(256)\n\
2738
  - a text string encoded using the specified encoding\n\
2739
  - a bytes or a buffer object\n\
2740
  - any object implementing the buffer API.\n\
2741
  - an integer");
2742
2743
2744
static PyObject *bytearray_iter(PyObject *seq);
2745
2746
PyTypeObject PyByteArray_Type = {
2747
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
2748
    "bytearray",
2749
    sizeof(PyByteArrayObject),
2750
    0,
2751
    bytearray_dealloc,                  /* tp_dealloc */
2752
    0,                                  /* tp_vectorcall_offset */
2753
    0,                                  /* tp_getattr */
2754
    0,                                  /* tp_setattr */
2755
    0,                                  /* tp_as_async */
2756
    bytearray_repr,                     /* tp_repr */
2757
    &bytearray_as_number,               /* tp_as_number */
2758
    &bytearray_as_sequence,             /* tp_as_sequence */
2759
    &bytearray_as_mapping,              /* tp_as_mapping */
2760
    0,                                  /* tp_hash */
2761
    0,                                  /* tp_call */
2762
    bytearray_str,                      /* tp_str */
2763
    PyObject_GenericGetAttr,            /* tp_getattro */
2764
    0,                                  /* tp_setattro */
2765
    &bytearray_as_buffer,               /* tp_as_buffer */
2766
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
2767
        _Py_TPFLAGS_MATCH_SELF,       /* tp_flags */
2768
    bytearray_doc,                      /* tp_doc */
2769
    0,                                  /* tp_traverse */
2770
    0,                                  /* tp_clear */
2771
    bytearray_richcompare,              /* tp_richcompare */
2772
    0,                                  /* tp_weaklistoffset */
2773
    bytearray_iter,                     /* tp_iter */
2774
    0,                                  /* tp_iternext */
2775
    bytearray_methods,                  /* tp_methods */
2776
    0,                                  /* tp_members */
2777
    0,                                  /* tp_getset */
2778
    0,                                  /* tp_base */
2779
    0,                                  /* tp_dict */
2780
    0,                                  /* tp_descr_get */
2781
    0,                                  /* tp_descr_set */
2782
    0,                                  /* tp_dictoffset */
2783
    bytearray___init__,                 /* tp_init */
2784
    PyType_GenericAlloc,                /* tp_alloc */
2785
    PyType_GenericNew,                  /* tp_new */
2786
    PyObject_Free,                      /* tp_free */
2787
    .tp_version_tag = _Py_TYPE_VERSION_BYTEARRAY,
2788
};
2789
2790
/*********************** Bytearray Iterator ****************************/
2791
2792
typedef struct {
2793
    PyObject_HEAD
2794
    Py_ssize_t it_index;
2795
    PyByteArrayObject *it_seq; /* Set to NULL when iterator is exhausted */
2796
} bytesiterobject;
2797
2798
16
#define _bytesiterobject_CAST(op)   ((bytesiterobject *)(op))
2799
2800
static void
2801
bytearrayiter_dealloc(PyObject *self)
2802
16
{
2803
16
    bytesiterobject *it = _bytesiterobject_CAST(self);
2804
16
    _PyObject_GC_UNTRACK(it);
2805
16
    Py_XDECREF(it->it_seq);
2806
16
    PyObject_GC_Del(it);
2807
16
}
2808
2809
static int
2810
bytearrayiter_traverse(PyObject *self, visitproc visit, void *arg)
2811
0
{
2812
0
    bytesiterobject *it = _bytesiterobject_CAST(self);
2813
0
    Py_VISIT(it->it_seq);
2814
0
    return 0;
2815
0
}
2816
2817
static PyObject *
2818
bytearrayiter_next(PyObject *self)
2819
0
{
2820
0
    bytesiterobject *it = _bytesiterobject_CAST(self);
2821
0
    int val;
2822
2823
0
    assert(it != NULL);
2824
0
    Py_ssize_t index = FT_ATOMIC_LOAD_SSIZE_RELAXED(it->it_index);
2825
0
    if (index < 0) {
2826
0
        return NULL;
2827
0
    }
2828
0
    PyByteArrayObject *seq = it->it_seq;
2829
0
    assert(PyByteArray_Check(seq));
2830
2831
0
    Py_BEGIN_CRITICAL_SECTION(seq);
2832
0
    if (index < Py_SIZE(seq)) {
2833
0
        val = (unsigned char)PyByteArray_AS_STRING(seq)[index];
2834
0
    }
2835
0
    else {
2836
0
        val = -1;
2837
0
    }
2838
0
    Py_END_CRITICAL_SECTION();
2839
2840
0
    if (val == -1) {
2841
0
        FT_ATOMIC_STORE_SSIZE_RELAXED(it->it_index, -1);
2842
0
#ifndef Py_GIL_DISABLED
2843
0
        Py_CLEAR(it->it_seq);
2844
0
#endif
2845
0
        return NULL;
2846
0
    }
2847
0
    FT_ATOMIC_STORE_SSIZE_RELAXED(it->it_index, index + 1);
2848
0
    return _PyLong_FromUnsignedChar((unsigned char)val);
2849
0
}
2850
2851
static PyObject *
2852
bytearrayiter_length_hint(PyObject *self, PyObject *Py_UNUSED(ignored))
2853
0
{
2854
0
    bytesiterobject *it = _bytesiterobject_CAST(self);
2855
0
    Py_ssize_t len = 0;
2856
0
    Py_ssize_t index = FT_ATOMIC_LOAD_SSIZE_RELAXED(it->it_index);
2857
0
    if (index >= 0) {
2858
0
        len = PyByteArray_GET_SIZE(it->it_seq) - index;
2859
0
        if (len < 0) {
2860
0
            len = 0;
2861
0
        }
2862
0
    }
2863
0
    return PyLong_FromSsize_t(len);
2864
0
}
2865
2866
PyDoc_STRVAR(length_hint_doc,
2867
    "Private method returning an estimate of len(list(it)).");
2868
2869
static PyObject *
2870
bytearrayiter_reduce(PyObject *self, PyObject *Py_UNUSED(ignored))
2871
0
{
2872
0
    PyObject *iter = _PyEval_GetBuiltin(&_Py_ID(iter));
2873
2874
    /* _PyEval_GetBuiltin can invoke arbitrary code,
2875
     * call must be before access of iterator pointers.
2876
     * see issue #101765 */
2877
0
    bytesiterobject *it = _bytesiterobject_CAST(self);
2878
0
    Py_ssize_t index = FT_ATOMIC_LOAD_SSIZE_RELAXED(it->it_index);
2879
0
    if (index >= 0) {
2880
0
        return Py_BuildValue("N(O)n", iter, it->it_seq, index);
2881
0
    }
2882
0
    return Py_BuildValue("N(())", iter);
2883
0
}
2884
2885
static PyObject *
2886
bytearrayiter_setstate(PyObject *self, PyObject *state)
2887
0
{
2888
0
    Py_ssize_t index = PyLong_AsSsize_t(state);
2889
0
    if (index == -1 && PyErr_Occurred()) {
2890
0
        return NULL;
2891
0
    }
2892
2893
0
    bytesiterobject *it = _bytesiterobject_CAST(self);
2894
0
    if (FT_ATOMIC_LOAD_SSIZE_RELAXED(it->it_index) >= 0) {
2895
0
        if (index < -1) {
2896
0
            index = -1;
2897
0
        }
2898
0
        else {
2899
0
            Py_ssize_t size = PyByteArray_GET_SIZE(it->it_seq);
2900
0
            if (index > size) {
2901
0
                index = size; /* iterator at end */
2902
0
            }
2903
0
        }
2904
0
        FT_ATOMIC_STORE_SSIZE_RELAXED(it->it_index, index);
2905
0
    }
2906
0
    Py_RETURN_NONE;
2907
0
}
2908
2909
PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
2910
2911
static PyMethodDef bytearrayiter_methods[] = {
2912
    {"__length_hint__", bytearrayiter_length_hint, METH_NOARGS,
2913
     length_hint_doc},
2914
     {"__reduce__",     bytearrayiter_reduce, METH_NOARGS,
2915
     bytearray_reduce__doc__},
2916
    {"__setstate__",    bytearrayiter_setstate, METH_O,
2917
     setstate_doc},
2918
    {NULL, NULL} /* sentinel */
2919
};
2920
2921
PyTypeObject PyByteArrayIter_Type = {
2922
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
2923
    "bytearray_iterator",              /* tp_name */
2924
    sizeof(bytesiterobject),           /* tp_basicsize */
2925
    0,                                 /* tp_itemsize */
2926
    /* methods */
2927
    bytearrayiter_dealloc,             /* tp_dealloc */
2928
    0,                                 /* tp_vectorcall_offset */
2929
    0,                                 /* tp_getattr */
2930
    0,                                 /* tp_setattr */
2931
    0,                                 /* tp_as_async */
2932
    0,                                 /* tp_repr */
2933
    0,                                 /* tp_as_number */
2934
    0,                                 /* tp_as_sequence */
2935
    0,                                 /* tp_as_mapping */
2936
    0,                                 /* tp_hash */
2937
    0,                                 /* tp_call */
2938
    0,                                 /* tp_str */
2939
    PyObject_GenericGetAttr,           /* tp_getattro */
2940
    0,                                 /* tp_setattro */
2941
    0,                                 /* tp_as_buffer */
2942
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
2943
    0,                                 /* tp_doc */
2944
    bytearrayiter_traverse,            /* tp_traverse */
2945
    0,                                 /* tp_clear */
2946
    0,                                 /* tp_richcompare */
2947
    0,                                 /* tp_weaklistoffset */
2948
    PyObject_SelfIter,                 /* tp_iter */
2949
    bytearrayiter_next,                /* tp_iternext */
2950
    bytearrayiter_methods,             /* tp_methods */
2951
    0,
2952
};
2953
2954
static PyObject *
2955
bytearray_iter(PyObject *seq)
2956
16
{
2957
16
    bytesiterobject *it;
2958
2959
16
    if (!PyByteArray_Check(seq)) {
2960
0
        PyErr_BadInternalCall();
2961
0
        return NULL;
2962
0
    }
2963
16
    it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type);
2964
16
    if (it == NULL)
2965
0
        return NULL;
2966
16
    it->it_index = 0;  // -1 indicates exhausted
2967
16
    it->it_seq = (PyByteArrayObject *)Py_NewRef(seq);
2968
16
    _PyObject_GC_TRACK(it);
2969
16
    return (PyObject *)it;
2970
16
}