Kaydet (Commit) 512a2377 authored tarafından Jeremy Hylton's avatar Jeremy Hylton

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.
üst 7667680d
...@@ -40,6 +40,8 @@ static PyObject *eval_code2(PyCodeObject *, ...@@ -40,6 +40,8 @@ static PyObject *eval_code2(PyCodeObject *,
PyObject **, int, PyObject **, int,
PyObject *); PyObject *);
static char *get_func_name(PyObject *);
static char *get_func_desc(PyObject *);
static PyObject *call_object(PyObject *, PyObject *, PyObject *); static PyObject *call_object(PyObject *, PyObject *, PyObject *);
static PyObject *call_cfunction(PyObject *, PyObject *, PyObject *); static PyObject *call_cfunction(PyObject *, PyObject *, PyObject *);
static PyObject *call_instance(PyObject *, PyObject *, PyObject *); static PyObject *call_instance(PyObject *, PyObject *, PyObject *);
...@@ -2741,6 +2743,43 @@ PyEval_CallObjectWithKeywords(PyObject *func, PyObject *arg, PyObject *kw) ...@@ -2741,6 +2743,43 @@ PyEval_CallObjectWithKeywords(PyObject *func, PyObject *arg, PyObject *kw)
most common, but not by such a large margin. 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 * static PyObject *
call_object(PyObject *func, PyObject *arg, PyObject *kw) call_object(PyObject *func, PyObject *arg, PyObject *kw)
{ {
...@@ -2992,12 +3031,12 @@ update_keyword_args(PyObject *orig_kwdict, int nk, PyObject ***pp_stack, ...@@ -2992,12 +3031,12 @@ update_keyword_args(PyObject *orig_kwdict, int nk, PyObject ***pp_stack,
PyObject *value = EXT_POP(*pp_stack); PyObject *value = EXT_POP(*pp_stack);
PyObject *key = EXT_POP(*pp_stack); PyObject *key = EXT_POP(*pp_stack);
if (PyDict_GetItem(kwdict, key) != NULL) { if (PyDict_GetItem(kwdict, key) != NULL) {
PyObject* fn = ((PyFunctionObject*) func)->func_name;
PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
"%.200s%s got multiple values " "%.200s%s got multiple values "
"for keyword argument '%.400s'", "for keyword argument '%.200s'",
fn ? PyString_AsString(fn) : "function", get_func_name(func),
fn ? "()" : "", PyString_AsString(key)); get_func_desc(func),
PyString_AsString(key));
Py_DECREF(key); Py_DECREF(key);
Py_DECREF(value); Py_DECREF(value);
Py_DECREF(kwdict); Py_DECREF(kwdict);
...@@ -3088,11 +3127,11 @@ ext_do_call(PyObject *func, PyObject ***pp_stack, int flags, int na, int nk) ...@@ -3088,11 +3127,11 @@ ext_do_call(PyObject *func, PyObject ***pp_stack, int flags, int na, int nk)
if (flags & CALL_FLAG_KW) { if (flags & CALL_FLAG_KW) {
kwdict = EXT_POP(*pp_stack); kwdict = EXT_POP(*pp_stack);
if (!(kwdict && PyDict_Check(kwdict))) { if (!(kwdict && PyDict_Check(kwdict))) {
PyObject* fn = ((PyFunctionObject*) func)->func_name;
PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
"%s%s argument after ** must be a dictionary", "%s%s argument after ** "
fn ? PyString_AsString(fn) : "function", "must be a dictionary",
fn ? "()" : ""); get_func_name(func),
get_func_desc(func));
goto ext_call_fail; goto ext_call_fail;
} }
} }
...@@ -3102,14 +3141,13 @@ ext_do_call(PyObject *func, PyObject ***pp_stack, int flags, int na, int nk) ...@@ -3102,14 +3141,13 @@ ext_do_call(PyObject *func, PyObject ***pp_stack, int flags, int na, int nk)
PyObject *t = NULL; PyObject *t = NULL;
t = PySequence_Tuple(stararg); t = PySequence_Tuple(stararg);
if (t == NULL) { if (t == NULL) {
if (PyErr_ExceptionMatches(PyExc_TypeError)) { if (PyErr_ExceptionMatches(PyExc_TypeError)) {
PyObject* fn = PyErr_Format(PyExc_TypeError,
((PyFunctionObject*) func)->func_name; "%s%s argument after * "
PyErr_Format(PyExc_TypeError, "must be a sequence",
"%s%s argument after * must be a sequence", get_func_name(func),
fn ? PyString_AsString(fn) : "function", get_func_desc(func));
fn ? "()" : ""); }
}
goto ext_call_fail; goto ext_call_fail;
} }
Py_DECREF(stararg); Py_DECREF(stararg);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment