Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > C extension module doesn't throw exception after setting errorindicator through PyErr_SetString()

Reply
Thread Tools

C extension module doesn't throw exception after setting errorindicator through PyErr_SetString()

 
 
rahul
Guest
Posts: n/a
 
      08-02-2012
I am implementing a C extension module, during this I saw that when I set the global error indicator and error message through PyErr_SetString() API and return false.

But it doesn't throw any error when I tried to check the error through sys.exc_info() then it returns (NULL, NULL, NULL) tuple.

When I return NULL through the C extension module's function then it works correctly and throws the exception as expected.

The skeleton looks like:

static PyObject* check(PyObject* sef, PyObject* args)
{
PyObject* input = NULL;
if (!PyArg_ParseTuple(args, "O", &input)){
return NULL;
}
.....
.....
PyErr_SetString(PyExc_Exception, "Throwing Error through check function");
Py_RETURN_FALSE;
}

Any idea on why this is happening? Any help will be appreciated.

Thanks,
Rahul
 
Reply With Quote
 
 
 
 
Tim Golden
Guest
Posts: n/a
 
      08-02-2012
On 02/08/2012 09:57, rahul wrote:
> I am implementing a C extension module, during this I saw that when I
> set the global error indicator and error message through
> PyErr_SetString() API and return false.
>
> But it doesn't throw any error when I tried to check the error
> through sys.exc_info() then it returns (NULL, NULL, NULL) tuple.
>
> When I return NULL through the C extension module's function then it
> works correctly and throws the exception as expected.
>
> The skeleton looks like:
>
> static PyObject* check(PyObject* sef, PyObject* args) { PyObject*
> input = NULL; if (!PyArg_ParseTuple(args, "O", &input)){ return
> NULL; } ..... ..... PyErr_SetString(PyExc_Exception, "Throwing Error
> through check function"); Py_RETURN_FALSE; }
>
> Any idea on why this is happening? Any help will be appreciated.



Because you're returning False. You should be returning NULL. Which is
why it works when you do

Have a look at the first line of this page:

http://docs.python.org/py3k/extendin...and-exceptions


Which piece of documentation led you to think that returning False was
the thing to do here? Perhaps there's a doc that needs fixing?


TJG
 
Reply With Quote
 
 
 
 
rahul
Guest
Posts: n/a
 
      08-02-2012

Hi TJG,

The above link also doesn't strictly said that return value should be NULL only, it only said that usually NULL pointer used. No where I saw that it is nessasory t

At http://docs.python.org/c-api/exceptions.html. it is written that "Most functions also return an error indicator, usually NULL if they are supposed to return a pointer, or -1 if they return an integer (exception: the PyArg_*() functions return 1 for success and 0 for failure)." this also told thatusually NULL is used but we can change the return error indicator to any value. As like PyArg_*() used 0 for error value.

Thanks,
Rahul
 
Reply With Quote
 
rahul
Guest
Posts: n/a
 
      08-02-2012

Hi TJG,

The above link also doesn't strictly said that return value should be NULL only, it only said that usually NULL pointer used. No where I saw that it is nessasory t

At http://docs.python.org/c-api/exceptions.html. it is written that "Most functions also return an error indicator, usually NULL if they are supposed to return a pointer, or -1 if they return an integer (exception: the PyArg_*() functions return 1 for success and 0 for failure)." this also told thatusually NULL is used but we can change the return error indicator to any value. As like PyArg_*() used 0 for error value.

Thanks,
Rahul
 
Reply With Quote
 
Tim Golden
Guest
Posts: n/a
 
      08-02-2012
On 02/08/2012 10:21, rahul wrote:
>
> Hi TJG,
>
> The above link also doesn't strictly said that return value should be
> NULL only, it only said that usually NULL pointer used. No where I
> saw that it is nessasory t
>
> At http://docs.python.org/c-api/exceptions.html. it is written that
> "Most functions also return an error indicator, usually NULL if they
> are supposed to return a pointer, or -1 if they return an integer
> (exception: the PyArg_*() functions return 1 for success and 0 for
> failure)." this also told that usually NULL is used but we can change
> the return error indicator to any value. As like PyArg_*() used 0 for
> error value.


The docs you quote are very slightly confusing because they're combining
the standard practice (return NULL), the uncommon alternative (return
-1) and a few special cases present in the core functions.

In short, any function you expose in an extension module will be
returning a PyObject* and should return NULL if it is setting or
cascading an exception.

I'm not convinced that the docs need altering here: this is the first
time I've come across anyone who was confused. But if you think some
different wording might help, feel free to propose something.

TJG
 
Reply With Quote
 
rahul
Guest
Posts: n/a
 
      08-02-2012
When I use same code base for Python 3.x, then behavior is different. In this when I return false then also it throws exception but only when any other statement get executed after this

like below code:
...
...
b = None
try:
a = testModule.check(None)
except:
b = sys.exc_info()
then code execution doesn't come to except block.
But when I add one statement after calling check function then code execution goes into except block.

...
...
b = None
try:
a = testModule.check(None)
print( a )
except:
b = sys.exc_info()


On Thursday, 2 August 2012 15:07:08 UTC+5:30, Tim Golden wrote:
> On 02/08/2012 10:21, rahul wrote:
>
> >

>
> > Hi TJG,

>
> >

>
> > The above link also doesn't strictly said that return value should be

>
> > NULL only, it only said that usually NULL pointer used. No where I

>
> > saw that it is nessasory t

>
> >

>
> > At http://docs.python.org/c-api/exceptions.html. it is written that

>
> > "Most functions also return an error indicator, usually NULL if they

>
> > are supposed to return a pointer, or -1 if they return an integer

>
> > (exception: the PyArg_*() functions return 1 for success and 0 for

>
> > failure)." this also told that usually NULL is used but we can change

>
> > the return error indicator to any value. As like PyArg_*() used 0 for

>
> > error value.

>
>
>
> The docs you quote are very slightly confusing because they're combining
>
> the standard practice (return NULL), the uncommon alternative (return
>
> -1) and a few special cases present in the core functions.
>
>
>
> In short, any function you expose in an extension module will be
>
> returning a PyObject* and should return NULL if it is setting or
>
> cascading an exception.
>
>
>
> I'm not convinced that the docs need altering here: this is the first
>
> time I've come across anyone who was confused. But if you think some
>
> different wording might help, feel free to propose something.
>
>
>
> TJG

 
Reply With Quote
 
rahul
Guest
Posts: n/a
 
      08-02-2012
When I use same code base for Python 3.x, then behavior is different. In this when I return false then also it throws exception but only when any other statement get executed after this

like below code:
...
...
b = None
try:
a = testModule.check(None)
except:
b = sys.exc_info()
then code execution doesn't come to except block.
But when I add one statement after calling check function then code execution goes into except block.

...
...
b = None
try:
a = testModule.check(None)
print( a )
except:
b = sys.exc_info()


On Thursday, 2 August 2012 15:07:08 UTC+5:30, Tim Golden wrote:
> On 02/08/2012 10:21, rahul wrote:
>
> >

>
> > Hi TJG,

>
> >

>
> > The above link also doesn't strictly said that return value should be

>
> > NULL only, it only said that usually NULL pointer used. No where I

>
> > saw that it is nessasory t

>
> >

>
> > At http://docs.python.org/c-api/exceptions.html. it is written that

>
> > "Most functions also return an error indicator, usually NULL if they

>
> > are supposed to return a pointer, or -1 if they return an integer

>
> > (exception: the PyArg_*() functions return 1 for success and 0 for

>
> > failure)." this also told that usually NULL is used but we can change

>
> > the return error indicator to any value. As like PyArg_*() used 0 for

>
> > error value.

>
>
>
> The docs you quote are very slightly confusing because they're combining
>
> the standard practice (return NULL), the uncommon alternative (return
>
> -1) and a few special cases present in the core functions.
>
>
>
> In short, any function you expose in an extension module will be
>
> returning a PyObject* and should return NULL if it is setting or
>
> cascading an exception.
>
>
>
> I'm not convinced that the docs need altering here: this is the first
>
> time I've come across anyone who was confused. But if you think some
>
> different wording might help, feel free to propose something.
>
>
>
> TJG

 
Reply With Quote
 
Tim Golden
Guest
Posts: n/a
 
      08-02-2012
On 02/08/2012 10:50, rahul wrote:
> When I use same code base for Python 3.x, then behavior is different. In this when I return false then also it throws exception but only when any other statement get executed after this
>
> like below code:
> ...
> ...
> b = None
> try:
> a = testModule.check(None)
> except:
> b = sys.exc_info()
> then code execution doesn't come to except block.
> But when I add one statement after calling check function then code execution goes into except block.
>
> ...
> ...
> b = None
> try:
> a = testModule.check(None)
> print( a )
> except:
> b = sys.exc_info()



Sounds like you're entering into undefined behaviour. If you set an
exception and don't return NULL, you're leaving Python's internals in an
inconsistent state. I don't know the internal code paths, but presumably
in one version it just ignored the exception state while in the other it
noticed it but in a different point in the code at which point it raised
the exception. Or something.

Long-and-short: return NULL from an extension module function once
you've raised (or are cascading) an exception condition. Anything else
is undefined unless you know *exactly* what you're doing.


TJG
 
Reply With Quote
 
Stefan Behnel
Guest
Posts: n/a
 
      08-02-2012
rahul, 02.08.2012 11:50:
> When I use same code base for Python 3.x, then behavior is different.


You might want to take a look at Cython. It moves most of these "funny"
little details off your shoulders.

Stefan


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
To throw or to throw not? Emanuele D'Arrigo Python 6 11-15-2008 04:12 PM
JNI's throw new does not throw an exception yarona@m-sys.com Java 15 09-08-2005 08:36 AM
throw exception in the finalize z. f. ASP .Net 1 07-05-2004 12:36 PM
How to throw Application_Errors as SOAP-Exception ASP .Net 1 03-02-2004 06:35 AM
Throw Exception Vs Throw New Exception Kerri ASP .Net 2 10-27-2003 02:13 PM



Advertisments