Pergunta

I am using what seems to be the exact usgae of PyArg_ParseTuple, yet the code is still failing to work. I am using python 2.7

This is my C code for the Python Extension I am writing:

static PyObject* tpp(PyObject* self, PyObject* args)
{
PyObject* obj;
PyObject* seq;
int i, len; 
PyObject* item;
int arrayValue, temp;

if (!PyArg_ParseTuple(args, "O", &obj)){
    printf("Item is not a list\n");
    return NULL;
}
seq = PySequence_Fast(obj, "expected a sequence");
len = PySequence_Size(obj);
arrayValue = -5;
printf("[\n");
for (i = 0; i < len; i++) {
    item = PySequence_Fast_GET_ITEM(seq, i);
    // printf("%d : %d, PyArg: ", item, *item);
    // PyArg_ParseTuple(item, "I", &temp);

    PyObject* objectsRepresentation = PyObject_Repr(item);
    const char* s = PyString_AsString(objectsRepresentation);
    printf("%s\n", s);


    PyObject* objType = PyObject_Type(item);
    PyObject* objTypeString = PyObject_Repr(objType);
    const char* sType = PyString_AsString(objTypeString);
    printf("%s\n", sType);

    if (PyArg_ParseTuple(item, "i", &arrayValue) != 0){
        printf("%d\n", arrayValue);
        printf("horray!\n");
    } 
}
Py_DECREF(seq);
printf("]\n");
printf("Item is a list!\n");
Py_RETURN_NONE;
}

Then I just build the extension and go to the terminal import et and then et.tpp([1,2]) fails to print the line if (PyArg_ParseTuple(item, "i", &arrayValue) != 0){ printf("%d\n", arrayValue); printf("horray!\n"); }

I checked the type, as you can see in the code, of the elements in the list, and it prints 'int'. Yet for some reason PyArg_ParseTuple is having errors.

I need to be able to access information from lists in python to copy some data, pass it to my C code elsewhere, and then return the result to python.

Thank you so much!

Foi útil?

Solução

The answer is to use long PyInt_AsLong(PyObject *io)

"long PyInt_AsLong(PyObject *io) Will first attempt to cast the object to a PyIntObject, if it is not already one, and then return its value. If there is an error, -1 is returned, and the caller should check PyErr_Occurred() to find out whether there was an error, or whether the value just happened to be -1."

This is from http://docs.python.org/2/c-api/int.html That is the official c python int objects documentation which has all relevant methods.

Unfortunately this returns only a long value. However, a simple cast should suffice if the expected values will be small.

Outras dicas

PyArg_ParseTuple() is about parsing tuples only, as the name suggests. In your code, item is an int, not a tuple. In order to convert an int object to a C value, you need to use arrayValue = PyInt_AsLong(item). Note that it returns a C long, not an int, so you should declare arrayValue as a long.

(EDIT: previously I mentioned PyInt_FromLong by mistake.)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top