/* * Walk into subarray, and add items for hashing in l * * Return 0 on success */ static int _array_descr_walk_subarray(PyArray_ArrayDescr* adescr, PyObject *l) { PyObject *item; Py_ssize_t i; int st; /* * Add shape and descr itself to the list of object to hash */ if (PyTuple_Check(adescr->shape)) { for(i = 0; i < PyTuple_Size(adescr->shape); ++i) { item = PyTuple_GetItem(adescr->shape, i); if (item == NULL) { PyErr_SetString(PyExc_SystemError, "(Hash) Error while getting shape item of subarray dtype ???"); return -1; } PyList_Append(l, item); } } else if (PyInt_Check(adescr->shape)) { PyList_Append(l, adescr->shape); } else { PyErr_SetString(PyExc_SystemError, "(Hash) Shape of subarray dtype neither a tuple or int ???"); return -1; } Py_INCREF(adescr->base); st = _array_descr_walk(adescr->base, l); Py_DECREF(adescr->base); return st; }
/* * Walk inside the fields and add every item which will be used for hashing * into the list l * * Return 0 on success */ static int _array_descr_walk_fields(PyObject* fields, PyObject* l) { PyObject *key, *value, *foffset, *fdescr; Py_ssize_t pos = 0; int st; while (PyDict_Next(fields, &pos, &key, &value)) { /* * For each field, add the key + descr + offset to l */ /* XXX: are those checks necessary ? */ if (!PyUString_Check(key)) { PyErr_SetString(PyExc_SystemError, "(Hash) key of dtype dict not a string ???"); return -1; } if (!PyTuple_Check(value)) { PyErr_SetString(PyExc_SystemError, "(Hash) value of dtype dict not a dtype ???"); return -1; } if (PyTuple_Size(value) < 2) { PyErr_SetString(PyExc_SystemError, "(Hash) Less than 2 items in dtype dict ???"); return -1; } Py_INCREF(key); PyList_Append(l, key); fdescr = PyTuple_GetItem(value, 0); if (!PyArray_DescrCheck(fdescr)) { PyErr_SetString(PyExc_SystemError, "(Hash) First item in compound dtype tuple not a descr ???"); return -1; } else { Py_INCREF(fdescr); st = _array_descr_walk((PyArray_Descr*)fdescr, l); Py_DECREF(fdescr); if (st) { return -1; } } foffset = PyTuple_GetItem(value, 1); if (!PyInt_Check(foffset)) { PyErr_SetString(PyExc_SystemError, "(Hash) Second item in compound dtype tuple not an int ???"); return -1; } else { Py_INCREF(foffset); PyList_Append(l, foffset); } } return 0; }
/* * Return 0 if successfull */ static int _PyArray_DescrHashImp(PyArray_Descr *descr, long *hash) { PyObject *l, *tl, *item; Py_ssize_t i; int st; l = PyList_New(0); if (l == NULL) { return -1; } st = _array_descr_walk(descr, l); if (st) { goto clean_l; } /* * Convert the list to tuple and compute the tuple hash using python * builtin function */ tl = PyTuple_New(PyList_Size(l)); for(i = 0; i < PyList_Size(l); ++i) { item = PyList_GetItem(l, i); if (item == NULL) { PyErr_SetString(PyExc_SystemError, "(Hash) Error while translating the list into a tuple " \ "(NULL item)"); goto clean_tl; } PyTuple_SetItem(tl, i, item); } *hash = PyObject_Hash(tl); if (*hash == -1) { /* XXX: does PyObject_Hash set an exception on failure ? */ #if 0 PyErr_SetString(PyExc_SystemError, "(Hash) Error while hashing final tuple"); #endif goto clean_tl; } Py_DECREF(tl); Py_DECREF(l); return 0; clean_tl: Py_DECREF(tl); clean_l: Py_DECREF(l); return -1; }
/* * Return 0 if successful */ static int _PyArray_DescrHashImp(PyArray_Descr *descr, npy_hash_t *hash) { PyObject *l, *tl; int st; l = PyList_New(0); if (l == NULL) { return -1; } st = _array_descr_walk(descr, l); if (st) { Py_DECREF(l); return -1; } /* * Convert the list to tuple and compute the tuple hash using python * builtin function */ tl = PyList_AsTuple(l); Py_DECREF(l); if (tl == NULL) return -1; *hash = PyObject_Hash(tl); Py_DECREF(tl); if (*hash == -1) { /* XXX: does PyObject_Hash set an exception on failure ? */ #if 0 PyErr_SetString(PyExc_SystemError, "(Hash) Error while hashing final tuple"); #endif return -1; } return 0; }
/* * Walk inside the fields and add every item which will be used for hashing * into the list l * * Return 0 on success */ static int _array_descr_walk_fields(PyObject *names, PyObject* fields, PyObject* l) { PyObject *key, *value, *foffset, *fdescr, *ftitle; Py_ssize_t pos = 0; int st; if (!PyTuple_Check(names)) { PyErr_SetString(PyExc_SystemError, "(Hash) names is not a tuple ???"); return -1; } if (!PyDict_Check(fields)) { PyErr_SetString(PyExc_SystemError, "(Hash) fields is not a dict ???"); return -1; } for (pos = 0; pos < PyTuple_GET_SIZE(names); pos++) { /* * For each field, add the key + descr + offset to l */ key = PyTuple_GET_ITEM(names, pos); value = PyDict_GetItem(fields, key); /* XXX: are those checks necessary ? */ if (value == NULL) { PyErr_SetString(PyExc_SystemError, "(Hash) names and fields inconsistent ???"); return -1; } if (!PyUString_Check(key)) { PyErr_SetString(PyExc_SystemError, "(Hash) key of dtype dict not a string ???"); return -1; } if (!PyTuple_Check(value)) { PyErr_SetString(PyExc_SystemError, "(Hash) value of dtype dict not a dtype ???"); return -1; } if (PyTuple_GET_SIZE(value) < 2) { PyErr_SetString(PyExc_SystemError, "(Hash) Less than 2 items in dtype dict ???"); return -1; } PyList_Append(l, key); fdescr = PyTuple_GET_ITEM(value, 0); if (!PyArray_DescrCheck(fdescr)) { PyErr_SetString(PyExc_SystemError, "(Hash) First item in compound dtype tuple not a descr ???"); return -1; } else { Py_INCREF(fdescr); st = _array_descr_walk((PyArray_Descr*)fdescr, l); Py_DECREF(fdescr); if (st) { return -1; } } foffset = PyTuple_GET_ITEM(value, 1); if (!PyInt_Check(foffset)) { PyErr_SetString(PyExc_SystemError, "(Hash) Second item in compound dtype tuple not an int ???"); return -1; } else { PyList_Append(l, foffset); } if (PyTuple_GET_SIZE(value) > 2) { ftitle = PyTuple_GET_ITEM(value, 2); PyList_Append(l, ftitle); } } return 0; }