Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 8f67d08

Browse filesBrowse files
committed
make hashes always the size of pointers; introduce Py_hash_t #9778
1 parent 6fb4575 commit 8f67d08
Copy full SHA for 8f67d08
Expand file treeCollapse file tree

31 files changed

+137
-131
lines changed

‎Doc/c-api/object.rst

Copy file name to clipboardExpand all lines: Doc/c-api/object.rst
+7-2Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,15 +247,20 @@ is considered sufficient for this determination.
247247
*NULL* on failure.
248248
249249
250-
.. c:function:: long PyObject_Hash(PyObject *o)
250+
.. c:function:: Py_hash_t PyObject_Hash(PyObject *o)
251251
252252
.. index:: builtin: hash
253253
254254
Compute and return the hash value of an object *o*. On failure, return ``-1``.
255255
This is the equivalent of the Python expression ``hash(o)``.
256256
257+
.. versionchanged:: 3.2
257258
258-
.. c:function:: long PyObject_HashNotImplemented(PyObject *o)
259+
The return type is now Py_hash_t. This is a signed integer the same size
260+
as Py_ssize_t.
261+
262+
263+
.. c:function:: Py_hash_t PyObject_HashNotImplemented(PyObject *o)
259264
260265
Set a :exc:`TypeError` indicating that ``type(o)`` is not hashable and return ``-1``.
261266
This function receives special treatment when stored in a ``tp_hash`` slot,

‎Doc/c-api/typeobj.rst

Copy file name to clipboardExpand all lines: Doc/c-api/typeobj.rst
+4-4Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -306,10 +306,10 @@ type objects) *must* have the :attr:`ob_size` field.
306306
An optional pointer to a function that implements the built-in function
307307
:func:`hash`.
308308

309-
The signature is the same as for :c:func:`PyObject_Hash`; it must return a C
310-
long. The value ``-1`` should not be returned as a normal return value; when an
311-
error occurs during the computation of the hash value, the function should set
312-
an exception and return ``-1``.
309+
The signature is the same as for :c:func:`PyObject_Hash`; it must return a
310+
value of the type Py_hash_t. The value ``-1`` should not be returned as a
311+
normal return value; when an error occurs during the computation of the hash
312+
value, the function should set an exception and return ``-1``.
313313

314314
This field can be set explicitly to :c:func:`PyObject_HashNotImplemented` to
315315
block inheritance of the hash method from a parent type. This is interpreted

‎Include/bytesobject.h

Copy file name to clipboardExpand all lines: Include/bytesobject.h
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ functions should be applied to nil objects.
2929

3030
typedef struct {
3131
PyObject_VAR_HEAD
32-
long ob_shash;
32+
Py_hash_t ob_shash;
3333
char ob_sval[1];
3434

3535
/* Invariants:

‎Include/datetime.h

Copy file name to clipboardExpand all lines: Include/datetime.h
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ extern "C" {
3434
typedef struct
3535
{
3636
PyObject_HEAD
37-
long hashcode; /* -1 when unknown */
37+
Py_hash_t hashcode; /* -1 when unknown */
3838
int days; /* -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS */
3939
int seconds; /* 0 <= seconds < 24*3600 is invariant */
4040
int microseconds; /* 0 <= microseconds < 1000000 is invariant */
@@ -51,7 +51,7 @@ typedef struct
5151
*/
5252
#define _PyTZINFO_HEAD \
5353
PyObject_HEAD \
54-
long hashcode; \
54+
Py_hash_t hashcode; \
5555
char hastzinfo; /* boolean flag */
5656

5757
/* No _PyDateTime_BaseTZInfo is allocated; it's just to have something

‎Include/dictobject.h

Copy file name to clipboardExpand all lines: Include/dictobject.h
+5-8Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,8 @@ meaning otherwise.
4848
#define PyDict_MINSIZE 8
4949

5050
typedef struct {
51-
/* Cached hash code of me_key. Note that hash codes are C longs.
52-
* We have to use Py_ssize_t instead because dict_popitem() abuses
53-
* me_hash to hold a search finger.
54-
*/
55-
Py_ssize_t me_hash;
51+
/* Cached hash code of me_key. */
52+
Py_hash_t me_hash;
5653
PyObject *me_key;
5754
PyObject *me_value;
5855
} PyDictEntry;
@@ -84,7 +81,7 @@ struct _dictobject {
8481
* setitem calls.
8582
*/
8683
PyDictEntry *ma_table;
87-
PyDictEntry *(*ma_lookup)(PyDictObject *mp, PyObject *key, long hash);
84+
PyDictEntry *(*ma_lookup)(PyDictObject *mp, PyObject *key, Py_hash_t hash);
8885
PyDictEntry ma_smalltable[PyDict_MINSIZE];
8986
};
9087

