Skip to content

Commit dfcdee4

Browse files
authored
gh-94808: Add coverage for bytesarray_setitem (#95802)
1 parent 187e853 commit dfcdee4

File tree

2 files changed

+85
-41
lines changed

2 files changed

+85
-41
lines changed

Lib/test/test_bytes.py

+70-41
Original file line numberDiff line numberDiff line change
@@ -1225,6 +1225,8 @@ class SubBytes(bytes):
12251225
class ByteArrayTest(BaseBytesTest, unittest.TestCase):
12261226
type2test = bytearray
12271227

1228+
_testcapi = import_helper.import_module('_testcapi')
1229+
12281230
def test_getitem_error(self):
12291231
b = bytearray(b'python')
12301232
msg = "bytearray indices must be integers or slices"
@@ -1317,47 +1319,73 @@ def by(s):
13171319
self.assertEqual(re.findall(br"\w+", b), [by("Hello"), by("world")])
13181320

13191321
def test_setitem(self):
1320-
b = bytearray([1, 2, 3])
1321-
b[1] = 100
1322-
self.assertEqual(b, bytearray([1, 100, 3]))
1323-
b[-1] = 200
1324-
self.assertEqual(b, bytearray([1, 100, 200]))
1325-
b[0] = Indexable(10)
1326-
self.assertEqual(b, bytearray([10, 100, 200]))
1327-
try:
1328-
b[3] = 0
1329-
self.fail("Didn't raise IndexError")
1330-
except IndexError:
1331-
pass
1332-
try:
1333-
b[-10] = 0
1334-
self.fail("Didn't raise IndexError")
1335-
except IndexError:
1336-
pass
1337-
try:
1338-
b[0] = 256
1339-
self.fail("Didn't raise ValueError")
1340-
except ValueError:
1341-
pass
1342-
try:
1343-
b[0] = Indexable(-1)
1344-
self.fail("Didn't raise ValueError")
1345-
except ValueError:
1346-
pass
1347-
try:
1348-
b[0] = None
1349-
self.fail("Didn't raise TypeError")
1350-
except TypeError:
1351-
pass
1322+
def setitem_as_mapping(b, i, val):
1323+
b[i] = val
1324+
1325+
def setitem_as_sequence(b, i, val):
1326+
self._testcapi.sequence_setitem(b, i, val)
1327+
1328+
def do_tests(setitem):
1329+
b = bytearray([1, 2, 3])
1330+
setitem(b, 1, 100)
1331+
self.assertEqual(b, bytearray([1, 100, 3]))
1332+
setitem(b, -1, 200)
1333+
self.assertEqual(b, bytearray([1, 100, 200]))
1334+
setitem(b, 0, Indexable(10))
1335+
self.assertEqual(b, bytearray([10, 100, 200]))
1336+
try:
1337+
setitem(b, 3, 0)
1338+
self.fail("Didn't raise IndexError")
1339+
except IndexError:
1340+
pass
1341+
try:
1342+
setitem(b, -10, 0)
1343+
self.fail("Didn't raise IndexError")
1344+
except IndexError:
1345+
pass
1346+
try:
1347+
setitem(b, 0, 256)
1348+
self.fail("Didn't raise ValueError")
1349+
except ValueError:
1350+
pass
1351+
try:
1352+
setitem(b, 0, Indexable(-1))
1353+
self.fail("Didn't raise ValueError")
1354+
except ValueError:
1355+
pass
1356+
try:
1357+
setitem(b, 0, None)
1358+
self.fail("Didn't raise TypeError")
1359+
except TypeError:
1360+
pass
1361+
1362+
with self.subTest("tp_as_mapping"):
1363+
do_tests(setitem_as_mapping)
1364+
1365+
with self.subTest("tp_as_sequence"):
1366+
do_tests(setitem_as_sequence)
13521367

13531368
def test_delitem(self):
1354-
b = bytearray(range(10))
1355-
del b[0]
1356-
self.assertEqual(b, bytearray(range(1, 10)))
1357-
del b[-1]
1358-
self.assertEqual(b, bytearray(range(1, 9)))
1359-
del b[4]
1360-
self.assertEqual(b, bytearray([1, 2, 3, 4, 6, 7, 8]))
1369+
def del_as_mapping(b, i):
1370+
del b[i]
1371+
1372+
def del_as_sequence(b, i):
1373+
self._testcapi.sequence_delitem(b, i)
1374+
1375+
def do_tests(delete):
1376+
b = bytearray(range(10))
1377+
delete(b, 0)
1378+
self.assertEqual(b, bytearray(range(1, 10)))
1379+
delete(b, -1)
1380+
self.assertEqual(b, bytearray(range(1, 9)))
1381+
delete(b, 4)
1382+
self.assertEqual(b, bytearray([1, 2, 3, 4, 6, 7, 8]))
1383+
1384+
with self.subTest("tp_as_mapping"):
1385+
do_tests(del_as_mapping)
1386+
1387+
with self.subTest("tp_as_sequence"):
1388+
do_tests(del_as_sequence)
13611389

13621390
def test_setslice(self):
13631391
b = bytearray(range(10))
@@ -1729,6 +1757,8 @@ def test_repeat_after_setslice(self):
17291757
self.assertEqual(b3, b'xcxcxc')
17301758

17311759
def test_mutating_index(self):
1760+
# See gh-91153
1761+
17321762
class Boom:
17331763
def __index__(self):
17341764
b.clear()
@@ -1740,10 +1770,9 @@ def __index__(self):
17401770
b[0] = Boom()
17411771

17421772
with self.subTest("tp_as_sequence"):
1743-
_testcapi = import_helper.import_module('_testcapi')
17441773
b = bytearray(b'Now you see me...')
17451774
with self.assertRaises(IndexError):
1746-
_testcapi.sequence_setitem(b, 0, Boom())
1775+
self._testcapi.sequence_setitem(b, 0, Boom())
17471776

17481777

17491778
class AssortedBytesTest(unittest.TestCase):

Modules/_testcapimodule.c

+15
Original file line numberDiff line numberDiff line change
@@ -4846,6 +4846,20 @@ sequence_setitem(PyObject *self, PyObject *args)
48464846
}
48474847

48484848

4849+
static PyObject *
4850+
sequence_delitem(PyObject *self, PyObject *args)
4851+
{
4852+
Py_ssize_t i;
4853+
PyObject *seq;
4854+
if (!PyArg_ParseTuple(args, "On", &seq, &i)) {
4855+
return NULL;
4856+
}
4857+
if (PySequence_DelItem(seq, i)) {
4858+
return NULL;
4859+
}
4860+
Py_RETURN_NONE;
4861+
}
4862+
48494863
static PyObject *
48504864
hasattr_string(PyObject *self, PyObject* args)
48514865
{
@@ -5885,6 +5899,7 @@ static PyMethodDef TestMethods[] = {
58855899
{"write_unraisable_exc", test_write_unraisable_exc, METH_VARARGS},
58865900
{"sequence_getitem", sequence_getitem, METH_VARARGS},
58875901
{"sequence_setitem", sequence_setitem, METH_VARARGS},
5902+
{"sequence_delitem", sequence_delitem, METH_VARARGS},
58885903
{"hasattr_string", hasattr_string, METH_VARARGS},
58895904
{"meth_varargs", meth_varargs, METH_VARARGS},
58905905
{"meth_varargs_keywords", _PyCFunction_CAST(meth_varargs_keywords), METH_VARARGS|METH_KEYWORDS},

0 commit comments

Comments
 (0)