Awkwardness of C API for making tuples

Dave Cole djc at object-craft.com.au
Wed Feb 2 23:31:35 EST 2005


John Machin wrote:
> Dave Opstad wrote:
> 
>>One of the functions in a C extension I'm writing needs to return a
>>tuple of integers, where the length of the tuple is only known at
>>runtime. I'm currently doing a loop calling PyInt_FromLong to make
> 
> the
> 
>>integers,
> 
> 
> What is the purpose of this first loop?
> 
> In what variable-length storage are you storing these (Python) integers
> during this first loop? Something you created with (a) PyMem_Malloc (b)
> malloc (c) alloca (d) your_own_malloc?
> 
> 
>>then PyTuple_New, and finally a loop calling PyTuple_SET_ITEM
>>to set the tuple's items. Whew.
> 
> 
> Whew indeed.
> 
> 
>>Does anyone know of a simpler way? I can't use Py_BuildValue because
> 
> I
> 
>>don't know at compile-time how many values there are going to be. And
> 
> 
>>there doesn't seem to be a PyTuple_FromArray() function.
>>
>>If I'm overlooking something obvious, please clue me in!
> 
> 
> 1. Determine the length of the required tuple; this may need a loop,
> but only to _count_ the number of C longs that you have.
> 2. Use PyTuple_New.
> 3. Loop to fill the tuple, using PyInt_FromLong and PyTuple_SetItem.
> 
> Much later, after thoroughly testing your code, gingerly change
> PyTuple_SetItem to PyTuple_SET_ITEM. Benchmark the difference. Is it
> anywhere near what you saved by cutting out the store_in_temp_array
> thing in the first loop?

Shouldn't something like this (uncompiled) do what you want?

- Dave

PyObject *PyTuple_FromArray(int *values, int num_values)
{
     PyObject *tuple;
     int i;

     tuple = PyTuple_New(num_values);
     if (tuple == NULL)
	return NULL;

     for (i = 0; i < num_values; i++) {
	PyObject *obj;

	obj = PyInt_FromLong(value[i]);
	if (obj == NULL
             || PyTuple_SetItem(tuple, i, obj) != 0) {
	    Py_DECREF(tuple);
	    return NULL;
	}
     }

     return tuple;
}


-- 
http://www.object-craft.com.au



More information about the Python-list mailing list