@@ -116,14 +113,14 @@ PyAPI_FUNC(void) PyDict_Clear(PyObject *mp);
116113
PyAPI_FUNC(int) PyDict_Next(
117114
PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value);
118115
PyAPI_FUNC(int) _PyDict_Next(
119-
PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value, long *hash);
116+
PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value, Py_hash_t *hash);
120117
PyAPI_FUNC(PyObject *) PyDict_Keys(PyObject *mp);
121118
PyAPI_FUNC(PyObject *) PyDict_Values(PyObject *mp);
122119
PyAPI_FUNC(PyObject *) PyDict_Items(PyObject *mp);
123120
PyAPI_FUNC(Py_ssize_t) PyDict_Size(PyObject *mp);
124121
PyAPI_FUNC(PyObject *) PyDict_Copy(PyObject *mp);
125122
PyAPI_FUNC(int) PyDict_Contains(PyObject *mp, PyObject *key);
126-
PyAPI_FUNC(int) _PyDict_Contains(PyObject *mp, PyObject *key, long hash);
123+
PyAPI_FUNC(int) _PyDict_Contains(PyObject *mp, PyObject *key, Py_hash_t hash);
127124
PyAPI_FUNC(PyObject *) _PyDict_NewPresized(Py_ssize_t minused);
128125
PyAPI_FUNC(void) _PyDict_MaybeUntrack(PyObject *mp);
129126
PyAPI_FUNC(int) _PyDict_HasOnlyStringKeys(PyObject *mp);

‎Include/object.h

Copy file name to clipboardExpand all lines: Include/object.h
+5-5Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ typedef PyObject *(*getattrofunc)(PyObject *, PyObject *);
275275
typedef int (*setattrfunc)(PyObject *, char *, PyObject *);
276276
typedef int (*setattrofunc)(PyObject *, PyObject *, PyObject *);
277277
typedef PyObject *(*reprfunc)(PyObject *);
278-
typedef long (*hashfunc)(PyObject *);
278+
typedef Py_hash_t (*hashfunc)(PyObject *);
279279
typedef PyObject *(*richcmpfunc) (PyObject *, PyObject *, int);
280280
typedef PyObject *(*getiterfunc) (PyObject *);
281281
typedef PyObject *(*iternextfunc) (PyObject *);
@@ -440,8 +440,8 @@ PyAPI_FUNC(PyObject *) _PyObject_NextNotImplemented(PyObject *);
440440
PyAPI_FUNC(PyObject *) PyObject_GenericGetAttr(PyObject *, PyObject *);
441441
PyAPI_FUNC(int) PyObject_GenericSetAttr(PyObject *,
442442
PyObject *, PyObject *);
443-
PyAPI_FUNC(long) PyObject_Hash(PyObject *);
444-
PyAPI_FUNC(long) PyObject_HashNotImplemented(PyObject *);
443+
PyAPI_FUNC(Py_hash_t) PyObject_Hash(PyObject *);
444+
PyAPI_FUNC(Py_hash_t) PyObject_HashNotImplemented(PyObject *);
445445
PyAPI_FUNC(int) PyObject_IsTrue(PyObject *);
446446
PyAPI_FUNC(int) PyObject_Not(PyObject *);
447447
PyAPI_FUNC(int) PyCallable_Check(PyObject *);
@@ -470,8 +470,8 @@ PyAPI_FUNC(int) Py_ReprEnter(PyObject *);
470470
PyAPI_FUNC(void) Py_ReprLeave(PyObject *);
471471

472472
/* Helpers for hash functions */
473-
PyAPI_FUNC(long) _Py_HashDouble(double);
474-
PyAPI_FUNC(long) _Py_HashPointer(void*);
473+
PyAPI_FUNC(Py_hash_t) _Py_HashDouble(double);
474+
PyAPI_FUNC(Py_hash_t) _Py_HashPointer(void*);
475475

476476
/* Helper for passing objects to printf and the like */
477477
#define PyObject_REPR(obj) _PyUnicode_AsString(PyObject_Repr(obj))

‎Include/pyport.h

Copy file name to clipboardExpand all lines: Include/pyport.h
+4-1Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ Used in: PY_LONG_LONG
130130
_PyHash_Double in Objects/object.c. Numeric hashes are based on
131131
reduction modulo the prime 2**_PyHASH_BITS - 1. */
132132

133-
#if SIZEOF_LONG >= 8
133+
#if SIZEOF_VOID_P >= 8
134134
#define _PyHASH_BITS 61
135135
#else
136136
#define _PyHASH_BITS 31
@@ -177,6 +177,9 @@ typedef Py_intptr_t Py_ssize_t;
177177
# error "Python needs a typedef for Py_ssize_t in pyport.h."
178178
#endif
179179

