* Attempts to subscript an array using a field name or list of field names. * * ret = 0, view != NULL: view points to the requested fields of arr * ret = 0, view == NULL: an error occurred * ret = -1, view == NULL: unrecognized input, this is not a field index. */
| 1327 | * ret = -1, view == NULL: unrecognized input, this is not a field index. |
| 1328 | */ |
| 1329 | NPY_NO_EXPORT int |
| 1330 | _get_field_view(PyArrayObject *arr, PyObject *ind, PyArrayObject **view) |
| 1331 | { |
| 1332 | *view = NULL; |
| 1333 | |
| 1334 | /* first check for a single field name */ |
| 1335 | if (PyUnicode_Check(ind)) { |
| 1336 | PyObject *tup; |
| 1337 | PyArray_Descr *fieldtype; |
| 1338 | npy_intp offset; |
| 1339 | |
| 1340 | /* get the field offset and dtype */ |
| 1341 | tup = PyDict_GetItemWithError(PyArray_DESCR(arr)->fields, ind); |
| 1342 | if (tup == NULL && PyErr_Occurred()) { |
| 1343 | return 0; |
| 1344 | } |
| 1345 | else if (tup == NULL){ |
| 1346 | PyErr_Format(PyExc_ValueError, "no field of name %S", ind); |
| 1347 | return 0; |
| 1348 | } |
| 1349 | if (_unpack_field(tup, &fieldtype, &offset) < 0) { |
| 1350 | return 0; |
| 1351 | } |
| 1352 | |
| 1353 | /* view the array at the new offset+dtype */ |
| 1354 | Py_INCREF(fieldtype); |
| 1355 | *view = (PyArrayObject*)PyArray_NewFromDescr_int( |
| 1356 | Py_TYPE(arr), |
| 1357 | fieldtype, |
| 1358 | PyArray_NDIM(arr), |
| 1359 | PyArray_SHAPE(arr), |
| 1360 | PyArray_STRIDES(arr), |
| 1361 | PyArray_BYTES(arr) + offset, |
| 1362 | PyArray_FLAGS(arr), |
| 1363 | (PyObject *)arr, (PyObject *)arr, |
| 1364 | /* We do not preserve the dtype for a subarray one, only str */ |
| 1365 | _NPY_ARRAY_ALLOW_EMPTY_STRING); |
| 1366 | if (*view == NULL) { |
| 1367 | return 0; |
| 1368 | } |
| 1369 | return 0; |
| 1370 | } |
| 1371 | |
| 1372 | /* next check for a list of field names */ |
| 1373 | else if (PySequence_Check(ind) && !PyTuple_Check(ind)) { |
| 1374 | npy_intp seqlen, i; |
| 1375 | PyArray_Descr *view_dtype; |
| 1376 | |
| 1377 | seqlen = PySequence_Size(ind); |
| 1378 | |
| 1379 | /* quit if have a fake sequence-like, which errors on len()*/ |
| 1380 | if (seqlen == -1) { |
| 1381 | PyErr_Clear(); |
| 1382 | return -1; |
| 1383 | } |
| 1384 | /* 0-len list is handled elsewhere as an integer index */ |
| 1385 | if (seqlen == 0) { |
| 1386 | return -1; |
no test coverage detected