(original) (raw)
changeset: 84964:de1ea7f84e08 user: Victor Stinner victor.stinner@gmail.com date: Fri Aug 02 00:47:47 2013 +0200 files: Modules/_ctypes/callbacks.c description: Issue #18609, #18408: _ctypes_add_traceback() now clears the current exception while adding the traceback, because it may call indirectly a Python function and Python functions must not be called with an exception set. In the case of the issue #18609, _ctypes_add_traceback() called the iso8859-1 decoder which is implemented in Python. Python has a ISO-8859-1 codec implemented in C. It is not used because PyUnicode_Decode() only uses the C codec for other names (aliases) of this codec ("latin-1", "latin1" and "iso-8859-1"). diff -r 3ffd9a270e14 -r de1ea7f84e08 Modules/_ctypes/callbacks.c --- a/Modules/_ctypes/callbacks.c Thu Aug 01 15:39:47 2013 -0700 +++ b/Modules/_ctypes/callbacks.c Fri Aug 02 00:47:47 2013 +0200 @@ -98,20 +98,37 @@ PyObject *py_globals = 0; PyCodeObject *py_code = 0; PyFrameObject *py_frame = 0; + PyObject *exception, *value, *tb; + + /* (Save and) Clear the current exception. Python functions must not be + called with an exception set. Calling Python functions happens when + the codec of the filesystem encoding is implemented in pure Python. */ + PyErr_Fetch(&exception, &value, &tb); py_globals = PyDict_New(); - if (!py_globals) goto bad; + if (!py_globals) + goto bad; py_code = PyCode_NewEmpty(filename, funcname, lineno); - if (!py_code) goto bad; + if (!py_code) + goto bad; py_frame = PyFrame_New( PyThreadState_Get(), /*PyThreadState *tstate,*/ py_code, /*PyCodeObject *code,*/ py_globals, /*PyObject *globals,*/ 0 /*PyObject *locals*/ ); - if (!py_frame) goto bad; + if (!py_frame) + goto bad; py_frame->f_lineno = lineno; + + PyErr_Restore(exception, value, tb); PyTraceBack_Here(py_frame); + + Py_DECREF(py_globals); + Py_DECREF(py_code); + Py_DECREF(py_frame); + return; + bad: Py_XDECREF(py_globals); Py_XDECREF(py_code); /victor.stinner@gmail.com