Mercurial > cpython-lru_cache-weakref
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; }
