A
Austin Bingham
I've noticed that several (many?) python functions seem to clear the
error/exception indicators when they're called from a C/C++ program.
For example, both PyImport_ImportModule and traceback.extract_tb()
(called via the function call methods) do this: if error indicators
are set prior to their call (as indicated by PyErr_Fetch, and
including a call to PyErr_Restore), I see that they are unset (using
the same method) after the call. This happens even when the functions
succeed.
The functions that do this don't seem to indicate in their
documentation that this will happen. So first, does anyone know why
this is happening? Is it because of the context in which I'm making
the calls? Is there any pattern or reason behind which functions will
do this? Or am I just doing something wrong?
If the problem is context-dependent (e.g. I haven't properly
established a call stack, or something of that flavor), any pointers
on doing things properly would be great.
Here's some example code demonstrating the problem:
---
#include <Python.h>
int main(int argc, char** argv)
{
Py_Initialize();
// Cause an IndexError
PyObject* list = PyList_New(0);
PyObject* obj = PyList_GetItem(list, 100);
PyObject *t = NULL, *v = NULL, *tb = NULL;
// Verify that we see the error
PyErr_Fetch(&t, &v, &tb);
assert(t);
PyErr_Restore(t, v, tb);
// Import a module, which seems to be clearing the error indicator
PyObject* mod = PyImport_ImportModule("sys");
assert(PyObject_HasAttrString(mod, "path"));
// Verify that the error indicator has been cleared
PyErr_Fetch(&t, &v, &tb);
assert(!t); // <=== The error is gone!
PyErr_Restore(t, v, tb);
Py_Finalize();
return 0;
}
error/exception indicators when they're called from a C/C++ program.
For example, both PyImport_ImportModule and traceback.extract_tb()
(called via the function call methods) do this: if error indicators
are set prior to their call (as indicated by PyErr_Fetch, and
including a call to PyErr_Restore), I see that they are unset (using
the same method) after the call. This happens even when the functions
succeed.
The functions that do this don't seem to indicate in their
documentation that this will happen. So first, does anyone know why
this is happening? Is it because of the context in which I'm making
the calls? Is there any pattern or reason behind which functions will
do this? Or am I just doing something wrong?
If the problem is context-dependent (e.g. I haven't properly
established a call stack, or something of that flavor), any pointers
on doing things properly would be great.
Here's some example code demonstrating the problem:
---
#include <Python.h>
int main(int argc, char** argv)
{
Py_Initialize();
// Cause an IndexError
PyObject* list = PyList_New(0);
PyObject* obj = PyList_GetItem(list, 100);
PyObject *t = NULL, *v = NULL, *tb = NULL;
// Verify that we see the error
PyErr_Fetch(&t, &v, &tb);
assert(t);
PyErr_Restore(t, v, tb);
// Import a module, which seems to be clearing the error indicator
PyObject* mod = PyImport_ImportModule("sys");
assert(PyObject_HasAttrString(mod, "path"));
// Verify that the error indicator has been cleared
PyErr_Fetch(&t, &v, &tb);
assert(!t); // <=== The error is gone!
PyErr_Restore(t, v, tb);
Py_Finalize();
return 0;
}