Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I properly use Python's C API and exceptions?

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;
 }
like image 609
dejay Avatar asked Nov 27 '13 02:11

dejay


People also ask

How do you pass exceptions in Python?

Catching Exceptions in Python In Python, exceptions can be handled using a try statement. The critical operation which can raise an exception is placed inside the try clause. The code that handles the exceptions is written in the except clause.

What keywords do you use in Python to handle exceptions?

Python uses try and except keywords to handle exceptions. Both keywords are followed by indented blocks. The try: block contains one or more statements which are likely to encounter an exception.

Should I use exceptions in Python?

In Python programming, exception handling allows a programmer to enable flow control. And it has no. of built-in exceptions to catch errors in case your code breaks. Using try-except is the most common and natural way of handling unexpected errors along with many more exception handling constructs.

What is the use of @Python/C API?

Python/C API Reference Manual ¶ This manual documents the API used by C and C++ programmers who want to write extension modules or embed Python. It is a companion to Extending and Embedding the Python Interpreter, which describes the general principles of extension writing but does not document the API functions in detail.

How do you handle exceptions in Python?

An interesting aspect of exception handling is that if an exception is raised in a function that was previously called in the try clause of another function and the function itself does not handle it, the caller will handle it if there is an appropriate except clause. According to the Python Documentation:

How to start using an API with Python?

How to Start Using an API with Python. Having dealt with the nuances of working with API in Python, we can create a step-by-step guide: 1. Get an API key. An API Key is (usually) a unique string of letters and numbers. In order to start working with most APIs – you must register and get an API key.

What happens if Python/C API errors are not handled properly?

If the error is not handled or carefully propagated, additional calls into the Python/C API may not behave as intended and may fail in mysterious ways. The error indicator is not the result of sys.exc_info () .


2 Answers

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

like image 101
Ignacio Vazquez-Abrams Avatar answered Oct 22 '22 15:10

Ignacio Vazquez-Abrams


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
}
like image 39
Jonathon Reinhart Avatar answered Oct 22 '22 16:10

Jonathon Reinhart