简体   繁体   中英

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

在C中引发异常是通过设置异常对象或字符串,然后从函数返回NULL来完成的。

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
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM