Kaydet (Commit) 9035ad93 authored tarafından Victor Stinner's avatar Victor Stinner

Issue #18408: In debug mode, PyCFunction_Call() now checks if an exception was

raised if the result is NULL to help to find bugs in C mode (get the error
earlier than the SystemError in ceval.c).
üst 526daabf
...@@ -79,23 +79,34 @@ PyCFunction_GetFlags(PyObject *op) ...@@ -79,23 +79,34 @@ PyCFunction_GetFlags(PyObject *op)
PyObject * PyObject *
PyCFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) PyCFunction_Call(PyObject *func, PyObject *arg, PyObject *kw)
{ {
#define CHECK_RESULT(res) assert(res != NULL || PyErr_Occurred())
PyCFunctionObject* f = (PyCFunctionObject*)func; PyCFunctionObject* f = (PyCFunctionObject*)func;
PyCFunction meth = PyCFunction_GET_FUNCTION(func); PyCFunction meth = PyCFunction_GET_FUNCTION(func);
PyObject *self = PyCFunction_GET_SELF(func); PyObject *self = PyCFunction_GET_SELF(func);
PyObject *res;
Py_ssize_t size; Py_ssize_t size;
switch (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST)) { switch (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST)) {
case METH_VARARGS: case METH_VARARGS:
if (kw == NULL || PyDict_Size(kw) == 0) if (kw == NULL || PyDict_Size(kw) == 0) {
return (*meth)(self, arg); res = (*meth)(self, arg);
CHECK_RESULT(res);
return res;
}
break; break;
case METH_VARARGS | METH_KEYWORDS: case METH_VARARGS | METH_KEYWORDS:
return (*(PyCFunctionWithKeywords)meth)(self, arg, kw); res = (*(PyCFunctionWithKeywords)meth)(self, arg, kw);
CHECK_RESULT(res);
return res;
case METH_NOARGS: case METH_NOARGS:
if (kw == NULL || PyDict_Size(kw) == 0) { if (kw == NULL || PyDict_Size(kw) == 0) {
size = PyTuple_GET_SIZE(arg); size = PyTuple_GET_SIZE(arg);
if (size == 0) if (size == 0) {
return (*meth)(self, NULL); res = (*meth)(self, NULL);
CHECK_RESULT(res);
return res;
}
PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
"%.200s() takes no arguments (%zd given)", "%.200s() takes no arguments (%zd given)",
f->m_ml->ml_name, size); f->m_ml->ml_name, size);
...@@ -105,8 +116,11 @@ PyCFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) ...@@ -105,8 +116,11 @@ PyCFunction_Call(PyObject *func, PyObject *arg, PyObject *kw)
case METH_O: case METH_O:
if (kw == NULL || PyDict_Size(kw) == 0) { if (kw == NULL || PyDict_Size(kw) == 0) {
size = PyTuple_GET_SIZE(arg); size = PyTuple_GET_SIZE(arg);
if (size == 1) if (size == 1) {
return (*meth)(self, PyTuple_GET_ITEM(arg, 0)); res = (*meth)(self, PyTuple_GET_ITEM(arg, 0));
CHECK_RESULT(res);
return res;
}
PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
"%.200s() takes exactly one argument (%zd given)", "%.200s() takes exactly one argument (%zd given)",
f->m_ml->ml_name, size); f->m_ml->ml_name, size);
...@@ -123,6 +137,8 @@ PyCFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) ...@@ -123,6 +137,8 @@ PyCFunction_Call(PyObject *func, PyObject *arg, PyObject *kw)
PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments", PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments",
f->m_ml->ml_name); f->m_ml->ml_name);
return NULL; return NULL;
#undef CHECK_RESULT
} }
/* Methods (the standard built-in methods, that is) */ /* Methods (the standard built-in methods, that is) */
......
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