import copy
import functools
import pickle
+import sysconfig
import tempfile
import textwrap
+import threading
import unittest
import test.support
+from test import support
from test.support import import_helper
+from test.support import threading_helper
from test.support import warnings_helper
import test.string_tests
import test.list_tests
type2test = BytesSubclass
+class FreeThreadingTest(unittest.TestCase):
+ @unittest.skipUnless(support.Py_GIL_DISABLED, 'this test can only possibly fail with GIL disabled')
+ @threading_helper.reap_threads
+ @threading_helper.requires_working_threading()
+ def test_free_threading_bytearray(self):
+ # Test pretty much everything that can break under free-threading.
+ # Non-deterministic, but at least one of these things will fail if
+ # bytearray module is not free-thread safe.
+
+ def clear(b, a, *args): # MODIFIES!
+ b.wait()
+ try: a.clear()
+ except BufferError: pass
+
+ def clear2(b, a, c): # MODIFIES c!
+ b.wait()
+ try: c.clear()
+ except BufferError: pass
+
+ def pop1(b, a): # MODIFIES!
+ b.wait()
+ try: a.pop()
+ except IndexError: pass
+
+ def append1(b, a): # MODIFIES!
+ b.wait()
+ a.append(0)
+
+ def insert1(b, a): # MODIFIES!
+ b.wait()
+ a.insert(0, 0)
+
+ def extend(b, a): # MODIFIES!
+ c = bytearray(b'0' * 0x400000)
+ b.wait()
+ a.extend(c)
+
+ def remove(b, a): # MODIFIES!
+ c = ord('0')
+ b.wait()
+ try: a.remove(c)
+ except ValueError: pass
+
+ def reverse(b, a): # modifies inplace
+ b.wait()
+ a.reverse()
+
+ def reduce(b, a):
+ b.wait()
+ a.__reduce__()
+
+ def reduceex2(b, a):
+ b.wait()
+ a.__reduce_ex__(2)
+
+ def reduceex3(b, a):
+ b.wait()
+ c = a.__reduce_ex__(3)
+ assert not c[1] or 0xdd not in c[1][0]
+
+ def count0(b, a):
+ b.wait()
+ a.count(0)
+
+ def decode(b, a):
+ b.wait()
+ a.decode()
+
+ def find(b, a):
+ c = bytearray(b'0' * 0x40000)
+ b.wait()
+ a.find(c)
+
+ def hex(b, a):
+ b.wait()
+ a.hex('_')
+
+ def join(b, a):
+ b.wait()
+ a.join([b'1', b'2', b'3'])
+
+ def replace(b, a):
+ b.wait()
+ a.replace(b'0', b'')
+
+ def maketrans(b, a, c):
+ b.wait()
+ try: a.maketrans(a, c)
+ except ValueError: pass
+
+ def translate(b, a, c):
+ b.wait()
+ a.translate(c)
+
+ def copy(b, a):
+ b.wait()
+ c = a.copy()
+ if c: assert c[0] == 48 # '0'
+
+ def endswith(b, a):
+ b.wait()
+ assert not a.endswith(b'\xdd')
+
+ def index(b, a):
+ b.wait()
+ try: a.index(b'\xdd')
+ except ValueError: return
+ assert False
+
+ def lstrip(b, a):
+ b.wait()
+ assert not a.lstrip(b'0')
+
+ def partition(b, a):
+ b.wait()
+ assert not a.partition(b'\xdd')[2]
+
+ def removeprefix(b, a):
+ b.wait()
+ assert not a.removeprefix(b'0')
+
+ def removesuffix(b, a):
+ b.wait()
+ assert not a.removesuffix(b'0')
+
+ def rfind(b, a):
+ b.wait()
+ assert a.rfind(b'\xdd') == -1
+
+ def rindex(b, a):
+ b.wait()
+ try: a.rindex(b'\xdd')
+ except ValueError: return
+ assert False
+
+ def rpartition(b, a):
+ b.wait()
+ assert not a.rpartition(b'\xdd')[0]
+
+ def rsplit(b, a):
+ b.wait()
+ assert len(a.rsplit(b'\xdd')) == 1
+
+ def rstrip(b, a):
+ b.wait()
+ assert not a.rstrip(b'0')
+
+ def split(b, a):
+ b.wait()
+ assert len(a.split(b'\xdd')) == 1
+
+ def splitlines(b, a):
+ b.wait()
+ l = len(a.splitlines())
+ assert l > 1 or l == 0
+
+ def startswith(b, a):
+ b.wait()
+ assert not a.startswith(b'\xdd')
+
+ def strip(b, a):
+ b.wait()
+ assert not a.strip(b'0')
+
+ def repeat(b, a):
+ b.wait()
+ a * 2
+
+ def contains(b, a):
+ b.wait()
+ assert 0xdd not in a
+
+ def iconcat(b, a): # MODIFIES!
+ c = bytearray(b'0' * 0x400000)
+ b.wait()
+ a += c
+
+ def irepeat(b, a): # MODIFIES!
+ b.wait()
+ a *= 2
+
+ def subscript(b, a):
+ b.wait()
+ try: assert a[0] != 0xdd
+ except IndexError: pass
+
+ def ass_subscript(b, a): # MODIFIES!
+ c = bytearray(b'0' * 0x400000)
+ b.wait()
+ a[:] = c
+
+ def mod(b, a):
+ c = tuple(range(4096))
+ b.wait()
+ try: a % c
+ except TypeError: pass
+
+ def repr_(b, a):
+ b.wait()
+ repr(a)
+
+ def capitalize(b, a):
+ b.wait()
+ c = a.capitalize()
+ assert not c or c[0] not in (0xdd, 0xcd)
+
+ def center(b, a):
+ b.wait()
+ c = a.center(0x60000)
+ assert not c or c[0x20000] not in (0xdd, 0xcd)
+
+ def expandtabs(b, a):
+ b.wait()
+ c = a.expandtabs()
+ assert not c or c[0] not in (0xdd, 0xcd)
+
+ def ljust(b, a):
+ b.wait()
+ c = a.ljust(0x600000)
+ assert not c or c[0] not in (0xdd, 0xcd)
+
+ def lower(b, a):
+ b.wait()
+ c = a.lower()
+ assert not c or c[0] not in (0xdd, 0xcd)
+
+ def rjust(b, a):
+ b.wait()
+ c = a.rjust(0x600000)
+ assert not c or c[-1] not in (0xdd, 0xcd)
+
+ def swapcase(b, a):
+ b.wait()
+ c = a.swapcase()
+ assert not c or c[-1] not in (0xdd, 0xcd)
+
+ def title(b, a):
+ b.wait()
+ c = a.title()
+ assert not c or c[-1] not in (0xdd, 0xcd)
+
+ def upper(b, a):
+ b.wait()
+ c = a.upper()
+ assert not c or c[-1] not in (0xdd, 0xcd)
+
+ def zfill(b, a):
+ b.wait()
+ c = a.zfill(0x400000)
+ assert not c or c[-1] not in (0xdd, 0xcd)
+
+ def check(funcs, a=None, *args):
+ if a is None:
+ a = bytearray(b'0' * 0x400000)
+
+ barrier = threading.Barrier(len(funcs))
+ threads = []
+
+ for func in funcs:
+ thread = threading.Thread(target=func, args=(barrier, a, *args))
+
+ threads.append(thread)
+
+ with threading_helper.start_threads(threads):
+ pass
+
+ for thread in threads:
+ threading_helper.join_thread(thread)
+
+ # hard errors
+
+ check([clear] + [reduce] * 10)
+ check([clear] + [reduceex2] * 10)
+ check([clear] + [append1] * 10)
+ check([clear] * 10)
+ check([clear] + [count0] * 10)
+ check([clear] + [decode] * 10)
+ check([clear] + [extend] * 10)
+ check([clear] + [find] * 10)
+ check([clear] + [hex] * 10)
+ check([clear] + [insert1] * 10)
+ check([clear] + [join] * 10)
+ check([clear] + [pop1] * 10)
+ check([clear] + [remove] * 10)
+ check([clear] + [replace] * 10)
+ check([clear] + [reverse] * 10)
+ check([clear, clear2] + [maketrans] * 10, bytearray(range(128)), bytearray(range(128)))
+ check([clear] + [translate] * 10, None, bytearray.maketrans(bytearray(range(128)), bytearray(range(128))))
+
+ check([clear] + [repeat] * 10)
+ check([clear] + [iconcat] * 10)
+ check([clear] + [irepeat] * 10)
+ check([clear] + [ass_subscript] * 10)
+ check([clear] + [repr_] * 10)
+
+ # value errors
+
+ check([clear] + [reduceex3] * 10, bytearray(b'a' * 0x40000))
+ check([clear] + [copy] * 10)
+ check([clear] + [endswith] * 10)
+ check([clear] + [index] * 10)
+ check([clear] + [lstrip] * 10)
+ check([clear] + [partition] * 10)
+ check([clear] + [removeprefix] * 10, bytearray(b'0'))
+ check([clear] + [removesuffix] * 10, bytearray(b'0'))
+ check([clear] + [rfind] * 10)
+ check([clear] + [rindex] * 10)
+ check([clear] + [rpartition] * 10)
+ check([clear] + [rsplit] * 10, bytearray(b'0' * 0x4000))
+ check([clear] + [rstrip] * 10)
+ check([clear] + [split] * 10, bytearray(b'0' * 0x4000))
+ check([clear] + [splitlines] * 10, bytearray(b'\n' * 0x400))
+ check([clear] + [startswith] * 10)
+ check([clear] + [strip] * 10)
+
+ check([clear] + [contains] * 10)
+ check([clear] + [subscript] * 10)
+ check([clear] + [mod] * 10, bytearray(b'%d' * 4096))
+
+ check([clear] + [capitalize] * 10, bytearray(b'a' * 0x40000))
+ check([clear] + [center] * 10, bytearray(b'a' * 0x40000))
+ check([clear] + [expandtabs] * 10, bytearray(b'0\t' * 4096))
+ check([clear] + [ljust] * 10, bytearray(b'0' * 0x400000))
+ check([clear] + [lower] * 10, bytearray(b'A' * 0x400000))
+ check([clear] + [rjust] * 10, bytearray(b'0' * 0x400000))
+ check([clear] + [swapcase] * 10, bytearray(b'aA' * 0x200000))
+ check([clear] + [title] * 10, bytearray(b'aA' * 0x200000))
+ check([clear] + [upper] * 10, bytearray(b'a' * 0x400000))
+ check([clear] + [zfill] * 10, bytearray(b'1' * 0x200000))
+
+
if __name__ == "__main__":
unittest.main()
#include "pycore_bytes_methods.h"
#include "pycore_bytesobject.h"
#include "pycore_ceval.h" // _PyEval_GetBuiltin()
+#include "pycore_critical_section.h"
#include "pycore_object.h" // _PyObject_GC_UNTRACK()
#include "pycore_strhex.h" // _Py_strhex_with_sep()
#include "pycore_long.h" // _PyLong_FromUnsignedChar()
+#include "pycore_pyatomic_ft_wrappers.h"
#include "bytesobject.h"
/*[clinic input]
}
static int
-bytearray_getbuffer(PyObject *self, Py_buffer *view, int flags)
+bytearray_getbuffer_lock_held(PyObject *self, Py_buffer *view, int flags)
{
+ _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(self);
PyByteArrayObject *obj = _PyByteArray_CAST(self);
if (view == NULL) {
PyErr_SetString(PyExc_BufferError,
return 0;
}
+static int
+bytearray_getbuffer(PyObject *self, Py_buffer *view, int flags)
+{
+ int ret;
+ Py_BEGIN_CRITICAL_SECTION(self);
+ ret = bytearray_getbuffer_lock_held(self, view, flags);
+ Py_END_CRITICAL_SECTION();
+ return ret;
+}
+
static void
bytearray_releasebuffer(PyObject *self, Py_buffer *view)
{
+ Py_BEGIN_CRITICAL_SECTION(self);
PyByteArrayObject *obj = _PyByteArray_CAST(self);
obj->ob_exports--;
assert(obj->ob_exports >= 0);
+ Py_END_CRITICAL_SECTION();
}
static int
return PyByteArray_AS_STRING(self);
}
-int
-PyByteArray_Resize(PyObject *self, Py_ssize_t requested_size)
+static int
+bytearray_resize_lock_held(PyObject *self, Py_ssize_t requested_size)
{
+ _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(self);
void *sval;
PyByteArrayObject *obj = ((PyByteArrayObject *)self);
/* All computations are done unsigned to avoid integer overflows
obj->ob_bytes = obj->ob_start = sval;
Py_SET_SIZE(self, size);
- obj->ob_alloc = alloc;
+ FT_ATOMIC_STORE_SSIZE_RELAXED(obj->ob_alloc, alloc);
obj->ob_bytes[size] = '\0'; /* Trailing null byte */
return 0;
}
+int
+PyByteArray_Resize(PyObject *self, Py_ssize_t requested_size)
+{
+ int ret;
+ Py_BEGIN_CRITICAL_SECTION(self);
+ ret = bytearray_resize_lock_held(self, requested_size);
+ Py_END_CRITICAL_SECTION();
+ return ret;
+}
+
PyObject *
PyByteArray_Concat(PyObject *a, PyObject *b)
{
static Py_ssize_t
bytearray_length(PyObject *op)
{
- PyByteArrayObject *self = _PyByteArray_CAST(op);
- return Py_SIZE(self);
+ return PyByteArray_GET_SIZE(op);
}
static PyObject *
-bytearray_iconcat(PyObject *op, PyObject *other)
+bytearray_iconcat_lock_held(PyObject *op, PyObject *other)
{
+ _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
PyByteArrayObject *self = _PyByteArray_CAST(op);
Py_buffer vo;
return PyErr_NoMemory();
}
- if (PyByteArray_Resize((PyObject *)self, size + vo.len) < 0) {
+ if (bytearray_resize_lock_held((PyObject *)self, size + vo.len) < 0) {
PyBuffer_Release(&vo);
return NULL;
}
}
static PyObject *
-bytearray_repeat(PyObject *op, Py_ssize_t count)
+bytearray_iconcat(PyObject *op, PyObject *other)
{
+ PyObject *ret;
+ Py_BEGIN_CRITICAL_SECTION(op);
+ ret = bytearray_iconcat_lock_held(op, other);
+ Py_END_CRITICAL_SECTION();
+ return ret;
+}
+
+static PyObject *
+bytearray_repeat_lock_held(PyObject *op, Py_ssize_t count)
+{
+ _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
PyByteArrayObject *self = _PyByteArray_CAST(op);
if (count < 0) {
count = 0;
}
static PyObject *
-bytearray_irepeat(PyObject *op, Py_ssize_t count)
+bytearray_repeat(PyObject *op, Py_ssize_t count)
{
+ PyObject *ret;
+ Py_BEGIN_CRITICAL_SECTION(op);
+ ret = bytearray_repeat_lock_held(op, count);
+ Py_END_CRITICAL_SECTION();
+ return ret;
+}
+
+static PyObject *
+bytearray_irepeat_lock_held(PyObject *op, Py_ssize_t count)
+{
+ _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
PyByteArrayObject *self = _PyByteArray_CAST(op);
if (count < 0) {
count = 0;
return PyErr_NoMemory();
}
const Py_ssize_t size = mysize * count;
- if (PyByteArray_Resize((PyObject *)self, size) < 0) {
+ if (bytearray_resize_lock_held((PyObject *)self, size) < 0) {
return NULL;
}
}
static PyObject *
-bytearray_getitem(PyObject *op, Py_ssize_t i)
+bytearray_irepeat(PyObject *op, Py_ssize_t count)
+{
+ PyObject *ret;
+ Py_BEGIN_CRITICAL_SECTION(op);
+ ret = bytearray_irepeat_lock_held(op, count);
+ Py_END_CRITICAL_SECTION();
+ return ret;
+}
+
+static PyObject *
+bytearray_getitem_lock_held(PyObject *op, Py_ssize_t i)
{
+ _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
PyByteArrayObject *self = _PyByteArray_CAST(op);
if (i < 0 || i >= Py_SIZE(self)) {
PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
}
static PyObject *
-bytearray_subscript(PyObject *op, PyObject *index)
+bytearray_getitem(PyObject *op, Py_ssize_t i)
+{
+ PyObject *ret;
+ Py_BEGIN_CRITICAL_SECTION(op);
+ ret = bytearray_getitem_lock_held(op, i);
+ Py_END_CRITICAL_SECTION();
+ return ret;
+}
+
+static PyObject *
+bytearray_subscript_lock_held(PyObject *op, PyObject *index)
{
+ _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
PyByteArrayObject *self = _PyByteArray_CAST(op);
if (_PyIndex_Check(index)) {
Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
}
}
+static PyObject *
+bytearray_subscript(PyObject *op, PyObject *index)
+{
+ PyObject *ret;
+ Py_BEGIN_CRITICAL_SECTION(op);
+ ret = bytearray_subscript_lock_held(op, index);
+ Py_END_CRITICAL_SECTION();
+ return ret;
+
+}
+
static int
bytearray_setslice_linear(PyByteArrayObject *self,
Py_ssize_t lo, Py_ssize_t hi,
char *bytes, Py_ssize_t bytes_len)
{
+ _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(self);
Py_ssize_t avail = hi - lo;
char *buf = PyByteArray_AS_STRING(self);
Py_ssize_t growth = bytes_len - avail;
memmove(buf + lo + bytes_len, buf + hi,
Py_SIZE(self) - hi);
}
- if (PyByteArray_Resize((PyObject *)self,
+ if (bytearray_resize_lock_held((PyObject *)self,
Py_SIZE(self) + growth) < 0) {
/* Issue #19578: Handling the memory allocation failure here is
tricky here because the bytearray object has already been
return -1;
}
- if (PyByteArray_Resize((PyObject *)self,
+ if (bytearray_resize_lock_held((PyObject *)self,
Py_SIZE(self) + growth) < 0) {
return -1;
}
bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
PyObject *values)
{
+ _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(self);
Py_ssize_t needed;
void *bytes;
Py_buffer vbytes;
}
static int
-bytearray_setitem(PyObject *op, Py_ssize_t i, PyObject *value)
+bytearray_setitem_lock_held(PyObject *op, Py_ssize_t i, PyObject *value)
{
+ _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
PyByteArrayObject *self = _PyByteArray_CAST(op);
// GH-91153: We need to do this *before* the size check, in case value has a
}
static int
-bytearray_ass_subscript(PyObject *op, PyObject *index, PyObject *values)
+bytearray_setitem(PyObject *op, Py_ssize_t i, PyObject *value)
{
+ int ret;
+ Py_BEGIN_CRITICAL_SECTION(op);
+ ret = bytearray_setitem_lock_held(op, i, value);
+ Py_END_CRITICAL_SECTION();
+ return ret;
+}
+
+static int
+bytearray_ass_subscript_lock_held(PyObject *op, PyObject *index, PyObject *values)
+{
+ _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
PyByteArrayObject *self = _PyByteArray_CAST(op);
Py_ssize_t start, stop, step, slicelen;
char *buf = PyByteArray_AS_STRING(self);
values = PyByteArray_FromObject(values);
if (values == NULL)
return -1;
- err = bytearray_ass_subscript((PyObject*)self, index, values);
+ err = bytearray_ass_subscript_lock_held((PyObject*)self, index, values);
Py_DECREF(values);
return err;
}
buf + cur,
PyByteArray_GET_SIZE(self) - cur);
}
- if (PyByteArray_Resize((PyObject *)self,
+ if (bytearray_resize_lock_held((PyObject *)self,
PyByteArray_GET_SIZE(self) - slicelen) < 0)
return -1;
}
}
+static int
+bytearray_ass_subscript(PyObject *op, PyObject *index, PyObject *values)
+{
+ int ret;
+ Py_BEGIN_CRITICAL_SECTION(op);
+ ret = bytearray_ass_subscript_lock_held(op, index, values);
+ Py_END_CRITICAL_SECTION();
+ return ret;
+}
+
/*[clinic input]
bytearray.__init__
/* Mostly copied from string_repr, but without the
"smart quote" functionality. */
static PyObject *
-bytearray_repr(PyObject *op)
+bytearray_repr_lock_held(PyObject *op)
{
+ _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
PyByteArrayObject *self = _PyByteArray_CAST(op);
const char *className = _PyType_Name(Py_TYPE(self));
const char *quote_prefix = "(b";
return v;
}
+static PyObject *
+bytearray_repr(PyObject *op)
+{
+ PyObject *ret;
+ Py_BEGIN_CRITICAL_SECTION(op);
+ ret = bytearray_repr_lock_held(op);
+ Py_END_CRITICAL_SECTION();
+ return ret;
+}
+
static PyObject *
bytearray_str(PyObject *op)
{
/*[clinic input]
+@critical_section
@text_signature "($self, sub[, start[, end]], /)"
bytearray.find
static PyObject *
bytearray_find_impl(PyByteArrayObject *self, PyObject *sub, Py_ssize_t start,
Py_ssize_t end)
-/*[clinic end generated code: output=413e1cab2ae87da0 input=793dfad803e2952f]*/
+/*[clinic end generated code: output=413e1cab2ae87da0 input=1de9f4558df68336]*/
{
return _Py_bytes_find(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
sub, start, end);
}
/*[clinic input]
+@critical_section
bytearray.count = bytearray.find
Return the number of non-overlapping occurrences of subsection 'sub' in bytes B[start:end].
static PyObject *
bytearray_count_impl(PyByteArrayObject *self, PyObject *sub,
Py_ssize_t start, Py_ssize_t end)
-/*[clinic end generated code: output=a21ee2692e4f1233 input=4deb529db38deda8]*/
+/*[clinic end generated code: output=a21ee2692e4f1233 input=2608c30644614724]*/
{
return _Py_bytes_count(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
sub, start, end);
}
/*[clinic input]
+@critical_section
bytearray.copy
Return a copy of B.
static PyObject *
bytearray_copy_impl(PyByteArrayObject *self)
-/*[clinic end generated code: output=68cfbcfed484c132 input=6597b0c01bccaa9e]*/
+/*[clinic end generated code: output=68cfbcfed484c132 input=b96f8b01f73851ad]*/
{
return PyByteArray_FromStringAndSize(PyByteArray_AS_STRING((PyObject *)self),
PyByteArray_GET_SIZE(self));
}
/*[clinic input]
+@critical_section
bytearray.index = bytearray.find
Return the lowest index in B where subsection 'sub' is found, such that 'sub' is contained within B[start:end].
static PyObject *
bytearray_index_impl(PyByteArrayObject *self, PyObject *sub,
Py_ssize_t start, Py_ssize_t end)
-/*[clinic end generated code: output=067a1e78efc672a7 input=8cbaf6836dbd2a9a]*/
+/*[clinic end generated code: output=067a1e78efc672a7 input=0086ba0ab9bf44a5]*/
{
return _Py_bytes_index(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
sub, start, end);
}
/*[clinic input]
+@critical_section
bytearray.rfind = bytearray.find
Return the highest index in B where subsection 'sub' is found, such that 'sub' is contained within B[start:end].
static PyObject *
bytearray_rfind_impl(PyByteArrayObject *self, PyObject *sub,
Py_ssize_t start, Py_ssize_t end)
-/*[clinic end generated code: output=51bf886f932b283c input=eaa107468a158423]*/
+/*[clinic end generated code: output=51bf886f932b283c input=ac73593305d5c1d1]*/
{
return _Py_bytes_rfind(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
sub, start, end);
}
/*[clinic input]
+@critical_section
bytearray.rindex = bytearray.find
Return the highest index in B where subsection 'sub' is found, such that 'sub' is contained within B[start:end].
static PyObject *
bytearray_rindex_impl(PyByteArrayObject *self, PyObject *sub,
Py_ssize_t start, Py_ssize_t end)
-/*[clinic end generated code: output=38e1cf66bafb08b9 input=81cf49d0af4d5bd0]*/
+/*[clinic end generated code: output=38e1cf66bafb08b9 input=0cf331bf5ebe0e91]*/
{
return _Py_bytes_rindex(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
sub, start, end);
static int
bytearray_contains(PyObject *self, PyObject *arg)
{
- return _Py_bytes_contains(PyByteArray_AS_STRING(self),
- PyByteArray_GET_SIZE(self),
- arg);
+ int ret;
+ Py_BEGIN_CRITICAL_SECTION(self);
+ ret = _Py_bytes_contains(PyByteArray_AS_STRING(self),
+ PyByteArray_GET_SIZE(self),
+ arg);
+ Py_END_CRITICAL_SECTION();
+ return ret;
}
/*[clinic input]
+@critical_section
@text_signature "($self, prefix[, start[, end]], /)"
bytearray.startswith
static PyObject *
bytearray_startswith_impl(PyByteArrayObject *self, PyObject *subobj,
Py_ssize_t start, Py_ssize_t end)
-/*[clinic end generated code: output=a3d9b6d44d3662a6 input=76385e0b376b45c1]*/
+/*[clinic end generated code: output=a3d9b6d44d3662a6 input=ea8d036d09df34b2]*/
{
return _Py_bytes_startswith(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
subobj, start, end);
}
/*[clinic input]
+@critical_section
@text_signature "($self, suffix[, start[, end]], /)"
bytearray.endswith
static PyObject *
bytearray_endswith_impl(PyByteArrayObject *self, PyObject *subobj,
Py_ssize_t start, Py_ssize_t end)
-/*[clinic end generated code: output=e75ea8c227954caa input=9b8baa879aa3d74b]*/
+/*[clinic end generated code: output=e75ea8c227954caa input=c61b90bb23a689ce]*/
{
return _Py_bytes_endswith(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
subobj, start, end);
}
/*[clinic input]
+@critical_section
bytearray.removeprefix as bytearray_removeprefix
prefix: Py_buffer
static PyObject *
bytearray_removeprefix_impl(PyByteArrayObject *self, Py_buffer *prefix)
-/*[clinic end generated code: output=6cabc585e7f502e0 input=968aada38aedd262]*/
+/*[clinic end generated code: output=6cabc585e7f502e0 input=4323ba6d275fe7a8]*/
{
const char *self_start = PyByteArray_AS_STRING(self);
Py_ssize_t self_len = PyByteArray_GET_SIZE(self);
}
/*[clinic input]
+@critical_section
bytearray.removesuffix as bytearray_removesuffix
suffix: Py_buffer
static PyObject *
bytearray_removesuffix_impl(PyByteArrayObject *self, Py_buffer *suffix)
-/*[clinic end generated code: output=2bc8cfb79de793d3 input=c1827e810b2f6b99]*/
+/*[clinic end generated code: output=2bc8cfb79de793d3 input=f71ba2e1a40c47dd]*/
{
const char *self_start = PyByteArray_AS_STRING(self);
Py_ssize_t self_len = PyByteArray_GET_SIZE(self);
/*[clinic input]
+@critical_section
bytearray.translate
table: object
static PyObject *
bytearray_translate_impl(PyByteArrayObject *self, PyObject *table,
PyObject *deletechars)
-/*[clinic end generated code: output=b6a8f01c2a74e446 input=cfff956d4d127a9b]*/
+/*[clinic end generated code: output=b6a8f01c2a74e446 input=cd6fa93ca04e05bc]*/
{
char *input, *output;
const char *table_chars;
/*[clinic input]
+@critical_section
bytearray.replace
old: Py_buffer
static PyObject *
bytearray_replace_impl(PyByteArrayObject *self, Py_buffer *old,
Py_buffer *new, Py_ssize_t count)
-/*[clinic end generated code: output=d39884c4dc59412a input=aa379d988637c7fb]*/
+/*[clinic end generated code: output=d39884c4dc59412a input=6992755672c8a807]*/
{
return stringlib_replace((PyObject *)self,
(const char *)old->buf, old->len,
}
/*[clinic input]
+@critical_section
bytearray.split
sep: object = None
static PyObject *
bytearray_split_impl(PyByteArrayObject *self, PyObject *sep,
Py_ssize_t maxsplit)
-/*[clinic end generated code: output=833e2cf385d9a04d input=24f82669f41bf523]*/
+/*[clinic end generated code: output=833e2cf385d9a04d input=1c367486b9938909]*/
{
Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
const char *s = PyByteArray_AS_STRING(self), *sub;
}
/*[clinic input]
+@critical_section
bytearray.partition
sep: object
[clinic start generated code]*/
static PyObject *
-bytearray_partition(PyByteArrayObject *self, PyObject *sep)
-/*[clinic end generated code: output=45d2525ddd35f957 input=8f644749ee4fc83a]*/
+bytearray_partition_impl(PyByteArrayObject *self, PyObject *sep)
+/*[clinic end generated code: output=b5fa1e03f10cfccb input=632855f986733f34]*/
{
PyObject *bytesep, *result;
}
/*[clinic input]
+@critical_section
bytearray.rpartition
sep: object
[clinic start generated code]*/
static PyObject *
-bytearray_rpartition(PyByteArrayObject *self, PyObject *sep)
-/*[clinic end generated code: output=440de3c9426115e8 input=7e3df3e6cb8fa0ac]*/
+bytearray_rpartition_impl(PyByteArrayObject *self, PyObject *sep)
+/*[clinic end generated code: output=0186ce7b1ef61289 input=4318e3d125497450]*/
{
PyObject *bytesep, *result;
}
/*[clinic input]
+@critical_section
bytearray.rsplit = bytearray.split
Return a list of the sections in the bytearray, using sep as the delimiter.
static PyObject *
bytearray_rsplit_impl(PyByteArrayObject *self, PyObject *sep,
Py_ssize_t maxsplit)
-/*[clinic end generated code: output=a55e0b5a03cb6190 input=a68286e4dd692ffe]*/
+/*[clinic end generated code: output=a55e0b5a03cb6190 input=3cd513c2b94a53c1]*/
{
Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
const char *s = PyByteArray_AS_STRING(self), *sub;
}
/*[clinic input]
+@critical_section
bytearray.reverse
Reverse the order of the values in B in place.
static PyObject *
bytearray_reverse_impl(PyByteArrayObject *self)
-/*[clinic end generated code: output=9f7616f29ab309d3 input=543356319fc78557]*/
+/*[clinic end generated code: output=9f7616f29ab309d3 input=2f3d5ce3180ffc53]*/
{
char swap, *head, *tail;
Py_ssize_t i, j, n = Py_SIZE(self);
/*[clinic input]
+@critical_section
bytearray.insert
index: Py_ssize_t
static PyObject *
bytearray_insert_impl(PyByteArrayObject *self, Py_ssize_t index, int item)
-/*[clinic end generated code: output=76c775a70e7b07b7 input=b2b5d07e9de6c070]*/
+/*[clinic end generated code: output=76c775a70e7b07b7 input=b3e14ede546dd8cc]*/
{
Py_ssize_t n = Py_SIZE(self);
char *buf;
"cannot add more objects to bytearray");
return NULL;
}
- if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
+ if (bytearray_resize_lock_held((PyObject *)self, n + 1) < 0)
return NULL;
buf = PyByteArray_AS_STRING(self);
Py_RETURN_NONE;
}
+static PyObject *
+bytearray_isalnum(PyObject *self, PyObject *Py_UNUSED(ignored))
+{
+ PyObject *ret;
+ Py_BEGIN_CRITICAL_SECTION(self);
+ ret = stringlib_isalnum(self, NULL);
+ Py_END_CRITICAL_SECTION();
+ return ret;
+}
+
+static PyObject *
+bytearray_isalpha(PyObject *self, PyObject *Py_UNUSED(ignored))
+{
+ PyObject *ret;
+ Py_BEGIN_CRITICAL_SECTION(self);
+ ret = stringlib_isalpha(self, NULL);
+ Py_END_CRITICAL_SECTION();
+ return ret;
+}
+
+static PyObject *
+bytearray_isascii(PyObject *self, PyObject *Py_UNUSED(ignored))
+{
+ PyObject *ret;
+ Py_BEGIN_CRITICAL_SECTION(self);
+ ret = stringlib_isascii(self, NULL);
+ Py_END_CRITICAL_SECTION();
+ return ret;
+}
+
+static PyObject *
+bytearray_isdigit(PyObject *self, PyObject *Py_UNUSED(ignored))
+{
+ PyObject *ret;
+ Py_BEGIN_CRITICAL_SECTION(self);
+ ret = stringlib_isdigit(self, NULL);
+ Py_END_CRITICAL_SECTION();
+ return ret;
+}
+
+static PyObject *
+bytearray_islower(PyObject *self, PyObject *Py_UNUSED(ignored))
+{
+ PyObject *ret;
+ Py_BEGIN_CRITICAL_SECTION(self);
+ ret = stringlib_islower(self, NULL);
+ Py_END_CRITICAL_SECTION();
+ return ret;
+}
+
+static PyObject *
+bytearray_isspace(PyObject *self, PyObject *Py_UNUSED(ignored))
+{
+ PyObject *ret;
+ Py_BEGIN_CRITICAL_SECTION(self);
+ ret = stringlib_isspace(self, NULL);
+ Py_END_CRITICAL_SECTION();
+ return ret;
+}
+
+static PyObject *
+bytearray_istitle(PyObject *self, PyObject *Py_UNUSED(ignored))
+{
+ PyObject *ret;
+ Py_BEGIN_CRITICAL_SECTION(self);
+ ret = stringlib_istitle(self, NULL);
+ Py_END_CRITICAL_SECTION();
+ return ret;
+}
+
+static PyObject *
+bytearray_isupper(PyObject *self, PyObject *Py_UNUSED(ignored))
+{
+ PyObject *ret;
+ Py_BEGIN_CRITICAL_SECTION(self);
+ ret = stringlib_isupper(self, NULL);
+ Py_END_CRITICAL_SECTION();
+ return ret;
+}
+
/*[clinic input]
+@critical_section
bytearray.append
item: bytesvalue
static PyObject *
bytearray_append_impl(PyByteArrayObject *self, int item)
-/*[clinic end generated code: output=a154e19ed1886cb6 input=20d6bec3d1340593]*/
+/*[clinic end generated code: output=a154e19ed1886cb6 input=a874689bac8bd352]*/
{
Py_ssize_t n = Py_SIZE(self);
"cannot add more objects to bytearray");
return NULL;
}
- if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
+ if (bytearray_resize_lock_held((PyObject *)self, n + 1) < 0)
return NULL;
PyByteArray_AS_STRING(self)[n] = item;
Py_RETURN_NONE;
}
+static PyObject *
+bytearray_capitalize(PyObject *self, PyObject *Py_UNUSED(ignored))
+{
+ PyObject *ret;
+ Py_BEGIN_CRITICAL_SECTION(self);
+ ret = stringlib_capitalize(self, NULL);
+ Py_END_CRITICAL_SECTION();
+ return ret;
+}
+
+static PyObject *
+bytearray_center(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
+{
+ PyObject *ret;
+ Py_BEGIN_CRITICAL_SECTION(self);
+ ret = stringlib_center(self, args, nargs);
+ Py_END_CRITICAL_SECTION();
+ return ret;
+}
+
+static PyObject *
+bytearray_expandtabs(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+ PyObject *ret;
+ Py_BEGIN_CRITICAL_SECTION(self);
+ ret = stringlib_expandtabs(self, args, nargs, kwnames);
+ Py_END_CRITICAL_SECTION();
+ return ret;
+}
+
/*[clinic input]
+@critical_section
bytearray.extend
iterable_of_ints: object
[clinic start generated code]*/
static PyObject *
-bytearray_extend(PyByteArrayObject *self, PyObject *iterable_of_ints)
-/*[clinic end generated code: output=98155dbe249170b1 input=c617b3a93249ba28]*/
+bytearray_extend_impl(PyByteArrayObject *self, PyObject *iterable_of_ints)
+/*[clinic end generated code: output=2f25e0ce72b98748 input=86e65beaba444650]*/
{
PyObject *it, *item, *bytearray_obj;
Py_ssize_t buf_size = 0, len = 0;
buf_size = PY_SSIZE_T_MAX;
else
buf_size = len + addition + 1;
- if (PyByteArray_Resize((PyObject *)bytearray_obj, buf_size) < 0) {
+ if (bytearray_resize_lock_held((PyObject *)bytearray_obj, buf_size) < 0) {
Py_DECREF(it);
Py_DECREF(bytearray_obj);
return NULL;
}
/* Resize down to exact size. */
- if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) {
+ if (bytearray_resize_lock_held((PyObject *)bytearray_obj, len) < 0) {
Py_DECREF(bytearray_obj);
return NULL;
}
}
/*[clinic input]
+@critical_section
bytearray.pop
index: Py_ssize_t = -1
static PyObject *
bytearray_pop_impl(PyByteArrayObject *self, Py_ssize_t index)
-/*[clinic end generated code: output=e0ccd401f8021da8 input=3591df2d06c0d237]*/
+/*[clinic end generated code: output=e0ccd401f8021da8 input=fc0fd8de4f97661c]*/
{
int value;
Py_ssize_t n = Py_SIZE(self);
buf = PyByteArray_AS_STRING(self);
value = buf[index];
memmove(buf + index, buf + index + 1, n - index);
- if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
+ if (bytearray_resize_lock_held((PyObject *)self, n - 1) < 0)
return NULL;
return _PyLong_FromUnsignedChar((unsigned char)value);
}
/*[clinic input]
+@critical_section
bytearray.remove
value: bytesvalue
static PyObject *
bytearray_remove_impl(PyByteArrayObject *self, int value)
-/*[clinic end generated code: output=d659e37866709c13 input=121831240cd51ddf]*/
+/*[clinic end generated code: output=d659e37866709c13 input=797588bc77f86afb]*/
{
Py_ssize_t where, n = Py_SIZE(self);
char *buf = PyByteArray_AS_STRING(self);
return NULL;
memmove(buf + where, buf + where + 1, n - where);
- if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
+ if (bytearray_resize_lock_held((PyObject *)self, n - 1) < 0)
return NULL;
Py_RETURN_NONE;
}
/*[clinic input]
+@critical_section
bytearray.strip
bytes: object = None
static PyObject *
bytearray_strip_impl(PyByteArrayObject *self, PyObject *bytes)
-/*[clinic end generated code: output=760412661a34ad5a input=ef7bb59b09c21d62]*/
+/*[clinic end generated code: output=760412661a34ad5a input=1f9026e5ad35388a]*/
{
return bytearray_strip_impl_helper(self, bytes, BOTHSTRIP);
}
+static PyObject *
+bytearray_swapcase(PyObject *self, PyObject *Py_UNUSED(ignored))
+{
+ PyObject *ret;
+ Py_BEGIN_CRITICAL_SECTION(self);
+ ret = stringlib_swapcase(self, NULL);
+ Py_END_CRITICAL_SECTION();
+ return ret;
+}
+
+static PyObject *
+bytearray_title(PyObject *self, PyObject *Py_UNUSED(ignored))
+{
+ PyObject *ret;
+ Py_BEGIN_CRITICAL_SECTION(self);
+ ret = stringlib_title(self, NULL);
+ Py_END_CRITICAL_SECTION();
+ return ret;
+}
+
+static PyObject *
+bytearray_upper(PyObject *self, PyObject *Py_UNUSED(ignored))
+{
+ PyObject *ret;
+ Py_BEGIN_CRITICAL_SECTION(self);
+ ret = stringlib_upper(self, NULL);
+ Py_END_CRITICAL_SECTION();
+ return ret;
+}
+
+static PyObject *
+bytearray_lower(PyObject *self, PyObject *Py_UNUSED(ignored))
+{
+ PyObject *ret;
+ Py_BEGIN_CRITICAL_SECTION(self);
+ ret = stringlib_lower(self, NULL);
+ Py_END_CRITICAL_SECTION();
+ return ret;
+}
+
+static PyObject *
+bytearray_zfill(PyObject *self, PyObject *arg)
+{
+ PyObject *ret;
+ Py_BEGIN_CRITICAL_SECTION(self);
+ ret = stringlib_zfill(self, arg);
+ Py_END_CRITICAL_SECTION();
+ return ret;
+}
+
/*[clinic input]
+@critical_section
bytearray.lstrip
bytes: object = None
static PyObject *
bytearray_lstrip_impl(PyByteArrayObject *self, PyObject *bytes)
-/*[clinic end generated code: output=d005c9d0ab909e66 input=80843f975dd7c480]*/
+/*[clinic end generated code: output=d005c9d0ab909e66 input=ed86e00eb2023625]*/
{
return bytearray_strip_impl_helper(self, bytes, LEFTSTRIP);
}
/*[clinic input]
+@critical_section
bytearray.rstrip
bytes: object = None
static PyObject *
bytearray_rstrip_impl(PyByteArrayObject *self, PyObject *bytes)
-/*[clinic end generated code: output=030e2fbd2f7276bd input=e728b994954cfd91]*/
+/*[clinic end generated code: output=030e2fbd2f7276bd input=d9ca66cf20fe7649]*/
{
return bytearray_strip_impl_helper(self, bytes, RIGHTSTRIP);
}
/*[clinic input]
+@critical_section
bytearray.decode
encoding: str(c_default="NULL") = 'utf-8'
static PyObject *
bytearray_decode_impl(PyByteArrayObject *self, const char *encoding,
const char *errors)
-/*[clinic end generated code: output=f57d43f4a00b42c5 input=f28d8f903020257b]*/
+/*[clinic end generated code: output=f57d43f4a00b42c5 input=86c303ee376b8453]*/
{
if (encoding == NULL)
encoding = PyUnicode_GetDefaultEncoding();
bytearray_alloc(PyObject *op, PyObject *Py_UNUSED(ignored))
{
PyByteArrayObject *self = _PyByteArray_CAST(op);
- return PyLong_FromSsize_t(self->ob_alloc);
+ return PyLong_FromSsize_t(FT_ATOMIC_LOAD_SSIZE_RELAXED(self->ob_alloc));
}
/*[clinic input]
+@critical_section
bytearray.join
iterable_of_bytes: object
[clinic start generated code]*/
static PyObject *
-bytearray_join(PyByteArrayObject *self, PyObject *iterable_of_bytes)
-/*[clinic end generated code: output=a8516370bf68ae08 input=aba6b1f9b30fcb8e]*/
+bytearray_join_impl(PyByteArrayObject *self, PyObject *iterable_of_bytes)
+/*[clinic end generated code: output=0ced382b5846a7ee input=49627e07ca31ca26]*/
{
+ PyObject *ret;
self->ob_exports++; // this protects `self` from being cleared/resized if `iterable_of_bytes` is a custom iterator
- PyObject* ret = stringlib_bytes_join((PyObject*)self, iterable_of_bytes);
+ ret = stringlib_bytes_join((PyObject*)self, iterable_of_bytes);
self->ob_exports--; // unexport `self`
return ret;
}
+static PyObject *
+bytearray_ljust(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
+{
+ PyObject *ret;
+ Py_BEGIN_CRITICAL_SECTION(self);
+ ret = stringlib_ljust(self, args, nargs);
+ Py_END_CRITICAL_SECTION();
+ return ret;
+}
+
+static PyObject *
+bytearray_rjust(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
+{
+ PyObject *ret;
+ Py_BEGIN_CRITICAL_SECTION(self);
+ ret = stringlib_rjust(self, args, nargs);
+ Py_END_CRITICAL_SECTION();
+ return ret;
+}
+
/*[clinic input]
+@critical_section
bytearray.splitlines
keepends: bool = False
static PyObject *
bytearray_splitlines_impl(PyByteArrayObject *self, int keepends)
-/*[clinic end generated code: output=4223c94b895f6ad9 input=66b2dcdea8d093bf]*/
+/*[clinic end generated code: output=4223c94b895f6ad9 input=874cd662866a66a1]*/
{
return stringlib_splitlines(
(PyObject*) self, PyByteArray_AS_STRING(self),
}
/*[clinic input]
+@critical_section
bytearray.hex
sep: object = NULL
static PyObject *
bytearray_hex_impl(PyByteArrayObject *self, PyObject *sep, int bytes_per_sep)
-/*[clinic end generated code: output=29c4e5ef72c565a0 input=808667e49bcccb54]*/
+/*[clinic end generated code: output=29c4e5ef72c565a0 input=7784107de7048873]*/
{
char* argbuf = PyByteArray_AS_STRING(self);
Py_ssize_t arglen = PyByteArray_GET_SIZE(self);
}
/*[clinic input]
+@critical_section
bytearray.__reduce__ as bytearray_reduce
Return state information for pickling.
static PyObject *
bytearray_reduce_impl(PyByteArrayObject *self)
-/*[clinic end generated code: output=52bf304086464cab input=44b5737ada62dd3f]*/
+/*[clinic end generated code: output=52bf304086464cab input=0fac78e4b7d84dd2]*/
{
return _common_reduce(self, 2);
}
/*[clinic input]
+@critical_section
bytearray.__reduce_ex__ as bytearray_reduce_ex
proto: int = 0
static PyObject *
bytearray_reduce_ex_impl(PyByteArrayObject *self, int proto)
-/*[clinic end generated code: output=52eac33377197520 input=f129bc1a1aa151ee]*/
+/*[clinic end generated code: output=52eac33377197520 input=751718f477033a29]*/
{
return _common_reduce(self, proto);
}
/*[clinic end generated code: output=738abdd17951c427 input=e27320fd98a4bc5a]*/
{
size_t res = _PyObject_SIZE(Py_TYPE(self));
- res += (size_t)self->ob_alloc * sizeof(char);
+ res += (size_t)FT_ATOMIC_LOAD_SSIZE_RELAXED(self->ob_alloc) * sizeof(char);
return PyLong_FromSize_t(res);
}
BYTEARRAY_REDUCE_EX_METHODDEF
BYTEARRAY_SIZEOF_METHODDEF
BYTEARRAY_APPEND_METHODDEF
- {"capitalize", stringlib_capitalize, METH_NOARGS,
- _Py_capitalize__doc__},
- STRINGLIB_CENTER_METHODDEF
+ {"capitalize", bytearray_capitalize, METH_NOARGS, _Py_capitalize__doc__},
+ {"center", _PyCFunction_CAST(bytearray_center), METH_FASTCALL,
+ stringlib_center__doc__},
BYTEARRAY_CLEAR_METHODDEF
BYTEARRAY_COPY_METHODDEF
BYTEARRAY_COUNT_METHODDEF
BYTEARRAY_DECODE_METHODDEF
BYTEARRAY_ENDSWITH_METHODDEF
- STRINGLIB_EXPANDTABS_METHODDEF
+ {"expandtabs", _PyCFunction_CAST(bytearray_expandtabs),
+ METH_FASTCALL|METH_KEYWORDS, stringlib_expandtabs__doc__},
BYTEARRAY_EXTEND_METHODDEF
BYTEARRAY_FIND_METHODDEF
BYTEARRAY_FROMHEX_METHODDEF
BYTEARRAY_HEX_METHODDEF
BYTEARRAY_INDEX_METHODDEF
BYTEARRAY_INSERT_METHODDEF
- {"isalnum", stringlib_isalnum, METH_NOARGS,
- _Py_isalnum__doc__},
- {"isalpha", stringlib_isalpha, METH_NOARGS,
- _Py_isalpha__doc__},
- {"isascii", stringlib_isascii, METH_NOARGS,
- _Py_isascii__doc__},
- {"isdigit", stringlib_isdigit, METH_NOARGS,
- _Py_isdigit__doc__},
- {"islower", stringlib_islower, METH_NOARGS,
- _Py_islower__doc__},
- {"isspace", stringlib_isspace, METH_NOARGS,
- _Py_isspace__doc__},
- {"istitle", stringlib_istitle, METH_NOARGS,
- _Py_istitle__doc__},
- {"isupper", stringlib_isupper, METH_NOARGS,
- _Py_isupper__doc__},
+ {"isalnum", bytearray_isalnum, METH_NOARGS, _Py_isalnum__doc__},
+ {"isalpha", bytearray_isalpha, METH_NOARGS, _Py_isalpha__doc__},
+ {"isascii", bytearray_isascii, METH_NOARGS, _Py_isascii__doc__},
+ {"isdigit", bytearray_isdigit, METH_NOARGS, _Py_isdigit__doc__},
+ {"islower", bytearray_islower, METH_NOARGS, _Py_islower__doc__},
+ {"isspace", bytearray_isspace, METH_NOARGS, _Py_isspace__doc__},
+ {"istitle", bytearray_istitle, METH_NOARGS, _Py_istitle__doc__},
+ {"isupper", bytearray_isupper, METH_NOARGS, _Py_isupper__doc__},
BYTEARRAY_JOIN_METHODDEF
- STRINGLIB_LJUST_METHODDEF
- {"lower", stringlib_lower, METH_NOARGS, _Py_lower__doc__},
+ {"ljust", _PyCFunction_CAST(bytearray_ljust), METH_FASTCALL,
+ stringlib_ljust__doc__},
+ {"lower", bytearray_lower, METH_NOARGS, _Py_lower__doc__},
BYTEARRAY_LSTRIP_METHODDEF
BYTEARRAY_MAKETRANS_METHODDEF
BYTEARRAY_PARTITION_METHODDEF
BYTEARRAY_REVERSE_METHODDEF
BYTEARRAY_RFIND_METHODDEF
BYTEARRAY_RINDEX_METHODDEF
- STRINGLIB_RJUST_METHODDEF
+ {"rjust", _PyCFunction_CAST(bytearray_rjust), METH_FASTCALL,
+ stringlib_rjust__doc__},
BYTEARRAY_RPARTITION_METHODDEF
BYTEARRAY_RSPLIT_METHODDEF
BYTEARRAY_RSTRIP_METHODDEF
BYTEARRAY_SPLITLINES_METHODDEF
BYTEARRAY_STARTSWITH_METHODDEF
BYTEARRAY_STRIP_METHODDEF
- {"swapcase", stringlib_swapcase, METH_NOARGS,
- _Py_swapcase__doc__},
- {"title", stringlib_title, METH_NOARGS, _Py_title__doc__},
+ {"swapcase", bytearray_swapcase, METH_NOARGS, _Py_swapcase__doc__},
+ {"title", bytearray_title, METH_NOARGS, _Py_title__doc__},
BYTEARRAY_TRANSLATE_METHODDEF
- {"upper", stringlib_upper, METH_NOARGS, _Py_upper__doc__},
- STRINGLIB_ZFILL_METHODDEF
+ {"upper", bytearray_upper, METH_NOARGS, _Py_upper__doc__},
+ {"zfill", bytearray_zfill, METH_O, stringlib_zfill__doc__},
{NULL}
};
static PyObject *
-bytearray_mod(PyObject *v, PyObject *w)
+bytearray_mod_lock_held(PyObject *v, PyObject *w)
{
+ _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(v);
if (!PyByteArray_Check(v))
Py_RETURN_NOTIMPLEMENTED;
return _PyBytes_FormatEx(PyByteArray_AS_STRING(v), PyByteArray_GET_SIZE(v), w, 1);
}
+static PyObject *
+bytearray_mod(PyObject *v, PyObject *w)
+{
+ PyObject *ret;
+ Py_BEGIN_CRITICAL_SECTION(v);
+ ret = bytearray_mod_lock_held(v, w);
+ Py_END_CRITICAL_SECTION();
+ return ret;
+}
+
static PyNumberMethods bytearray_as_number = {
0, /*nb_add*/
0, /*nb_subtract*/
# include "pycore_runtime.h" // _Py_ID()
#endif
#include "pycore_abstract.h" // _PyNumber_Index()
+#include "pycore_critical_section.h"// Py_BEGIN_CRITICAL_SECTION()
#include "pycore_modsupport.h" // _PyArg_UnpackKeywords()
static int
goto exit;
}
skip_optional:
+ Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_find_impl((PyByteArrayObject *)self, sub, start, end);
+ Py_END_CRITICAL_SECTION();
exit:
return return_value;
goto exit;
}
skip_optional:
+ Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_count_impl((PyByteArrayObject *)self, sub, start, end);
+ Py_END_CRITICAL_SECTION();
exit:
return return_value;
static PyObject *
bytearray_copy(PyObject *self, PyObject *Py_UNUSED(ignored))
{
- return bytearray_copy_impl((PyByteArrayObject *)self);
+ PyObject *return_value = NULL;
+
+ Py_BEGIN_CRITICAL_SECTION(self);
+ return_value = bytearray_copy_impl((PyByteArrayObject *)self);
+ Py_END_CRITICAL_SECTION();
+
+ return return_value;
}
PyDoc_STRVAR(bytearray_index__doc__,
goto exit;
}
skip_optional:
+ Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_index_impl((PyByteArrayObject *)self, sub, start, end);
+ Py_END_CRITICAL_SECTION();
exit:
return return_value;
goto exit;
}
skip_optional:
+ Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_rfind_impl((PyByteArrayObject *)self, sub, start, end);
+ Py_END_CRITICAL_SECTION();
exit:
return return_value;
goto exit;
}
skip_optional:
+ Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_rindex_impl((PyByteArrayObject *)self, sub, start, end);
+ Py_END_CRITICAL_SECTION();
exit:
return return_value;
goto exit;
}
skip_optional:
+ Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_startswith_impl((PyByteArrayObject *)self, subobj, start, end);
+ Py_END_CRITICAL_SECTION();
exit:
return return_value;
goto exit;
}
skip_optional:
+ Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_endswith_impl((PyByteArrayObject *)self, subobj, start, end);
+ Py_END_CRITICAL_SECTION();
exit:
return return_value;
if (PyObject_GetBuffer(arg, &prefix, PyBUF_SIMPLE) != 0) {
goto exit;
}
+ Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_removeprefix_impl((PyByteArrayObject *)self, &prefix);
+ Py_END_CRITICAL_SECTION();
exit:
/* Cleanup for prefix */
if (PyObject_GetBuffer(arg, &suffix, PyBUF_SIMPLE) != 0) {
goto exit;
}
+ Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_removesuffix_impl((PyByteArrayObject *)self, &suffix);
+ Py_END_CRITICAL_SECTION();
exit:
/* Cleanup for suffix */
}
deletechars = args[1];
skip_optional_pos:
+ Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_translate_impl((PyByteArrayObject *)self, table, deletechars);
+ Py_END_CRITICAL_SECTION();
exit:
return return_value;
count = ival;
}
skip_optional:
+ Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_replace_impl((PyByteArrayObject *)self, &old, &new, count);
+ Py_END_CRITICAL_SECTION();
exit:
/* Cleanup for old */
maxsplit = ival;
}
skip_optional_pos:
+ Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_split_impl((PyByteArrayObject *)self, sep, maxsplit);
+ Py_END_CRITICAL_SECTION();
exit:
return return_value;
#define BYTEARRAY_PARTITION_METHODDEF \
{"partition", (PyCFunction)bytearray_partition, METH_O, bytearray_partition__doc__},
+static PyObject *
+bytearray_partition_impl(PyByteArrayObject *self, PyObject *sep);
+
+static PyObject *
+bytearray_partition(PyByteArrayObject *self, PyObject *sep)
+{
+ PyObject *return_value = NULL;
+
+ Py_BEGIN_CRITICAL_SECTION(self);
+ return_value = bytearray_partition_impl((PyByteArrayObject *)self, sep);
+ Py_END_CRITICAL_SECTION();
+
+ return return_value;
+}
+
PyDoc_STRVAR(bytearray_rpartition__doc__,
"rpartition($self, sep, /)\n"
"--\n"
#define BYTEARRAY_RPARTITION_METHODDEF \
{"rpartition", (PyCFunction)bytearray_rpartition, METH_O, bytearray_rpartition__doc__},
+static PyObject *
+bytearray_rpartition_impl(PyByteArrayObject *self, PyObject *sep);
+
+static PyObject *
+bytearray_rpartition(PyByteArrayObject *self, PyObject *sep)
+{
+ PyObject *return_value = NULL;
+
+ Py_BEGIN_CRITICAL_SECTION(self);
+ return_value = bytearray_rpartition_impl((PyByteArrayObject *)self, sep);
+ Py_END_CRITICAL_SECTION();
+
+ return return_value;
+}
+
PyDoc_STRVAR(bytearray_rsplit__doc__,
"rsplit($self, /, sep=None, maxsplit=-1)\n"
"--\n"
maxsplit = ival;
}
skip_optional_pos:
+ Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_rsplit_impl((PyByteArrayObject *)self, sep, maxsplit);
+ Py_END_CRITICAL_SECTION();
exit:
return return_value;
static PyObject *
bytearray_reverse(PyObject *self, PyObject *Py_UNUSED(ignored))
{
- return bytearray_reverse_impl((PyByteArrayObject *)self);
+ PyObject *return_value = NULL;
+
+ Py_BEGIN_CRITICAL_SECTION(self);
+ return_value = bytearray_reverse_impl((PyByteArrayObject *)self);
+ Py_END_CRITICAL_SECTION();
+
+ return return_value;
}
PyDoc_STRVAR(bytearray_insert__doc__,
if (!_getbytevalue(args[1], &item)) {
goto exit;
}
+ Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_insert_impl((PyByteArrayObject *)self, index, item);
+ Py_END_CRITICAL_SECTION();
exit:
return return_value;
if (!_getbytevalue(arg, &item)) {
goto exit;
}
+ Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_append_impl((PyByteArrayObject *)self, item);
+ Py_END_CRITICAL_SECTION();
exit:
return return_value;
#define BYTEARRAY_EXTEND_METHODDEF \
{"extend", (PyCFunction)bytearray_extend, METH_O, bytearray_extend__doc__},
+static PyObject *
+bytearray_extend_impl(PyByteArrayObject *self, PyObject *iterable_of_ints);
+
+static PyObject *
+bytearray_extend(PyByteArrayObject *self, PyObject *iterable_of_ints)
+{
+ PyObject *return_value = NULL;
+
+ Py_BEGIN_CRITICAL_SECTION(self);
+ return_value = bytearray_extend_impl((PyByteArrayObject *)self, iterable_of_ints);
+ Py_END_CRITICAL_SECTION();
+
+ return return_value;
+}
+
PyDoc_STRVAR(bytearray_pop__doc__,
"pop($self, index=-1, /)\n"
"--\n"
index = ival;
}
skip_optional:
+ Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_pop_impl((PyByteArrayObject *)self, index);
+ Py_END_CRITICAL_SECTION();
exit:
return return_value;
if (!_getbytevalue(arg, &value)) {
goto exit;
}
+ Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_remove_impl((PyByteArrayObject *)self, value);
+ Py_END_CRITICAL_SECTION();
exit:
return return_value;
}
bytes = args[0];
skip_optional:
+ Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_strip_impl((PyByteArrayObject *)self, bytes);
+ Py_END_CRITICAL_SECTION();
exit:
return return_value;
}
bytes = args[0];
skip_optional:
+ Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_lstrip_impl((PyByteArrayObject *)self, bytes);
+ Py_END_CRITICAL_SECTION();
exit:
return return_value;
}
bytes = args[0];
skip_optional:
+ Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_rstrip_impl((PyByteArrayObject *)self, bytes);
+ Py_END_CRITICAL_SECTION();
exit:
return return_value;
goto exit;
}
skip_optional_pos:
+ Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_decode_impl((PyByteArrayObject *)self, encoding, errors);
+ Py_END_CRITICAL_SECTION();
exit:
return return_value;
#define BYTEARRAY_JOIN_METHODDEF \
{"join", (PyCFunction)bytearray_join, METH_O, bytearray_join__doc__},
+static PyObject *
+bytearray_join_impl(PyByteArrayObject *self, PyObject *iterable_of_bytes);
+
+static PyObject *
+bytearray_join(PyByteArrayObject *self, PyObject *iterable_of_bytes)
+{
+ PyObject *return_value = NULL;
+
+ Py_BEGIN_CRITICAL_SECTION(self);
+ return_value = bytearray_join_impl((PyByteArrayObject *)self, iterable_of_bytes);
+ Py_END_CRITICAL_SECTION();
+
+ return return_value;
+}
+
PyDoc_STRVAR(bytearray_splitlines__doc__,
"splitlines($self, /, keepends=False)\n"
"--\n"
goto exit;
}
skip_optional_pos:
+ Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_splitlines_impl((PyByteArrayObject *)self, keepends);
+ Py_END_CRITICAL_SECTION();
exit:
return return_value;
goto exit;
}
skip_optional_pos:
+ Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_hex_impl((PyByteArrayObject *)self, sep, bytes_per_sep);
+ Py_END_CRITICAL_SECTION();
exit:
return return_value;
static PyObject *
bytearray_reduce(PyObject *self, PyObject *Py_UNUSED(ignored))
{
- return bytearray_reduce_impl((PyByteArrayObject *)self);
+ PyObject *return_value = NULL;
+
+ Py_BEGIN_CRITICAL_SECTION(self);
+ return_value = bytearray_reduce_impl((PyByteArrayObject *)self);
+ Py_END_CRITICAL_SECTION();
+
+ return return_value;
}
PyDoc_STRVAR(bytearray_reduce_ex__doc__,
goto exit;
}
skip_optional:
+ Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_reduce_ex_impl((PyByteArrayObject *)self, proto);
+ Py_END_CRITICAL_SECTION();
exit:
return return_value;
{
return bytearray_sizeof_impl((PyByteArrayObject *)self);
}
-/*[clinic end generated code: output=41bb67a8a181e733 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=5e33422343b47af9 input=a9049054013a1b77]*/