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

Ziga Seilnacht ziga.seilnacht at gmail.com
Mon Feb 26 14:49:14 EST 2007


zefciu wrote:
> 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.
>
> >>> 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>>> 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




More information about the Python-list mailing list