diff -r 867de88b69f0 Lib/test/test_memoryview.py --- a/Lib/test/test_memoryview.py +++ b/Lib/test/test_memoryview.py @@ -443,6 +443,11 @@ class ArrayMemoryviewTest(unittest.TestC m[:] = new_a self.assertEqual(a, new_a) + def test_array_eq(self): + values = [array.array(t, range(10)) for t in 'bBhHiIlL'] + for v in values: + for w in values: + self.assertEqual(memoryview(v), memoryview(w)) class BytesMemorySliceTest(unittest.TestCase, BaseMemorySliceTests, BaseBytesMemoryTests): diff -r 867de88b69f0 Objects/memoryobject.c --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -58,6 +58,7 @@ return NULL; \ } +static PyObject * _IntTupleFromSsizet(int len, Py_ssize_t *vals); Py_LOCAL_INLINE(_PyManagedBufferObject *) mbuf_alloc(void) @@ -2384,11 +2385,12 @@ cmp_rec(const char *p, const char *q, static PyObject * memory_richcompare(PyObject *v, PyObject *w, int op) { - PyObject *res; + PyObject *res, *vval, *wval; Py_buffer wbuf, *vv, *ww = NULL; const char *vfmt, *wfmt; int equal = -1; /* Py_NotImplemented */ + vval = wval = NULL; if (op != Py_EQ && op != Py_NE) goto result; /* Py_NotImplemented */ @@ -2422,9 +2424,29 @@ memory_richcompare(PyObject *v, PyObject } if (cmp_structure(vv, ww) < 0) { + /* Different structures. Compare tolist representations. */ PyErr_Clear(); - equal = 0; - goto result; + equal = -1; + wval = 0; + vval = _IntTupleFromSsizet(vv->ndim, vv->shape); + if (!vval) + goto result; + wval = _IntTupleFromSsizet(ww->ndim, ww->shape); + if (!wval) + goto result; + equal = PyObject_RichCompareBool(vval, wval, Py_EQ); + if (equal != 1) + goto result; + Py_CLEAR(vval); + Py_CLEAR(wval); + vval = memory_tolist((PyMemoryViewObject*)v, NULL); + if (!vval) + goto result; + wval = memory_tolist((PyMemoryViewObject*)w, NULL); + if (!wval) + goto result; + equal = PyObject_RichCompareBool(vval, wval, Py_EQ); + goto result; } if (vv->ndim == 0) { @@ -2444,6 +2466,8 @@ memory_richcompare(PyObject *v, PyObject } result: + Py_XDECREF(vval); + Py_XDECREF(wval); if (equal < 0) res = Py_NotImplemented; else if ((equal && op == Py_EQ) || (!equal && op == Py_NE))