Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #26384 > unrolled thread

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

Started byrahul <rahul03535@gmail.com>
First post2012-08-02 01:57 -0700
Last post2012-08-02 02:50 -0700
Articles 9 — 3 participants

Back to article view | Back to comp.lang.python


Contents

  C extension module doesn't throw exception after setting error indicator through PyErr_SetString() rahul <rahul03535@gmail.com> - 2012-08-02 01:57 -0700
    Re: C extension module doesn't throw exception after setting error indicator through PyErr_SetString() Tim Golden <mail@timgolden.me.uk> - 2012-08-02 10:06 +0100
      Re: C extension module doesn't throw exception after setting error indicator through PyErr_SetString() rahul <rahul03535@gmail.com> - 2012-08-02 02:21 -0700
      Re: C extension module doesn't throw exception after setting error indicator through PyErr_SetString() rahul <rahul03535@gmail.com> - 2012-08-02 02:21 -0700
        Re: C extension module doesn't throw exception after setting error indicator through PyErr_SetString() Tim Golden <mail@timgolden.me.uk> - 2012-08-02 10:37 +0100
          Re: C extension module doesn't throw exception after setting error indicator through PyErr_SetString() rahul <rahul03535@gmail.com> - 2012-08-02 02:50 -0700
            Re: C extension module doesn't throw exception after setting error indicator through PyErr_SetString() Tim Golden <mail@timgolden.me.uk> - 2012-08-02 11:45 +0100
            Re: C extension module doesn't throw exception after setting error indicator through PyErr_SetString() Stefan Behnel <stefan_ml@behnel.de> - 2012-08-02 12:54 +0200
          Re: C extension module doesn't throw exception after setting error indicator through PyErr_SetString() rahul <rahul03535@gmail.com> - 2012-08-02 02:50 -0700

#26384 — C extension module doesn't throw exception after setting error indicator through PyErr_SetString()

Fromrahul <rahul03535@gmail.com>
Date2012-08-02 01:57 -0700
SubjectC extension module doesn't throw exception after setting error indicator through PyErr_SetString()
Message-ID<fa944ed7-8101-4b2f-a49a-363eb8d05d1d@googlegroups.com>
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

[toc] | [next] | [standalone]


#26385

FromTim Golden <mail@timgolden.me.uk>
Date2012-08-02 10:06 +0100
Message-ID<mailman.2856.1343898392.4697.python-list@python.org>
In reply to#26384
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/extending/extending.html#intermezzo-errors-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

[toc] | [prev] | [next] | [standalone]


#26387

Fromrahul <rahul03535@gmail.com>
Date2012-08-02 02:21 -0700
Message-ID<mailman.2858.1343899291.4697.python-list@python.org>
In reply to#26385
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.

Thanks,
Rahul

[toc] | [prev] | [next] | [standalone]


#26388

Fromrahul <rahul03535@gmail.com>
Date2012-08-02 02:21 -0700
Message-ID<acb579e1-b716-46d9-b732-9dca094cedac@googlegroups.com>
In reply to#26385
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.

Thanks,
Rahul

[toc] | [prev] | [next] | [standalone]


#26390

FromTim Golden <mail@timgolden.me.uk>
Date2012-08-02 10:37 +0100
Message-ID<mailman.2860.1343900238.4697.python-list@python.org>
In reply to#26388
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

[toc] | [prev] | [next] | [standalone]


#26391

Fromrahul <rahul03535@gmail.com>
Date2012-08-02 02:50 -0700
Message-ID<d6e4ea1d-53cd-4a50-92ed-79a0b535dbd1@googlegroups.com>
In reply to#26390
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

[toc] | [prev] | [next] | [standalone]


#26396

FromTim Golden <mail@timgolden.me.uk>
Date2012-08-02 11:45 +0100
Message-ID<mailman.2865.1343904351.4697.python-list@python.org>
In reply to#26391
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

[toc] | [prev] | [next] | [standalone]


#26397

FromStefan Behnel <stefan_ml@behnel.de>
Date2012-08-02 12:54 +0200
Message-ID<mailman.2866.1343904911.4697.python-list@python.org>
In reply to#26391
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

[toc] | [prev] | [next] | [standalone]


#26392

Fromrahul <rahul03535@gmail.com>
Date2012-08-02 02:50 -0700
Message-ID<mailman.2861.1343901024.4697.python-list@python.org>
In reply to#26390
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

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web