473,897 Members | 2,557 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

question: numarray c extension error handling?

I'm writing a C extension for numarray and am puzzled about the idiom
for error handling.

The documentation seems to say one should always decref an array after
calling NA_InputArray, etc., to convert numarray args to C arrays.

However, the example and also the numarray code suggests that it's OK to
return early via (for example) PyErr_Format without doing the DECREF.
For example, I have appended a very abbreviated version of the sample
code.

Comments? I'll plow ahead and follow the example (i.e. with early
return) but I was wondering if anyone knew why this was OK. Perhaps I
should put in a request to the numarray project for a clarification in
the documentation.

-- Russell

static PyObject * Py_Convolve1d(P yObject *obj, PyObject *args)
{
PyObject *okernel,...;
PyArrayObject *kernel...;

if (!PyArg_ParseTu ple(args, "OO|O", &okernel, ...))
return PyErr_Format(_c onvolveError,
"Convolve1d : Invalid parameters.");

/* Align, Byteswap, Contiguous, Typeconvert */
kernel = NA_IoArray(oker nel, tFloat64, C_ARRAY);
....
if (!kernel...)
return PyErr_Format( _convolveError,
"Convolve1d : error converting array inputs.");
....
Py_XDECREF(kern el);
....
}

The relevant section of the docs (section 12.3 High-level API):

The return value of each function (NA_InputArray, NA_OutputArray, or
NA_IoArray) is either a reference to the original numarray object, or a
reference to a temporary numarray. Following execution of the C-code in
the extension function body this pointer should *always* be DECREFed.
Jul 18 '05 #1
8 1803
At some point, "Russell E. Owen" <no@spam.invali d> wrote:
I'm writing a C extension for numarray and am puzzled about the idiom
for error handling.

The documentation seems to say one should always decref an array after
calling NA_InputArray, etc., to convert numarray args to C arrays.

However, the example and also the numarray code suggests that it's OK to
return early via (for example) PyErr_Format without doing the DECREF.
For example, I have appended a very abbreviated version of the sample
code.

Comments? I'll plow ahead and follow the example (i.e. with early
return) but I was wondering if anyone knew why this was OK. Perhaps I
should put in a request to the numarray project for a clarification in
the documentation.

-- Russell

