@@ -938,34 +938,36 @@ Tests are in ``tests/unit/test_c_seqobject.py`` which includes failure modes:
938
938
Implementation
939
939
--------------
940
940
941
+ .. warning ::
942
+
943
+ There is an undocumented feature when using `sq_ass_item ` from `PyObject_SetItem() `_ and `PyObject_DelItem() `_
944
+ when using negative indexes when the negative index is *out of range *.
945
+ In this case, before the `sq_ass_item ` function is called the index will have had the sequence length added to it.
946
+
947
+ For example if the sequence length is 3 and the given index is -4 then the index that the `sq_ass_item ` function
948
+ receives is -1.
949
+ If the given index is -5 then the index that the `sq_ass_item ` function receives is -2.
950
+
951
+ Thus the slightly odd code below to fix this problem.
952
+ Failing to do this will mean out of range errors will not be detected by the `sq_ass_item ` function.
953
+
954
+
941
955
In ``src/cpy/Object/cSeqObject.c ``:
942
956
943
957
.. code-block :: c
944
958
945
959
static int
946
960
SequenceLongObject_sq_ass_item(PyObject *self, Py_ssize_t index, PyObject *value) {
947
- fprintf(
948
- stdout, "%s()#%d: self=%p index=%zd value=%p\n",
949
- __FUNCTION__, __LINE__, (void *) self, index, (void *) value
950
- );
951
- /* This is very weird. */
961
+ /* See warning above. */
952
962
if (index < 0) {
953
- fprintf(
954
- stdout, "%s()#%d: Fixing index index=%zd to %zd\n", __FUNCTION__, __LINE__,
955
- index, index - SequenceLongObject_sq_length(self)
956
- );
957
963
index -= SequenceLongObject_sq_length(self);
958
964
}
959
- /* Isn't it? */
965
+
960
966
Py_ssize_t my_index = index;
961
967
if (my_index < 0) {
962
968
my_index += SequenceLongObject_sq_length(self);
963
969
}
964
970
// Corner case example: len(self) == 0 and index < 0
965
- fprintf(
966
- stdout, "%s()#%d: len=%zd index=%zd my_index=%zd\n", __FUNCTION__, __LINE__,
967
- SequenceLongObject_sq_length(self), index, my_index
968
- );
969
971
if (my_index < 0 || my_index >= SequenceLongObject_sq_length(self)) {
970
972
PyErr_Format(
971
973
PyExc_IndexError,
@@ -992,13 +994,11 @@ In ``src/cpy/Object/cSeqObject.c``:
992
994
SequenceLongObject *self_as_slo = (SequenceLongObject *) self;
993
995
/* Special case: deleting the only item in the array. */
994
996
if (self_as_slo->size == 1) {
995
- fprintf(stdout, "%s()#%d: deleting empty index\n", __FUNCTION__, __LINE__);
996
997
free(self_as_slo->array_long);
997
998
self_as_slo->array_long = NULL;
998
999
self_as_slo->size = 0;
999
1000
} else {
1000
1001
/* Delete the value and re-compose the array. */
1001
- fprintf(stdout, "%s()#%d: deleting index=%zd\n", __FUNCTION__, __LINE__, index);
1002
1002
long *new_array = malloc((self_as_slo->size - 1) * sizeof(long));
1003
1003
if (!new_array) {
1004
1004
PyErr_Format(
0 commit comments