From ab2f8f7bd556c16a2b30aa8ec05d4c9d8c50d311 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20v=2E=20L=C3=B6wis?= Date: Wed, 9 Aug 2006 07:57:39 +0000 Subject: __hash__ may now return long int; the final hash value is obtained by invoking hash on the long int. Fixes #1536021. --- Doc/ref/ref3.tex | 5 +++++ Lib/test/test_builtin.py | 9 +++++++++ Misc/NEWS | 3 +++ Objects/classobject.c | 8 +++----- Objects/typeobject.c | 5 ++++- 5 files changed, 24 insertions(+), 6 deletions(-) diff --git a/Doc/ref/ref3.tex b/Doc/ref/ref3.tex index 8ec9e2b..15fc188 100644 --- a/Doc/ref/ref3.tex +++ b/Doc/ref/ref3.tex @@ -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} diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index 70480be..26bfe87 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -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') diff --git a/Misc/NEWS b/Misc/NEWS index 24b1645..d7f17a4 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -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 diff --git a/Objects/classobject.c b/Objects/classobject.c index c69ba74..56bf29c 100644 --- a/Objects/classobject.c +++ b/Objects/classobject.c @@ -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"); diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 67e6104..652009b 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -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 { -- cgit v0.12