Commit fd3f8e1e authored by Martin v. Löwis's avatar Martin v. Löwis

__hash__ may now return long int; the final hash

  value is obtained by invoking hash on the long int.
Fixes #1536021.
parent 703bb1dd
...@@ -1307,6 +1307,11 @@ defines mutable objects and implements a \method{__cmp__()} or ...@@ -1307,6 +1307,11 @@ defines mutable objects and implements a \method{__cmp__()} or
since the dictionary implementation requires that a key's hash value since the dictionary implementation requires that a key's hash value
is immutable (if the object's hash value changes, it will be in the is immutable (if the object's hash value changes, it will be in the
wrong hash bucket). wrong hash bucket).
\versionchanged[\method{__hash__()} may now also return a long
integer object; the 32-bit integer is then derived from the hash
of that object]{2.5}
\withsubitem{(object method)}{\ttindex{__cmp__()}} \withsubitem{(object method)}{\ttindex{__cmp__()}}
\end{methoddesc} \end{methoddesc}
......
...@@ -640,6 +640,15 @@ class BuiltinTest(unittest.TestCase): ...@@ -640,6 +640,15 @@ class BuiltinTest(unittest.TestCase):
def f(): pass def f(): pass
self.assertRaises(TypeError, hash, []) self.assertRaises(TypeError, hash, [])
self.assertRaises(TypeError, hash, {}) self.assertRaises(TypeError, hash, {})
# Bug 1536021: Allow hash to return long objects
class X:
def __hash__(self):
return 2**100
self.assertEquals(type(hash(X())), int)
class Y(object):
def __hash__(self):
return 2**100
self.assertEquals(type(hash(Y())), int)
def test_hex(self): def test_hex(self):
self.assertEqual(hex(16), '0x10') self.assertEqual(hex(16), '0x10')
......
...@@ -12,6 +12,9 @@ What's New in Python 2.5 release candidate 1? ...@@ -12,6 +12,9 @@ What's New in Python 2.5 release candidate 1?
Core and builtins Core and builtins
----------------- -----------------
- Bug #1536021: __hash__ may now return long int; the final hash
value is obtained by invoking hash on the long int.
- Bug #1536786: buffer comparison could emit a RuntimeWarning. - Bug #1536786: buffer comparison could emit a RuntimeWarning.
- Bug #1535165: fixed a segfault in input() and raw_input() when - Bug #1535165: fixed a segfault in input() and raw_input() when
......
...@@ -934,11 +934,9 @@ instance_hash(PyInstanceObject *inst) ...@@ -934,11 +934,9 @@ instance_hash(PyInstanceObject *inst)
Py_DECREF(func); Py_DECREF(func);
if (res == NULL) if (res == NULL)
return -1; return -1;
if (PyInt_Check(res)) { if (PyInt_Check(res) || PyLong_Check(res))
outcome = PyInt_AsLong(res); /* This already converts a -1 result to -2. */
if (outcome == -1) outcome = res->ob_type->tp_hash(res);
outcome = -2;
}
else { else {
PyErr_SetString(PyExc_TypeError, PyErr_SetString(PyExc_TypeError,
"__hash__() should return an int"); "__hash__() should return an int");
......
...@@ -4559,7 +4559,10 @@ slot_tp_hash(PyObject *self) ...@@ -4559,7 +4559,10 @@ slot_tp_hash(PyObject *self)
Py_DECREF(func); Py_DECREF(func);
if (res == NULL) if (res == NULL)
return -1; return -1;
h = PyInt_AsLong(res); if (PyLong_Check(res))
h = res->ob_type->tp_hash(res);
else
h = PyInt_AsLong(res);
Py_DECREF(res); Py_DECREF(res);
} }
else { else {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment