[Jaime Wyant] > I've found that the code below will crash if I don't have the > PyErr_Clear() function call. Should I always call PyErr_Clear()?
That's not the right approach. Nearly all Python C API calls can fail. They return a special value if they do, primarily NULL for a call that returns a pointer, or -1 for a call that returns an int. The correct thing to do is to explicitly check every call that *might* fail to see whether it *did* fail. If it did, then you also have to explictly decide what to do about it: either pass the exception on to your caller (by returning your function's error value), or suppress the exception via PyErr_Clear(), or replace it with another exception. You have to do one of those before making another Python C API call. Ignoring these issues always leads to bad problems eventually. > /* Code that fails if PyErr_Clear() is removed */ > #include "python.h" > > int main() > { > PyObject *pName, *pModule; > int i; > > Py_Initialize(); > for (i = 0 ; i < 30; i++) { > // First, import the module > pName = PyString_FromString("badmodule"); That can fail. You must check whether pName == NULL, and either pass the exception on (although that doesn't make much sense in a main()), or clear the error. > pModule = PyImport_Import(pName); Ditto. > Py_DECREF(pName); That can't fail, if the code preceding it is correct. But it's not in this case. The PyString_FromString() call from which pName was set may have failed (for example, it may not have been able to find enough memory to create a new string object). In that case, the Py_DECREF would segfault, because pName would be NULL here. > if (!pModule) > { > fprintf(stderr, "couldn't import badmodule\n"); > PyErr_Clear(); > } > } That's OK, although it's tempting fate to stuff code between a call and checking that call's return value for an error. Note that the Python implementation itself uses the Python C API heavily, in its C files. You can study those to get many examples of best practice. It will help to remember that coding in C isn't supposed to fun <0.9 wink>. -- http://mail.python.org/mailman/listinfo/python-list