[Pyrex] Regression: Pyrex throw away explicit type cast

Alexander Belchenko bialix at ukr.net
Tue Sep 9 12:34:18 CEST 2008


It seems like regression in Pyrex 0.9.8.x comparing to 0.9.6.x and older.
In following code Pyrex now throw away explicit type cast and therefore
C-compiler starts to produce warnings for me.

# bitarray.pyx (excerpt)

cdef extern from "bitarray.h":
     unsigned char  get_bit(unsigned char *array, unsigned char addr)

cdef class Bitarray:
     cdef readonly char *parray
     cdef readonly object size
     cdef readonly size_t bytes

     def get(self, unsigned short addr):
	# ^-- I should use unsigned short in function declaration because older
	# versions of Pyrex have bug and don't allow me to use
	# unsigned char there.
         if addr >= self.size:
             raise ValueError('Address out of array size')
         return bool(get_bit(<unsigned char*>self.parray, <unsigned char>addr))


And here generated C-code for the get method produced by Pyrex 0.9.8.5:

static PyObject *__pyx_f_6emulib_5tests_8bitarray_8Bitarray_get(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject 
*__pyx_kwds); /*proto*/
static PyObject *__pyx_f_6emulib_5tests_8bitarray_8Bitarray_get(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject 
*__pyx_kwds) {
   unsigned short __pyx_v_addr;
   PyObject *__pyx_r;
   PyObject *__pyx_1 = 0;
   int __pyx_2;
   static char *__pyx_argnames[] = {"addr",0};
   if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "H", __pyx_argnames, &__pyx_v_addr)) return 0;
   Py_INCREF(__pyx_v_self);
   __pyx_1 = PyInt_FromLong(get_bit(((unsigned char *)((struct __pyx_obj_6emulib_5tests_8bitarray_Bitarray 
*)__pyx_v_self)->parray),__pyx_v_addr)); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; goto __pyx_L1;}
   __pyx_2 = PyObject_IsTrue(__pyx_1); if (__pyx_2 == -1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
   __pyx_1 = PyInt_FromLong(__pyx_2); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; goto __pyx_L1;}
   __pyx_r = __pyx_1;
   __pyx_1 = 0;
   goto __pyx_L0;

   __pyx_r = Py_None; Py_INCREF(Py_None);
   goto __pyx_L0;
   __pyx_L1:;
   Py_XDECREF(__pyx_1);
   __Pyx_AddTraceback("emulib.tests.bitarray.Bitarray.get");
   __pyx_r = 0;
   __pyx_L0:;
   Py_DECREF(__pyx_v_self);
   return __pyx_r;
}


Here is buggy part:

   __pyx_1 = PyInt_FromLong(get_bit(((unsigned char *)((struct __pyx_obj_6emulib_5tests_8bitarray_Bitarray 
*)__pyx_v_self)->parray),__pyx_v_addr));


^-- __pyx_v_addr is not casted to unsigned char.

And here the result of pyx->C translation (only for the line above) with Pyrex 0.9.6.4:

   __pyx_2 = PyInt_FromLong(get_bit(((unsigned char *)((struct __pyx_obj_8bitarray_Bitarray 
*)__pyx_v_self)->parray),((unsigned char)__pyx_v_addr)));


As you could see all casts preserved.




More information about the Pyrex mailing list