Skip to content

Commit 5f24775

Browse files
committed
gh-94808: Add coverage for bytesarray_setitem
1 parent 62f0650 commit 5f24775

File tree

2 files changed

+86
-41
lines changed

2 files changed

+86
-41
lines changed

Lib/test/test_bytes.py

+70-41
Original file line numberDiff line numberDiff line change
@@ -1207,6 +1207,8 @@ class SubBytes(bytes):
12071207
class ByteArrayTest(BaseBytesTest, unittest.TestCase):
12081208
type2test = bytearray
12091209

1210+
_testcapi = import_helper.import_module('_testcapi')
1211+
12101212
def test_getitem_error(self):
12111213
b = bytearray(b'python')
12121214
msg = "bytearray indices must be integers or slices"
@@ -1299,47 +1301,73 @@ def by(s):
12991301
self.assertEqual(re.findall(br"\w+", b), [by("Hello"), by("world")])
13001302

13011303
def test_setitem(self):
1302-
b = bytearray([1, 2, 3])
1303-
b[1] = 100
1304-
self.assertEqual(b, bytearray([1, 100, 3]))
1305-
b[-1] = 200
1306-
self.assertEqual(b, bytearray([1, 100, 200]))
1307-
b[0] = Indexable(10)
1308-
self.assertEqual(b, bytearray([10, 100, 200]))
1309-
try:
1310-
b[3] = 0
1311-
self.fail("Didn't raise IndexError")
1312-
except IndexError:
1313-
pass
1314-
try:
1315-
b[-10] = 0
1316-
self.fail("Didn't raise IndexError")
1317-
except IndexError:
1318-
pass
1319-
try:
1320-
b[0] = 256
1321-
self.fail("Didn't raise ValueError")
1322-
except ValueError:
1323-
pass
1324-
try:
1325-
b[0] = Indexable(-1)
1326-
self.fail("Didn't raise ValueError")
1327-
except ValueError:
1328-
pass
1329-
try:
1330-
b[0] = None
1331-
self.fail("Didn't raise TypeError")
1332-
except TypeError:
1333-
pass
1304+
def setitem_as_mapping(b, i, val):
1305+
b[i] = val
1306+
1307+
def setitem_as_sequence(b, i, val):
1308+
self._testcapi.sequence_setitem(b, i, val)
1309+
1310+
def do_tests(setitem):
1311+
b = bytearray([1, 2, 3])
1312+
setitem(b, 1, 100)
1313+
self.assertEqual(b, bytearray([1, 100, 3]))
1314+
setitem(b, -1, 200)
1315+
self.assertEqual(b, bytearray([1, 100, 200]))
1316+
setitem(b, 0, Indexable(10))
1317+
self.assertEqual(b, bytearray([10, 100, 200]))
1318+
try:
1319+
setitem(b, 3, 0)
1320+
self.fail("Didn't raise IndexError")
1321+
except IndexError:
1322+
pass
1323+
try:
1324+
setitem(b, -10, 0)
1325+
self.fail("Didn't raise IndexError")
1326+
except IndexError:
1327+
pass
1328+
try:
1329+
setitem(b, 0, 256)
1330+
self.fail("Didn't raise ValueError")
1331+
except ValueError:
1332+
pass
1333+
try:
1334+
setitem(b, 0, Indexable(-1))
1335+
self.fail("Didn't raise ValueError")
1336+
except ValueError:
1337+
pass
1338+
try:
1339+
setitem(b, 0, None)
1340+
self.fail("Didn't raise TypeError")
1341+
except TypeError:
1342+
pass
1343+
1344+
with self.subTest("tp_as_mapping"):
1345+
do_tests(setitem_as_mapping)
1346+
1347+
with self.subTest("tp_as_sequence"):
1348+
do_tests(setitem_as_sequence)
13341349

13351350
def test_delitem(self):
1336-
b = bytearray(range(10))
1337-
del b[0]
1338-
self.assertEqual(b, bytearray(range(1, 10)))
1339-
del b[-1]
1340-
self.assertEqual(b, bytearray(range(1, 9)))
1341-
del b[4]
1342-
self.assertEqual(b, bytearray([1, 2, 3, 4, 6, 7, 8]))
1351+
def del_as_mapping(b, i):
1352+
del b[i]
1353+
1354+
def del_as_sequence(b, i):
1355+
self._testcapi.sequence_delitem(b, i)
1356+
1357+
def do_tests(delete):
1358+
b = bytearray(range(10))
1359+
delete(b, 0)
1360+
self.assertEqual(b, bytearray(range(1, 10)))
1361+
delete(b, -1)
1362+
self.assertEqual(b, bytearray(range(1, 9)))
1363+
delete(b, 4)
1364+
self.assertEqual(b, bytearray([1, 2, 3, 4, 6, 7, 8]))
1365+
1366+
with self.subTest("tp_as_mapping"):
1367+
do_tests(del_as_mapping)
1368+
1369+
with self.subTest("tp_as_sequence"):
1370+
do_tests(del_as_sequence)
13431371

13441372
def test_setslice(self):
13451373
b = bytearray(range(10))
@@ -1711,6 +1739,8 @@ def test_repeat_after_setslice(self):
17111739
self.assertEqual(b3, b'xcxcxc')
17121740

17131741
def test_mutating_index(self):
1742+
# See gh-91153
1743+
17141744
class Boom:
17151745
def __index__(self):
17161746
b.clear()
@@ -1722,10 +1752,9 @@ def __index__(self):
17221752
b[0] = Boom()
17231753

17241754
with self.subTest("tp_as_sequence"):
1725-
_testcapi = import_helper.import_module('_testcapi')
17261755
b = bytearray(b'Now you see me...')
17271756
with self.assertRaises(IndexError):
1728-
_testcapi.sequence_setitem(b, 0, Boom())
1757+
self._testcapi.sequence_setitem(b, 0, Boom())
17291758

17301759

17311760
class AssortedBytesTest(unittest.TestCase):

Modules/_testcapimodule.c

+16
Original file line numberDiff line numberDiff line change
@@ -5152,6 +5152,21 @@ sequence_setitem(PyObject *self, PyObject *args)
51525152
}
51535153

51545154

5155+
static PyObject *
5156+
sequence_delitem(PyObject *self, PyObject *args)
5157+
{
5158+
Py_ssize_t i;
5159+
PyObject *seq;
5160+
if (!PyArg_ParseTuple(args, "On", &seq, &i)) {
5161+
return NULL;
5162+
}
5163+
if (PySequence_DelItem(seq, i)) {
5164+
return NULL;
5165+
}
5166+
Py_RETURN_NONE;
5167+
}
5168+
5169+
51555170
/* Functions for testing C calling conventions (METH_*) are named meth_*,
51565171
* e.g. "meth_varargs" for METH_VARARGS.
51575172
*
@@ -6026,6 +6041,7 @@ static PyMethodDef TestMethods[] = {
60266041
{"write_unraisable_exc", test_write_unraisable_exc, METH_VARARGS},
60276042
{"sequence_getitem", sequence_getitem, METH_VARARGS},
60286043
{"sequence_setitem", sequence_setitem, METH_VARARGS},
6044+
{"sequence_delitem", sequence_delitem, METH_VARARGS},
60296045
{"meth_varargs", meth_varargs, METH_VARARGS},
60306046
{"meth_varargs_keywords", _PyCFunction_CAST(meth_varargs_keywords), METH_VARARGS|METH_KEYWORDS},
60316047
{"meth_o", meth_o, METH_O},

0 commit comments

Comments
 (0)