summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/test/test_bytes.py111
-rw-r--r--Modules/_testcapimodule.c15
2 files changed, 85 insertions, 41 deletions
diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py
index 53ba1ad..7c62b72 100644
--- a/Lib/test/test_bytes.py
+++ b/Lib/test/test_bytes.py
@@ -1225,6 +1225,8 @@ class BytesTest(BaseBytesTest, unittest.TestCase):
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"
@@ -1317,47 +1319,73 @@ class ByteArrayTest(BaseBytesTest, unittest.TestCase):
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))
@@ -1729,6 +1757,8 @@ class ByteArrayTest(BaseBytesTest, unittest.TestCase):
self.assertEqual(b3, b'xcxcxc')
def test_mutating_index(self):
+ # See gh-91153
+
class Boom:
def __index__(self):
b.clear()
@@ -1740,10 +1770,9 @@ class ByteArrayTest(BaseBytesTest, unittest.TestCase):
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):
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index 173d7c2..95c67fc 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -4847,6 +4847,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)
{
PyObject* obj;
@@ -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},