]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
make hashes always the size of pointers; introduce Py_hash_t #9778
authorBenjamin Peterson <benjamin@python.org>
Sun, 17 Oct 2010 20:54:53 +0000 (20:54 +0000)
committerBenjamin Peterson <benjamin@python.org>
Sun, 17 Oct 2010 20:54:53 +0000 (20:54 +0000)
31 files changed:
Doc/c-api/object.rst
Doc/c-api/typeobj.rst
Include/bytesobject.h
Include/datetime.h
Include/dictobject.h
Include/object.h
Include/pyport.h
Include/setobject.h
Include/unicodeobject.h
Include/weakrefobject.h
Misc/NEWS
Modules/_datetimemodule.c
Modules/_pickle.c
Objects/bytesobject.c
Objects/classobject.c
Objects/codeobject.c
Objects/complexobject.c
Objects/descrobject.c
Objects/dictobject.c
Objects/floatobject.c
Objects/longobject.c
Objects/methodobject.c
Objects/object.c
Objects/setobject.c
Objects/tupleobject.c
Objects/typeobject.c
Objects/unicodeobject.c
Objects/weakrefobject.c
Python/bltinmodule.c
Python/ceval.c
Python/sysmodule.c

index 7efc0d2dcc7a8a839b1cc30006954747cef334ca..8410934423fae332eee67cec169561ea6d49f732 100644 (file)
@@ -247,15 +247,20 @@ is considered sufficient for this determination.
    *NULL* on failure.
 
 
-.. c:function:: long PyObject_Hash(PyObject *o)
+.. c:function:: Py_hash_t PyObject_Hash(PyObject *o)
 
    .. index:: builtin: hash
 
    Compute and return the hash value of an object *o*.  On failure, return ``-1``.
    This is the equivalent of the Python expression ``hash(o)``.
 
+   .. versionchanged:: 3.2
 
-.. c:function:: long PyObject_HashNotImplemented(PyObject *o)
+      The return type is now Py_hash_t.  This is a signed integer the same size
+      as Py_ssize_t.
+
+
+.. c:function:: Py_hash_t PyObject_HashNotImplemented(PyObject *o)
 
    Set a :exc:`TypeError` indicating that ``type(o)`` is not hashable and return ``-1``.
    This function receives special treatment when stored in a ``tp_hash`` slot,
index a25ca41a45cc6bca5bb2e3688c356f6510865116..fe751c21f2876de7f2062a6b979312be12d01035 100644 (file)
@@ -306,10 +306,10 @@ type objects) *must* have the :attr:`ob_size` field.
    An optional pointer to a function that implements the built-in function
    :func:`hash`.
 
-   The signature is the same as for :c:func:`PyObject_Hash`; it must return a C
-   long.  The value ``-1`` should not be returned as a normal return value; when an
-   error occurs during the computation of the hash value, the function should set
-   an exception and return ``-1``.
+   The signature is the same as for :c:func:`PyObject_Hash`; it must return a
+   value of the type Py_hash_t.  The value ``-1`` should not be returned as a
+   normal return value; when an error occurs during the computation of the hash
+   value, the function should set an exception and return ``-1``.
 
    This field can be set explicitly to :c:func:`PyObject_HashNotImplemented` to
    block inheritance of the hash method from a parent type. This is interpreted
index 916e3f7ce883d280bf82b20bfaf16b81687b6a92..3c69d25b50344445fed5c1e5d7e9fc327965ac66 100644 (file)
@@ -29,7 +29,7 @@ functions should be applied to nil objects.
 
 typedef struct {
     PyObject_VAR_HEAD
-    long ob_shash;
+    Py_hash_t ob_shash;
     char ob_sval[1];
 
     /* Invariants:
index f472c421dcbded5aa56cd4adb564cfd44e3a5d30..2d71fced8dc6d3633a957143dac94a8a143d2a7b 100644 (file)
@@ -34,7 +34,7 @@ extern "C" {
 typedef struct
 {
     PyObject_HEAD
-    long hashcode;              /* -1 when unknown */
+    Py_hash_t hashcode;         /* -1 when unknown */
     int days;                   /* -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS */
     int seconds;                /* 0 <= seconds < 24*3600 is invariant */
     int microseconds;           /* 0 <= microseconds < 1000000 is invariant */
@@ -51,7 +51,7 @@ typedef struct
  */
 #define _PyTZINFO_HEAD          \
     PyObject_HEAD               \
-    long hashcode;              \
+    Py_hash_t hashcode;         \
     char hastzinfo;             /* boolean flag */
 
 /* No _PyDateTime_BaseTZInfo is allocated; it's just to have something
index 248192194921a6560175eaaa2a8a7e3948e474fb..024a688d2a9b52b458361fd0bdfbfc4989b759dd 100644 (file)
@@ -48,11 +48,8 @@ meaning otherwise.
 #define PyDict_MINSIZE 8
 
 typedef struct {
-    /* Cached hash code of me_key.  Note that hash codes are C longs.
-     * We have to use Py_ssize_t instead because dict_popitem() abuses
-     * me_hash to hold a search finger.
-     */
-    Py_ssize_t me_hash;
+    /* Cached hash code of me_key. */
+    Py_hash_t me_hash;
     PyObject *me_key;
     PyObject *me_value;
 } PyDictEntry;
