PyArray_DescrFromType can return NULL static PyArray_Descr * PyArray_DescrFromType(int type) { PyArray_Descr *ret = NULL; if (type < PyArray_NTYPES) { ret = _builtin_descrs[type]; } else if (type == PyArray_NOTYPE) { /* * This needs to not raise an error so * that PyArray_DescrFromType(PyArray_NOTYPE) * works for backwards-compatible C-API */ return NULL; } else if ((type == PyArray_CHAR) || (type == PyArray_CHARLTR)) { ret = PyArray_DescrNew(_builtin_descrs[PyArray_STRING]); if (ret == NULL) { return NULL; } ret->elsize = 1; ret->type = PyArray_CHARLTR; return ret; } else if (PyTypeNum_ISUSERDEF(type)) { ret = userdescrs[type - PyArray_USERDEF]; } else { int num = PyArray_NTYPES; if (type < _MAX_LETTER) { num = (int) _letter_to_num[type]; } if (num >= PyArray_NTYPES) { ret = NULL; } else { ret = _builtin_descrs[num]; } } if (ret == NULL) { PyErr_SetString(PyExc_ValueError, "Invalid data-type for array"); } else { Py_INCREF(ret); } return ret; } Yet it is unchecked in several places: static int PyArray_CanCastSafely(int fromtype, int totype) { PyArray_Descr *from, *to; register int felsize, telsize; if (fromtype == totype) return 1; if (fromtype == PyArray_BOOL) return 1; if (totype == PyArray_BOOL) return 0; if (totype == PyArray_OBJECT || totype == PyArray_VOID) return 1; if (fromtype == PyArray_OBJECT || fromtype == PyArray_VOID) return 0; from = PyArray_DescrFromType(fromtype); /* * cancastto is a PyArray_NOTYPE terminated C-int-array of types that * the data-type can be cast to safely. */ if (from->f->cancastto) { int *curtype; curtype = from->f->cancastto; while (*curtype != PyArray_NOTYPE) { if (*curtype++ == totype) return 1; } } if (PyTypeNum_ISUSERDEF(totype)) return 0; to = PyArray_DescrFromType(totype); telsize = to->elsize; felsize = from->elsize; Py_DECREF(from); Py_DECREF(to); switch(fromtype) { case PyArray_BYTE: case PyArray_SHORT: case PyArray_INT: case PyArray_LONG: case PyArray_LONGLONG: if (PyTypeNum_ISINTEGER(totype)) { if (PyTypeNum_ISUNSIGNED(totype)) { return 0; } else { return (telsize >= felsize); } } else if (PyTypeNum_ISFLOAT(totype)) { if (felsize < 8) return (telsize > felsize); else return (telsize >= felsize); } else if (PyTypeNum_ISCOMPLEX(totype)) { if (felsize < 8) return ((telsize >> 1) > felsize); else return ((telsize >> 1) >= felsize); } else return totype > fromtype; case PyArray_UBYTE: case PyArray_USHORT: case PyArray_UINT: case PyArray_ULONG: case PyArray_ULONGLONG: if (PyTypeNum_ISINTEGER(totype)) { if (PyTypeNum_ISSIGNED(totype)) { return (telsize > felsize); } else { return (telsize >= felsize); } } else if (PyTypeNum_ISFLOAT(totype)) { if (felsize < 8) return (telsize > felsize); else return (telsize >= felsize); } else if (PyTypeNum_ISCOMPLEX(totype)) { if (felsize < 8) return ((telsize >> 1) > felsize); else return ((telsize >> 1) >= felsize); } else return totype > fromtype; case PyArray_FLOAT: case PyArray_DOUBLE: case PyArray_LONGDOUBLE: if (PyTypeNum_ISCOMPLEX(totype)) return ((telsize >> 1) >= felsize); else return (totype > fromtype); case PyArray_CFLOAT: case PyArray_CDOUBLE: case PyArray_CLONGDOUBLE: return (totype > fromtype); case PyArray_STRING: case PyArray_UNICODE: return (totype > fromtype); default: return 0; } } Furthermore, the last function can fail, but doesn't seem to have an error return. What is the best way to go about cleaning this up? Chuck