SystemError: new style getargs format but argument is not a tuple

Z

zefciu

I am trying to embed a c function in my python script for a first time.
When I try to call it I get an error

SystemError: new style getargs format but argument is not a tuple

Guido said on some mailing list, that it is probably an effect of the
lack of METH_VARARGS in the functions' array, but it's ok in my source
code. Here is the full code:

#include <python2.4/Python.h>

static PyObject * mandelpixel(PyObject *self, PyObject *args)
{
double z_real = 0, z_imag = 0, z_real2 = 0, z_imag2 = 0, c_real,
c_imag, bailoutsquare;
int iteration_number;
register int i;
PyObject coord;
if (!PyArg_ParseTuple(args, "Oid", &coord, &iteration_number,
&bailoutsquare))
return NULL;
if (!PyArg_ParseTuple(&coord, "dd", &c_real, &c_imag))
return NULL;



for(i = 1; i <= iteration_number; i++)
{
z_imag = 2 * z_real * z_imag + c_imag;
z_real = z_real2 - z_imag2 + c_real;
z_real2 = z_real * z_real;
z_imag2 = z_imag * z_imag;
if (z_real2 + z_imag2 > bailoutsquare)
return Py_BuildValue("i", i);
}
return Py_BuildValue("i", 0);
}

static PyMethodDef MandelcMethods[] =
{
{
"mandelpixel", mandelpixel, METH_VARARGS, "check the pixel for
Mandelbrot set"
},
{
NULL, NULL, 0, NULL
}
};

PyMODINIT_FUNC initmandelc(void)
{
(void) Py_InitModule ("mandelc", MandelcMethods);
}

int main(int argc, char **argv)
{
Py_SetProgramName(argv[0]);
Py_Initialize();
initmandelc();
return 0;
}

Greets
zefciu
 
T

Thinker

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
I am trying to embed a c function in my python script for a first
time. When I try to call it I get an error

SystemError: new style getargs format but argument is not a tuple

Guido said on some mailing list, that it is probably an effect of
the lack of METH_VARARGS in the functions' array, but it's ok in my
source code. Here is the full code:

#include <python2.4/Python.h>

