summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2015-03-06 22:35:27 (GMT)
committerVictor Stinner <victor.stinner@gmail.com>2015-03-06 22:35:27 (GMT)
commit4a7cc8847276df27c8f52987cda619ca279687c2 (patch)
tree9bc7cfee8bf0fc27dc7f14ba4853c935d9f21b4c /Python
parentd81431f587e9eab67db683908548b0ad46847b38 (diff)
downloadcpython-4a7cc8847276df27c8f52987cda619ca279687c2.zip
cpython-4a7cc8847276df27c8f52987cda619ca279687c2.tar.gz
cpython-4a7cc8847276df27c8f52987cda619ca279687c2.tar.bz2
Issue #23571: PyObject_Call(), PyCFunction_Call() and call_function() now
raise a SystemError if a function returns a result and raises an exception. The SystemError is chained to the previous exception. Refactor also PyObject_Call() and PyCFunction_Call() to make them more readable. Remove some checks which became useless (duplicate checks). Change reviewed by Serhiy Storchaka.
Diffstat (limited to 'Python')
-rw-r--r--Python/ceval.c30
1 files changed, 11 insertions, 19 deletions
diff --git a/Python/ceval.c b/Python/ceval.c
index 5cefdcf..1c6089d 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -3192,8 +3192,7 @@ fast_block_end:
if (why != WHY_RETURN)
retval = NULL;
- assert((retval != NULL && !PyErr_Occurred())
- || (retval == NULL && PyErr_Occurred()));
+ assert((retval != NULL) ^ (PyErr_Occurred() != NULL));
fast_yield:
if (co->co_flags & CO_GENERATOR) {
@@ -3254,7 +3253,7 @@ exit_eval_frame:
f->f_executing = 0;
tstate->frame = f->f_back;
- return retval;
+ return _Py_CheckFunctionResult(retval, "PyEval_EvalFrameEx");
}
static void
@@ -4119,13 +4118,6 @@ PyEval_CallObjectWithKeywords(PyObject *func, PyObject *arg, PyObject *kw)
{
PyObject *result;
-#ifdef Py_DEBUG
- /* PyEval_CallObjectWithKeywords() must not be called with an exception
- set, because it may clear it (directly or indirectly)
- and so the caller looses its exception */
- assert(!PyErr_Occurred());
-#endif
-
if (arg == NULL) {
arg = PyTuple_New(0);
if (arg == NULL)
@@ -4149,8 +4141,6 @@ PyEval_CallObjectWithKeywords(PyObject *func, PyObject *arg, PyObject *kw)
result = PyObject_Call(func, arg, kw);
Py_DECREF(arg);
- assert((result != NULL && !PyErr_Occurred())
- || (result == NULL && PyErr_Occurred()));
return result;
}
@@ -4253,11 +4243,15 @@ call_function(PyObject ***pp_stack, int oparg
PyObject *self = PyCFunction_GET_SELF(func);
if (flags & METH_NOARGS && na == 0) {
C_TRACE(x, (*meth)(self,NULL));
+
+ x = _Py_CheckFunctionResult(x, "call_function");
}
else if (flags & METH_O && na == 1) {
PyObject *arg = EXT_POP(*pp_stack);
C_TRACE(x, (*meth)(self,arg));
Py_DECREF(arg);
+
+ x = _Py_CheckFunctionResult(x, "call_function");
}
else {
err_args(func, flags, na);
@@ -4277,7 +4271,8 @@ call_function(PyObject ***pp_stack, int oparg
x = NULL;
}
}
- } else {
+ }
+ else {
if (PyMethod_Check(func) && PyMethod_GET_SELF(func) != NULL) {
/* optimize access to bound methods */
PyObject *self = PyMethod_GET_SELF(func);
@@ -4299,9 +4294,9 @@ call_function(PyObject ***pp_stack, int oparg
x = do_call(func, pp_stack, na, nk);
READ_TIMESTAMP(*pintr1);
Py_DECREF(func);
+
+ assert((x != NULL) ^ (PyErr_Occurred() != NULL));
}
- assert((x != NULL && !PyErr_Occurred())
- || (x == NULL && PyErr_Occurred()));
/* Clear the stack of the function object. Also removes
the arguments in case they weren't consumed already
@@ -4313,8 +4308,7 @@ call_function(PyObject ***pp_stack, int oparg
PCALL(PCALL_POP);
}
- assert((x != NULL && !PyErr_Occurred())
- || (x == NULL && PyErr_Occurred()));
+ assert((x != NULL) ^ (PyErr_Occurred() != NULL));
return x;
}
@@ -4601,8 +4595,6 @@ ext_call_fail:
Py_XDECREF(callargs);
Py_XDECREF(kwdict);
Py_XDECREF(stararg);
- assert((result != NULL && !PyErr_Occurred())
- || (result == NULL && PyErr_Occurred()));
return result;
}