Question

if I do something like

 >>> x = int(1,2,3,4,5)

I immediately get a fatal error (one that would end program execution if it was in a pre-written script)

 Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
 TypeError: int() takes at most 2 arguments (5 given)

and x remains undefined:

 >>> x
 Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
 NameError: name 'x' is not defined

How would I go about implementing that in Python's C API? I found some documentation for it, but I am not sure that I know how to use it correctly.

Here is what I have been trying:

  1. Print:

    if(something) {
        PyErr_SetString(PyExc_TypeError, "Oh no!");
        PyErr_Print();
    }
    

    This, unfortunately, only prints the exception and the program continues. Additionally,—if I understand it correctly—PyErr_Print() removes the exception from some sort of queue so Python thinks that it is handled. This is what it looks like:

    >>> import awesomemod
    >>> x = awesomemod.thing()
    TypeError: Oh no!
    >>> x # x is defined because the function returns None eventually
    >>> 
    
  2. PyErr_Occurred():

    if(something) {
        PyErr_SetString(PyExc_TypeError, "Oh no!");
        PyErr_Occurred();
    }
    

    Behavior:

    >>> import awesomemod
    >>> awesomemod.thing()
    >>>
    TypeError: Oh no!
    >>>
    

    So it does it kind of late...

  3. return PyErr_Occurred():

    if(something) {
        PyErr_SetString(PyExc_TypeError, "Oh no!");
        return PyErr_Occurred();
    }
    

    Behavior:

    >>> import awesomemod
    >>> awesomemod.thing()
    <type 'exceptions.TypeError'>
    >>>
    TypeError: Oh no!
    

    This one is just really weird.

What do I need to do to get the behavior of built-in functions?

Edit: I tried what @user2864740 suggested in a comment and it worked perfectly!

 if(something) {
     PyErr_SetString(PyExc_TypeError, "Oh no!");
     return (PyObject *) NULL;
 }
Was it helpful?

Solution

Raising an exception in C is done by setting the exception object or string and then returning NULL from the function.

OTHER TIPS

As Ignacio Vazquez-Abrams said:

Raising an exception in C is done by setting the exception object or string and then returning NULL from the function.

There are convenience functions which make this easy to do for common exception types. For example, PyErr_NoMemory can be used like this:

PyObject *my_function(void)
{
    return PyErr_NoMemory();  // Sets the exception and returns NULL
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top