diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2015-03-21 14:04:43 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@gmail.com> | 2015-03-21 14:04:43 (GMT) |
commit | efde146b0c42f2643f96d00896c99a90d501fb69 (patch) | |
tree | ccb5f7484b0c55bf005ec9b5eb80558d8adb7e46 /Objects | |
parent | 6921c13bbbb2c9695edd87331d98f7aa1e48f7f2 (diff) | |
download | cpython-efde146b0c42f2643f96d00896c99a90d501fb69.zip cpython-efde146b0c42f2643f96d00896c99a90d501fb69.tar.gz cpython-efde146b0c42f2643f96d00896c99a90d501fb69.tar.bz2 |
Issue #23571: _Py_CheckFunctionResult() now gives the name of the function
which returned an invalid result (result+error or no result without error) in
the exception message.
Add also unit test to check that the exception contains the name of the
function.
Special case: the final _PyEval_EvalFrameEx() check doesn't mention the
function since it didn't execute a single function but a whole frame.
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/abstract.c | 26 | ||||
-rw-r--r-- | Objects/methodobject.c | 2 |
2 files changed, 21 insertions, 7 deletions
diff --git a/Objects/abstract.c b/Objects/abstract.c index 50d893d..a19d28c 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -2074,10 +2074,12 @@ PyObject_CallObject(PyObject *o, PyObject *a) } PyObject* -_Py_CheckFunctionResult(PyObject *result, const char *func_name) +_Py_CheckFunctionResult(PyObject *func, PyObject *result, const char *where) { int err_occurred = (PyErr_Occurred() != NULL); + assert((func != NULL) ^ (where != NULL)); + #ifndef NDEBUG /* In debug mode: abort() with an assertion error. Use two different assertions, so if an assertion fails, it's possible to know @@ -2090,8 +2092,14 @@ _Py_CheckFunctionResult(PyObject *result, const char *func_name) if (result == NULL) { if (!err_occurred) { - PyErr_Format(PyExc_SystemError, - "NULL result without error in %s", func_name); + if (func) + PyErr_Format(PyExc_SystemError, + "%R returned NULL without setting an error", + func); + else + PyErr_Format(PyExc_SystemError, + "%s returned NULL without setting an error", + where); return NULL; } } @@ -2102,8 +2110,14 @@ _Py_CheckFunctionResult(PyObject *result, const char *func_name) Py_DECREF(result); - PyErr_Format(PyExc_SystemError, - "result with error in %s", func_name); + if (func) + PyErr_Format(PyExc_SystemError, + "%R returned a result with an error set", + func); + else + PyErr_Format(PyExc_SystemError, + "%s returned a result with an error set", + where); _PyErr_ChainExceptions(exc, val, tb); return NULL; } @@ -2136,7 +2150,7 @@ PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) Py_LeaveRecursiveCall(); - return _Py_CheckFunctionResult(result, "PyObject_Call"); + return _Py_CheckFunctionResult(func, result, NULL); } static PyObject* diff --git a/Objects/methodobject.c b/Objects/methodobject.c index 85b413f..b5467a4 100644 --- a/Objects/methodobject.c +++ b/Objects/methodobject.c @@ -142,7 +142,7 @@ PyCFunction_Call(PyObject *func, PyObject *args, PyObject *kwds) } } - return _Py_CheckFunctionResult(res, "PyCFunction_Call"); + return _Py_CheckFunctionResult(func, res, NULL); } /* Methods (the standard built-in methods, that is) */ |