Index: Modules/_testcapimodule.c =================================================================== --- Modules/_testcapimodule.c (révision 65930) +++ Modules/_testcapimodule.c (copie de travail) @@ -600,6 +600,10 @@ if (!PyArg_ParseTuple(args, "Oi:raise_exception", &exc, &num_args)) return NULL; + if (!PyExceptionClass_Check(exc)) { + PyErr_Format(PyExc_TypeError, "an exception class is required"); + return NULL; + } exc_args = PyTuple_New(num_args); if (exc_args == NULL) @@ -628,14 +632,17 @@ */ static PyThread_type_lock thread_done = NULL; -static void +static int _make_call(void *callable) { PyObject *rc; + int success; PyGILState_STATE s = PyGILState_Ensure(); rc = PyObject_CallFunction((PyObject *)callable, ""); + success = (rc != NULL); Py_XDECREF(rc); PyGILState_Release(s); + return success; } /* Same thing, but releases `thread_done` when it returns. This variant @@ -652,10 +659,17 @@ test_thread_state(PyObject *self, PyObject *args) { PyObject *fn; + int success = 1; if (!PyArg_ParseTuple(args, "O:test_thread_state", &fn)) return NULL; + if (!PyCallable_Check(fn)) { + PyErr_Format(PyExc_TypeError, "'%s' object is not callable", + fn->ob_type->tp_name); + return NULL; + } + /* Ensure Python is set up for threading */ PyEval_InitThreads(); thread_done = PyThread_allocate_lock(); @@ -666,10 +680,10 @@ /* Start a new thread with our callback. */ PyThread_start_new_thread(_make_call_from_thread, fn); /* Make the callback with the thread lock held by this thread */ - _make_call(fn); + success &= _make_call(fn); /* Do it all again, but this time with the thread-lock released */ Py_BEGIN_ALLOW_THREADS - _make_call(fn); + success &= _make_call(fn); PyThread_acquire_lock(thread_done, 1); /* wait for thread to finish */ Py_END_ALLOW_THREADS @@ -679,7 +693,7 @@ */ Py_BEGIN_ALLOW_THREADS PyThread_start_new_thread(_make_call_from_thread, fn); - _make_call(fn); + success &= _make_call(fn); PyThread_acquire_lock(thread_done, 1); /* wait for thread to finish */ Py_END_ALLOW_THREADS @@ -687,6 +701,8 @@ PyThread_release_lock(thread_done); PyThread_free_lock(thread_done); + if (!success) + return NULL; Py_RETURN_NONE; } #endif