Why not just show the out-of-range index?

BJörn Lindqvist bjourne at gmail.com
Mon Dec 4 16:07:23 EST 2006


On 12/4/06, Fredrik Lundh <fredrik at pythonware.com> wrote:
> BJörn Lindqvist wrote:
>
> > Sorry I haven't thought this through 100%
>
> obviously not.

And you're not helping. Anyway, here's the patch:

Index: Objects/listobject.c
===================================================================
--- Objects/listobject.c        (revision 52915)
+++ Objects/listobject.c        (arbetskopia)
@@ -131,7 +131,18 @@
                return ((PyListObject *)op) -> ob_size;
 }

-static PyObject *indexerr = NULL;
+static int
+list_check_index(PyListObject *o, const char *ob_name, int i)
+{
+        if (i < 0 || i >= o->ob_size) {
+                const char fmt[] = "%s index %d not in range(%d)";
+                char buf[256];
+                snprintf(buf, 256, fmt, ob_name, i, o->ob_size);
+                PyErr_SetString(PyExc_IndexError, buf);
+                return -1;
+        }
+        return 0;
+}

 PyObject *
 PyList_GetItem(PyObject *op, Py_ssize_t i)
@@ -140,13 +151,9 @@
                PyErr_BadInternalCall();
                return NULL;
        }
-       if (i < 0 || i >= ((PyListObject *)op) -> ob_size) {
-               if (indexerr == NULL)
-                       indexerr = PyString_FromString(
-                               "list index out of range");
-               PyErr_SetObject(PyExc_IndexError, indexerr);
-               return NULL;
-       }
+
+        if (list_check_index((PyListObject *)op, "list", i) == -1)
+                return NULL;
        return ((PyListObject *)op) -> ob_item[i];
 }

@@ -161,12 +168,10 @@
                PyErr_BadInternalCall();
                return -1;
        }
-       if (i < 0 || i >= ((PyListObject *)op) -> ob_size) {
-               Py_XDECREF(newitem);
-               PyErr_SetString(PyExc_IndexError,
-                               "list assignment index out of range");
-               return -1;
-       }
+        if (list_check_index((PyListObject *)op, "list", i) == -1) {
+                Py_XDECREF(newitem);
+                return -1;
+        }
        p = ((PyListObject *)op) -> ob_item + i;
        olditem = *p;
        *p = newitem;
@@ -387,15 +392,10 @@
 static PyObject *
 list_item(PyListObject *a, Py_ssize_t i)
 {
-       if (i < 0 || i >= a->ob_size) {
-               if (indexerr == NULL)
-                       indexerr = PyString_FromString(
-                               "list index out of range");
-               PyErr_SetObject(PyExc_IndexError, indexerr);
-               return NULL;
-       }
-       Py_INCREF(a->ob_item[i]);
-       return a->ob_item[i];
+        if (list_check_index(a, "list", i) == -1)
+                return NULL;
+        Py_INCREF(a->ob_item[i]);
+        return a->ob_item[i];
 }

 static PyObject *
@@ -692,11 +692,9 @@
 list_ass_item(PyListObject *a, Py_ssize_t i, PyObject *v)
 {
        PyObject *old_value;
-       if (i < 0 || i >= a->ob_size) {
-               PyErr_SetString(PyExc_IndexError,
-                               "list assignment index out of range");
-               return -1;
-       }
+        if (list_check_index(a, "list", i) == -1)
+                return -1;
+
        if (v == NULL)
                return list_ass_slice(a, i, i+1, v);
        Py_INCREF(v);

And the result:

>>> L = range(10)
>>> L[44]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index 44 not in range(10)
>>> L[11] = 77
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index 11 not in range(10)

... And it was damn easy.

-- 
mvh Björn
-------------- next part --------------
A non-text attachment was scrubbed...
Name: better-index-error.patch
Type: text/x-patch
Size: 2560 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/python-list/attachments/20061204/026c6e48/attachment.bin>


More information about the Python-list mailing list