Index: Lib/test/test_list.py =================================================================== --- Lib/test/test_list.py (revision 83023) +++ Lib/test/test_list.py (working copy) @@ -59,6 +59,24 @@ self.assertRaises((MemoryError, OverflowError), mul, lst, n) self.assertRaises((MemoryError, OverflowError), imul, lst, n) + def test_exceptions(self): + class A: + def __repr__(self): + raise RuntimeError + for method in ([].remove, [].index): + try: + method('a') + except ValueError as err: + self.assert_("'a'" in err.args[0]) + else: + self.fail('ValueError not raised') + try: + method(A()) + except ValueError as err: + self.assert_("item" in err.args[0]) + else: + self.fail('ValueError not raised') + def test_main(verbose=None): support.run_unittest(ListTest) Index: Objects/listobject.c =================================================================== --- Objects/listobject.c (revision 83023) +++ Objects/listobject.c (working copy) @@ -72,6 +72,36 @@ return 0; } +static PyObject *indexerr = NULL; +static PyObject *notfounderr_format = NULL; + +static void +set_not_found_err(PyObject* v) +{ + PyObject *repr, *format_tuple, *err_string; + if (notfounderr_format == NULL) { + notfounderr_format = PyUnicode_FromString("%s is not in list"); + if (notfounderr_format == NULL) + return; + } + repr = PyObject_Repr(v); + if (repr == NULL) { + repr = PyUnicode_FromString("item"); + if (repr == NULL) + return; + } + format_tuple = PyTuple_Pack(1, repr); + Py_DECREF(repr); + if (format_tuple == NULL) + return; + err_string = PyUnicode_Format(notfounderr_format, format_tuple); + Py_DECREF(format_tuple); + if (err_string == NULL) + return; + PyErr_SetObject(PyExc_ValueError, err_string); + Py_DECREF(err_string); +} + /* Debug statistic to compare allocations with reuse through the free list */ #undef SHOW_ALLOC_COUNT #ifdef SHOW_ALLOC_COUNT @@ -173,8 +203,6 @@ return Py_SIZE(op); } -static PyObject *indexerr = NULL; - PyObject * PyList_GetItem(PyObject *op, Py_ssize_t i) { @@ -2098,8 +2126,7 @@ listindex(PyListObject *self, PyObject *args) { Py_ssize_t i, start=0, stop=Py_SIZE(self); - PyObject *v, *format_tuple, *err_string; - static PyObject *err_format = NULL; + PyObject *v; if (!PyArg_ParseTuple(args, "O|O&O&:index", &v, _PyEval_SliceIndex, &start, @@ -2122,20 +2149,7 @@ else if (cmp < 0) return NULL; } - if (err_format == NULL) { - err_format = PyUnicode_FromString("%r is not in list"); - if (err_format == NULL) - return NULL; - } - format_tuple = PyTuple_Pack(1, v); - if (format_tuple == NULL) - return NULL; - err_string = PyUnicode_Format(err_format, format_tuple); - Py_DECREF(format_tuple); - if (err_string == NULL) - return NULL; - PyErr_SetObject(PyExc_ValueError, err_string); - Py_DECREF(err_string); + set_not_found_err(v); return NULL; } @@ -2171,7 +2185,7 @@ else if (cmp < 0) return NULL; } - PyErr_SetString(PyExc_ValueError, "list.remove(x): x not in list"); + set_not_found_err(v); return NULL; }