static PyObject * Py_Convolve1d(P yObject *obj, PyObject *args)
{
PyObject *okernel,...;
PyArrayObject *kernel...;

if (!PyArg_ParseTu ple(args, "OO|O", &okernel, ...))
return PyErr_Format(_c onvolveError,
"Convolve1d : Invalid parameters.");
This is ok; if PyArg_ParseTupl e is NULL, no objects are created (or
INCREF'd). Also, if it's not NULL, okernel is a borrowed reference;
you shouldn't DECREF it.

/* Align, Byteswap, Contiguous, Typeconvert */
kernel = NA_IoArray(oker nel, tFloat64, C_ARRAY);
...
if (!kernel...)
return PyErr_Format( _convolveError,
"Convolve1d : error converting array inputs.");
This is also ok (assuming there is nothing between this and the above
which makes a reference to objects). If NA_IoArray returns NULL,
there isn't anything to DECREF.
...
Py_XDECREF(kern el);
...
}


Personally, I write it like this:

static PyObject * Py_Convolve1d(P yObject *obj, PyObject *args)
{
PyObject *okernel,...;
PyArrayObject *kernel = NULL;

if (!PyArg_ParseTu ple(args, "OO|O", &okernel, ...)) {
PyErr_Format(_c onvolveError,
"Convolve1d : Invalid parameters.");
goto error;
}
kernel = NA_IoArray(oker nel, tFloat64, C_ARRAY);
if (!kernel...) {
PyErr_Format( _convolveError,
"Convolve1d : error converting array inputs.");
goto error;
}

...more stuff...

Py_XDECREF(kern el)
return the result
error:
Py_XDECREF(kern el)
return NULL;
}

Notice that kernel was initialized to NULL, so Py_XDECREF will work in
all cases. Clean error-handling code like this is one of the few
places I use goto in C. You now have only two exits out of the
function, at the bottom, and so it's _much_ easier to keep track of
what needs to be DECREF'd.

--
|>|\/|<
/--------------------------------------------------------------------------\
|David M. Cooke
|cookedm(at)phy sics(dot)mcmast er(dot)ca
Jul 18 '05 #2
In article <qn************ *@arbutus.physi cs.mcmaster.ca> ,
co**********@ph ysics.mcmaster. ca (David M. Cooke) wrote:
...
/* Align, Byteswap, Contiguous, Typeconvert */
kernel = NA_IoArray(oker nel, tFloat64, C_ARRAY);
...
if (!kernel...)
return PyErr_Format( _convolveError,
"Convolve1d : error converting array inputs.");


This is also ok (assuming there is nothing between this and the above
which makes a reference to objects). If NA_IoArray returns NULL,
there isn't anything to DECREF.


I'm afraid I was too selective in extracting code, making it look like
no DECREF was even wanted. Here is a more complete extract. The first
test can fail even if one or two of the arrays was successfullly
"extracted" , so a DECREF is wanted then, and all the more so for the two
tests after that:

....
/* Align, Byteswap, Contiguous, Typeconvert */
kernel = NA_IoArray(oker nel, tFloat64, C_ARRAY);
data = NA_IoArray(odat a, tFloat64, C_ARRAY);
convolved = NA_OptionalOutp utArray(oconvol ved, tFloat64, C_ARRAY,
data);

if (!kernel || !data || !convolved)
return PyErr_Format( _convolveError,
"Convolve1d : error converting array inputs.");

if ((kernel->nd != 1) || (data->nd != 1))
return PyErr_Format(_c onvolveError,
"Convolve1d : numarray must have 1 dimensions.");

if (!NA_ShapeEqual (data, convolved))
return PyErr_Format(_c onvolveError,
"Convolve1d : data and output numarray need identitcal
shapes.");

Convolve1d(kern el->dimensions[0],
NA_OFFSETDATA(k ernel),
data->dimensions[0],
NA_OFFSETDATA(d ata),
NA_OFFSETDATA(c onvolved));

Py_XDECREF(kern el);
Py_XDECREF(data );
....

It sounds as if I should submit a bug report on the example.

-- Russell
Jul 18 '05 #3
Here's a nice use of goto's in a Python C extension for those who have
been following the goto thread. I like it (see code at end and the nice
resolve for returns the goto's give). I hope Mr. Cooke does not mind me
"borrowing" his code. :-)
In article <qn************ *@arbutus.physi cs.mcmaster.ca> ,
co**********@ph ysics.mcmaster. ca (David M. Cooke) wrote:
At some point, "Russell E. Owen" <no@spam.invali d> wrote:
I'm writing a C extension for numarray and am puzzled about the idiom
for error handling.

The documentation seems to say one should always decref an array after
calling NA_InputArray, etc., to convert numarray args to C arrays.

However, the example and also the numarray code suggests that it's OK to
return early via (for example) PyErr_Format without doing the DECREF.
For example, I have appended a very abbreviated version of the sample
code.

Comments? I'll plow ahead and follow the example (i.e. with early
return) but I was wondering if anyone knew why this was OK. Perhaps I
should put in a request to the numarray project for a clarification in
the documentation.

-- Russell

static PyObject * Py_Convolve1d(P yObject *obj, PyObject *args)
{
PyObject *okernel,...;
PyArrayObject *kernel...;

if (!PyArg_ParseTu ple(args, "OO|O", &okernel, ...))
return PyErr_Format(_c onvolveError,
"Convolve1d : Invalid parameters.");


This is ok; if PyArg_ParseTupl e is NULL, no objects are created (or
INCREF'd). Also, if it's not NULL, okernel is a borrowed reference;
you shouldn't DECREF it.

/* Align, Byteswap, Contiguous, Typeconvert */
kernel = NA_IoArray(oker nel, tFloat64, C_ARRAY);
...
if (!kernel...)
return PyErr_Format( _convolveError,
"Convolve1d : error converting array inputs.");


This is also ok (assuming there is nothing between this and the above
which makes a reference to objects). If NA_IoArray returns NULL,
there isn't anything to DECREF.
...
Py_XDECREF(kern el);
...
}


Personally, I write it like this:

static PyObject * Py_Convolve1d(P yObject *obj, PyObject *args)
{
PyObject *okernel,...;
PyArrayObject *kernel = NULL;

if (!PyArg_ParseTu ple(args, "OO|O", &okernel, ...)) {
PyErr_Format(_c onvolveError,
"Convolve1d : Invalid parameters.");
goto error;
}
kernel = NA_IoArray(oker nel, tFloat64, C_ARRAY);
if (!kernel...) {
PyErr_Format( _convolveError,
"Convolve1d : error converting array inputs.");
goto error;
}

...more stuff...

Py_XDECREF(kern el)
return the result
error:
Py_XDECREF(kern el)
return NULL;
}

Notice that kernel was initialized to NULL, so Py_XDECREF will work in
all cases. Clean error-handling code like this is one of the few
places I use goto in C. You now have only two exits out of the
function, at the bottom, and so it's _much_ easier to keep track of
what needs to be DECREF'd.


-- Lou Pecora
My views are my own.
Jul 18 '05 #4
At some point, Lou Pecora <pe****@anvil.n rl.navy.mil> wrote:
Here's a nice use of goto's in a Python C extension for those who have
been following the goto thread. I like it (see code at end and the nice
resolve for returns the goto's give). I hope Mr. Cooke does not mind me
"borrowing" his code. :-)


Not a problem; I wish more people would :-)

--
|>|\/|<
/--------------------------------------------------------------------------\
|David M. Cooke
|cookedm(at)phy sics(dot)mcmast er(dot)ca
Jul 18 '05 #5
It is arbitrarily trivial to convert it to use an error boolean.

- Josiah

static PyObject * Py_Convolve1d(P yObject *obj, PyObject *args)
{
PyObject *okernel,...;
PyArrayObject *kernel = NULL;
bool error = 0;

if (!PyArg_ParseTu ple(args, "OO|O", &okernel, ...)) {
PyErr_Format(_c onvolveError,
"Convolve1d : Invalid parameters.");
error = 1;
}
kernel = NA_IoArray(oker nel, tFloat64, C_ARRAY);
if (!kernel...) {
PyErr_Format( _convolveError,
"Convolve1d : error converting array inputs.");
error = 1;
}

...more stuff...

if (!error) {
Py_XDECREF(kern el)
return the result
} else {
Py_XDECREF(kern el)
return NULL;
}
}
Jul 18 '05 #6
In article <c2**********@n ews.service.uci .edu>, Josiah Carlson wrote:
It is arbitrarily trivial to convert it to use an error boolean.
No, it isn't, as evidenced by the fact that you did it wrong.
static PyObject * Py_Convolve1d(P yObject *obj, PyObject *args)
{
PyObject *okernel,...;
PyArrayObject *kernel = NULL;
bool error = 0;

if (!PyArg_ParseTu ple(args, "OO|O", &okernel, ...)) {
PyErr_Format(_c onvolveError,
"Convolve1d : Invalid parameters.");
error = 1;
}
if (!error) { kernel = NA_IoArray(oker nel, tFloat64, C_ARRAY);
if (!kernel...) {
PyErr_Format( _convolveError,
"Convolve1d : error converting array inputs.");
error = 1;
} }

if (!error) { ...more stuff... }
if (!error) {
Py_XDECREF(kern el)
return the result
} else {
Py_XDECREF(kern el)
return NULL;
}
}


You have to remember to check the error variable at every step in the
function, or use else clauses and deal with heavy nesting. This is a
perfect situation for GOTO.

Joe
Jul 18 '05 #7
> You have to remember to check the error variable at every step in the
function, or use else clauses and deal with heavy nesting. This is a
perfect situation for GOTO.


I did slip, but it is still fairly easy to do, I just wasn't paying
attention. It does show a situation where GOTO can be useful, I'll give
you that. Depending on the code, it may be a case where a macro would
be better suited.

- Josiah
Jul 18 '05 #8
>>>>> "Josiah" == Josiah Carlson <jc******@nospa m.uci.edu> writes:

Josiah> I did slip, but it is still fairly easy to do

This "fairly easy" ignores the possibility that later you need to add or
modify the line that must be executed before the function returns. Macro
might be a solution, although I consider the goto solution cleaner (doesn't
need a separate language (and thus different indentation rules), won't
pollute the namespace, ease the compiler to reduce compiled code size, etc).

Regards,
Isaac.
Jul 18 '05 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
2998
by: RJS | last post by:
Hi all, I can't get a py2exe compiled app to run with numarray (numarray-0.5.win32- py2.2). Also wxPythonWIN32-2.3.3.1-Py22 and ActivePython-2.2.1-222. In the sample below, commenting out "import numarray" allows the exe to run. Left in, I get "4.exe has generated errors" etc. I'm going around and around and there isn't much on Google. py2exe output is last.
3
1834
by: Alexander Schwaigkofler | last post by:
Hi! I have the following problem with numarray. I read the install.txt manual, but it doesn't already work. OS: Microsoft Windows 2000 python: Python 2.2.3 (#42, May 30 2003, 18:12:08) on win32 numarray: Version 0.7 the output from the installation (by hand) you can see below:
4
1991
by: Marco Bubke | last post by:
Hi I have tried to include numarray in Pyrex but I get allways this error: Traceback (most recent call last): File "gears.py", line 9, in ? import gl File "/home/marco/projects/test_pyrex/gl.pyx", line 40, in gl ctypedef class numarray.NumArray :
2
2978
by: Marc Schellens | last post by:
Following the NumPy documentation, I took over some C code, but run into an error. Does anybody have a suggestion? Thanks, marc gdlpython.cpp:225: `PyArray_Type' undeclared (first use this function) #include <python2.3/Python.h>
3
1609
by: SunX | last post by:
I tried to initialize a float point array by: import numarray xur = numarray.fromfunction(lambda x,y,z:x*y*z, (2, 2, 2)) but I ended up with an integer array even though x, y, and z are all floats. BTW, how do you unzip NumTut in windows? And is there a newer version? Thank you
11
2003
by: grv | last post by:
So it is supposed to be very fast to have an array of say 5 million integers stored in a binary file and do a = numarray.fromfile('filename', (2, 2, 2)) numarray.add(a, 9, a) but how is that faster than reading the entire file into memory and then having a for loop in C: (loop over range) { *p++ += 9 }
2
1935
by: maxwell | last post by:
I'm trying to use the 'numarray' package (v1.1.1) under Python 2.4 running under CygWin. I initially downloaded the Windows executable version of the numarray package, and installed it under C:\program files\python\lib\site-packages. That works with the Windows version of Python, but not the CygWin version, where it fails with the msg: ImportError: No module named _conv The file _conf.pyd exists, but my guess is that the .pyd suffix is...
3
3403
by: PL | last post by:
I want to pass a 2D array from Python to C++, manipulate it in C++ (for example, add 1 to each element) and pass it back to Python. With these building blocks I will be able to figure out all the rest of what I need to do for my project. I am very familiar with Python, but less so with C++ and Boost or SWIG. Does anyone have an example with all steps that I can follow? More specifically I am looking for the C++ code, ".i" file for...
11
2031
by: Trent | last post by:
Running this I see that on first run, both bubble and selection sort have 9 sort counts while insertion sort has ZERO. With a sorted list, should this be ZERO for all? Also bsort and Ssort have the same exact sorting counts also..shouldn't they differ somewhat? Source and data file below. Thanks
0
9990
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, weíll explore What is ONU, What Is Router, ONU & Routerís main usage, and What is the difference between ONU and Router. Letís take a closer look ! Part I. Meaning of...
0
9837
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
11250
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10850
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
10478
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
8032
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Duprť who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5873
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
6074
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4698
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.