Skip to content

Commit

Permalink
pythongh-94808: Add coverage for bytesarray_setitem (python#95802)
Browse files Browse the repository at this point in the history
  • Loading branch information
mdboom authored and mpage committed Oct 11, 2022
1 parent 70a2708 commit fbfd13b
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 41 deletions.
111 changes: 70 additions & 41 deletions Lib/test/test_bytes.py
Original file line number Diff line number Diff line change
Expand Up @@ -1225,6 +1225,8 @@ class SubBytes(bytes):
class ByteArrayTest(BaseBytesTest, unittest.TestCase):
type2test = bytearray

_testcapi = import_helper.import_module('_testcapi')

def test_getitem_error(self):
b = bytearray(b'python')
msg = "bytearray indices must be integers or slices"
Expand Down Expand Up @@ -1317,47 +1319,73 @@ def by(s):
self.assertEqual(re.findall(br"\w+", b), [by("Hello"), by("world")])

def test_setitem(self):
b = bytearray([1, 2, 3])
b[1] = 100
self.assertEqual(b, bytearray([1, 100, 3]))
b[-1] = 200
self.assertEqual(b, bytearray([1, 100, 200]))
b[0] = Indexable(10)
self.assertEqual(b, bytearray([10, 100, 200]))
try:
b[3] = 0
self.fail("Didn't raise IndexError")
except IndexError:
pass
try:
b[-10] = 0
self.fail("Didn't raise IndexError")
except IndexError:
pass
try:
b[0] = 256
self.fail("Didn't raise ValueError")
except ValueError:
pass
try:
b[0] = Indexable(-1)
self.fail("Didn't raise ValueError")
except ValueError:
pass
try:
b[0] = None
self.fail("Didn't raise TypeError")
except TypeError:
pass
def setitem_as_mapping(b, i, val):
b[i] = val

def setitem_as_sequence(b, i, val):
self._testcapi.sequence_setitem(b, i, val)

def do_tests(setitem):
b = bytearray([1, 2, 3])
setitem(b, 1, 100)
self.assertEqual(b, bytearray([1, 100, 3]))
setitem(b, -1, 200)
self.assertEqual(b, bytearray([1, 100, 200]))
setitem(b, 0, Indexable(10))
self.assertEqual(b, bytearray([10, 100, 200]))
try:
setitem(b, 3, 0)
self.fail("Didn't raise IndexError")
except IndexError:
pass
try:
setitem(b, -10, 0)
self.fail("Didn't raise IndexError")
except IndexError:
pass
try:
setitem(b, 0, 256)
self.fail("Didn't raise ValueError")
except ValueError:
pass
try:
setitem(b, 0, Indexable(-1))
self.fail("Didn't raise ValueError")
except ValueError:
pass
try:
setitem(b, 0, None)
self.fail("Didn't raise TypeError")
except TypeError:
pass

with self.subTest("tp_as_mapping"):
do_tests(setitem_as_mapping)

with self.subTest("tp_as_sequence"):
do_tests(setitem_as_sequence)

def test_delitem(self):
b = bytearray(range(10))
del b[0]
self.assertEqual(b, bytearray(range(1, 10)))
del b[-1]
self.assertEqual(b, bytearray(range(1, 9)))
del b[4]
self.assertEqual(b, bytearray([1, 2, 3, 4, 6, 7, 8]))
def del_as_mapping(b, i):
del b[i]

def del_as_sequence(b, i):
self._testcapi.sequence_delitem(b, i)

def do_tests(delete):
b = bytearray(range(10))
delete(b, 0)
self.assertEqual(b, bytearray(range(1, 10)))
delete(b, -1)
self.assertEqual(b, bytearray(range(1, 9)))
delete(b, 4)
self.assertEqual(b, bytearray([1, 2, 3, 4, 6, 7, 8]))

with self.subTest("tp_as_mapping"):
do_tests(del_as_mapping)

with self.subTest("tp_as_sequence"):
do_tests(del_as_sequence)

def test_setslice(self):
b = bytearray(range(10))
Expand Down Expand Up @@ -1729,6 +1757,8 @@ def test_repeat_after_setslice(self):
self.assertEqual(b3, b'xcxcxc')

def test_mutating_index(self):
# See gh-91153

class Boom:
def __index__(self):
b.clear()
Expand All @@ -1740,10 +1770,9 @@ def __index__(self):
b[0] = Boom()

with self.subTest("tp_as_sequence"):
_testcapi = import_helper.import_module('_testcapi')
b = bytearray(b'Now you see me...')
with self.assertRaises(IndexError):
_testcapi.sequence_setitem(b, 0, Boom())
self._testcapi.sequence_setitem(b, 0, Boom())


class AssortedBytesTest(unittest.TestCase):
Expand Down
15 changes: 15 additions & 0 deletions Modules/_testcapimodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -4846,6 +4846,20 @@ sequence_setitem(PyObject *self, PyObject *args)
}


static PyObject *
sequence_delitem(PyObject *self, PyObject *args)
{
Py_ssize_t i;
PyObject *seq;
if (!PyArg_ParseTuple(args, "On", &seq, &i)) {
return NULL;
}
if (PySequence_DelItem(seq, i)) {
return NULL;
}
Py_RETURN_NONE;
}

static PyObject *
hasattr_string(PyObject *self, PyObject* args)
{
Expand Down Expand Up @@ -5885,6 +5899,7 @@ static PyMethodDef TestMethods[] = {
{"write_unraisable_exc", test_write_unraisable_exc, METH_VARARGS},
{"sequence_getitem", sequence_getitem, METH_VARARGS},
{"sequence_setitem", sequence_setitem, METH_VARARGS},
{"sequence_delitem", sequence_delitem, METH_VARARGS},
{"hasattr_string", hasattr_string, METH_VARARGS},
{"meth_varargs", meth_varargs, METH_VARARGS},
{"meth_varargs_keywords", _PyCFunction_CAST(meth_varargs_keywords), METH_VARARGS|METH_KEYWORDS},
Expand Down

0 comments on commit fbfd13b

Please sign in to comment.