@@ -84,7 +81,7 @@ struct _dictobject {
      * setitem calls.
      */
     PyDictEntry *ma_table;
-    PyDictEntry *(*ma_lookup)(PyDictObject *mp, PyObject *key, long hash);
+    PyDictEntry *(*ma_lookup)(PyDictObject *mp, PyObject *key, Py_hash_t hash);
     PyDictEntry ma_smalltable[PyDict_MINSIZE];
 };
 
@@ -116,14 +113,14 @@ PyAPI_FUNC(void) PyDict_Clear(PyObject *mp);
 PyAPI_FUNC(int) PyDict_Next(
     PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value);
 PyAPI_FUNC(int) _PyDict_Next(
-    PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value, long *hash);
+    PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value, Py_hash_t *hash);
 PyAPI_FUNC(PyObject *) PyDict_Keys(PyObject *mp);
 PyAPI_FUNC(PyObject *) PyDict_Values(PyObject *mp);
 PyAPI_FUNC(PyObject *) PyDict_Items(PyObject *mp);
 PyAPI_FUNC(Py_ssize_t) PyDict_Size(PyObject *mp);
 PyAPI_FUNC(PyObject *) PyDict_Copy(PyObject *mp);
 PyAPI_FUNC(int) PyDict_Contains(PyObject *mp, PyObject *key);
-PyAPI_FUNC(int) _PyDict_Contains(PyObject *mp, PyObject *key, long hash);
+PyAPI_FUNC(int) _PyDict_Contains(PyObject *mp, PyObject *key, Py_hash_t hash);
 PyAPI_FUNC(PyObject *) _PyDict_NewPresized(Py_ssize_t minused);
 PyAPI_FUNC(void) _PyDict_MaybeUntrack(PyObject *mp);
 PyAPI_FUNC(int) _PyDict_HasOnlyStringKeys(PyObject *mp);
index ef73a213d16f1e5aae85e6a32dcc753d34c27605..f14fd07a04a2dedf2916b20e75f1a4cafc159594 100644 (file)
@@ -275,7 +275,7 @@ typedef PyObject *(*getattrofunc)(PyObject *, PyObject *);
 typedef int (*setattrfunc)(PyObject *, char *, PyObject *);
 typedef int (*setattrofunc)(PyObject *, PyObject *, PyObject *);
 typedef PyObject *(*reprfunc)(PyObject *);
-typedef long (*hashfunc)(PyObject *);
+typedef Py_hash_t (*hashfunc)(PyObject *);
 typedef PyObject *(*richcmpfunc) (PyObject *, PyObject *, int);
 typedef PyObject *(*getiterfunc) (PyObject *);
 typedef PyObject *(*iternextfunc) (PyObject *);
@@ -440,8 +440,8 @@ PyAPI_FUNC(PyObject *) _PyObject_NextNotImplemented(PyObject *);
 PyAPI_FUNC(PyObject *) PyObject_GenericGetAttr(PyObject *, PyObject *);
 PyAPI_FUNC(int) PyObject_GenericSetAttr(PyObject *,
                                               PyObject *, PyObject *);
-PyAPI_FUNC(long) PyObject_Hash(PyObject *);
-PyAPI_FUNC(long) PyObject_HashNotImplemented(PyObject *);
+PyAPI_FUNC(Py_hash_t) PyObject_Hash(PyObject *);
+PyAPI_FUNC(Py_hash_t) PyObject_HashNotImplemented(PyObject *);
 PyAPI_FUNC(int) PyObject_IsTrue(PyObject *);
 PyAPI_FUNC(int) PyObject_Not(PyObject *);
 PyAPI_FUNC(int) PyCallable_Check(PyObject *);
@@ -470,8 +470,8 @@ PyAPI_FUNC(int) Py_ReprEnter(PyObject *);
 PyAPI_FUNC(void) Py_ReprLeave(PyObject *);
 
 /* Helpers for hash functions */
-PyAPI_FUNC(long) _Py_HashDouble(double);
-PyAPI_FUNC(long) _Py_HashPointer(void*);
+PyAPI_FUNC(Py_hash_t) _Py_HashDouble(double);
+PyAPI_FUNC(Py_hash_t) _Py_HashPointer(void*);
 
 /* Helper for passing objects to printf and the like */
 #define PyObject_REPR(obj) _PyUnicode_AsString(PyObject_Repr(obj))
index 5e98f0b8156dee7be2d1ac6847136b826d5816f3..4331bf984451cd2fbe4b687b9417085a7c35ba81 100644 (file)
@@ -130,7 +130,7 @@ Used in:  PY_LONG_LONG
    _PyHash_Double in Objects/object.c.  Numeric hashes are based on
    reduction modulo the prime 2**_PyHASH_BITS - 1. */
 
-#if SIZEOF_LONG >= 8
+#if SIZEOF_VOID_P >= 8
 #define _PyHASH_BITS 61
 #else
 #define _PyHASH_BITS 31
@@ -177,6 +177,9 @@ typedef Py_intptr_t     Py_ssize_t;
 #   error "Python needs a typedef for Py_ssize_t in pyport.h."
 #endif
 
