* VOID-type arrays can only be compared equal and not-equal * in which case the fields are all compared by extracting the fields * and testing one at a time... * equality testing is performed using logical_ands on all the fields. * in-equality testing is performed using logical_ors on all the fields. * * VOID-type arrays without fields are compared for equality by comparing their * memory a
| 663 | * memory at each location directly (using string-code). |
| 664 | */ |
| 665 | static PyObject * |
| 666 | _void_compare(PyArrayObject *self, PyArrayObject *other, int cmp_op) |
| 667 | { |
| 668 | if (!(cmp_op == Py_EQ || cmp_op == Py_NE)) { |
| 669 | PyErr_SetString(PyExc_TypeError, |
| 670 | "Void-arrays can only be compared for equality."); |
| 671 | return NULL; |
| 672 | } |
| 673 | if (PyArray_TYPE(other) != NPY_VOID) { |
| 674 | PyErr_SetString(PyExc_TypeError, |
| 675 | "Cannot compare structured or void to non-void arrays."); |
| 676 | return NULL; |
| 677 | } |
| 678 | if (PyArray_HASFIELDS(self) && PyArray_HASFIELDS(other)) { |
| 679 | PyArray_Descr *self_descr = PyArray_DESCR(self); |
| 680 | PyArray_Descr *other_descr = PyArray_DESCR(other); |
| 681 | |
| 682 | /* Use promotion to decide whether the comparison is valid */ |
| 683 | PyArray_Descr *promoted = PyArray_PromoteTypes(self_descr, other_descr); |
| 684 | if (promoted == NULL) { |
| 685 | PyErr_SetString(PyExc_TypeError, |
| 686 | "Cannot compare structured arrays unless they have a " |
| 687 | "common dtype. I.e. `np.result_type(arr1, arr2)` must " |
| 688 | "be defined."); |
| 689 | return NULL; |
| 690 | } |
| 691 | Py_DECREF(promoted); |
| 692 | |
| 693 | npy_intp result_ndim = PyArray_NDIM(self) > PyArray_NDIM(other) ? |
| 694 | PyArray_NDIM(self) : PyArray_NDIM(other); |
| 695 | |
| 696 | int field_count = PyTuple_GET_SIZE(self_descr->names); |
| 697 | if (field_count != PyTuple_GET_SIZE(other_descr->names)) { |
| 698 | PyErr_SetString(PyExc_TypeError, |
| 699 | "Cannot compare structured dtypes with different number of " |
| 700 | "fields. (unreachable error please report to NumPy devs)"); |
| 701 | return NULL; |
| 702 | } |
| 703 | |
| 704 | PyObject *op = (cmp_op == Py_EQ ? n_ops.logical_and : n_ops.logical_or); |
| 705 | PyObject *res = NULL; |
| 706 | for (int i = 0; i < field_count; ++i) { |
| 707 | PyObject *fieldname, *temp, *temp2; |
| 708 | |
| 709 | fieldname = PyTuple_GET_ITEM(self_descr->names, i); |
| 710 | PyArrayObject *a = (PyArrayObject *)array_subscript_asarray( |
| 711 | self, fieldname); |
| 712 | if (a == NULL) { |
| 713 | Py_XDECREF(res); |
| 714 | return NULL; |
| 715 | } |
| 716 | fieldname = PyTuple_GET_ITEM(other_descr->names, i); |
| 717 | PyArrayObject *b = (PyArrayObject *)array_subscript_asarray( |
| 718 | other, fieldname); |
| 719 | if (b == NULL) { |
| 720 | Py_XDECREF(res); |
| 721 | Py_DECREF(a); |
| 722 | return NULL; |
no test coverage detected