@@ -84,6 +84,7 @@ PyMemoryView_FromBuffer(Py_buffer *info)
8484 PyObject_GC_New (PyMemoryViewObject , & PyMemoryView_Type );
8585 if (mview == NULL )
8686 return NULL ;
87+ mview -> hash = -1 ;
8788 dup_buffer (& mview -> view , info );
8889 /* NOTE: mview->view.obj should already have been incref'ed as
8990 part of PyBuffer_FillInfo(). */
@@ -512,6 +513,37 @@ memory_repr(PyMemoryViewObject *self)
512513 return PyUnicode_FromFormat ("<memory at %p>" , self );
513514}
514515
516+ static Py_hash_t
517+ memory_hash (PyMemoryViewObject * self )
518+ {
519+ if (self -> hash == -1 ) {
520+ Py_buffer * view = & self -> view ;
521+ CHECK_RELEASED_INT (self );
522+ if (view -> ndim > 1 ) {
523+ PyErr_SetString (PyExc_NotImplementedError ,
524+ "can't hash multi-dimensional memoryview object" );
525+ return -1 ;
526+ }
527+ if (view -> strides && view -> strides [0 ] != view -> itemsize ) {
528+ PyErr_SetString (PyExc_NotImplementedError ,
529+ "can't hash strided memoryview object" );
530+ return -1 ;
531+ }
532+ if (!view -> readonly ) {
533+ PyErr_SetString (PyExc_ValueError ,
534+ "can't hash writable memoryview object" );
535+ return -1 ;
536+ }
537+ if (view -> obj != NULL && PyObject_Hash (view -> obj ) == -1 ) {
538+ /* Keep the original error message */
539+ return -1 ;
540+ }
541+ /* Can't fail */
542+ self -> hash = _Py_HashBytes ((unsigned char * ) view -> buf , view -> len );
543+ }
544+ return self -> hash ;
545+ }
546+
515547/* Sequence methods */
516548static Py_ssize_t
517549memory_length (PyMemoryViewObject * self )
@@ -829,7 +861,7 @@ PyTypeObject PyMemoryView_Type = {
829861 0 , /* tp_as_number */
830862 & memory_as_sequence , /* tp_as_sequence */
831863 & memory_as_mapping , /* tp_as_mapping */
832- 0 , /* tp_hash */
864+ ( hashfunc ) memory_hash , /* tp_hash */
833865 0 , /* tp_call */
834866 0 , /* tp_str */
835867 PyObject_GenericGetAttr , /* tp_getattro */
0 commit comments