+/* Py_hash_t is the same size as a pointer. */
+typedef Py_ssize_t Py_hash_t;
+
 /* Largest possible value of size_t.
    SIZE_MAX is part of C99, so it might be defined on some
    platforms. If it is not defined, (size_t)-1 is a portable
index 574caf73803289cd296d8690fd60d5ea4b079b56..023c5fa758182567da7a2dd078836cb67dda87da 100644 (file)
@@ -22,11 +22,8 @@ no meaning otherwise.
 #define PySet_MINSIZE 8
 
 typedef struct {
-    /* Cached hash code of the key.  Note that hash codes are C longs.
-     * We have to use Py_ssize_t instead because set_pop() abuses
-     * the hash field to hold a search finger.
-     */
-    Py_ssize_t hash;
+    /* Cached hash code of the key. */
+    Py_hash_t hash;
     PyObject *key;
 } setentry;
 
@@ -53,10 +50,10 @@ struct _setobject {
      * saves repeated runtime null-tests.
      */
     setentry *table;
-    setentry *(*lookup)(PySetObject *so, PyObject *key, long hash);
+    setentry *(*lookup)(PySetObject *so, PyObject *key, Py_hash_t hash);
     setentry smalltable[PySet_MINSIZE];
 
-    long hash;                  /* only used by frozenset objects */
+    Py_hash_t hash;                  /* only used by frozenset objects */
     PyObject *weakreflist;      /* List of weak references */
 };
 
@@ -93,7 +90,7 @@ PyAPI_FUNC(int) PySet_Clear(PyObject *set);
 PyAPI_FUNC(int) PySet_Contains(PyObject *anyset, PyObject *key);
 PyAPI_FUNC(int) PySet_Discard(PyObject *set, PyObject *key);
 PyAPI_FUNC(int) PySet_Add(PyObject *set, PyObject *key);
-PyAPI_FUNC(int) _PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, long *hash);
+PyAPI_FUNC(int) _PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash);
 PyAPI_FUNC(PyObject *) PySet_Pop(PyObject *set);
 PyAPI_FUNC(int) _PySet_Update(PyObject *set, PyObject *iterable);
 
