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


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

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
    Replies:
    5
    Views:
    861
    Tony Cheng
    Mar 23, 2005
  2. Robin Becker
    Replies:
    3
    Views:
    408
    Andrew MacIntyre
    Nov 29, 2004
  3. Jaime Wyant
    Replies:
    0
    Views:
    334
    Jaime Wyant
    Dec 21, 2004
  4. Replies:
    0
    Views:
    569
  5. Newb Newb
    Replies:
    3
    Views:
    107
    7stud --
    Apr 29, 2009
Loading...

Share This Page