[Python-checkins] gh-94808: add tests covering `PySequence_{Set, Del}Slice` (GH-99123)
miss-islington
webhook-mailer at python.org
Sat Nov 5 13:32:51 EDT 2022
https://github.com/python/cpython/commit/d8c11b75e2669c28f2a020883783f281f29864a4
commit: d8c11b75e2669c28f2a020883783f281f29864a4
branch: 3.11
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: miss-islington <31488909+miss-islington at users.noreply.github.com>
date: 2022-11-05T10:32:46-07:00
summary:
gh-94808: add tests covering `PySequence_{Set,Del}Slice` (GH-99123)
(cherry picked from commit c5c40773cbadc8c35212877ea315a375f3bfaa4b)
Co-authored-by: Nikita Sobolev <mail at sobolevn.me>
files:
M Lib/test/test_capi.py
M Modules/_testcapimodule.c
diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py
index 3e6549625870..b30b8d18d8aa 100644
--- a/Lib/test/test_capi.py
+++ b/Lib/test/test_capi.py
@@ -415,6 +415,86 @@ class SubDict(dict):
self.assertTrue(_testcapi.mapping_has_key(dct2, 'a'))
self.assertFalse(_testcapi.mapping_has_key(dct2, 'b'))
+ def test_sequence_set_slice(self):
+ # Correct case:
+ data = [1, 2, 3, 4, 5]
+ data_copy = data.copy()
+
+ _testcapi.sequence_set_slice(data, 1, 3, [8, 9])
+ data_copy[1:3] = [8, 9]
+ self.assertEqual(data, data_copy)
+ self.assertEqual(data, [1, 8, 9, 4, 5])
+
+ # Custom class:
+ class Custom:
+ def __setitem__(self, index, value):
+ self.index = index
+ self.value = value
+
+ c = Custom()
+ _testcapi.sequence_set_slice(c, 0, 5, 'abc')
+ self.assertEqual(c.index, slice(0, 5))
+ self.assertEqual(c.value, 'abc')
+
+ # Immutable sequences must raise:
+ bad_seq1 = (1, 2, 3, 4)
+ with self.assertRaises(TypeError):
+ _testcapi.sequence_set_slice(bad_seq1, 1, 3, (8, 9))
+ self.assertEqual(bad_seq1, (1, 2, 3, 4))
+
+ bad_seq2 = 'abcd'
+ with self.assertRaises(TypeError):
+ _testcapi.sequence_set_slice(bad_seq2, 1, 3, 'xy')
+ self.assertEqual(bad_seq2, 'abcd')
+
+ # Not a sequence:
+ with self.assertRaises(TypeError):
+ _testcapi.sequence_set_slice(None, 1, 3, 'xy')
+
+ mapping = {1: 'a', 2: 'b', 3: 'c'}
+ with self.assertRaises(TypeError):
+ _testcapi.sequence_set_slice(mapping, 1, 3, 'xy')
+ self.assertEqual(mapping, {1: 'a', 2: 'b', 3: 'c'})
+
+ def test_sequence_del_slice(self):
+ # Correct case:
+ data = [1, 2, 3, 4, 5]
+ data_copy = data.copy()
+
+ _testcapi.sequence_del_slice(data, 1, 3)
+ del data_copy[1:3]
+ self.assertEqual(data, data_copy)
+ self.assertEqual(data, [1, 4, 5])
+
+ # Custom class:
+ class Custom:
+ def __delitem__(self, index):
+ self.index = index
+
+ c = Custom()
+ _testcapi.sequence_del_slice(c, 0, 5)
+ self.assertEqual(c.index, slice(0, 5))
+
+ # Immutable sequences must raise:
+ bad_seq1 = (1, 2, 3, 4)
+ with self.assertRaises(TypeError):
+ _testcapi.sequence_del_slice(bad_seq1, 1, 3)
+ self.assertEqual(bad_seq1, (1, 2, 3, 4))
+
+ bad_seq2 = 'abcd'
+ with self.assertRaises(TypeError):
+ _testcapi.sequence_del_slice(bad_seq2, 1, 3)
+ self.assertEqual(bad_seq2, 'abcd')
+
+ # Not a sequence:
+ with self.assertRaises(TypeError):
+ _testcapi.sequence_del_slice(None, 1, 3)
+
+ mapping = {1: 'a', 2: 'b', 3: 'c'}
+ with self.assertRaises(TypeError):
+ _testcapi.sequence_del_slice(mapping, 1, 3)
+ self.assertEqual(mapping, {1: 'a', 2: 'b', 3: 'c'})
+
@unittest.skipUnless(hasattr(_testcapi, 'negative_refcount'),
'need _testcapi.negative_refcount')
def test_negative_refcount(self):
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index 3ec91bf14cfc..1291eff481cb 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -5382,6 +5382,37 @@ mapping_has_key(PyObject* self, PyObject *args)
return PyLong_FromLong(PyMapping_HasKey(context, key));
}
+static PyObject *
+sequence_set_slice(PyObject* self, PyObject *args)
+{
+ PyObject *sequence, *obj;
+ Py_ssize_t i1, i2;
+ if (!PyArg_ParseTuple(args, "OnnO", &sequence, &i1, &i2, &obj)) {
+ return NULL;
+ }
+
+ int res = PySequence_SetSlice(sequence, i1, i2, obj);
+ if (res == -1) {
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
+static PyObject *
+sequence_del_slice(PyObject* self, PyObject *args)
+{
+ PyObject *sequence;
+ Py_ssize_t i1, i2;
+ if (!PyArg_ParseTuple(args, "Onn", &sequence, &i1, &i2)) {
+ return NULL;
+ }
+
+ int res = PySequence_DelSlice(sequence, i1, i2);
+ if (res == -1) {
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
static PyObject *
test_pythread_tss_key_state(PyObject *self, PyObject *args)
@@ -6424,6 +6455,8 @@ static PyMethodDef TestMethods[] = {
{"get_mapping_items", get_mapping_items, METH_O},
{"test_mapping_has_key_string", test_mapping_has_key_string, METH_NOARGS},
{"mapping_has_key", mapping_has_key, METH_VARARGS},
+ {"sequence_set_slice", sequence_set_slice, METH_VARARGS},
+ {"sequence_del_slice", sequence_del_slice, METH_VARARGS},
{"test_pythread_tss_key_state", test_pythread_tss_key_state, METH_VARARGS},
{"hamt", new_hamt, METH_NOARGS},
{"bad_get", _PyCFunction_CAST(bad_get), METH_FASTCALL},
More information about the Python-checkins
mailing list