index f61712bdbc6efe885ff27aec0443af5a488d57e4..42da8c338c94a9ede967bf6abb67a5cdc1a870e3 100644 (file)
@@ -372,7 +372,7 @@ typedef struct {
     PyObject_HEAD
     Py_ssize_t length;          /* Length of raw Unicode data in buffer */
     Py_UNICODE *str;            /* Raw Unicode buffer */
-    long hash;                  /* Hash value; -1 if not set */
+    Py_hash_t hash;             /* Hash value; -1 if not set */
     int state;                  /* != 0 if interned. In this case the two
                                  * references from the dictionary to this object
                                  * are *not* counted in ob_refcnt. */
index f15c9d9c128365866ae725bbc766f52bf9cfcb2e..b201d0814cc8f7d6a0d7e99f202232d52aaaad88 100644 (file)
@@ -27,7 +27,7 @@ struct _PyWeakReference {
     /* A cache for wr_object's hash code.  As usual for hashes, this is -1
      * if the hash code isn't known yet.
      */
-    long hash;
+    Py_hash_t hash;
 
     /* If wr_object is weakly referenced, wr_object has a doubly-linked NULL-
      * terminated list of weak references to it.  These are the list pointers.
index 6ee769c387a5dcd1b77d11f225ea3b20f35d0160..fa3725a8da7a2e5da8ce80b091259ef5f57089f5 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -93,6 +93,12 @@ Extensions
 
 - The Unicode database was updated to 6.0.0.
 
+C-API
+-----
+
+- Issue #9778: Hash values are now always the size of pointers. A new Py_hash_t
+  type has been introduced.
+
 Tools/Demos
 -----------
 
index 9a04549787dd376bc01ec6cae850520e4eb0068f..d791cdeca897b1f6fb3aa492500e9c16b635cd4e 100644 (file)
@@ -1843,7 +1843,7 @@ delta_richcompare(PyObject *self, PyObject *other, int op)
 
 static PyObject *delta_getstate(PyDateTime_Delta *self);
 
-static long
+static Py_hash_t
 delta_hash(PyDateTime_Delta *self)
 {
     if (self->hashcode == -1) {
@@ -2777,11 +2777,11 @@ date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
 /*
     Borrowed from stringobject.c, originally it was string_hash()
 */
-static long
+static Py_hash_t
 generic_hash(unsigned char *data, int len)
 {
     register unsigned char *p;
-    register long x;
+    register Py_hash_t x;
 
     p = (unsigned char *) data;
     x = *p << 7;
@@ -2797,7 +2797,7 @@ generic_hash(unsigned char *data, int len)
 
 static PyObject *date_getstate(PyDateTime_Date *self);
 
-static long
+static Py_hash_t
 date_hash(PyDateTime_Date *self)
 {
     if (self->hashcode == -1)
@@ -3246,7 +3246,7 @@ timezone_richcompare(PyDateTime_TimeZone *self,
     return delta_richcompare(self->offset, other->offset, op);
 }
 
-static long
+static Py_hash_t
 timezone_hash(PyDateTime_TimeZone *self)
 {
     return delta_hash((PyDateTime_Delta *)self->offset);
@@ -3751,7 +3751,7 @@ time_richcompare(PyObject *self, PyObject *other, int op)
     return result;
 }
 
-static long
+static Py_hash_t
 time_hash(PyDateTime_Time *self)
 {
     if (self->hashcode == -1) {
@@ -4640,7 +4640,7 @@ datetime_richcompare(PyObject *self, PyObject *other, int op)
     return result;
 }
 
-static long
+static Py_hash_t
 datetime_hash(PyDateTime_DateTime *self)
 {
     if (self->hashcode == -1) {
index 61db7cd5cbbc6c8af497c8eeb5e92192c22dd833..b810301cd58465f693a215f620bb1fe1333945ec 100644 (file)
@@ -486,7 +486,7 @@ _PyMemoTable_Lookup(PyMemoTable *self, PyObject *key)
     size_t mask = (size_t)self->mt_mask;
     PyMemoEntry *table = self->mt_table;
     PyMemoEntry *entry;
-    long hash = (long)key >> 3;
+    Py_hash_t hash = (Py_hash_t)key >> 3;
 
     i = hash & mask;
     entry = &table[i];
index fc644f24c065915004794d2dc98ac7b2888869d2..2b965c37aeda999df8811862ae2e7924cf92c6fd 100644 (file)
@@ -868,12 +868,12 @@ bytes_richcompare(PyBytesObject *a, PyBytesObject *b, int op)
     return result;
 }
 
-static long
+static Py_hash_t
 bytes_hash(PyBytesObject *a)
 {
     register Py_ssize_t len;
     register unsigned char *p;
-    register long x;
+    register Py_hash_t x;
 
     if (a->ob_shash != -1)
         return a->ob_shash;
index afd4ec3dc6ec2e4249c3117f07c5b71c02a8455c..6df930fdcf629b35aa2f54b7d181927114d0476e 100644 (file)
@@ -263,10 +263,10 @@ method_repr(PyMethodObject *a)
     return result;
 }
 
-static long
+static Py_hash_t
 method_hash(PyMethodObject *a)
 {
-    long x, y;
+    Py_hash_t x, y;
     if (a->im_self == NULL)
         x = PyObject_Hash(Py_None);
     else
index da5c09ac8d276a52eb4be87ba85f276b341d83e8..54c23aec36d9ee3b9515ca2745b1a7421d71f51f 100644 (file)
@@ -417,10 +417,10 @@ code_richcompare(PyObject *self, PyObject *other, int op)
     return res;
 }
 
-static long
+static Py_hash_t
 code_hash(PyCodeObject *co)
 {
-    long h, h0, h1, h2, h3, h4, h5, h6;
+    Py_hash_t h, h0, h1, h2, h3, h4, h5, h6;
     h0 = PyObject_Hash(co->co_name);
     if (h0 == -1) return -1;
     h1 = PyObject_Hash(co->co_code);
index 674362f9ebcbad768679e89becf756d9dcec9bc7..c4ced31cb943e3d84cc3d66f3d82480f38a59989 100644 (file)
@@ -394,7 +394,7 @@ complex_repr(PyComplexObject *v)
     return complex_format(v, 0, 'r');
 }
 
-static long
+static Py_hash_t
 complex_hash(PyComplexObject *v)
 {
     unsigned long hashreal, hashimag, combined;
@@ -413,7 +413,7 @@ complex_hash(PyComplexObject *v)
     combined = hashreal + _PyHASH_IMAG * hashimag;
     if (combined == (unsigned long)-1)
         combined = (unsigned long)-2;
-    return (long)combined;
+    return (Py_hash_t)combined;
 }
 
 /* This macro may return! */
index 8a2ddfd8a8a42efbace234b9bc78c6f0745074a4..11418d19e57bbf62c31bbcf07db8449e1a80cd46 100644 (file)
@@ -916,10 +916,10 @@ wrapper_richcompare(PyObject *a, PyObject *b, int op)
     return v;
 }
 
-static long
+static Py_hash_t
 wrapper_hash(wrapperobject *wp)
 {
-    int x, y;
+    Py_hash_t x, y;
     x = _Py_HashPointer(wp->descr);
     if (x == -1)
         return -1;
index 241790ceba27d0212b05d73e3372198aa1dbe2a7..7fd586b3d99c3087ae3e4efac97e3fbce8122e2b 100644 (file)
@@ -318,7 +318,7 @@ the caller can (if it wishes) add the <key, value> pair to the returned
 PyDictEntry*.
 */
 static PyDictEntry *
-lookdict(PyDictObject *mp, PyObject *key, register long hash)
+lookdict(PyDictObject *mp, PyObject *key, register Py_hash_t hash)
 {
     register size_t i;
     register size_t perturb;
@@ -407,7 +407,7 @@ lookdict(PyDictObject *mp, PyObject *key, register long hash)
  * This is valuable because dicts with only unicode keys are very common.
  */
 static PyDictEntry *
-lookdict_unicode(PyDictObject *mp, PyObject *key, register long hash)
+lookdict_unicode(PyDictObject *mp, PyObject *key, register Py_hash_t hash)
 {
     register size_t i;
     register size_t perturb;
@@ -527,7 +527,7 @@ Eats a reference to key and one to value.
 Returns -1 if an error occurred, or 0 on success.
 */
 static int
-insertdict(register PyDictObject *mp, PyObject *key, long hash, PyObject *value)
+insertdict(register PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value)
 {
     PyObject *old_value;
     register PyDictEntry *ep;
@@ -555,7 +555,7 @@ insertdict(register PyDictObject *mp, PyObject *key, long hash, PyObject *value)
             Py_DECREF(dummy);
         }
         ep->me_key = key;
-        ep->me_hash = (Py_ssize_t)hash;
+        ep->me_hash = hash;
         ep->me_value = value;
         mp->ma_used++;
     }
@@ -571,7 +571,7 @@ Note that no refcounts are changed by this routine; if needed, the caller
 is responsible for incref'ing `key` and `value`.
 */
 static void
-insertdict_clean(register PyDictObject *mp, PyObject *key, long hash,
+insertdict_clean(register PyDictObject *mp, PyObject *key, Py_hash_t hash,
                  PyObject *value)
 {
     register size_t i;
@@ -590,7 +590,7 @@ insertdict_clean(register PyDictObject *mp, PyObject *key, long hash,
     assert(ep->me_value == NULL);
     mp->ma_fill++;
     ep->me_key = key;
-    ep->me_hash = (Py_ssize_t)hash;
+    ep->me_hash = hash;
     ep->me_value = value;
     mp->ma_used++;
 }
@@ -667,8 +667,7 @@ dictresize(PyDictObject *mp, Py_ssize_t minused)
     for (ep = oldtable; i > 0; ep++) {
         if (ep->me_value != NULL) {             /* active entry */
             --i;
-            insertdict_clean(mp, ep->me_key, (long)ep->me_hash,
-                             ep->me_value);
+            insertdict_clean(mp, ep->me_key, ep->me_hash, ep->me_value);
         }
         else if (ep->me_key != NULL) {          /* dummy entry */
             --i;
@@ -713,7 +712,7 @@ _PyDict_NewPresized(Py_ssize_t minused)
 PyObject *
 PyDict_GetItem(PyObject *op, PyObject *key)
 {
-    long hash;
+    Py_hash_t hash;
     PyDictObject *mp = (PyDictObject *)op;
     PyDictEntry *ep;
     PyThreadState *tstate;
@@ -763,7 +762,7 @@ PyDict_GetItem(PyObject *op, PyObject *key)
 PyObject *
 PyDict_GetItemWithError(PyObject *op, PyObject *key)
 {
-    long hash;
+    Py_hash_t hash;
     PyDictObject*mp = (PyDictObject *)op;
     PyDictEntry *ep;
 
@@ -796,7 +795,7 @@ int
 PyDict_SetItem(register PyObject *op, PyObject *key, PyObject *value)
 {
     register PyDictObject *mp;
-    register long hash;
+    register Py_hash_t hash;
     register Py_ssize_t n_used;
 
     if (!PyDict_Check(op)) {
@@ -842,7 +841,7 @@ int
 PyDict_DelItem(PyObject *op, PyObject *key)
 {
     register PyDictObject *mp;
-    register long hash;
+    register Py_hash_t hash;
     register PyDictEntry *ep;
     PyObject *old_value, *old_key;
 
@@ -988,7 +987,7 @@ PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue)
 
 /* Internal version of PyDict_Next that returns a hash value in addition to the key and value.*/
 int
-_PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue, long *phash)
+_PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue, Py_hash_t *phash)
 {
     register Py_ssize_t i;
     register Py_ssize_t mask;
@@ -1006,7 +1005,7 @@ _PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue,
     *ppos = i+1;
     if (i > mask)
         return 0;
-    *phash = (long)(ep[i].me_hash);
+    *phash = ep[i].me_hash;
     if (pkey)
         *pkey = ep[i].me_key;
     if (pvalue)
@@ -1128,7 +1127,7 @@ static PyObject *
 dict_subscript(PyDictObject *mp, register PyObject *key)
 {
     PyObject *v;
-    long hash;
+    Py_hash_t hash;
     PyDictEntry *ep;
     assert(mp->ma_table != NULL);
     if (!PyUnicode_CheckExact(key) ||
@@ -1322,7 +1321,7 @@ dict_fromkeys(PyObject *cls, PyObject *args)
         PyObject *oldvalue;
         Py_ssize_t pos = 0;
         PyObject *key;
-        long hash;
+        Py_hash_t hash;
 
         if (dictresize(mp, Py_SIZE(seq)))
             return NULL;
@@ -1340,7 +1339,7 @@ dict_fromkeys(PyObject *cls, PyObject *args)
         PyDictObject *mp = (PyDictObject *)d;
         Py_ssize_t pos = 0;
         PyObject *key;
-        long hash;
+        Py_hash_t hash;
 
         if (dictresize(mp, PySet_GET_SIZE(seq)))
             return NULL;
@@ -1549,7 +1548,7 @@ PyDict_Merge(PyObject *a, PyObject *b, int override)
                 Py_INCREF(entry->me_key);
                 Py_INCREF(entry->me_value);
                 if (insertdict(mp, entry->me_key,
-                               (long)entry->me_hash,
+                               entry->me_hash,
                                entry->me_value) != 0)
                     return -1;
             }
@@ -1732,7 +1731,7 @@ dict_richcompare(PyObject *v, PyObject *w, int op)
 static PyObject *
 dict_contains(register PyDictObject *mp, PyObject *key)
 {
-    long hash;
+    Py_hash_t hash;
     PyDictEntry *ep;
 
     if (!PyUnicode_CheckExact(key) ||
@@ -1753,7 +1752,7 @@ dict_get(register PyDictObject *mp, PyObject *args)
     PyObject *key;
     PyObject *failobj = Py_None;
     PyObject *val = NULL;
-    long hash;
+    Py_hash_t hash;
     PyDictEntry *ep;
 
     if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &failobj))
@@ -1782,7 +1781,7 @@ dict_setdefault(register PyDictObject *mp, PyObject *args)
     PyObject *key;
     PyObject *failobj = Py_None;
     PyObject *val = NULL;
-    long hash;
+    Py_hash_t hash;
     PyDictEntry *ep;
 
     if (!PyArg_UnpackTuple(args, "setdefault", 1, 2, &key, &failobj))
@@ -1818,7 +1817,7 @@ dict_clear(register PyDictObject *mp)
 static PyObject *
 dict_pop(PyDictObject *mp, PyObject *args)
 {
-    long hash;
+    Py_hash_t hash;
     PyDictEntry *ep;
     PyObject *old_value, *old_key;
     PyObject *key, *deflt = NULL;
@@ -1864,7 +1863,7 @@ dict_pop(PyDictObject *mp, PyObject *args)
 static PyObject *
 dict_popitem(PyDictObject *mp)
 {
-    Py_ssize_t i = 0;
+    Py_hash_t i = 0;
     PyDictEntry *ep;
     PyObject *res;
 
@@ -2039,7 +2038,7 @@ static PyMethodDef mapp_methods[] = {
 int
 PyDict_Contains(PyObject *op, PyObject *key)
 {
-    long hash;
+    Py_hash_t hash;
     PyDictObject *mp = (PyDictObject *)op;
     PyDictEntry *ep;
 
@@ -2055,7 +2054,7 @@ PyDict_Contains(PyObject *op, PyObject *key)
 
 /* Internal version of PyDict_Contains used when the hash value is already known */
 int
-_PyDict_Contains(PyObject *op, PyObject *key, long hash)
+_PyDict_Contains(PyObject *op, PyObject *key, Py_hash_t hash)
 {
     PyDictObject *mp = (PyDictObject *)op;
     PyDictEntry *ep;
index b792c196e25c67b89da095fbaf065602e6043fac..d0173e8d1340c1b8eee9dc52d8b2a0212cd78b21 100644 (file)
@@ -522,7 +522,7 @@ float_richcompare(PyObject *v, PyObject *w, int op)
     return Py_NotImplemented;
 }
 
-static long
+static Py_hash_t
 float_hash(PyFloatObject *v)
 {
     return _Py_HashDouble(v->ob_fval);
index c9c9817f12300fdeaf08fa376c0bf02a72d8326c..cf7eb2c2b343c4f534943979b3311eac47832d22 100644 (file)
@@ -2552,7 +2552,7 @@ long_richcompare(PyObject *self, PyObject *other, int op)
     return v;
 }
 
-static long
+static Py_hash_t
 long_hash(PyLongObject *v)
 {
     unsigned long x;
@@ -2606,7 +2606,7 @@ long_hash(PyLongObject *v)
     x = x * sign;
     if (x == (unsigned long)-1)
         x = (unsigned long)-2;
-    return (long)x;
+    return (Py_hash_t)x;
 }
 
 
index 356d16184233c88dc242d34d5311b177cd262272..f1a9f4b7022d07aa118a759ddb5dd7f4d53bf7d8 100644 (file)
@@ -224,10 +224,10 @@ meth_richcompare(PyObject *self, PyObject *other, int op)
     return res;
 }
 
-static long
+static Py_hash_t
 meth_hash(PyCFunctionObject *a)
 {
-    long x,y;
+    Py_hash_t x, y;
     if (a->m_self == NULL)
         x = 0;
     else {
index ff3363f43294cc6040973b68f488308c59ac854e..2f544ba67e0d49a52aa6e12bd0efaab904aed25f 100644 (file)
@@ -687,7 +687,7 @@ PyObject_RichCompareBool(PyObject *v, PyObject *w, int op)
 
    */
 
-long
+Py_hash_t
 _Py_HashDouble(double v)
 {
     int e, sign;
@@ -730,24 +730,24 @@ _Py_HashDouble(double v)
     x = x * sign;
     if (x == (unsigned long)-1)
         x = (unsigned long)-2;
-    return (long)x;
+    return (Py_hash_t)x;
 }
 
-long
+Py_hash_t
 _Py_HashPointer(void *p)
 {
-    long x;
+    Py_hash_t x;
     size_t y = (size_t)p;
     /* bottom 3 or 4 bits are likely to be 0; rotate y by 4 to avoid
        excessive hash collisions for dicts and sets */
     y = (y >> 4) | (y << (8 * SIZEOF_VOID_P - 4));
-    x = (long)y;
+    x = (Py_hash_t)y;
     if (x == -1)
         x = -2;
     return x;
 }
 
-long
+Py_hash_t
 PyObject_HashNotImplemented(PyObject *v)
 {
     PyErr_Format(PyExc_TypeError, "unhashable type: '%.200s'",
@@ -755,7 +755,7 @@ PyObject_HashNotImplemented(PyObject *v)
     return -1;
 }
 
-long
+Py_hash_t
 PyObject_Hash(PyObject *v)
 {
     PyTypeObject *tp = Py_TYPE(v);
index 7eac1aa9c1e73612f152c9c58651aaaccdf531f3..54b14da21c58e07d3a88b77b8186e7cf70ca0ec2 100644 (file)
@@ -75,7 +75,7 @@ NULL if the rich comparison returns an error.
 */
 
 static setentry *
-set_lookkey(PySetObject *so, PyObject *key, register long hash)
+set_lookkey(PySetObject *so, PyObject *key, register Py_hash_t hash)
 {
     register Py_ssize_t i;
     register size_t perturb;
@@ -157,7 +157,7 @@ set_lookkey(PySetObject *so, PyObject *key, register long hash)
  * see if the comparison altered the table.
  */
 static setentry *
-set_lookkey_unicode(PySetObject *so, PyObject *key, register long hash)
+set_lookkey_unicode(PySetObject *so, PyObject *key, register Py_hash_t hash)
 {
     register Py_ssize_t i;
     register size_t perturb;
@@ -211,7 +211,7 @@ Used by the public insert routine.
 Eats a reference to key.
 */
 static int
-set_insert_key(register PySetObject *so, PyObject *key, long hash)
+set_insert_key(register PySetObject *so, PyObject *key, Py_hash_t hash)
 {
     register setentry *entry;
     typedef setentry *(*lookupfunc)(PySetObject *, PyObject *, long);
@@ -248,7 +248,7 @@ Note that no refcounts are changed by this routine; if needed, the caller
 is responsible for incref'ing `key`.
 */
 static void
-set_insert_clean(register PySetObject *so, PyObject *key, long hash)
+set_insert_clean(register PySetObject *so, PyObject *key, Py_hash_t hash)
 {
     register size_t i;
     register size_t perturb;
@@ -349,7 +349,7 @@ set_table_resize(PySetObject *so, Py_ssize_t minused)
         } else {
             /* ACTIVE */
             --i;
-            set_insert_clean(so, entry->key, (long) entry->hash);
+            set_insert_clean(so, entry->key, entry->hash);
         }
     }
 
@@ -369,7 +369,7 @@ set_add_entry(register PySetObject *so, setentry *entry)
     assert(so->fill <= so->mask);  /* at least one empty slot */
     n_used = so->used;
     Py_INCREF(key);
-    if (set_insert_key(so, key, (long) entry->hash) == -1) {
+    if (set_insert_key(so, key, entry->hash) == -1) {
         Py_DECREF(key);
         return -1;
     }
@@ -381,7 +381,7 @@ set_add_entry(register PySetObject *so, setentry *entry)
 static int
 set_add_key(register PySetObject *so, PyObject *key)
 {
-    register long hash;
+    register Py_hash_t hash;
     register Py_ssize_t n_used;
 
     if (!PyUnicode_CheckExact(key) ||
@@ -410,7 +410,7 @@ set_discard_entry(PySetObject *so, setentry *oldentry)
 {       register setentry *entry;
     PyObject *old_key;
 
-    entry = (so->lookup)(so, oldentry->key, (long) oldentry->hash);
+    entry = (so->lookup)(so, oldentry->key, oldentry->hash);
     if (entry == NULL)
         return -1;
     if (entry->key == NULL  ||  entry->key == dummy)
@@ -426,7 +426,7 @@ set_discard_entry(PySetObject *so, setentry *oldentry)
 static int
 set_discard_key(PySetObject *so, PyObject *key)
 {
-    register long hash;
+    register Py_hash_t hash;
     register setentry *entry;
     PyObject *old_key;
 
@@ -675,7 +675,7 @@ set_merge(PySetObject *so, PyObject *otherset)
 static int
 set_contains_key(PySetObject *so, PyObject *key)
 {
-    long hash;
+    Py_hash_t hash;
     setentry *entry;
 
     if (!PyUnicode_CheckExact(key) ||
@@ -697,7 +697,7 @@ set_contains_entry(PySetObject *so, setentry *entry)
     PyObject *key;
     setentry *lu_entry;
 
-    lu_entry = (so->lookup)(so, entry->key, (long) entry->hash);
+    lu_entry = (so->lookup)(so, entry->key, entry->hash);
     if (lu_entry == NULL)
         return -1;
     key = lu_entry->key;
@@ -761,11 +761,11 @@ set_traverse(PySetObject *so, visitproc visit, void *arg)
     return 0;
 }
 
-static long
+static Py_hash_t
 frozenset_hash(PyObject *self)
 {
     PySetObject *so = (PySetObject *)self;
-    long h, hash = 1927868237L;
+    Py_hash_t h, hash = 1927868237L;
     setentry *entry;
     Py_ssize_t pos = 0;
 
@@ -926,7 +926,7 @@ set_update_internal(PySetObject *so, PyObject *other)
     if (PyDict_CheckExact(other)) {
         PyObject *value;
         Py_ssize_t pos = 0;
-        long hash;
+        Py_hash_t hash;
         Py_ssize_t dictsize = PyDict_Size(other);
 
         /* Do one big resize at the start, rather than
@@ -1114,7 +1114,7 @@ set_swap_bodies(PySetObject *a, PySetObject *b)
 {
     Py_ssize_t t;
     setentry *u;
-    setentry *(*f)(PySetObject *so, PyObject *key, long hash);
+    setentry *(*f)(PySetObject *so, PyObject *key, Py_ssize_t hash);
     setentry tab[PySet_MINSIZE];
     long h;
 
@@ -1285,7 +1285,7 @@ set_intersection(PySetObject *so, PyObject *other)
     while ((key = PyIter_Next(it)) != NULL) {
         int rv;
         setentry entry;
-        long hash = PyObject_Hash(key);
+        Py_hash_t hash = PyObject_Hash(key);
 
         if (hash == -1) {
             Py_DECREF(it);
@@ -1442,7 +1442,7 @@ set_isdisjoint(PySetObject *so, PyObject *other)
     while ((key = PyIter_Next(it)) != NULL) {
         int rv;
         setentry entry;
-        long hash = PyObject_Hash(key);
+        Py_hash_t hash = PyObject_Hash(key);
 
         if (hash == -1) {
             Py_DECREF(key);
@@ -1641,7 +1641,7 @@ set_symmetric_difference_update(PySetObject *so, PyObject *other)
     if (PyDict_CheckExact(other)) {
         PyObject *value;
         int rv;
-        long hash;
+        Py_hash_t hash;
         while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
             setentry an_entry;
 
@@ -2308,7 +2308,7 @@ PySet_Add(PyObject *anyset, PyObject *key)
 }
 
 int
-_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, long *hash)
+_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
 {
     setentry *entry;
 
@@ -2319,7 +2319,7 @@ _PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, long *hash)
     if (set_next((PySetObject *)set, pos, &entry) == 0)
         return 0;
     *key = entry->key;
-    *hash = (long) entry->hash;
+    *hash = entry->hash;
     return 1;
 }
 
@@ -2363,7 +2363,7 @@ test_c_api(PySetObject *so)
     Py_ssize_t i;
     PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x;
     PyObject *ob = (PyObject *)so;
-    long hash;
+    Py_hash_t hash;
     PyObject *str;
 
     /* Verify preconditions */
index aa3be821bbe18a4f761faa1dd13cc1beb404ac85..c55ad65d9536e867aaac59b399baf960b22e5278 100644 (file)
@@ -312,10 +312,10 @@ Done:
      1330111, 1412633, 1165069, 1247599, 1495177, 1577699
 */
 
-static long
+static Py_hash_t
 tuplehash(PyTupleObject *v)
 {
-    register long x, y;
+    register Py_hash_t x, y;
     register Py_ssize_t len = Py_SIZE(v);
     register PyObject **p;
     long mult = 1000003L;
index faa03df60316414a11ab4c13c89a1d8f1bd9f67f..a3905d84c709dc53c6e2e90a0865cb679f90e5d6 100644 (file)
@@ -4918,13 +4918,12 @@ slot_tp_str(PyObject *self)
     }
 }
 
-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 @@ slot_tp_hash(PyObject *self)
                         "__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;
 }
 
index 9fe9c4279688bdb7d00bd8a9ca455b6719b69b0f..0e2f95018a55833b265017a6cc77492b03f90d8b 100644 (file)
@@ -7444,12 +7444,12 @@ unicode_getitem(PyUnicodeObject *self, Py_ssize_t index)
 
 /* Believe it or not, this produces the same value for ASCII strings
    as string_hash(). */
-static long
+static Py_hash_t
 unicode_hash(PyUnicodeObject *self)
 {
     Py_ssize_t len;
     Py_UNICODE *p;
-    long x;
+    Py_hash_t x;
 
     if (self->hash != -1)
         return self->hash;
index f43b68d607f733d7968af629d035a2a054eafeb3..7a2c1bda32375cd40fba027dd0dea8c8d42ae73b 100644 (file)
@@ -139,7 +139,7 @@ weakref_call(PyWeakReference *self, PyObject *args, PyObject *kw)
 }
 
 
-static long
+static Py_hash_t
 weakref_hash(PyWeakReference *self)
 {
     if (self->hash != -1)
index ece2a3728e8cc777b3443419cba3003392dec143..46045192cfdb58f820f7a71917de9f46c46b93a3 100644 (file)
@@ -1148,12 +1148,12 @@ Delete a named attribute on an object; delattr(x, 'y') is equivalent to\n\
 static PyObject *
 builtin_hash(PyObject *self, PyObject *v)
 {
-    long x;
+    Py_hash_t x;
 
     x = PyObject_Hash(v);
     if (x == -1)
         return NULL;
-    return PyLong_FromLong(x);
+    return PyLong_FromSsize_t(x);
 }
 
 PyDoc_STRVAR(hash_doc,
index f85f33ad02ede3fe288fbbee676b962dcbf231a9..1eb5f6204ba37f24581d11ce81e201beaec59afa 100644 (file)
@@ -2102,7 +2102,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
                 /* Inline the PyDict_GetItem() calls.
                    WARNING: this is an extreme speed hack.
                    Do not try this at home. */
-                long hash = ((PyUnicodeObject *)w)->hash;
+                Py_hash_t hash = ((PyUnicodeObject *)w)->hash;
                 if (hash != -1) {
                     PyDictObject *d;
                     PyDictEntry *e;
index 6c563f0d373b06330063cfb91219e634e9c1dd83..033c9d5e564122b76a2ff181faff3a5efe0e5d99 100644 (file)
@@ -567,7 +567,7 @@ get_hash_info(void)
     if (hash_info == NULL)
         return NULL;
     PyStructSequence_SET_ITEM(hash_info, field++,
-                              PyLong_FromLong(8*sizeof(long)));
+                              PyLong_FromLong(8*sizeof(Py_hash_t)));
     PyStructSequence_SET_ITEM(hash_info, field++,
                               PyLong_FromLong(_PyHASH_MODULUS));
     PyStructSequence_SET_ITEM(hash_info, field++,