diff options
author | Georg Brandl <georg@python.org> | 2006-06-18 22:17:29 (GMT) |
---|---|---|
committer | Georg Brandl <georg@python.org> | 2006-06-18 22:17:29 (GMT) |
commit | ccff78525889fe2fa1a3512c4084a407994f9ce3 (patch) | |
tree | d8f3482e702a64e147455613d56bf471042e1e62 | |
parent | 066769c3073fb080e5ba0b68499e726c56d509c0 (diff) | |
download | cpython-ccff78525889fe2fa1a3512c4084a407994f9ce3.zip cpython-ccff78525889fe2fa1a3512c4084a407994f9ce3.tar.gz cpython-ccff78525889fe2fa1a3512c4084a407994f9ce3.tar.bz2 |
Patch #1507676: improve exception messages in abstract.c, object.c and typeobject.c.
-rw-r--r-- | Lib/test/test_genexps.py | 2 | ||||
-rw-r--r-- | Objects/abstract.c | 82 | ||||
-rw-r--r-- | Objects/object.c | 30 | ||||
-rw-r--r-- | Objects/typeobject.c | 33 |
4 files changed, 82 insertions, 65 deletions
diff --git a/Lib/test/test_genexps.py b/Lib/test/test_genexps.py index e414757..2598a79 100644 --- a/Lib/test/test_genexps.py +++ b/Lib/test/test_genexps.py @@ -109,7 +109,7 @@ for iterability Traceback (most recent call last): File "<pyshell#4>", line 1, in -toplevel- (i for i in 6) - TypeError: iteration over non-sequence + TypeError: 'int' object is not iterable Verify late binding for the outermost if-expression diff --git a/Objects/abstract.c b/Objects/abstract.c index e85fe20..d16660b 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -14,9 +14,9 @@ /* Shorthands to return certain errors */ static PyObject * -type_error(const char *msg) +type_error(const char *msg, PyObject *obj) { - PyErr_SetString(PyExc_TypeError, msg); + PyErr_Format(PyExc_TypeError, msg, obj->ob_type->tp_name); return NULL; } @@ -130,10 +130,11 @@ PyObject_GetItem(PyObject *o, PyObject *key) return PySequence_GetItem(o, key_value); } else if (o->ob_type->tp_as_sequence->sq_item) - return type_error("sequence index must be integer"); + return type_error("sequence index must " + "be integer, not '%.200s'", key); } - return type_error("unsubscriptable object"); + return type_error("'%.200s' object is unsubscriptable", o); } int @@ -158,12 +159,13 @@ PyObject_SetItem(PyObject *o, PyObject *key, PyObject *value) return PySequence_SetItem(o, key_value, value); } else if (o->ob_type->tp_as_sequence->sq_ass_item) { - type_error("sequence index must be integer"); + type_error("sequence index must be " + "integer, not '%.200s'", key); return -1; } } - type_error("object does not support item assignment"); + type_error("'%.200s' object does not support item assignment", o); return -1; } @@ -189,12 +191,13 @@ PyObject_DelItem(PyObject *o, PyObject *key) return PySequence_DelItem(o, key_value); } else if (o->ob_type->tp_as_sequence->sq_ass_item) { - type_error("sequence index must be integer"); + type_error("sequence index must be " + "integer, not '%.200s'", key); return -1; } } - type_error("object does not support item deletion"); + type_error("'%.200s' object does not support item deletion", o); return -1; } @@ -435,7 +438,8 @@ static PyObject * binop_type_error(PyObject *v, PyObject *w, const char *op_name) { PyErr_Format(PyExc_TypeError, - "unsupported operand type(s) for %s: '%s' and '%s'", + "unsupported operand type(s) for %.100s: " + "'%.100s' and '%.100s'", op_name, v->ob_type->tp_name, w->ob_type->tp_name); @@ -601,14 +605,14 @@ ternary_op(PyObject *v, PyErr_Format( PyExc_TypeError, "unsupported operand type(s) for ** or pow(): " - "'%s' and '%s'", + "'%.100s' and '%.100s'", v->ob_type->tp_name, w->ob_type->tp_name); else PyErr_Format( PyExc_TypeError, "unsupported operand type(s) for pow(): " - "'%s', '%s', '%s'", + "'%.100s', '%.100s', '%.100s'", v->ob_type->tp_name, w->ob_type->tp_name, z->ob_type->tp_name); @@ -656,8 +660,8 @@ sequence_repeat(ssizeargfunc repeatfunc, PyObject *seq, PyObject *n) return NULL; } else { - return type_error( - "can't multiply sequence by non-int"); + return type_error("can't multiply sequence by " + "non-int of type '%.200s'", n); } return (*repeatfunc)(seq, count); } @@ -870,7 +874,7 @@ PyNumber_Negative(PyObject *o) if (m && m->nb_negative) return (*m->nb_negative)(o); - return type_error("bad operand type for unary -"); + return type_error("bad operand type for unary -: '%.200s'", o); } PyObject * @@ -884,7 +888,7 @@ PyNumber_Positive(PyObject *o) if (m && m->nb_positive) return (*m->nb_positive)(o); - return type_error("bad operand type for unary +"); + return type_error("bad operand type for unary +: '%.200s'", o); } PyObject * @@ -898,7 +902,7 @@ PyNumber_Invert(PyObject *o) if (m && m->nb_invert) return (*m->nb_invert)(o); - return type_error("bad operand type for unary ~"); + return type_error("bad operand type for unary ~: '%.200s'", o); } PyObject * @@ -912,7 +916,7 @@ PyNumber_Absolute(PyObject *o) if (m && m->nb_absolute) return m->nb_absolute(o); - return type_error("bad operand type for abs()"); + return type_error("bad operand type for abs(): '%.200s'", o); } /* Add a check for embedded NULL-bytes in the argument. */ @@ -992,7 +996,8 @@ PyNumber_Int(PyObject *o) if (!PyObject_AsCharBuffer(o, &buffer, &buffer_len)) return int_from_string((char*)buffer, buffer_len); - return type_error("int() argument must be a string or a number"); + return type_error("int() argument must be a string or a " + "number, not '%.200s'", o); } /* Add a check for embedded NULL-bytes in the argument. */ @@ -1054,7 +1059,8 @@ PyNumber_Long(PyObject *o) if (!PyObject_AsCharBuffer(o, &buffer, &buffer_len)) return long_from_string(buffer, buffer_len); - return type_error("long() argument must be a string or a number"); + return type_error("long() argument must be a string or a " + "number, not '%.200s'", o); } PyObject * @@ -1108,7 +1114,7 @@ PySequence_Size(PyObject *s) if (m && m->sq_length) return m->sq_length(s); - type_error("len() of unsized object"); + type_error("non-sequence object of type '%.200s' has no len()", s); return -1; } @@ -1141,7 +1147,7 @@ PySequence_Concat(PyObject *s, PyObject *o) return result; Py_DECREF(result); } - return type_error("object can't be concatenated"); + return type_error("'%.200s' object can't be concatenated", s); } PyObject * @@ -1170,7 +1176,7 @@ PySequence_Repeat(PyObject *o, Py_ssize_t count) return result; Py_DECREF(result); } - return type_error("object can't be repeated"); + return type_error("'%.200s' object can't be repeated", o); } PyObject * @@ -1194,7 +1200,7 @@ PySequence_InPlaceConcat(PyObject *s, PyObject *o) return result; Py_DECREF(result); } - return type_error("object can't be concatenated"); + return type_error("'%.200s' object can't be concatenated", s); } PyObject * @@ -1223,7 +1229,7 @@ PySequence_InPlaceRepeat(PyObject *o, Py_ssize_t count) return result; Py_DECREF(result); } - return type_error("object can't be repeated"); + return type_error("'%.200s' object can't be repeated", o); } PyObject * @@ -1247,7 +1253,7 @@ PySequence_GetItem(PyObject *s, Py_ssize_t i) return m->sq_item(s, i); } - return type_error("unindexable object"); + return type_error("'%.200s' object is unindexable", s); } PyObject * @@ -1282,7 +1288,7 @@ PySequence_GetSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2) return res; } - return type_error("unsliceable object"); + return type_error("'%.200s' object is unsliceable", s); } int @@ -1308,7 +1314,7 @@ PySequence_SetItem(PyObject *s, Py_ssize_t i, PyObject *o) return m->sq_ass_item(s, i, o); } - type_error("object does not support item assignment"); + type_error("'%.200s' object does not support item assignment", s); return -1; } @@ -1335,7 +1341,7 @@ PySequence_DelItem(PyObject *s, Py_ssize_t i) return m->sq_ass_item(s, i, (PyObject *)NULL); } - type_error("object doesn't support item deletion"); + type_error("'%.200s' object doesn't support item deletion", s); return -1; } @@ -1374,7 +1380,7 @@ PySequence_SetSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2, PyObject *o) return res; } - type_error("object doesn't support slice assignment"); + type_error("'%.200s' object doesn't support slice assignment", s); return -1; } @@ -1403,7 +1409,7 @@ PySequence_DelSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2) } return m->sq_ass_slice(s, i1, i2, (PyObject *)NULL); } - type_error("object doesn't support slice deletion"); + type_error("'%.200s' object doesn't support slice deletion", s); return -1; } @@ -1534,7 +1540,7 @@ PySequence_Fast(PyObject *v, const char *m) it = PyObject_GetIter(v); if (it == NULL) { if (PyErr_ExceptionMatches(PyExc_TypeError)) - return type_error(m); + PyErr_SetString(PyExc_TypeError, m); return NULL; } @@ -1564,7 +1570,7 @@ _PySequence_IterSearch(PyObject *seq, PyObject *obj, int operation) it = PyObject_GetIter(seq); if (it == NULL) { - type_error("iterable argument required"); + type_error("argument of type '%.200s' is not iterable", seq); return -1; } @@ -1699,7 +1705,7 @@ PyMapping_Size(PyObject *o) if (m && m->mp_length) return m->mp_length(o); - type_error("len() of unsized object"); + type_error("non-mapping object of type '%.200s' has no len()", o); return -1; } @@ -1807,7 +1813,7 @@ PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) "NULL result without error in PyObject_Call"); return result; } - PyErr_Format(PyExc_TypeError, "'%s' object is not callable", + PyErr_Format(PyExc_TypeError, "'%.200s' object is not callable", func->ob_type->tp_name); return NULL; } @@ -1896,7 +1902,7 @@ PyObject_CallMethod(PyObject *o, char *name, char *format, ...) } if (!PyCallable_Check(func)) { - type_error("call of non-callable attribute"); + type_error("attribute of type '%.200s' is not callable", func); goto exit; } @@ -1935,7 +1941,7 @@ _PyObject_CallMethod_SizeT(PyObject *o, char *name, char *format, ...) } if (!PyCallable_Check(func)) { - type_error("call of non-callable attribute"); + type_error("attribute of type '%.200s' is not callable", func); goto exit; } @@ -2287,9 +2293,7 @@ PyObject_GetIter(PyObject *o) if (f == NULL) { if (PySequence_Check(o)) return PySeqIter_New(o); - PyErr_SetString(PyExc_TypeError, - "iteration over non-sequence"); - return NULL; + return type_error("'%.200s' object is not iterable", o); } else { PyObject *res = (*f)(o); diff --git a/Objects/object.c b/Objects/object.c index 59d3960..73c8941 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -1068,7 +1068,8 @@ PyObject_Hash(PyObject *v) return _Py_HashPointer(v); /* Use address as hash value */ } /* If there's a cmp but no hash defined, the object can't be hashed */ - PyErr_SetString(PyExc_TypeError, "unhashable type"); + PyErr_Format(PyExc_TypeError, "unhashable type: '%.200s'", + v->ob_type->tp_name); return -1; } @@ -1133,8 +1134,9 @@ PyObject_GetAttr(PyObject *v, PyObject *name) else #endif { - PyErr_SetString(PyExc_TypeError, - "attribute name must be string"); + PyErr_Format(PyExc_TypeError, + "attribute name must be string, not '%.200s'", + name->ob_type->tp_name); return NULL; } } @@ -1179,8 +1181,9 @@ PyObject_SetAttr(PyObject *v, PyObject *name, PyObject *value) else #endif { - PyErr_SetString(PyExc_TypeError, - "attribute name must be string"); + PyErr_Format(PyExc_TypeError, + "attribute name must be string, not '%.200s'", + name->ob_type->tp_name); return -1; } } @@ -1277,8 +1280,9 @@ PyObject_GenericGetAttr(PyObject *obj, PyObject *name) else #endif { - PyErr_SetString(PyExc_TypeError, - "attribute name must be string"); + PyErr_Format(PyExc_TypeError, + "attribute name must be string, not '%.200s'", + name->ob_type->tp_name); return NULL; } } @@ -1399,8 +1403,9 @@ PyObject_GenericSetAttr(PyObject *obj, PyObject *name, PyObject *value) else #endif { - PyErr_SetString(PyExc_TypeError, - "attribute name must be string"); + PyErr_Format(PyExc_TypeError, + "attribute name must be string, not '%.200s'", + name->ob_type->tp_name); return -1; } } @@ -1450,7 +1455,7 @@ PyObject_GenericSetAttr(PyObject *obj, PyObject *name, PyObject *value) if (descr == NULL) { PyErr_Format(PyExc_AttributeError, - "'%.50s' object has no attribute '%.400s'", + "'%.100s' object has no attribute '%.200s'", tp->tp_name, PyString_AS_STRING(name)); goto done; } @@ -1773,8 +1778,9 @@ PyObject_Dir(PyObject *arg) assert(result); if (!PyList_Check(result)) { - PyErr_SetString(PyExc_TypeError, - "Expected keys() to be a list."); + PyErr_Format(PyExc_TypeError, + "Expected keys() to be a list, not '%.200s'", + result->ob_type->tp_name); goto error; } if (PyList_Sort(result) != 0) diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 0881ab1..439676f 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -1470,8 +1470,9 @@ subtype_setdict(PyObject *obj, PyObject *value, void *context) return -1; } if (value != NULL && !PyDict_Check(value)) { - PyErr_SetString(PyExc_TypeError, - "__dict__ must be set to a dictionary"); + PyErr_Format(PyExc_TypeError, + "__dict__ must be set to a dictionary, " + "not a '%.200s'", value->ob_type->tp_name); return -1; } dict = *dictptr; @@ -1534,8 +1535,9 @@ valid_identifier(PyObject *s) Py_ssize_t i, n; if (!PyString_Check(s)) { - PyErr_SetString(PyExc_TypeError, - "__slots__ must be strings"); + PyErr_Format(PyExc_TypeError, + "__slots__ items must be strings, not '%.200s'", + s->ob_type->tp_name); return 0; } p = (unsigned char *) PyString_AS_STRING(s); @@ -2575,8 +2577,9 @@ reduce_2(PyObject *obj) args = PyObject_CallObject(getnewargs, NULL); Py_DECREF(getnewargs); if (args != NULL && !PyTuple_Check(args)) { - PyErr_SetString(PyExc_TypeError, - "__getnewargs__ should return a tuple"); + PyErr_Format(PyExc_TypeError, + "__getnewargs__ should return a tuple, " + "not '%.200s'", args->ob_type->tp_name); goto end; } } @@ -4352,8 +4355,9 @@ slot_nb_index(PyObject *self) result = temp->ob_type->tp_as_number->nb_index(temp); } else { - PyErr_SetString(PyExc_TypeError, - "__index__ must return an int or a long"); + PyErr_Format(PyExc_TypeError, + "__index__ must return an int or a long, " + "not '%.200s'", temp->ob_type->tp_name); result = -1; } Py_DECREF(temp); @@ -4564,8 +4568,9 @@ slot_tp_hash(PyObject *self) func = lookup_method(self, "__cmp__", &cmp_str); } if (func != NULL) { + PyErr_Format(PyExc_TypeError, "unhashable type: '%.200s'", + self->ob_type->tp_name); Py_DECREF(func); - PyErr_SetString(PyExc_TypeError, "unhashable type"); return -1; } PyErr_Clear(); @@ -4742,8 +4747,9 @@ slot_tp_iter(PyObject *self) PyErr_Clear(); func = lookup_method(self, "__getitem__", &getitem_str); if (func == NULL) { - PyErr_SetString(PyExc_TypeError, - "iteration over non-sequence"); + PyErr_Format(PyExc_TypeError, + "'%.200s' object is not iterable", + self->ob_type->tp_name); return NULL; } Py_DECREF(func); @@ -4816,8 +4822,9 @@ slot_tp_init(PyObject *self, PyObject *args, PyObject *kwds) if (res == NULL) return -1; if (res != Py_None) { - PyErr_SetString(PyExc_TypeError, - "__init__() should return None"); + PyErr_Format(PyExc_TypeError, + "__init__() should return None, not '%.200s'", + res->ob_type->tp_name); Py_DECREF(res); return -1; } |