diff Objects/typeobject.c @ 65494:e8969fb822fc

make hashes always the size of pointers; introduce Py_hash_t #9778
author Benjamin Peterson <benjamin@python.org>
date Sun, 17 Oct 2010 20:54:53 +0000
parents dec08789a9b4
children b1bda1ec995f
line wrap: on
line diff
--- a/Objects/typeobject.c	Sun Oct 17 20:17:41 2010 +0000
+++ b/Objects/typeobject.c	Sun Oct 17 20:54:53 2010 +0000
@@ -4918,13 +4918,12 @@
     }
 }
 
-static long
+static Py_hash_t
 slot_tp_hash(PyObject *self)
 {
     PyObject *func, *res;
     static PyObject *hash_str;
-    long h;
-    int overflow;
+    Py_ssize_t h;
 
     func = lookup_method(self, "__hash__", &hash_str);
 
@@ -4947,20 +4946,20 @@
                         "__hash__ method should return an integer");
         return -1;
     }
-    /* Transform the PyLong `res` to a C long `h`.  For an existing
-       hashable Python object x, hash(x) will always lie within the range
-       of a C long.  Therefore our transformation must preserve values
-       that already lie within this range, to ensure that if x.__hash__()
-       returns hash(y) then hash(x) == hash(y). */
-    h = PyLong_AsLongAndOverflow(res, &overflow);
-    if (overflow)
-        /* res was not within the range of a C long, so we're free to
+    /* Transform the PyLong `res` to a Py_hash_t `h`.  For an existing
+       hashable Python object x, hash(x) will always lie within the range of
+       Py_hash_t.  Therefore our transformation must preserve values that
+       already lie within this range, to ensure that if x.__hash__() returns
+       hash(y) then hash(x) == hash(y). */
+    h = PyLong_AsSsize_t(res);
+    if (h == -1 && PyErr_Occurred()) {
+        /* res was not within the range of a Py_hash_t, so we're free to
            use any sufficiently bit-mixing transformation;
            long.__hash__ will do nicely. */
+        PyErr_Clear();
         h = PyLong_Type.tp_hash(res);
+    }
     Py_DECREF(res);
-    if (h == -1 && !PyErr_Occurred())
-        h = -2;
     return h;
 }