[Python-checkins] cpython (3.3): Issue #15814: Use hash function that is compatible with the equality

stefan.krah python-checkins at python.org
Fri Nov 2 18:07:03 CET 2012


http://hg.python.org/cpython/rev/969069d464bc
changeset: 80182:969069d464bc
branch: 3.3
parent: 80180:0b5f00ccf907
user: Stefan Krah <skrah at bytereef.org>
date: Fri Nov 02 17:49:22 2012 +0100
summary:
 Issue #15814: Use hash function that is compatible with the equality
definition from #15573.
files:
 Doc/library/stdtypes.rst | 6 -----
 Lib/test/test_buffer.py | 32 ++++++++++++++++++++++++++-
 Objects/memoryobject.c | 8 +++++++
 3 files changed, 38 insertions(+), 8 deletions(-)
diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst
--- a/Doc/library/stdtypes.rst
+++ b/Doc/library/stdtypes.rst
@@ -2393,12 +2393,6 @@
 .. versionchanged:: 3.3
 One-dimensional memoryviews with formats 'B', 'b' or 'c' are now hashable.
 
- .. note::
- Hashing of memoryviews with formats other than 'B', 'b' or 'c' as well
- as hashing of multi-dimensional memoryviews is possible in version 3.3.0,
- but will raise an error in 3.3.1 in order to be compatible with the new
- memoryview equality definition.
-
 :class:`memoryview` has several methods:
 
 .. method:: __eq__(exporter)
diff --git a/Lib/test/test_buffer.py b/Lib/test/test_buffer.py
--- a/Lib/test/test_buffer.py
+++ b/Lib/test/test_buffer.py
@@ -3999,14 +3999,42 @@
 m = memoryview(x)
 self.assertEqual(hash(m), hash(x))
 
+ # equality-hash invariant
+ x = ndarray(list(range(12)), shape=[12], format='B')
+ a = memoryview(nd)
+
+ y = ndarray(list(range(12)), shape=[12], format='b')
+ b = memoryview(nd)
+
+ z = ndarray(list(bytes(chr(x), 'latin-1') for x in range(12)),
+ shape=[12], format='c')
+ c = memoryview(nd)
+
+ if (a == b):
+ self.assertEqual(hash(a), hash(b))
+
+ if (a == c):
+ self.assertEqual(hash(a), hash(c))
+
+ if (b == c):
+ self.assertEqual(hash(b), hash(c))
+
 # non-byte formats
 nd = ndarray(list(range(12)), shape=[2,2,3], format='L')
 m = memoryview(nd)
- self.assertEqual(hash(m), hash(nd.tobytes()))
+ self.assertRaises(ValueError, m.__hash__)
 
 nd = ndarray(list(range(-6, 6)), shape=[2,2,3], format='h')
 m = memoryview(nd)
- self.assertEqual(hash(m), hash(nd.tobytes()))
+ self.assertRaises(ValueError, m.__hash__)
+
+ nd = ndarray(list(range(12)), shape=[2,2,3], format='= L')
+ m = memoryview(nd)
+ self.assertRaises(ValueError, m.__hash__)
+
+ nd = ndarray(list(range(-6, 6)), shape=[2,2,3], format='< h')
+ m = memoryview(nd)
+ self.assertRaises(ValueError, m.__hash__)
 
 def test_memoryview_release(self):
 
diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c
--- a/Objects/memoryobject.c
+++ b/Objects/memoryobject.c
@@ -2707,6 +2707,8 @@
 if (self->hash == -1) {
 Py_buffer *view = &self->view;
 char *mem = view->buf;
+ Py_ssize_t ret;
+ char fmt;
 
 CHECK_RELEASED_INT(self);
 
@@ -2715,6 +2717,12 @@
 "cannot hash writable memoryview object");
 return -1;
 }
+ ret = get_native_fmtchar(&fmt, view->format);
+ if (ret < 0 || !IS_BYTE_FORMAT(fmt)) {
+ PyErr_SetString(PyExc_ValueError,
+ "memoryview: hashing is restricted to formats 'B', 'b' or 'c'");
+ return -1;
+ }
 if (view->obj != NULL && PyObject_Hash(view->obj) == -1) {
 /* Keep the original error message */
 return -1;
-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /