numpy C API bugs?
![](https://secure.gravatar.com/avatar/debd930eac52f28f57b2883bf2c14283.jpg?s=120&d=mm&r=g)
Hi Travis and NumPy developers, I have recently been engaged in updating the PyNIO module (http://www.pyngl.ucar.edu/Nio.html) to work with the NumPy C API. It was originally coded using the Numeric's C API. In the process I have encountered what appear to me to be a couple of bugs in the interface. They were relatively minor and not difficult to work around, but you would probably like to know of them if you don't already. In the NumPy version of arrayobject.h the macros PyArray_GETITEM and PyArray_SETITEM are defined in way that does not work. Here is the GETITEM macro: #define PyArray_GETITEM(obj,itemptr) \ ((char *)itemptr, \ (PyArrayObject *)obj); When I try to use this macro in my code I get a compile error, because 'getitem' is not a member of NumPy's PyArray_Descr struct. Instead it is further nested within the struct member 'PyArray_ArrFuncs *f'. So, unless I misunderstand, the macro needs to access the 'getitem' function as ((PyArrayObject *)(obj))->descr->f->getitem(... The other issue with 'getitem', apparently the actual method, not just this macro, is that the 2 arguments are ordered oppositely from what is stated in "Guide To NumPy", as well as from the way this method was implemented in Numeric. Notice in the macro (and in NumPy's implementation), 'itemptr' is first and the PyArrayObject pointer is second. The documentation and Numeric has it the other way around. I hope this is useful. -dave
![](https://secure.gravatar.com/avatar/debd930eac52f28f57b2883bf2c14283.jpg?s=120&d=mm&r=g)
On Mar 9, 2006, at 4:56 PM, David Ian Brown wrote:
Hi Travis and NumPy developers,
I have recently been engaged in updating the PyNIO module (http://www.pyngl.ucar.edu/Nio.html) to work with the NumPy C API. It was originally coded using the Numeric's C API.
In the process I have encountered what appear to me to be a couple of bugs in the interface. They were relatively minor and not difficult to work around, but you would probably like to know of them if you don't already.
In the NumPy version of arrayobject.h the macros PyArray_GETITEM and PyArray_SETITEM are defined in way that does not work. Here is the GETITEM macro:
#define PyArray_GETITEM(obj,itemptr) \ ((char *)itemptr, \ (PyArrayObject *)obj);
When I try to use this macro in my code I get a compile error, because 'getitem' is not a member of NumPy's PyArray_Descr struct. Instead it is further nested within the struct member 'PyArray_ArrFuncs *f'. So, unless I misunderstand, the macro needs to access the 'getitem' function as
((PyArrayObject *)(obj))->descr->f->getitem(...
The other issue with 'getitem', apparently the actual method, not just this macro, is that the 2 arguments are ordered oppositely from what is stated in "Guide To NumPy", as well as from the way this method was implemented in Numeric. Notice in the macro (and in NumPy's implementation), 'itemptr' is first and the PyArrayObject pointer is second. The documentation and Numeric has it the other way around.
Correction: actually "Guide to NumPy" has the 'getitem' function documented with the arguments ordered as implemented in NumPy (but still opposite from Numeric). Only the macro is documented opposite from its implementation.
I hope this is useful. -dave
------------------------------------------------------- This SF.Net email is sponsored by xPML, a groundbreaking scripting language that extends applications into web and mobile media. Attend the live webcast and join the prime developer group breaking into this new coding territory! http://sel.as-us.falkag.net/sel? cmd=lnk&kid=110944&bid=241720&dat=121642 _______________________________________________ Numpy-discussion mailing list Numpy-discussion@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/numpy-discussion
![](https://secure.gravatar.com/avatar/49df8cd4b1b6056c727778925f86147a.jpg?s=120&d=mm&r=g)
David Ian Brown wrote:
I have recently been engaged in updating the PyNIO module (http://www.pyngl.ucar.edu/Nio.html) to work with the NumPy C API. It was originally coded using the Numeric's C API.
In the process I have encountered what appear to me to be a couple of bugs in the interface. They were relatively minor and not difficult to work around, but you would probably like to know of them if you don't already.
In the NumPy version of arrayobject.h the macros PyArray_GETITEM and PyArray_SETITEM are defined in way that does not work. Here is the GETITEM macro:
#define PyArray_GETITEM(obj,itemptr) \ ((char *)itemptr, \ (PyArrayObject *)obj);
Thank you very much for catching this. The introduction of 'f' was more recent then the writing of these macros and so this error crept in. I'm definitely glad to fix it.
Correction: actually "Guide to NumPy" has the 'getitem' function documented with the arguments ordered as implemented in NumPy (but still opposite from Numeric). Only the macro is documented opposite from its implementation.
I think further clarification is needed. First of all Numeric did not have macros. They just had function pointers to getitem. Second, Numpy's function pointers to getitem and setitem are almost exactly the same. The only difference is the *addition* of another argument to both functions to allow the array to be passed in (so that the size of the array and whether or not it's well-behaved can be known). So, the order is *not* different in NumPy and Numeric, there is just another argument needed. The new macros introduced do have a different order (and I don't think it's documented oppositely --- it's perhaps not documented well at all, however :-) and so may be confusing). It is recommended to use the macros. They are PyArray_GETITEM(array, itemptr) Return a Python object corresponding to the item in the array at the location itemptr. PyArray_SETITEM(array, itemptr, obj) Set object into the array at the memory pointed to by itemptr (an attempt is made to convert to the right type if that is possible). Thanks for the report. -Travis
![](https://secure.gravatar.com/avatar/debd930eac52f28f57b2883bf2c14283.jpg?s=120&d=mm&r=g)
Hi Travis, Yes, now I see that I just wasn't looking closely enough at the the docs, that Numeric's getitem did have only one argument, and the docs have the arguments in the correct order both for the function and the macro. I was just confused by the fact that the macro has the arguments in the opposite order of the function. So the only problem was the missing 'f' in the macro. -dave On Mar 9, 2006, at 10:28 PM, Travis Oliphant wrote:
David Ian Brown wrote:
I have recently been engaged in updating the PyNIO module (http://www.pyngl.ucar.edu/Nio.html) to work with the NumPy C API. It was originally coded using the Numeric's C API.
In the process I have encountered what appear to me to be a couple of bugs in the interface. They were relatively minor and not difficult to work around, but you would probably like to know of them if you don't already.
In the NumPy version of arrayobject.h the macros PyArray_GETITEM and PyArray_SETITEM are defined in way that does not work. Here is the GETITEM macro:
#define PyArray_GETITEM(obj,itemptr) \ ((char *)itemptr, \ (PyArrayObject *)obj);
Thank you very much for catching this. The introduction of 'f' was more recent then the writing of these macros and so this error crept in. I'm definitely glad to fix it.
Correction: actually "Guide to NumPy" has the 'getitem' function documented with the arguments ordered as implemented in NumPy (but still opposite from Numeric). Only the macro is documented opposite from its implementation.
I think further clarification is needed. First of all Numeric did not have macros. They just had function pointers to getitem. Second, Numpy's function pointers to getitem and setitem are almost exactly the same. The only difference is the *addition* of another argument to both functions to allow the array to be passed in (so that the size of the array and whether or not it's well-behaved can be known). So, the order is *not* different in NumPy and Numeric, there is just another argument needed. The new macros introduced do have a different order (and I don't think it's documented oppositely --- it's perhaps not documented well at all, however :-) and so may be confusing).
It is recommended to use the macros. They are
PyArray_GETITEM(array, itemptr)
Return a Python object corresponding to the item in the array at the location itemptr.
PyArray_SETITEM(array, itemptr, obj)
Set object into the array at the memory pointed to by itemptr (an attempt is made to convert to the right type if that is possible).
Thanks for the report.
-Travis
------------------------------------------------------- This SF.Net email is sponsored by xPML, a groundbreaking scripting language that extends applications into web and mobile media. Attend the live webcast and join the prime developer group breaking into this new coding territory! http://sel.as-us.falkag.net/sel? cmd=lnk&kid=110944&bid=241720&dat=121642 _______________________________________________ Numpy-discussion mailing list Numpy-discussion@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/numpy-discussion
participants (2)
-
David Ian Brown
-
Travis Oliphant