180+
/* Py_hash_t is the same size as a pointer. */
181+
typedef Py_ssize_t Py_hash_t;
182+
180183
/* Largest possible value of size_t.
181184
SIZE_MAX is part of C99, so it might be defined on some
182185
platforms. If it is not defined, (size_t)-1 is a portable

‎Include/setobject.h

Copy file name to clipboardExpand all lines: Include/setobject.h
+5-8Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,8 @@ no meaning otherwise.
2222
#define PySet_MINSIZE 8
2323

2424
typedef struct {
25-
/* Cached hash code of the key. Note that hash codes are C longs.
26-
* We have to use Py_ssize_t instead because set_pop() abuses
27-
* the hash field to hold a search finger.
28-
*/
29-
Py_ssize_t hash;
25+
/* Cached hash code of the key. */
26+
Py_hash_t hash;
3027
PyObject *key;
3128
} setentry;
3229

@@ -53,10 +50,10 @@ struct _setobject {
5350
* saves repeated runtime null-tests.
5451
*/
5552
setentry *table;
56-
setentry *(*lookup)(PySetObject *so, PyObject *key, long hash);
53+
setentry *(*lookup)(PySetObject *so, PyObject *key, Py_hash_t hash);
5754
setentry smalltable[PySet_MINSIZE];
5855

59-
long hash; /* only used by frozenset objects */
56+
Py_hash_t hash; /* only used by frozenset objects */
6057
PyObject *weakreflist; /* List of weak references */
6158
};
6259

@@ -93,7 +90,7 @@ PyAPI_FUNC(int) PySet_Clear(PyObject *set);
9390
PyAPI_FUNC(int) PySet_Contains(PyObject *anyset, PyObject *key);
9491
PyAPI_FUNC(int) PySet_Discard(PyObject *set, PyObject *key);
9592
PyAPI_FUNC(int) PySet_Add(PyObject *set, PyObject *key);
96-
PyAPI_FUNC(int) _PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, long *hash);
93+
PyAPI_FUNC(int) _PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash);
9794
PyAPI_FUNC(PyObject *) PySet_Pop(PyObject *set);
9895
PyAPI_FUNC(int) _PySet_Update(PyObject *set, PyObject *iterable);
9996

‎Include/unicodeobject.h

