[Pyrex] Initialisation of cdef global arrays with constants [resend]

sjmachin at lexicon.net sjmachin at lexicon.net
Sat Jan 29 23:28:03 CET 2005


On 30 Jan 2005 at 9:58, Greg Ewing wrote:

> sjmachin at lexicon.net wrote:
> > Where I'm coming from is (my belief/understanding) that a "Python function" hand 
> > coded in C _should_ return NULL in this circumstance, so that the precise exception set 
> > by the called function can be thrown, instead of a guess.
> 
> Oh, I see what you mean. Yes, that's what you would do
> if you were writing an extension module in C by hand.
> But in Pyrex you just use a "raise" statement, and
> Pyrex takes care of returning the NULL.

Apparently not: as one might expect, it generates code to do what Python does with a 
bare "raise" statement -- i.e. *RE*raise an already raised exception.

In my scenario, PyString_AsStringAndSize has *set* an exception, but it has not yet 
been raised; we need to return NULL back down the call chain until the exception is 
raised.

=== strargtest.pyx ===

cdef extern from "Python.h":
   int PyString_AsStringAndSize(object obj, char **buff, int *length) # -> -1 means error
   int PyString_Check(object obj)

   
def tester(s):
   cdef char *ucptr
   cdef int slen
   slen = -99
   if PyString_AsStringAndSize(s, &ucptr, &slen) == -1:
      raise
   print 'len(s) was', slen

=== tests ===

Python 2.4 (#60, Nov 30 2004, 11:49:19) [MSC v.1310 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import strargtest
>>> strargtest.tester('xyz')
len(s) was 3
>>> strargtest.tester('')
len(s) was 0
>>> strargtest.tester(999)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "strargtest.pyx", line 12, in strargtest.tester
    raise
None <<<<<<<<<<<<<<<<=============== Not what we want!
>>>

=== from generated code ===

  /* "C:\devel\bkt\strargtest.pyx":11 */
  __pyx_1 = 
(PyString_AsStringAndSize(__pyx_v_s,(&__pyx_v_ucptr),(&__pyx_v_slen)) == (-1));
  if (__pyx_1) {

    /* "C:\devel\bkt\strargtest.pyx":12 */
    __Pyx_ReRaise();
    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; goto __pyx_L1;}
    goto __pyx_L2;
  }




More information about the Pyrex mailing list