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.)
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index c49275b..f2e6f4d 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -1661,8 +1661,43 @@
 	{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 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 @@
 }
 
 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 @@
 }
 
 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}
 };