Should I always call PyErr_Clear() when an exception occurs?

Tim Peters tim.peters at gmail.com
Tue Dec 21 01:17:52 EST 2004


[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>.



More information about the Python-list mailing list