__hash__ may now return long int; the final hash

value is obtained by invoking hash on the long int.
Fixes #1536021.
This commit is contained in:
Martin v. Löwis 2006-08-09 07:57:39 +00:00
parent 209307eb3b
commit ab2f8f7bd5
5 changed files with 24 additions and 6 deletions

View File

@ -1307,6 +1307,11 @@ defines mutable objects and implements a \method{__cmp__()} or
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
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__()}}
\end{methoddesc}

View File

@ -640,6 +640,15 @@ class BuiltinTest(unittest.TestCase):
def f(): pass
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):
self.assertEqual(hex(16), '0x10')

View File

@ -12,6 +12,9 @@ What's New in Python 2.5 release candidate 1?
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 #1535165: fixed a segfault in input() and raw_input() when

View File

@ -934,11 +934,9 @@ instance_hash(PyInstanceObject *inst)
Py_DECREF(func);
if (res == NULL)
return -1;
if (PyInt_Check(res)) {
outcome = PyInt_AsLong(res);
if (outcome == -1)
outcome = -2;
}
if (PyInt_Check(res) || PyLong_Check(res))
/* This already converts a -1 result to -2. */
outcome = res->ob_type->tp_hash(res);
else {
PyErr_SetString(PyExc_TypeError,
"__hash__() should return an int");

View File

@ -4559,7 +4559,10 @@ slot_tp_hash(PyObject *self)
Py_DECREF(func);
if (res == NULL)
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);
}
else {