gh-129107: make bytearray thread safe (#129108)

Co-authored-by: Kumar Aditya <kumaraditya@python.org>
This commit is contained in:
Tomasz Pytel 2025-02-15 02:19:42 -05:00 committed by GitHub
parent d2e60d8e59
commit a05433f24a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 904 additions and 100 deletions

View file

@ -29,6 +29,10 @@ static inline char* PyByteArray_AS_STRING(PyObject *op)
static inline Py_ssize_t PyByteArray_GET_SIZE(PyObject *op) { static inline Py_ssize_t PyByteArray_GET_SIZE(PyObject *op) {
PyByteArrayObject *self = _PyByteArray_CAST(op); PyByteArrayObject *self = _PyByteArray_CAST(op);
#ifdef Py_GIL_DISABLED
return _Py_atomic_load_ssize_relaxed(&(_PyVarObject_CAST(self)->ob_size));
#else
return Py_SIZE(self); return Py_SIZE(self);
#endif
} }
#define PyByteArray_GET_SIZE(self) PyByteArray_GET_SIZE(_PyObject_CAST(self)) #define PyByteArray_GET_SIZE(self) PyByteArray_GET_SIZE(_PyObject_CAST(self))

View file

@ -11,12 +11,16 @@ import sys
import copy import copy
import functools import functools
import pickle import pickle
import sysconfig
import tempfile import tempfile
import textwrap import textwrap
import threading
import unittest import unittest
import test.support import test.support
from test import support
from test.support import import_helper from test.support import import_helper
from test.support import threading_helper
from test.support import warnings_helper from test.support import warnings_helper
import test.string_tests import test.string_tests
import test.list_tests import test.list_tests
@ -2185,5 +2189,336 @@ class BytesSubclassTest(SubclassTest, unittest.TestCase):
type2test = BytesSubclass 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__": if __name__ == "__main__":
unittest.main() unittest.main()

View file

@ -0,0 +1 @@
Make the :type:`bytearray` safe under :term:`free threading`.

File diff suppressed because it is too large Load diff

View file

@ -7,6 +7,7 @@ preserve
# include "pycore_runtime.h" // _Py_ID() # include "pycore_runtime.h" // _Py_ID()
#endif #endif
#include "pycore_abstract.h" // _PyNumber_Index() #include "pycore_abstract.h" // _PyNumber_Index()
#include "pycore_critical_section.h"// Py_BEGIN_CRITICAL_SECTION()
#include "pycore_modsupport.h" // _PyArg_UnpackKeywords() #include "pycore_modsupport.h" // _PyArg_UnpackKeywords()
static int static int
@ -147,7 +148,9 @@ bytearray_find(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
goto exit; goto exit;
} }
skip_optional: skip_optional:
Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_find_impl((PyByteArrayObject *)self, sub, start, end); return_value = bytearray_find_impl((PyByteArrayObject *)self, sub, start, end);
Py_END_CRITICAL_SECTION();
exit: exit:
return return_value; return return_value;
@ -196,7 +199,9 @@ bytearray_count(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
goto exit; goto exit;
} }
skip_optional: skip_optional:
Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_count_impl((PyByteArrayObject *)self, sub, start, end); return_value = bytearray_count_impl((PyByteArrayObject *)self, sub, start, end);
Py_END_CRITICAL_SECTION();
exit: exit:
return return_value; return return_value;
@ -235,7 +240,13 @@ bytearray_copy_impl(PyByteArrayObject *self);
static PyObject * static PyObject *
bytearray_copy(PyObject *self, PyObject *Py_UNUSED(ignored)) 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__, PyDoc_STRVAR(bytearray_index__doc__,
@ -283,7 +294,9 @@ bytearray_index(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
goto exit; goto exit;
} }
skip_optional: skip_optional:
Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_index_impl((PyByteArrayObject *)self, sub, start, end); return_value = bytearray_index_impl((PyByteArrayObject *)self, sub, start, end);
Py_END_CRITICAL_SECTION();
exit: exit:
return return_value; return return_value;
@ -334,7 +347,9 @@ bytearray_rfind(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
goto exit; goto exit;
} }
skip_optional: skip_optional:
Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_rfind_impl((PyByteArrayObject *)self, sub, start, end); return_value = bytearray_rfind_impl((PyByteArrayObject *)self, sub, start, end);
Py_END_CRITICAL_SECTION();
exit: exit:
return return_value; return return_value;
@ -385,7 +400,9 @@ bytearray_rindex(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
goto exit; goto exit;
} }
skip_optional: skip_optional:
Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_rindex_impl((PyByteArrayObject *)self, sub, start, end); return_value = bytearray_rindex_impl((PyByteArrayObject *)self, sub, start, end);
Py_END_CRITICAL_SECTION();
exit: exit:
return return_value; return return_value;
@ -436,7 +453,9 @@ bytearray_startswith(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
goto exit; goto exit;
} }
skip_optional: skip_optional:
Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_startswith_impl((PyByteArrayObject *)self, subobj, start, end); return_value = bytearray_startswith_impl((PyByteArrayObject *)self, subobj, start, end);
Py_END_CRITICAL_SECTION();
exit: exit:
return return_value; return return_value;
@ -487,7 +506,9 @@ bytearray_endswith(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
goto exit; goto exit;
} }
skip_optional: skip_optional:
Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_endswith_impl((PyByteArrayObject *)self, subobj, start, end); return_value = bytearray_endswith_impl((PyByteArrayObject *)self, subobj, start, end);
Py_END_CRITICAL_SECTION();
exit: exit:
return return_value; return return_value;
@ -518,7 +539,9 @@ bytearray_removeprefix(PyObject *self, PyObject *arg)
if (PyObject_GetBuffer(arg, &prefix, PyBUF_SIMPLE) != 0) { if (PyObject_GetBuffer(arg, &prefix, PyBUF_SIMPLE) != 0) {
goto exit; goto exit;
} }
Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_removeprefix_impl((PyByteArrayObject *)self, &prefix); return_value = bytearray_removeprefix_impl((PyByteArrayObject *)self, &prefix);
Py_END_CRITICAL_SECTION();
exit: exit:
/* Cleanup for prefix */ /* Cleanup for prefix */
@ -554,7 +577,9 @@ bytearray_removesuffix(PyObject *self, PyObject *arg)
if (PyObject_GetBuffer(arg, &suffix, PyBUF_SIMPLE) != 0) { if (PyObject_GetBuffer(arg, &suffix, PyBUF_SIMPLE) != 0) {
goto exit; goto exit;
} }
Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_removesuffix_impl((PyByteArrayObject *)self, &suffix); return_value = bytearray_removesuffix_impl((PyByteArrayObject *)self, &suffix);
Py_END_CRITICAL_SECTION();
exit: exit:
/* Cleanup for suffix */ /* Cleanup for suffix */
@ -668,7 +693,9 @@ bytearray_translate(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyO
} }
deletechars = args[1]; deletechars = args[1];
skip_optional_pos: skip_optional_pos:
Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_translate_impl((PyByteArrayObject *)self, table, deletechars); return_value = bytearray_translate_impl((PyByteArrayObject *)self, table, deletechars);
Py_END_CRITICAL_SECTION();
exit: exit:
return return_value; return return_value;
@ -775,7 +802,9 @@ bytearray_replace(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
count = ival; count = ival;
} }
skip_optional: skip_optional:
Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_replace_impl((PyByteArrayObject *)self, &old, &new, count); return_value = bytearray_replace_impl((PyByteArrayObject *)self, &old, &new, count);
Py_END_CRITICAL_SECTION();
exit: exit:
/* Cleanup for old */ /* Cleanup for old */
@ -872,7 +901,9 @@ bytearray_split(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObjec
maxsplit = ival; maxsplit = ival;
} }
skip_optional_pos: skip_optional_pos:
Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_split_impl((PyByteArrayObject *)self, sep, maxsplit); return_value = bytearray_split_impl((PyByteArrayObject *)self, sep, maxsplit);
Py_END_CRITICAL_SECTION();
exit: exit:
return return_value; return return_value;
@ -894,6 +925,21 @@ PyDoc_STRVAR(bytearray_partition__doc__,
#define BYTEARRAY_PARTITION_METHODDEF \ #define BYTEARRAY_PARTITION_METHODDEF \
{"partition", (PyCFunction)bytearray_partition, METH_O, bytearray_partition__doc__}, {"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__, PyDoc_STRVAR(bytearray_rpartition__doc__,
"rpartition($self, sep, /)\n" "rpartition($self, sep, /)\n"
"--\n" "--\n"
@ -911,6 +957,21 @@ PyDoc_STRVAR(bytearray_rpartition__doc__,
#define BYTEARRAY_RPARTITION_METHODDEF \ #define BYTEARRAY_RPARTITION_METHODDEF \
{"rpartition", (PyCFunction)bytearray_rpartition, METH_O, bytearray_rpartition__doc__}, {"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__, PyDoc_STRVAR(bytearray_rsplit__doc__,
"rsplit($self, /, sep=None, maxsplit=-1)\n" "rsplit($self, /, sep=None, maxsplit=-1)\n"
"--\n" "--\n"
@ -995,7 +1056,9 @@ bytearray_rsplit(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje
maxsplit = ival; maxsplit = ival;
} }
skip_optional_pos: skip_optional_pos:
Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_rsplit_impl((PyByteArrayObject *)self, sep, maxsplit); return_value = bytearray_rsplit_impl((PyByteArrayObject *)self, sep, maxsplit);
Py_END_CRITICAL_SECTION();
exit: exit:
return return_value; return return_value;
@ -1016,7 +1079,13 @@ bytearray_reverse_impl(PyByteArrayObject *self);
static PyObject * static PyObject *
bytearray_reverse(PyObject *self, PyObject *Py_UNUSED(ignored)) 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__, PyDoc_STRVAR(bytearray_insert__doc__,
@ -1061,7 +1130,9 @@ bytearray_insert(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
if (!_getbytevalue(args[1], &item)) { if (!_getbytevalue(args[1], &item)) {
goto exit; goto exit;
} }
Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_insert_impl((PyByteArrayObject *)self, index, item); return_value = bytearray_insert_impl((PyByteArrayObject *)self, index, item);
Py_END_CRITICAL_SECTION();
exit: exit:
return return_value; return return_value;
@ -1091,7 +1162,9 @@ bytearray_append(PyObject *self, PyObject *arg)
if (!_getbytevalue(arg, &item)) { if (!_getbytevalue(arg, &item)) {
goto exit; goto exit;
} }
Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_append_impl((PyByteArrayObject *)self, item); return_value = bytearray_append_impl((PyByteArrayObject *)self, item);
Py_END_CRITICAL_SECTION();
exit: exit:
return return_value; return return_value;
@ -1109,6 +1182,21 @@ PyDoc_STRVAR(bytearray_extend__doc__,
#define BYTEARRAY_EXTEND_METHODDEF \ #define BYTEARRAY_EXTEND_METHODDEF \
{"extend", (PyCFunction)bytearray_extend, METH_O, bytearray_extend__doc__}, {"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__, PyDoc_STRVAR(bytearray_pop__doc__,
"pop($self, index=-1, /)\n" "pop($self, index=-1, /)\n"
"--\n" "--\n"
@ -1152,7 +1240,9 @@ bytearray_pop(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
index = ival; index = ival;
} }
skip_optional: skip_optional:
Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_pop_impl((PyByteArrayObject *)self, index); return_value = bytearray_pop_impl((PyByteArrayObject *)self, index);
Py_END_CRITICAL_SECTION();
exit: exit:
return return_value; return return_value;
@ -1182,7 +1272,9 @@ bytearray_remove(PyObject *self, PyObject *arg)
if (!_getbytevalue(arg, &value)) { if (!_getbytevalue(arg, &value)) {
goto exit; goto exit;
} }
Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_remove_impl((PyByteArrayObject *)self, value); return_value = bytearray_remove_impl((PyByteArrayObject *)self, value);
Py_END_CRITICAL_SECTION();
exit: exit:
return return_value; return return_value;
@ -1216,7 +1308,9 @@ bytearray_strip(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
} }
bytes = args[0]; bytes = args[0];
skip_optional: skip_optional:
Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_strip_impl((PyByteArrayObject *)self, bytes); return_value = bytearray_strip_impl((PyByteArrayObject *)self, bytes);
Py_END_CRITICAL_SECTION();
exit: exit:
return return_value; return return_value;
@ -1250,7 +1344,9 @@ bytearray_lstrip(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
} }
bytes = args[0]; bytes = args[0];
skip_optional: skip_optional:
Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_lstrip_impl((PyByteArrayObject *)self, bytes); return_value = bytearray_lstrip_impl((PyByteArrayObject *)self, bytes);
Py_END_CRITICAL_SECTION();
exit: exit:
return return_value; return return_value;
@ -1284,7 +1380,9 @@ bytearray_rstrip(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
} }
bytes = args[0]; bytes = args[0];
skip_optional: skip_optional:
Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_rstrip_impl((PyByteArrayObject *)self, bytes); return_value = bytearray_rstrip_impl((PyByteArrayObject *)self, bytes);
Py_END_CRITICAL_SECTION();
exit: exit:
return return_value; return return_value;
@ -1386,7 +1484,9 @@ bytearray_decode(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje
goto exit; goto exit;
} }
skip_optional_pos: skip_optional_pos:
Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_decode_impl((PyByteArrayObject *)self, encoding, errors); return_value = bytearray_decode_impl((PyByteArrayObject *)self, encoding, errors);
Py_END_CRITICAL_SECTION();
exit: exit:
return return_value; return return_value;
@ -1405,6 +1505,21 @@ PyDoc_STRVAR(bytearray_join__doc__,
#define BYTEARRAY_JOIN_METHODDEF \ #define BYTEARRAY_JOIN_METHODDEF \
{"join", (PyCFunction)bytearray_join, METH_O, bytearray_join__doc__}, {"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__, PyDoc_STRVAR(bytearray_splitlines__doc__,
"splitlines($self, /, keepends=False)\n" "splitlines($self, /, keepends=False)\n"
"--\n" "--\n"
@ -1466,7 +1581,9 @@ bytearray_splitlines(PyObject *self, PyObject *const *args, Py_ssize_t nargs, Py
goto exit; goto exit;
} }
skip_optional_pos: skip_optional_pos:
Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_splitlines_impl((PyByteArrayObject *)self, keepends); return_value = bytearray_splitlines_impl((PyByteArrayObject *)self, keepends);
Py_END_CRITICAL_SECTION();
exit: exit:
return return_value; return return_value;
@ -1586,7 +1703,9 @@ bytearray_hex(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject
goto exit; goto exit;
} }
skip_optional_pos: skip_optional_pos:
Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_hex_impl((PyByteArrayObject *)self, sep, bytes_per_sep); return_value = bytearray_hex_impl((PyByteArrayObject *)self, sep, bytes_per_sep);
Py_END_CRITICAL_SECTION();
exit: exit:
return return_value; return return_value;
@ -1607,7 +1726,13 @@ bytearray_reduce_impl(PyByteArrayObject *self);
static PyObject * static PyObject *
bytearray_reduce(PyObject *self, PyObject *Py_UNUSED(ignored)) 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__, PyDoc_STRVAR(bytearray_reduce_ex__doc__,
@ -1639,7 +1764,9 @@ bytearray_reduce_ex(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
goto exit; goto exit;
} }
skip_optional: skip_optional:
Py_BEGIN_CRITICAL_SECTION(self);
return_value = bytearray_reduce_ex_impl((PyByteArrayObject *)self, proto); return_value = bytearray_reduce_ex_impl((PyByteArrayObject *)self, proto);
Py_END_CRITICAL_SECTION();
exit: exit:
return return_value; return return_value;
@ -1662,4 +1789,4 @@ bytearray_sizeof(PyObject *self, PyObject *Py_UNUSED(ignored))
{ {
return bytearray_sizeof_impl((PyByteArrayObject *)self); return bytearray_sizeof_impl((PyByteArrayObject *)self);
} }
/*[clinic end generated code: output=41bb67a8a181e733 input=a9049054013a1b77]*/ /*[clinic end generated code: output=5e33422343b47af9 input=a9049054013a1b77]*/