]> granicus.if.org Git - python/commitdiff
Patch #1507676: improve exception messages in abstract.c, object.c and typeobject.c.
authorGeorg Brandl <georg@python.org>
Sun, 18 Jun 2006 22:17:29 +0000 (22:17 +0000)
committerGeorg Brandl <georg@python.org>
Sun, 18 Jun 2006 22:17:29 +0000 (22:17 +0000)
Lib/test/test_genexps.py
Objects/abstract.c
Objects/object.c
Objects/typeobject.c

index e414757ab058cd02ed9d4995808a8face5cc25ca..2598a7913ad4e1a4a38e492b3f7b54cd46ade8d0 100644 (file)
@@ -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
 
index e85fe208721937994e00f7806a3470de5ab0e987..d16660bde1af5e6777b6674d9525583dbc7d8671 100644 (file)
@@ -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);
index 59d39605d25802c252264981f495f33ee2f819eb..73c89417eb8c4f1dd92b895054a425048307ff59 100644 (file)
@@ -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)
index 0881ab1f4cb617d86d8809e2b35c4bb078de2d5d..439676f751c4c5b239277a9464bda1da63afe153 100644 (file)
@@ -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;
        }