Problem in PyArg_ParseTuple on python 2.5.2 with AIX

John Machin sjmachin at lexicon.net
Mon Jul 27 05:25:19 EDT 2009


On Jul 27, 5:11 pm, abhi <abhigyan_agra... at in.ibm.com> wrote:
> Hi,
>     I am facing a problem using PyArg_ParseTuple() in my C-API
> extension. Here is a small repro of the function:
>
> static PyObject *parsetuple_test(PyObject *self, PyObject *args)
> {
>         SQLUSMALLINT param_no = 0;

Sorry, my crystal ball is on the fritz. What is SQLUSMALLINT on
Windows/Linux/AIX?
What does
    printf("%d %d %d\n", sizeof(SQLUSMALLINT), sizeof(int), sizeof
(long));
give you on each platform?

>         PyObject *py_obj = NULL;
>
>         if (!PyArg_ParseTuple(args, "Oi", &py_obj, &param_no)){
>
>                 return NULL;
>         }
>         printf("%d\n", param_no);
>         return NULL;
>
> }
>
> This function works fine and prints the correct value passed
> (param_no) when I test it on Linux or Windows. However, it always
> prints 0 (initial value defined in function) when I run it on AIX.

Consider that 0 could have been plucked out of the air and has nothing
to do with the initial value of param_no. Try initialising it to
something distinctive, like 0xfedcba98. Use %08x format in the printf
rather than %d.


>
> I think the problem is with "Oi" argument, if I replace that with "OO"
> and specifically convert it integer/sqlsmallint. It works fine on AIX,
> but I want to use "i" and not "O".
>
> Any ideas on what is the reason behind the problem and how to fix
> this?

I jump-started the crystal ball from the over-head tram wire and saw
this: """SQLSMALLINT is 16 bits on all platforms, int/long is 32 bits
on all platforms, first 2 are little-endian, AIX is bigendian, the "i"
format expects SIGNED int /long, so param_no is getting (win:x,
linux:x, aix:0) and the next 16 bits in memory are getting trashed
with (win:0, linux:0, aix:x) (when x is your input smallish integer)
and luckily this trashing didn't cause a crash. You can receive the
result from the function in an int/long then have code to reject it if
it won't fit into a SQLUSMALLINT, and cast it otherwise. If you don't
care about overflow (NOT recommended), just use "H" format instead if
"i" format"""

Could be wrong, really shouldn't subject precision instruments to 415V
DC, only OPs :-)

N.B. to detect endianness : use print sys.byteorder

HTH,
John



More information about the Python-list mailing list