SWIG wrappers: Inplace arrays

Hello all I am using the SWIG Numpy typemaps to wrap some C code. I ran into the following problem when wrapping a function with INPLACE_ARRAY1. In Python, I create the following array: x = array([],dtype='<i4') When this is passed to the C function expecting an int*, it goes via obj_to_array_no_conversion in numpy.i where a direct comparison of the typecodes is done, at which point a TypeError is raised. In this case: desired type = int [typecode 5] actual type = long [typecode 7] The typecode is obtained as follows: #define array_type(a) (int)(((PyArrayObject *)a)->descr->type_num) Given that I created the array with '<i4', I would expect type_num to map to int instead of long. Why isn't this happening? Assuming the is a good reason for type_num being what it is, I think obj_to_array_no_conversion needs to be slightly cleverer about the conversions it allows. Is there any way to figure out that int and long are actually identical (at least on my system) using the Numpy C API? Any other suggestions or comments for solving this problem? Thanks! Regards, Albert

Albert Strasheim wrote:
Hello all
I am using the SWIG Numpy typemaps to wrap some C code. I ran into the following problem when wrapping a function with INPLACE_ARRAY1.
In Python, I create the following array:
x = array([],dtype='<i4')
When this is passed to the C function expecting an int*, it goes via obj_to_array_no_conversion in numpy.i where a direct comparison of the typecodes is done, at which point a TypeError is raised.
In this case:
desired type = int [typecode 5] actual type = long [typecode 7]
The typecode is obtained as follows:
#define array_type(a) (int)(((PyArrayObject *)a)->descr->type_num)
Given that I created the array with '<i4', I would expect type_num to map to int instead of long. Why isn't this happening?
Actually there is ambiguity i4 can be either int or long. If you want to guarantee an int-type then use dtype=intc).
Assuming the is a good reason for type_num being what it is, I think obj_to_array_no_conversion needs to be slightly cleverer about the conversions it allows. Is there any way to figure out that int and long are actually identical (at least on my system) using the Numpy C API? Any other suggestions or comments for solving this problem?
Yes. You can use one of PyArray_EquivTypes(PyArray_Descr *dtype1, PyArray_Descr *dtype2) PyArray_EquivTypenums(int typenum1, int typenum2) PyArray_EquivArrTypes(PyObject *array1, PyObject *array2) These return TRUE (non-zero) if the two type representations are equivalent. -Travis

Albert Strasheim wrote:
Hello all
I am using the SWIG Numpy typemaps to wrap some C code. I ran into the following problem when wrapping a function with INPLACE_ARRAY1.
In Python, I create the following array:
x = array([],dtype='<i4')
When this is passed to the C function expecting an int*, it goes via obj_to_array_no_conversion in numpy.i where a direct comparison of the typecodes is done, at which point a TypeError is raised.
In this case:
desired type = int [typecode 5] actual type = long [typecode 7]
The typecode is obtained as follows:
#define array_type(a) (int)(((PyArrayObject *)a)->descr->type_num)
Given that I created the array with '<i4', I would expect type_num to map to int instead of long. Why isn't this happening?
Assuming the is a good reason for type_num being what it is, I think obj_to_array_no_conversion needs to be slightly cleverer about the conversions it allows. Is there any way to figure out that int and long are actually identical (at least on my system) using the Numpy C API? Any other suggestions or comments for solving this problem?
Here is the relevant new numpy.i code (just checked in...) PyArrayObject* obj_to_array_no_conversion(PyObject* input, int typecode) { PyArrayObject* ary = NULL; if (is_array(input) && (typecode == PyArray_NOTYPE || PyArray_EquivTypenums(array_type(input), typecode)) { ary = (PyArrayObject*) input; } else if is_array(input) { char* desired_type = typecode_string(typecode); char* actual_type = typecode_string(array_type(input)); PyErr_Format(PyExc_TypeError, "Array of type '%s' required. Array of type '%s' given", desired_type, actual_type); ary = NULL; } else { char * desired_type = typecode_string(typecode); char * actual_type = pytype_string(input); PyErr_Format(PyExc_TypeError, "Array of type '%s' required. A %s was given", desired_type, actual_type); ary = NULL; } return ary; }
participants (2)
-
Albert Strasheim
-
Travis Oliphant