New submission from Marc Horowitz <mhorow...@gmail.com>: I discovered this bug working with panda3d. I've attached a short python script which demonstrates the problem. After installing panda3d, run the script, and then hit q in the window which appears. You'll see that none of the cleanup code after the 'run()' main loop runs.
The underlying cause is in how panda3d uses the C API. It's got code like this (in src/pipeline/thread.cxx): // Call the user's function. result = PyObject_Call(function, args, NULL); if (result == (PyObject *)NULL && PyErr_Occurred()) { // We got an exception. Move the exception from the current // thread into the main thread, so it can be handled there. PyObject *exc, *val, *tb; PyErr_Fetch(&exc, &val, &tb); thread_cat.error() << "Exception occurred within " << *this << "\n"; // Temporarily restore the exception state so we can print a // callback on-the-spot. Py_XINCREF(exc); Py_XINCREF(val); Py_XINCREF(tb); PyErr_Restore(exc, val, tb); PyErr_Print(); ... If the code being called (generally a panda3d task function or event handler) calls sys.exit, the PyErr_Print() never returns. This is surprising, as the the documentation never mentions that a function with an innocuous name like "Print" might never return. However, I don't think this is a panda3d bug; I think that the function as documented is the way it should behave. Otherwise, the vast majority of calls to this method will need to look like if (!PyErr_ExceptionMatches(PyExc_SystemExit)) { PyErr_PrintEx(1); } which seems like a poor abstraction. Another unexpected side effect is when python is used with the -i flag. Because of the way this alters the normal exit behavior, the code runs the way I'd expect, and the cleanup code in the test application *does* run. It seems rather strange to me that cleanup code should run or not run based on the -i flag. I believe the fix for all this is that PyErr_PrintEx be changed to behave as documented, *not* call handle_system_exit() when passed SystemExit, and instead in the places where the interpreter main loop is run, followed by PyErr_PrintEx(), that SystemExit is special cased in those specific locations as needed. ---------- components: Interpreter Core files: exit_test.py messages: 122846 nosy: Marc.Horowitz priority: normal severity: normal status: open title: PyErr_PrintEx exits silently when passed SystemExit exception type: behavior versions: Python 2.6 Added file: http://bugs.python.org/file19875/exit_test.py _______________________________________ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue10582> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com