How to catch a usefull error message ?

MRAB python at mrabarnett.plus.com
Wed Apr 24 14:01:28 EDT 2019


On 2019-04-23 21:03, Vincent Vande Vyvre wrote:
> Le 23/04/19 à 21:48, MRAB a écrit :
>> On 2019-04-23 19:21, Vincent Vande Vyvre wrote:
>>> Le 23/04/19 à 19:23, Chris Angelico a écrit :
>>>> On Wed, Apr 24, 2019 at 3:18 AM Vincent Vande Vyvre
>>>> <vincent.vande.vyvre at telenet.be> wrote:
>>>>> Hi,
>>>>>
>>>>> In a CPython lib I have an _init() method wich take one argument, a 
>>>>> file
>>>>> name.
>>>>>
>>>>>       char *fname;
>>>>>
>>>>>       if (!PyArg_ParseTuple(args, "s", &fname))
>>>>>           return NULL;
>>>>>
>>>>> So, if I instanciate my object with a bad argument I've a good error
>>>>> message:
>>>>>
>>>>> tif = ImgProc(123)
>>>>> TypeError: argument 1 must be str, not int
>>>>> (followed by the traceback)
>>>>>
>>>>> But if I do:
>>>>> try:
>>>>>       tif = ImgProc(123)
>>>>> except Exception as why:
>>>>>       print("Error:", why)
>>>>>
>>>>> I get just:
>>>>>
>>>>> Error: <class '_liboqapy.ImgProc'> returned a result with an error set
>>>>>
>>>> It looks like there's an internal problem in the C function. Are you
>>>> sure it's hitting the PyArg_ParseTuple and then immediately returning
>>>> NULL? Post a bit more of your code; this error looks like something is
>>>> leaving an error state but then carrying on with the code.
>>>>
>>>> ChrisA
>>>
>>> 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;
>>> }
>>>
>> [snip]
>>
>> That function returns an int.
>>
>> If PyArg_ParseTuple fails, your function returns NULL, which is cast 
>> to an int, 0.
>>
>> If PyArg_ParseTuple succeeds, your function returns 0.
>>
>> Either way, it returns 0.
>>
>> So how does the caller know whether the function was successful? Does 
>> it check PyErr_Occurred?
> 
> No, the caller is in a block try-except for that.
> 
> The exact question here is why without a try-except I've the good one
> error and not in a try-except.
> 
> The /return 0;/ is usual in a /Foo_init()/ function.
> 
In an extension, if your C function has been called by Python then its 
return type should (usually) be "PyObject*". It should return a 
reference to an object on success or NULL on error.

Look more closely at the last example of section 1.2 at 
https://docs.python.org/3.5//extending/extending.html#back-to-the-example.


More information about the Python-list mailing list