summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Hylton <jeremy@alum.mit.edu>2001-04-11 13:52:29 (GMT)
committerJeremy Hylton <jeremy@alum.mit.edu>2001-04-11 13:52:29 (GMT)
commit512a237725c728faf495608c650f405522c3c5d4 (patch)
treee570f171f0bc83d060bb2ad63215307823b40ebd
parent7667680d703d32c796be342539b9265f9e280e98 (diff)
downloadcpython-512a237725c728faf495608c650f405522c3c5d4.zip
cpython-512a237725c728faf495608c650f405522c3c5d4.tar.gz
cpython-512a237725c728faf495608c650f405522c3c5d4.tar.bz2
Fix exception handling for non-PyFunction objects, SF bug 414743.
Fix based on patch #414750 by Michael Hudson. New functions get_func_name() and get_func_desc() return reasonable names and descriptions for all objects. XXX Even objects that aren't actually callable.
-rw-r--r--Python/ceval.c70
1 files changed, 54 insertions, 16 deletions
diff --git a/Python/ceval.c b/Python/ceval.c
index 0905572..10b5c5d 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -40,6 +40,8 @@ static PyObject *eval_code2(PyCodeObject *,
PyObject **, int,
PyObject *);
+static char *get_func_name(PyObject *);
+static char *get_func_desc(PyObject *);
static PyObject *call_object(PyObject *, PyObject *, PyObject *);
static PyObject *call_cfunction(PyObject *, PyObject *, PyObject *);
static PyObject *call_instance(PyObject *, PyObject *, PyObject *);
@@ -2741,6 +2743,43 @@ PyEval_CallObjectWithKeywords(PyObject *func, PyObject *arg, PyObject *kw)
most common, but not by such a large margin.
*/
+static char *
+get_func_name(PyObject *func)
+{
+ if (PyMethod_Check(func))
+ return get_func_name(PyMethod_GET_FUNCTION(func));
+ else if (PyFunction_Check(func))
+ return PyString_AsString(((PyFunctionObject*)func)->func_name);
+ else if (PyCFunction_Check(func))
+ return ((PyCFunctionObject*)func)->m_ml->ml_name;
+ else if (PyClass_Check(func))
+ return PyString_AsString(((PyClassObject*)func)->cl_name);
+ else if (PyInstance_Check(func)) {
+ return PyString_AsString(
+ ((PyInstanceObject*)func)->in_class->cl_name);
+ } else {
+ return func->ob_type->tp_name;
+ }
+}
+
+static char *
+get_func_desc(PyObject *func)
+{
+ if (PyMethod_Check(func))
+ return "()";
+ else if (PyFunction_Check(func))
+ return "()";
+ else if (PyCFunction_Check(func))
+ return "()";
+ else if (PyClass_Check(func))
+ return " constructor";
+ else if (PyInstance_Check(func)) {
+ return " instance";
+ } else {
+ return " object";
+ }
+}
+
static PyObject *
call_object(PyObject *func, PyObject *arg, PyObject *kw)
{
@@ -2992,12 +3031,12 @@ update_keyword_args(PyObject *orig_kwdict, int nk, PyObject ***pp_stack,
PyObject *value = EXT_POP(*pp_stack);
PyObject *key = EXT_POP(*pp_stack);
if (PyDict_GetItem(kwdict, key) != NULL) {
- PyObject* fn = ((PyFunctionObject*) func)->func_name;
PyErr_Format(PyExc_TypeError,
"%.200s%s got multiple values "
- "for keyword argument '%.400s'",
- fn ? PyString_AsString(fn) : "function",
- fn ? "()" : "", PyString_AsString(key));
+ "for keyword argument '%.200s'",
+ get_func_name(func),
+ get_func_desc(func),
+ PyString_AsString(key));
Py_DECREF(key);
Py_DECREF(value);
Py_DECREF(kwdict);
@@ -3088,11 +3127,11 @@ ext_do_call(PyObject *func, PyObject ***pp_stack, int flags, int na, int nk)
if (flags & CALL_FLAG_KW) {
kwdict = EXT_POP(*pp_stack);
if (!(kwdict && PyDict_Check(kwdict))) {
- PyObject* fn = ((PyFunctionObject*) func)->func_name;
PyErr_Format(PyExc_TypeError,
- "%s%s argument after ** must be a dictionary",
- fn ? PyString_AsString(fn) : "function",
- fn ? "()" : "");
+ "%s%s argument after ** "
+ "must be a dictionary",
+ get_func_name(func),
+ get_func_desc(func));
goto ext_call_fail;
}
}
@@ -3102,14 +3141,13 @@ ext_do_call(PyObject *func, PyObject ***pp_stack, int flags, int na, int nk)
PyObject *t = NULL;
t = PySequence_Tuple(stararg);
if (t == NULL) {
- if (PyErr_ExceptionMatches(PyExc_TypeError)) {
- PyObject* fn =
- ((PyFunctionObject*) func)->func_name;
- PyErr_Format(PyExc_TypeError,
- "%s%s argument after * must be a sequence",
- fn ? PyString_AsString(fn) : "function",
- fn ? "()" : "");
- }
+ if (PyErr_ExceptionMatches(PyExc_TypeError)) {
+ PyErr_Format(PyExc_TypeError,
+ "%s%s argument after * "
+ "must be a sequence",
+ get_func_name(func),
+ get_func_desc(func));
+ }
goto ext_call_fail;
}
Py_DECREF(stararg);