diff options
Diffstat (limited to 'Objects/memoryobject.c')
-rw-r--r-- | Objects/memoryobject.c | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c index e0d1a89..295a742 100644 --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -84,6 +84,7 @@ PyMemoryView_FromBuffer(Py_buffer *info) PyObject_GC_New(PyMemoryViewObject, &PyMemoryView_Type); if (mview == NULL) return NULL; + mview->hash = -1; dup_buffer(&mview->view, info); /* NOTE: mview->view.obj should already have been incref'ed as part of PyBuffer_FillInfo(). */ @@ -512,6 +513,37 @@ memory_repr(PyMemoryViewObject *self) return PyUnicode_FromFormat("<memory at %p>", self); } +static Py_hash_t +memory_hash(PyMemoryViewObject *self) +{ + if (self->hash == -1) { + Py_buffer *view = &self->view; + CHECK_RELEASED_INT(self); + if (view->ndim > 1) { + PyErr_SetString(PyExc_NotImplementedError, + "can't hash multi-dimensional memoryview object"); + return -1; + } + if (view->strides && view->strides[0] != view->itemsize) { + PyErr_SetString(PyExc_NotImplementedError, + "can't hash strided memoryview object"); + return -1; + } + if (!view->readonly) { + PyErr_SetString(PyExc_ValueError, + "can't hash writable memoryview object"); + return -1; + } + if (view->obj != NULL && PyObject_Hash(view->obj) == -1) { + /* Keep the original error message */ + return -1; + } + /* Can't fail */ + self->hash = _Py_HashBytes((unsigned char *) view->buf, view->len); + } + return self->hash; +} + /* Sequence methods */ static Py_ssize_t memory_length(PyMemoryViewObject *self) @@ -829,7 +861,7 @@ PyTypeObject PyMemoryView_Type = { 0, /* tp_as_number */ &memory_as_sequence, /* tp_as_sequence */ &memory_as_mapping, /* tp_as_mapping */ - 0, /* tp_hash */ + (hashfunc)memory_hash, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ |