Description
Description
Small integers hash to themselves, except -1.
Snippet preview
>>> for i in range(-4, 4):
... print(i, hash(i))
...
-4 -4
-3 -3
-2 -2
-1 -2
0 0
1 1
2 2
3 3
Explanation
See https://omairmajid.com/posts/2021-07-16-why-is-hash-in-python/ and https://www.reddit.com/r/Python/comments/oks5km/comment/h5a7ylc/
It's explained by u/ExoticMandibles
on Reddit:
The reference implementation of Python is "CPython", which is almost certainly the Python you're using. CPython is written in C, and unlike Python, C doesn't have exceptions. So, in C, when you design a function, and you want your function to be able to indicate "there was an error", it has to return that error as its return value.
The hash() function in CPython can return an error, so it defines a return code of -1 to mean "there was an error". But this could be confusing if the hash worked correctly, and the actual hash of an object was -1. So the convention is: if hashing worked, and you got a -1, return -2.
There's special code in the hash function for ints ("long objects") in CPython that does exactly that:
https://github.com/python/cpython/blob/main/Objects/longobject.c#L2967
And the mentioned CPython code snippet is:
static Py_hash_t
long_hash(PyObject *obj)
{
Py_uhash_t x;
// ...
if (x == (Py_uhash_t)-1)
x = (Py_uhash_t)-2;
return (Py_hash_t)x;
}
Checklist before calling for maintainers
- Have you checked to ensure there aren't other open Issues for the same update/change?
- Have you checked that this snippet is not similar to any of the existing snippets?
- Have you added an
Explanation
section? It shall include the reasons for changes and why you'd like us to include them