PyArg_ParseTuple part 2

Michael Hudson mwh at python.net
Wed Jun 13 16:05:44 EDT 2001


"John" <john.thai at dspfactory.com> writes:

> Okay, here's some code

Right, I think I've spotted your problem.

> (I've omitted some of the error checking for simplicity):

Hmm, and I've put some of it back in.  Never mind...

> static PyObject *PyGetComInterface(PyObject *self, PyObject *args) {
> 
>     PyObject *t;
>     PyObject *pyList;
>     int x;
      ^^^
should probably be a long; Python ints are C longs.

>     // extract list
>     PyArg_ParseTuple(args, "O!", &PyList_Type, pyList);
                                                 ^
this should be &pyList.  This is your main problem, I think.
 
and the whole statement should be

    if (!PyArg_ParseTuple(args, "O!", &PyList_Type, &pyList)) {
        return NULL;
    }

>     // make a tuple version of list
>     t = PyList_AsTuple(pyList);
> 
>     // extract an integer from list *Note: t is always null at this point
>     if (t != NULL) {

probably make that 

    if (t != NULL && PyInt_Check(PyTuple_GET_ITEM(t, 0))) {

>         PyArg_ParseTuple(t, "i", &x);

so you can write this as 

    x = PyInt_AsLong(PyTuple_GET_ITEM(t, 0))

(what you were doing before could have lead to you setting an
exception but not returning NULL, very much a no-no).

Hmm.  This still isn't really right (think 0 length tuple).

I'd write the function something like this:

static PyObject* 
PyGetComInterface(PyObject *self, PyObject *args)
{
        PyObject* list;
        long x;

        if (!PyArg_ParseTuple(args, "O!", &PyList_Type, &list)) {
                return NULL;
        }

        if (PyList_GET_SIZE(list) < 1) {
                PyErr_SetString(PyExc_TypeError,
                        "GetComInterface: expected list of length >= 1");
                return NULL;
        }

        if (!PyInt_Check(PyList_GET_ITEM(t, 0))) {
                PyErr_SetString(PyExc_TypeError,
                        "GetComInterface: list[0] must be integer");
                return NULL;
        }

        x = PyInt_AsLong(PyList_GET_ITEM(t, 0));

        fprintf(stderr, "x is %d\n", x);

        Py_INCREF(Py_None);
        return Py_None;
}

This is probably not perfect, but I hope it gets you on your way.

HTH,
M.
        
-- 
  ARTHUR:  Don't ask me how it works or I'll start to whimper.
                   -- The Hitch-Hikers Guide to the Galaxy, Episode 11




More information about the Python-list mailing list