On Thu, Apr 25, 2019 at 2:32 PM Vincent Vande Vyvre <vincent.vande.vy...@telenet.be> wrote: > > Le 24/04/19 à 19:57, MRAB a écrit : > > On 2019-04-23 20:21, Vincent Vande Vyvre wrote: > >> Le 23/04/19 à 20:54, Chris Angelico a écrit : > >>> On Wed, Apr 24, 2019 at 4:47 AM Vincent Vande Vyvre > >>> <vincent.vande.vy...@telenet.be> wrote: > >>> > >>> Into the lib: > >>> > >>> static int > >>> ImgProc_init(ImgProc *self, PyObject *args, PyObject *kwds) > >>> { > >>> PyObject *tmp; > >>> char *fname; > >>> > >>> if (!PyArg_ParseTuple(args, "s", &fname)) > >>> return NULL; > >>> > >>> tmp = self->src; > >>> self->src = PyUnicode_FromString(fname); > >>> Py_XDECREF(tmp); > >>> return 0; > >>> } > >>> > >>> If i do: > >>> try: > >>> tif = ImgProc(123) > >>> except Exception as why: > >>> print(sys.exc_info()) > >>> raise > >>> I get: > >>> (<class 'SystemError'>, SystemError("<class '_liboqapy.ImgProc'> > >>> returned a result with an error set",), <traceback object at > >>> 0x7f3bcac748c8>) > >>> TypeError: argument 1 must be str, not int > >>> > >>> The above exception was the direct cause of the following exception: > >>> > >>> Traceback (most recent call last): > >>> File "/home/vincent/oqapy-3/trunk/filters/ui_lenscorrection.py", > >>> line > >>> 104, in on_main_cursor_changed > >>> self.prepare_preview_process() > >>> File "/home/vincent/oqapy-3/trunk/filters/ui_lenscorrection.py", > >>> line > >>> 137, in prepare_preview_process > >>> self.main.process_on_preview(params) > >>> File "/home/vincent/oqapy-3/trunk/filters/lenscorrection.py", line > >>> 56, in process_on_preview > >>> tif = ImgProc(123) > >>> SystemError: <class '_liboqapy.ImgProc'> returned a result with an > >>> error set > >>> -------------------------------------------------------------------------------- > >>> > >>> Why a SystemError ? > >>> The SystemError means that you're using the Python C API in a way that > >>> doesn't make sense to the interpreter. You're leaving a marker saying > >>> "hey, I need you to throw an exception" but then you're also returning > >>> a value. You'll need to figure out where that's happening and exactly > >>> what is being called. How are you setting up your class? > >>> > >>> ChrisA > >> > >> The syntaxe > >> > >> if (!PyArg_ParseTuple(args, "s", &fname)) > >> return NULL; > >> > >> Is the usage described in the doc [*] > >> > >> And without block try-except I get the good one error. > >> > >> > >> [*] > >> https://docs.python.org/3.5//extending/extending.html#back-to-the-example > >> > >> > > If you look at the previous example, the function's return type is > > "PyObject *". > > > > On success it returns a reference (pointer) to an object; on error it > > returns NULL. > > > > Your function's return type is int. > > In this case yes, beause it need to return the result of the command system. > > But the "return 0" is a common case for an "Foo_init()" > > see: > https://docs.python.org/3.5//extending/newtypes.html#adding-data-and-methods-to-the-basic-example > > ... And that's nothing to do with my initial question
Actually, it is a lot to do with your initial question. Notice how there are two distinct signatures being demonstrated in the example you linked to: those declared as returning PyObject* and those declared as returning int. If something is meant to return an object, then returning NULL says "hey, I set an error state, unwind the stack and raise the exception". If it's meant to return an integer, though, it returns -1 to give that message. See details here (second paragraph): https://docs.python.org/3/c-api/intro.html#exceptions The __init__ function is defined as returning an integer: https://docs.python.org/3/c-api/typeobj.html#c.PyTypeObject.tp_init You're right that "return 0" is a common case; that isn't the problem. The problem is the "return NULL", which is correct for a function that normally returns a PyObject*, but not for one that returns an int. That's why you're getting a SystemError - you're setting the exception state, but then saying "hey, everything's fine, it's okay to return None". ChrisA -- https://mail.python.org/mailman/listinfo/python-list