static PyObject * mandelpixel(PyObject *self, PyObject *args) {
double z_real = 0, z_imag = 0, z_real2 = 0, z_imag2 = 0, c_real,
c_imag, bailoutsquare; int iteration_number; register int i;
PyObject coord; if (!PyArg_ParseTuple(args, "Oid", &coord,
&iteration_number, &bailoutsquare)) return NULL; if
(!PyArg_ParseTuple(&coord, "dd", &c_real, &c_imag)) return NULL;
Is coord always tuple?

- --
Thinker Li - (e-mail address removed) (e-mail address removed)
http://heaven.branda.to/~thinker/GinGin_CGI.py
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (FreeBSD)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFF4wQB1LDUVnWfY8gRAtWsAKCavY85KUtoppRSj0uQTeVnmLu5UwCgyfk1
0c5fkRgKaejDja1YWdKkaTg=
=vMjd
-----END PGP SIGNATURE-----
 
Z

zefciu

Is coord always tuple?

Yes it is. The script launches it with tuple and two numeric arguments.
On the other hand when I try it in interactive mode with
mandelpixel((1,1), 1, 1) it segfaults, which I completely don't understand.

zefciu
 
T

Thinker

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
I am trying to embed a c function in my python script for a first
time. When I try to call it I get an error

SystemError: new style getargs format but argument is not a tuple

Guido said on some mailing list, that it is probably an effect of
the lack of METH_VARARGS in the functions' array, but it's ok in my
source code. Here is the full code:

#include <python2.4/Python.h>

static PyObject * mandelpixel(PyObject *self, PyObject *args) {
double z_real = 0, z_imag = 0, z_real2 = 0, z_imag2 = 0, c_real,
c_imag, bailoutsquare; int iteration_number; register int i;
PyObject coord;
It should be "PyObject *coord;" .
Maybe, it is what is wrong with your program!

- --
Thinker Li - (e-mail address removed) (e-mail address removed)
http://heaven.branda.to/~thinker/GinGin_CGI.py
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (FreeBSD)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFF4xDz1LDUVnWfY8gRAmAAAJ9FJPqGyeI0InxrcvdNXHtGMXWK1wCg570r
z3hcYDsjmqRp4BnpEFjbDy0=
=REQM
-----END PGP SIGNATURE-----
 
Z

zefciu

Thinker said:
It should be "PyObject *coord;" .
Maybe, it is what is wrong with your program!
Should it? The gcc shows me a warning then:

warning: 'coord' is used uninitialized in this function

and during the execution I get the same error *plus* a segfault.

zefciu
 
T

Thinker

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Should it? The gcc shows me a warning then:

warning: 'coord' is used uninitialized in this function

and during the execution I get the same error *plus* a segfault.

zefciu
Yes! Please refer http://docs.python.org/api/arg-parsing.html#l2h-210
And your second PyArg_ParseTuple() call, should not make a reference
on coord.
It should be PyArg_ParseTuple(coord, ...) since you declare coord as a
pointer.
You can add some printf() to throw out messages to make sure where the
program stop at.
If you can compile the module with debug information and use gdb to
backtrace dump file,
it would be useful.

- --
Thinker Li - (e-mail address removed) (e-mail address removed)
http://heaven.branda.to/~thinker/GinGin_CGI.py
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (FreeBSD)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFF4xaG1LDUVnWfY8gRAsW7AKC7D3oZ8p8iWVFcBvkiVwMSrG1oNwCg36ym
e1Fa0AO3KzSD5FcYs0LK7P4=
=kYLW
-----END PGP SIGNATURE-----
 
Z

zefciu

Thinker said:
You can add some printf() to throw out messages to make sure where the
program stop at.
If you can compile the module with debug information and use gdb to
backtrace dump file,
it would be useful.

Did it. The arguments are parsed, but the coord tuple isn't. But can
PyArg_ParseTuple be used to tuples other than function arguments? If
not, what should I use?

zefciu
 
T

Thinker

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Did it. The arguments are parsed, but the coord tuple isn't. But
can PyArg_ParseTuple be used to tuples other than function
arguments? If not, what should I use?
Since PyArg_ParseTuple() is supposed to parse arguments, I recommand you
to use PyTuple_GetItem() or PyTuple_GET_ITEM(). You can find more
functions
at http://docs.python.org/api/genindex.html .

- --
Thinker Li - (e-mail address removed) (e-mail address removed)
http://heaven.branda.to/~thinker/GinGin_CGI.py
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (FreeBSD)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFF4xyq1LDUVnWfY8gRAilNAKDFTKwahXpuxFImhR57Yw5efAGP1wCfR/qU
o774g2YB5gMBLrUa9YltDSQ=
=/tWC
-----END PGP SIGNATURE-----
 
Z

zefciu

Thinker said:
Since PyArg_ParseTuple() is supposed to parse arguments, I recommand you
to use PyTuple_GetItem() or PyTuple_GET_ITEM().

Ok. Now I do it this way:

c_real = PyFloat_AsDouble(PyTuple_GetItem(coord,0));
c_imag = PyFloat_AsDouble(PyTuple_GetItem(coord,1));

And it worked... once. The problem is really funny - in the interactive
the function fails every second time.
args parsed
coord parsed
ii3args parsed
coord parsed
ii3TypeError: bad argument type for built-in operation

etcaetera.... (the "args parsed" "coord parsed" and "i" are effect of
printfs in the code, as you see when it fails, it doesn't even manage to
parse the arguments.

zefciu
 
T

Thinker

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Ok. Now I do it this way:

c_real = PyFloat_AsDouble(PyTuple_GetItem(coord,0)); c_imag =
PyFloat_AsDouble(PyTuple_GetItem(coord,1));

And it worked... once. The problem is really funny - in the
interactive the function fails every second time.

TypeError: bad argument type for built-in operation
I guess it is caused by ill handling reference count of coord.
You should call Py_INCREF() to get a reference since it is borrowed
from PyArg_ParseTuple().
You can find more information at http://docs.python.org/ext/refcounts.html

- --
Thinker Li - (e-mail address removed) (e-mail address removed)
http://heaven.branda.to/~thinker/GinGin_CGI.py
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (FreeBSD)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFF4yuP1LDUVnWfY8gRAqOmAJ0SaIwpnRk/GZYm2Z5nnC7xH7EYKwCgjz8o
0Z/S7i5PULQMeAFI7U/Cy5I=
=4C3l
-----END PGP SIGNATURE-----
 
Z

Ziga Seilnacht

zefciu said:
Ok. Now I do it this way:

c_real = PyFloat_AsDouble(PyTuple_GetItem(coord,0));
c_imag = PyFloat_AsDouble(PyTuple_GetItem(coord,1));

And it worked... once. The problem is really funny - in the interactive
the function fails every second time.


args parsed
coord parsed
ii3>>> mandelpixel((1.5, 1.5), 9, 2.2)

TypeError: bad argument type for built-in operation>>> mandelpixel((1.5, 1.5), 9, 2.2)

args parsed
coord parsed
ii3>>> mandelpixel((1.5, 1.5), 9, 2.2)

TypeError: bad argument type for built-in operation

etcaetera.... (the "args parsed" "coord parsed" and "i" are effect of
printfs in the code, as you see when it fails, it doesn't even manage to
parse the arguments.

The direct solution to your problem is to use the "tuple unpacking"
feature of PyArg_ParseTuple by using "(dd)id" as format argument.
This is shown in the first example.
The second example uses your approach and is a bit more cumbersome,
but still works. Could you post your current version of the code?
I don't understand where your problem could be.

#include "Python.h"

static PyObject *
mandelpixel1(PyObject *self, PyObject *args)
{
double z_real = 0, z_imag = 0, z_real2 = 0, z_imag2 = 0;
double c_real, c_imag, bailoutsquare;
int iteration_number;
register int i;

if (!PyArg_ParseTuple(args, "(dd)id", &c_real, &c_imag,
&iteration_number, &bailoutsquare))
return NULL;

for (i = 1; i <= iteration_number; i++) {
z_imag = 2 * z_real * z_imag + c_imag;
z_real = z_real2 - z_imag2 + c_real;
z_real2 = z_real * z_real;
z_imag2 = z_imag * z_imag;
if (z_real2 + z_imag2 > bailoutsquare)
return Py_BuildValue("i", i);
}

return Py_BuildValue("i", 0);
}

static PyObject *
mandelpixel2(PyObject *self, PyObject *args)
{
double z_real = 0, z_imag = 0, z_real2 = 0, z_imag2 = 0;
double c_real, c_imag, bailoutsquare;
int iteration_number;
PyObject *coord;
register int i;

if (!PyArg_ParseTuple(args, "Oid", &coord,
&iteration_number, &bailoutsquare))
return NULL;


if (!PyTuple_Check(coord)) {
PyErr_SetString(PyExc_TypeError, "something informative");
return NULL;
}

if (!PyArg_ParseTuple(coord, "dd", &c_real, &c_imag))
return NULL;

for (i = 1; i <= iteration_number; i++) {
z_imag = 2 * z_real * z_imag + c_imag;
z_real = z_real2 - z_imag2 + c_real;
z_real2 = z_real * z_real;
z_imag2 = z_imag * z_imag;
if (z_real2 + z_imag2 > bailoutsquare)
return Py_BuildValue("i", i);
}

return Py_BuildValue("i", 0);
}

static PyMethodDef MandelcMethods[] = {
{"mandelpixel1", mandelpixel1, METH_VARARGS, "first version"},
{"mandelpixel2", mandelpixel2, METH_VARARGS, "second version"},
{NULL, NULL, 0, NULL},
};

PyMODINIT_FUNC
initmandelc(void)
{
Py_InitModule("mandelc", MandelcMethods);
}

Ziga
 
Z

zefciu

Ziga said:
The second example uses your approach and is a bit more cumbersome,
but still works. Could you post your current version of the code?
I don't understand where your problem could be.

I think, there's no need to. Now I understand :)
if (!PyArg_ParseTuple(args, "Oid", &coord,
&iteration_number, &bailoutsquare))

There was no ampersand in my version before coord. I thought that as
coord is already a pointer, PyArg_ParseTuple will want it, not the
pointer to the pointer.

Now it works, but I will of course change it to get the simpler
parenthesised version as in your Example 1.

Great thanks :D

zefciu
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,066
Latest member
VytoKetoReviews

Latest Threads

Top