diff options
author | Guido van Rossum <guido@python.org> | 2001-08-17 21:57:47 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2001-08-17 21:57:47 (GMT) |
commit | 5d815f323bad407db37b428403df81d1b76018a5 (patch) | |
tree | 01f992bc9eec2929ec82e80ee4885e6c75bf3126 /Objects | |
parent | 65d5d7fac6b83b3ab4516cb8a4ae9698b3e5f186 (diff) | |
download | cpython-5d815f323bad407db37b428403df81d1b76018a5.zip cpython-5d815f323bad407db37b428403df81d1b76018a5.tar.gz cpython-5d815f323bad407db37b428403df81d1b76018a5.tar.bz2 |
Address SF bug #442813. The sequence getitem wrappers should do
interpretation of negative indices, since neither the sq_*item slots
nor the slot_ wrappers do this. (Slices are a different story, there
the size wrapping is done too early.)
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/typeobject.c | 58 |
1 files changed, 50 insertions, 8 deletions
diff --git a/Objects/typeobject.c b/Objects/typeobject.c index c49275b..f2e6f4d4 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -1661,8 +1661,43 @@ static struct wrapperbase tab_imul_int[] = { {0} }; +static int +getindex(PyObject *self, PyObject *arg) +{ + int i; + + i = PyInt_AsLong(arg); + if (i == -1 && PyErr_Occurred()) + return -1; + if (i < 0) { + PySequenceMethods *sq = self->ob_type->tp_as_sequence; + if (sq && sq->sq_length) { + int n = (*sq->sq_length)(self); + if (n < 0) + return -1; + i += n; + } + } + return i; +} + +static PyObject * +wrap_sq_item(PyObject *self, PyObject *args, void *wrapped) +{ + intargfunc func = (intargfunc)wrapped; + PyObject *arg; + int i; + + if (!PyArg_ParseTuple(args, "O", &arg)) + return NULL; + i = getindex(self, arg); + if (i == -1 && PyErr_Occurred()) + return NULL; + return (*func)(self, i); +} + static struct wrapperbase tab_getitem_int[] = { - {"__getitem__", (wrapperfunc)wrap_intargfunc, + {"__getitem__", (wrapperfunc)wrap_sq_item, "x.__getitem__(i) <==> x[i]"}, {0} }; @@ -1685,13 +1720,16 @@ static struct wrapperbase tab_getslice[] = { }; static PyObject * -wrap_intobjargproc(PyObject *self, PyObject *args, void *wrapped) +wrap_sq_setitem(PyObject *self, PyObject *args, void *wrapped) { intobjargproc func = (intobjargproc)wrapped; int i, res; - PyObject *value; + PyObject *arg, *value; - if (!PyArg_ParseTuple(args, "iO", &i, &value)) + if (!PyArg_ParseTuple(args, "OO", &arg, &value)) + return NULL; + i = getindex(self, arg); + if (i == -1 && PyErr_Occurred()) return NULL; res = (*func)(self, i, value); if (res == -1 && PyErr_Occurred()) @@ -1701,12 +1739,16 @@ wrap_intobjargproc(PyObject *self, PyObject *args, void *wrapped) } static PyObject * -wrap_delitem_int(PyObject *self, PyObject *args, void *wrapped) +wrap_sq_delitem(PyObject *self, PyObject *args, void *wrapped) { intobjargproc func = (intobjargproc)wrapped; int i, res; + PyObject *arg; - if (!PyArg_ParseTuple(args, "i", &i)) + if (!PyArg_ParseTuple(args, "O", &arg)) + return NULL; + i = getindex(self, arg); + if (i == -1 && PyErr_Occurred()) return NULL; res = (*func)(self, i, NULL); if (res == -1 && PyErr_Occurred()) @@ -1716,9 +1758,9 @@ wrap_delitem_int(PyObject *self, PyObject *args, void *wrapped) } static struct wrapperbase tab_setitem_int[] = { - {"__setitem__", (wrapperfunc)wrap_intobjargproc, + {"__setitem__", (wrapperfunc)wrap_sq_setitem, "x.__setitem__(i, y) <==> x[i]=y"}, - {"__delitem__", (wrapperfunc)wrap_delitem_int, + {"__delitem__", (wrapperfunc)wrap_sq_delitem, "x.__delitem__(y) <==> del x[y]"}, {0} }; |