Problem in PyArg_ParseTuple on python 2.5.2 with AIX

abhi abhigyan_agrawal at in.ibm.com
Mon Jul 27 12:49:04 CEST 2009


On Jul 27, 2:25 pm, John Machin <sjmac... at lexicon.net> wrote:
> 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

Hi,
    Thanks for the response. If I don't use SQLUSMALLINT and use int
instead, then also I see the same problem.
static PyObject *parsetuple_test(PyObject *self, PyObject *args)
 {
        int param_no = 0;
....
....
}
This also prints out 0 for AIX and actual value passed in other
platforms. If I initialize param_no with some other value (e.g. 90),
it prints out that value.

-
Abhigyan



More information about the Python-list mailing list