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

Discussion in 'Python' started by Tim Peters, Dec 21, 2004.

  1. Tim Peters

    Tim Peters Guest

    [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);


    > 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>.
    Tim Peters, Dec 21, 2004
    1. Advertisements

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Tony Cheng
    Tony Cheng
    Mar 23, 2005
  2. Robin Becker
    Andrew MacIntyre
    Nov 29, 2004
  3. Jaime Wyant
    Jaime Wyant
    Dec 21, 2004
  4. Replies:
  5. Newb Newb
    7stud --
    Apr 29, 2009

Share This Page