[Numpy-discussion] Missing NULL return checks?

Charles R Harris charlesr.harris@gmail....
Fri Jul 11 23:23:12 CDT 2008


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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://projects.scipy.org/pipermail/numpy-discussion/attachments/20080711/84a57e5e/attachment-0001.html 


More information about the Numpy-discussion mailing list