Python callbacks & PyGILState_Release()

Randall Hopper viznut at charter.net
Fri Apr 22 23:20:22 EDT 2005


     What is the correct way to propagate exceptions from Python callbacks?

     When I do this:

     Python -> C++ -> Python Callback

(example attached) an exception raised in the callback doesn't make it back
across C++ to Python.

     It appears that PyGILState_Release() at the bottom of the callback
wrapper is resetting the error state (as I can set a global based on
PyErr_Occurred() there, and can catch that up in the exception handler in
Python).

     This obviously isn't correct.  What should I be doing?

Thanks,

Randall


------------------------------------------------------------------------------
void callback_wrapper( void *user_data )
{
  // Acquire interpreter lock
  PyGILState_STATE gstate = PyGILState_Ensure();
  ...
  // Call Python
  pyresult = PyEval_CallObject( pyfunc, pyargs );
  ...
  /*********** At this point, PyErr_Occurred() is true   **************/
  /****** But it's not true when we return through C++ to Python  ******/

  // Free interpreter lock
  PyGILState_Release(gstate);
}

void registerCallback( PyObject *pyfunc )
{
  ...
  // Ensure threads inited, so we can use Ensure/Release in callbacks
  PyEval_InitThreads();

  // Ref pyfunc
  Py_INCREF( pyfunc );

  // Call underlying C++ method, registering the above C++ callback
  realRegisterCallback( callback_wrapper, pyfunc );
}



More information about the Python-list mailing list