diff options
author | Antoine Pitrou <solipsis@pitrou.net> | 2011-11-21 20:46:33 +0100 |
---|---|---|
committer | Antoine Pitrou <solipsis@pitrou.net> | 2011-11-21 20:46:33 +0100 |
commit | ce4a9da70535b4bb9048147b141f01004af2133d (patch) | |
tree | 853fa7484683a9c858f29bfab1320fb4baee5d98 /Objects/memoryobject.c | |
parent | 0a3229de6b80cfa9e432ef5a9c72548569503075 (diff) | |
download | cpython-git-ce4a9da70535b4bb9048147b141f01004af2133d.tar.gz |
Issue #13411: memoryview objects are now hashable when the underlying object is hashable.
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 e0d1a898b3..295a742d6d 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 */ |