gh-94808: Add coverage for bytesarray_setitem (#95802)

This commit is contained in:
Michael Droettboom 2022-10-10 11:28:41 -04:00 committed by GitHub
parent 187e853690
commit dfcdee4a18
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 85 additions and 41 deletions

View file

@ -1225,6 +1225,8 @@ class BytesTest(BaseBytesTest, unittest.TestCase):
class ByteArrayTest(BaseBytesTest, unittest.TestCase): class ByteArrayTest(BaseBytesTest, unittest.TestCase):
type2test = bytearray type2test = bytearray
_testcapi = import_helper.import_module('_testcapi')
def test_getitem_error(self): def test_getitem_error(self):
b = bytearray(b'python') b = bytearray(b'python')
msg = "bytearray indices must be integers or slices" msg = "bytearray indices must be integers or slices"
@ -1317,48 +1319,74 @@ class ByteArrayTest(BaseBytesTest, unittest.TestCase):
self.assertEqual(re.findall(br"\w+", b), [by("Hello"), by("world")]) self.assertEqual(re.findall(br"\w+", b), [by("Hello"), by("world")])
def test_setitem(self): def test_setitem(self):
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]) b = bytearray([1, 2, 3])
b[1] = 100 setitem(b, 1, 100)
self.assertEqual(b, bytearray([1, 100, 3])) self.assertEqual(b, bytearray([1, 100, 3]))
b[-1] = 200 setitem(b, -1, 200)
self.assertEqual(b, bytearray([1, 100, 200])) self.assertEqual(b, bytearray([1, 100, 200]))
b[0] = Indexable(10) setitem(b, 0, Indexable(10))
self.assertEqual(b, bytearray([10, 100, 200])) self.assertEqual(b, bytearray([10, 100, 200]))
try: try:
b[3] = 0 setitem(b, 3, 0)
self.fail("Didn't raise IndexError") self.fail("Didn't raise IndexError")
except IndexError: except IndexError:
pass pass
try: try:
b[-10] = 0 setitem(b, -10, 0)
self.fail("Didn't raise IndexError") self.fail("Didn't raise IndexError")
except IndexError: except IndexError:
pass pass
try: try:
b[0] = 256 setitem(b, 0, 256)
self.fail("Didn't raise ValueError") self.fail("Didn't raise ValueError")
except ValueError: except ValueError:
pass pass
try: try:
b[0] = Indexable(-1) setitem(b, 0, Indexable(-1))
self.fail("Didn't raise ValueError") self.fail("Didn't raise ValueError")
except ValueError: except ValueError:
pass pass
try: try:
b[0] = None setitem(b, 0, None)
self.fail("Didn't raise TypeError") self.fail("Didn't raise TypeError")
except TypeError: except TypeError:
pass 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): def test_delitem(self):
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)) b = bytearray(range(10))
del b[0] delete(b, 0)
self.assertEqual(b, bytearray(range(1, 10))) self.assertEqual(b, bytearray(range(1, 10)))
del b[-1] delete(b, -1)
self.assertEqual(b, bytearray(range(1, 9))) self.assertEqual(b, bytearray(range(1, 9)))
del b[4] delete(b, 4)
self.assertEqual(b, bytearray([1, 2, 3, 4, 6, 7, 8])) 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): def test_setslice(self):
b = bytearray(range(10)) b = bytearray(range(10))
self.assertEqual(list(b), list(range(10))) self.assertEqual(list(b), list(range(10)))
@ -1729,6 +1757,8 @@ class ByteArrayTest(BaseBytesTest, unittest.TestCase):
self.assertEqual(b3, b'xcxcxc') self.assertEqual(b3, b'xcxcxc')
def test_mutating_index(self): def test_mutating_index(self):
# See gh-91153
class Boom: class Boom:
def __index__(self): def __index__(self):
b.clear() b.clear()
@ -1740,10 +1770,9 @@ class ByteArrayTest(BaseBytesTest, unittest.TestCase):
b[0] = Boom() b[0] = Boom()
with self.subTest("tp_as_sequence"): with self.subTest("tp_as_sequence"):
_testcapi = import_helper.import_module('_testcapi')
b = bytearray(b'Now you see me...') b = bytearray(b'Now you see me...')
with self.assertRaises(IndexError): with self.assertRaises(IndexError):
_testcapi.sequence_setitem(b, 0, Boom()) self._testcapi.sequence_setitem(b, 0, Boom())
class AssortedBytesTest(unittest.TestCase): class AssortedBytesTest(unittest.TestCase):

View file

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