Copy file name to clipboardExpand all lines: Include/unicodeobject.h
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ typedef struct {
372372
PyObject_HEAD
373373
Py_ssize_t length; /* Length of raw Unicode data in buffer */
374374
Py_UNICODE *str; /* Raw Unicode buffer */
375-
long hash; /* Hash value; -1 if not set */
375+
Py_hash_t hash; /* Hash value; -1 if not set */
376376
int state; /* != 0 if interned. In this case the two
377377
* references from the dictionary to this object
378378
* are *not* counted in ob_refcnt. */

‎Include/weakrefobject.h

Copy file name to clipboardExpand all lines: Include/weakrefobject.h
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ struct _PyWeakReference {
2727
/* A cache for wr_object's hash code. As usual for hashes, this is -1
2828
* if the hash code isn't known yet.
2929
*/
30-
long hash;
30+
Py_hash_t hash;
3131

3232
/* If wr_object is weakly referenced, wr_object has a doubly-linked NULL-
3333
* terminated list of weak references to it. These are the list pointers.

‎Misc/NEWS

Copy file name to clipboardExpand all lines: Misc/NEWS
+6Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,12 @@ Extensions
9393

9494
- The Unicode database was updated to 6.0.0.
9595

96+
C-API
97+
-----
98+
99+
- Issue #9778: Hash values are now always the size of pointers. A new Py_hash_t
100+
type has been introduced.
101+
96102
Tools/Demos
97103
-----------
98104

‎Modules/_datetimemodule.c

Copy file name to clipboardExpand all lines: Modules/_datetimemodule.c
+7-7Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1843,7 +1843,7 @@ delta_richcompare(PyObject *self, PyObject *other, int op)
18431843

18441844
static PyObject *delta_getstate(PyDateTime_Delta *self);
18451845

1846-
static long
1846+
static Py_hash_t
18471847
delta_hash(PyDateTime_Delta *self)
18481848
{
18491849
if (self->hashcode == -1) {
@@ -2777,11 +2777,11 @@ date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
27772777
/*
27782778
Borrowed from stringobject.c, originally it was string_hash()
27792779
*/
2780-
static long
2780+
static Py_hash_t
27812781
generic_hash(unsigned char *data, int len)
27822782
{
27832783
register unsigned char *p;
2784-
register long x;
2784+
register Py_hash_t x;
27852785

27862786
p = (unsigned char *) data;
27872787
x = *p << 7;
@@ -2797,7 +2797,7 @@ generic_hash(unsigned char *data, int len)
27972797

27982798
static PyObject *date_getstate(PyDateTime_Date *self);
27992799

2800-
static long
2800+
static Py_hash_t
28012801
date_hash(PyDateTime_Date *self)
28022802
{
28032803
if (self->hashcode == -1)
@@ -3246,7 +3246,7 @@ timezone_richcompare(PyDateTime_TimeZone *self,
32463246
return delta_richcompare(self->offset, other->offset, op);
32473247
}
32483248

3249-
static long
3249+
static Py_hash_t
32503250
timezone_hash(PyDateTime_TimeZone *self)
32513251
{
32523252
return delta_hash((PyDateTime_Delta *)self->offset);
@@ -3751,7 +3751,7 @@ time_richcompare(PyObject *self, PyObject *other, int op)
37513751
return result;
37523752
}
37533753

3754-
static long
3754+
static Py_hash_t
37553755
time_hash(PyDateTime_Time *self)
37563756
{
37573757
if (self->hashcode == -1) {
@@ -4640,7 +4640,7 @@ datetime_richcompare(PyObject *self, PyObject *other, int op)
46404640
return result;
46414641
}
46424642

4643-
static long
4643+
static Py_hash_t
46444644
datetime_hash(PyDateTime_DateTime *self)
46454645
{
46464646
if (self->hashcode == -1) {

‎Modules/_pickle.c

Copy file name to clipboardExpand all lines: Modules/_pickle.c
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,7 @@ _PyMemoTable_Lookup(PyMemoTable *self, PyObject *key)
486486
size_t mask = (size_t)self->mt_mask;
487487
PyMemoEntry *table = self->mt_table;
488488
PyMemoEntry *entry;
489-
long hash = (long)key >> 3;
489+
Py_hash_t hash = (Py_hash_t)key >> 3;
490490

491491
i = hash & mask;
492492
entry = &table[i];

‎Objects/bytesobject.c

Copy file name to clipboardExpand all lines: Objects/bytesobject.c
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -868,12 +868,12 @@ bytes_richcompare(PyBytesObject *a, PyBytesObject *b, int op)
868868
return result;
869869
}
870870

871-
static long
871+
static Py_hash_t
872872
bytes_hash(PyBytesObject *a)
873873
{
874874
register Py_ssize_t len;
875875
register unsigned char *p;
876-
register long x;
876+
register Py_hash_t x;
877877

878878
if (a->ob_shash != -1)
879879
return a->ob_shash;

‎Objects/classobject.c

Copy file name to clipboardExpand all lines: Objects/classobject.c
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,10 +263,10 @@ method_repr(PyMethodObject *a)
263263
return result;
264264
}
265265

266-
static long
266+
static Py_hash_t
267267
method_hash(PyMethodObject *a)
268268
{
269-
long x, y;
269+
Py_hash_t x, y;
270270
if (a->im_self == NULL)
271271
x = PyObject_Hash(Py_None);
272272
else

‎Objects/codeobject.c

Copy file name to clipboardExpand all lines: Objects/codeobject.c
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -417,10 +417,10 @@ code_richcompare(PyObject *self, PyObject *other, int op)
417417
return res;
418418
}
419419

420-
static long
420+
static Py_hash_t
421421
code_hash(PyCodeObject *co)
422422
{
423-
long h, h0, h1, h2, h3, h4, h5, h6;
423+
Py_hash_t h, h0, h1, h2, h3, h4, h5, h6;
424424
h0 = PyObject_Hash(co->co_name);
425425
if (h0 == -1) return -1;
426426
h1 = PyObject_Hash(co->co_code);

‎Objects/complexobject.c

Copy file name to clipboardExpand all lines: Objects/complexobject.c
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ complex_repr(PyComplexObject *v)
394394
return complex_format(v, 0, 'r');
395395
}
396396

397-
static long
397+
static Py_hash_t
398398
complex_hash(PyComplexObject *v)
399399
{
400400
unsigned long hashreal, hashimag, combined;
@@ -413,7 +413,7 @@ complex_hash(PyComplexObject *v)
413413
combined = hashreal + _PyHASH_IMAG * hashimag;
414414
if (combined == (unsigned long)-1)
415415
combined = (unsigned long)-2;
416-
return (long)combined;
416+
return (Py_hash_t)combined;
417417
}
418418

419419
/* This macro may return! */

‎Objects/descrobject.c

Copy file name to clipboardExpand all lines: Objects/descrobject.c
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -916,10 +916,10 @@ wrapper_richcompare(PyObject *a, PyObject *b, int op)
916916
return v;
917917
}
918918

919-
static long
919+
static Py_hash_t
920920
wrapper_hash(wrapperobject *wp)
921921
{
922-
int x, y;
922+
Py_hash_t x, y;
923923
x = _Py_HashPointer(wp->descr);
924924
if (x == -1)
925925
return -1;

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.