gh-111389: replace deprecated occurrences of _PyHASH_* macros (#141236)

This commit is contained in:
Bénédikt Tran 2025-11-09 15:14:08 +01:00 committed by GitHub
parent 3ce2d57b2f
commit ae1f435071
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 41 additions and 41 deletions

View file

@ -7,7 +7,7 @@
/* Parameters used for the numeric hash implementation. See notes for /* Parameters used for the numeric hash implementation. See notes for
_Py_HashDouble in Python/pyhash.c. Numeric hashes are based on _Py_HashDouble in Python/pyhash.c. Numeric hashes are based on
reduction modulo the prime 2**_PyHASH_BITS - 1. */ reduction modulo the prime 2**PyHASH_BITS - 1. */
#if SIZEOF_VOID_P >= 8 #if SIZEOF_VOID_P >= 8
# define PyHASH_BITS 61 # define PyHASH_BITS 61
@ -15,7 +15,7 @@
# define PyHASH_BITS 31 # define PyHASH_BITS 31
#endif #endif
#define PyHASH_MODULUS (((size_t)1 << _PyHASH_BITS) - 1) #define PyHASH_MODULUS (((size_t)1 << PyHASH_BITS) - 1)
#define PyHASH_INF 314159 #define PyHASH_INF 314159
#define PyHASH_IMAG PyHASH_MULTIPLIER #define PyHASH_IMAG PyHASH_MULTIPLIER

View file

@ -5799,7 +5799,7 @@ _decimal_Decimal___floor___impl(PyObject *self, PyTypeObject *cls)
static Py_hash_t static Py_hash_t
_dec_hash(PyDecObject *v) _dec_hash(PyDecObject *v)
{ {
#if defined(CONFIG_64) && _PyHASH_BITS == 61 #if defined(CONFIG_64) && PyHASH_BITS == 61
/* 2**61 - 1 */ /* 2**61 - 1 */
mpd_uint_t p_data[1] = {2305843009213693951ULL}; mpd_uint_t p_data[1] = {2305843009213693951ULL};
mpd_t p = {MPD_POS|MPD_STATIC|MPD_CONST_DATA, 0, 19, 1, 1, p_data}; mpd_t p = {MPD_POS|MPD_STATIC|MPD_CONST_DATA, 0, 19, 1, 1, p_data};
@ -5807,7 +5807,7 @@ _dec_hash(PyDecObject *v)
mpd_uint_t inv10_p_data[1] = {2075258708292324556ULL}; mpd_uint_t inv10_p_data[1] = {2075258708292324556ULL};
mpd_t inv10_p = {MPD_POS|MPD_STATIC|MPD_CONST_DATA, mpd_t inv10_p = {MPD_POS|MPD_STATIC|MPD_CONST_DATA,
0, 19, 1, 1, inv10_p_data}; 0, 19, 1, 1, inv10_p_data};
#elif defined(CONFIG_32) && _PyHASH_BITS == 31 #elif defined(CONFIG_32) && PyHASH_BITS == 31
/* 2**31 - 1 */ /* 2**31 - 1 */
mpd_uint_t p_data[2] = {147483647UL, 2}; mpd_uint_t p_data[2] = {147483647UL, 2};
mpd_t p = {MPD_POS|MPD_STATIC|MPD_CONST_DATA, 0, 10, 2, 2, p_data}; mpd_t p = {MPD_POS|MPD_STATIC|MPD_CONST_DATA, 0, 10, 2, 2, p_data};
@ -5816,7 +5816,7 @@ _dec_hash(PyDecObject *v)
mpd_t inv10_p = {MPD_POS|MPD_STATIC|MPD_CONST_DATA, mpd_t inv10_p = {MPD_POS|MPD_STATIC|MPD_CONST_DATA,
0, 10, 2, 2, inv10_p_data}; 0, 10, 2, 2, inv10_p_data};
#else #else
#error "No valid combination of CONFIG_64, CONFIG_32 and _PyHASH_BITS" #error "No valid combination of CONFIG_64, CONFIG_32 and PyHASH_BITS"
#endif #endif
const Py_hash_t py_hash_inf = 314159; const Py_hash_t py_hash_inf = 314159;
mpd_uint_t ten_data[1] = {10}; mpd_uint_t ten_data[1] = {10};

View file

@ -644,7 +644,7 @@ complex_hash(PyObject *op)
* compare equal must have the same hash value, so that * compare equal must have the same hash value, so that
* hash(x + 0*j) must equal hash(x). * hash(x + 0*j) must equal hash(x).
*/ */
combined = hashreal + _PyHASH_IMAG * hashimag; combined = hashreal + PyHASH_IMAG * hashimag;
if (combined == (Py_uhash_t)-1) if (combined == (Py_uhash_t)-1)
combined = (Py_uhash_t)-2; combined = (Py_uhash_t)-2;
return (Py_hash_t)combined; return (Py_hash_t)combined;

View file

@ -3703,36 +3703,36 @@ long_hash(PyObject *obj)
#endif #endif
while (--i >= 0) { while (--i >= 0) {
/* Here x is a quantity in the range [0, _PyHASH_MODULUS); we /* Here x is a quantity in the range [0, PyHASH_MODULUS); we
want to compute x * 2**PyLong_SHIFT + v->long_value.ob_digit[i] modulo want to compute x * 2**PyLong_SHIFT + v->long_value.ob_digit[i] modulo
_PyHASH_MODULUS. PyHASH_MODULUS.
The computation of x * 2**PyLong_SHIFT % _PyHASH_MODULUS The computation of x * 2**PyLong_SHIFT % PyHASH_MODULUS
amounts to a rotation of the bits of x. To see this, write amounts to a rotation of the bits of x. To see this, write
x * 2**PyLong_SHIFT = y * 2**_PyHASH_BITS + z x * 2**PyLong_SHIFT = y * 2**PyHASH_BITS + z
where y = x >> (_PyHASH_BITS - PyLong_SHIFT) gives the top where y = x >> (PyHASH_BITS - PyLong_SHIFT) gives the top
PyLong_SHIFT bits of x (those that are shifted out of the PyLong_SHIFT bits of x (those that are shifted out of the
original _PyHASH_BITS bits, and z = (x << PyLong_SHIFT) & original PyHASH_BITS bits, and z = (x << PyLong_SHIFT) &
_PyHASH_MODULUS gives the bottom _PyHASH_BITS - PyLong_SHIFT PyHASH_MODULUS gives the bottom PyHASH_BITS - PyLong_SHIFT
bits of x, shifted up. Then since 2**_PyHASH_BITS is bits of x, shifted up. Then since 2**PyHASH_BITS is
congruent to 1 modulo _PyHASH_MODULUS, y*2**_PyHASH_BITS is congruent to 1 modulo PyHASH_MODULUS, y*2**PyHASH_BITS is
congruent to y modulo _PyHASH_MODULUS. So congruent to y modulo PyHASH_MODULUS. So
x * 2**PyLong_SHIFT = y + z (mod _PyHASH_MODULUS). x * 2**PyLong_SHIFT = y + z (mod PyHASH_MODULUS).
The right-hand side is just the result of rotating the The right-hand side is just the result of rotating the
_PyHASH_BITS bits of x left by PyLong_SHIFT places; since PyHASH_BITS bits of x left by PyLong_SHIFT places; since
not all _PyHASH_BITS bits of x are 1s, the same is true not all PyHASH_BITS bits of x are 1s, the same is true
after rotation, so 0 <= y+z < _PyHASH_MODULUS and y + z is after rotation, so 0 <= y+z < PyHASH_MODULUS and y + z is
the reduction of x*2**PyLong_SHIFT modulo the reduction of x*2**PyLong_SHIFT modulo
_PyHASH_MODULUS. */ PyHASH_MODULUS. */
x = ((x << PyLong_SHIFT) & _PyHASH_MODULUS) | x = ((x << PyLong_SHIFT) & PyHASH_MODULUS) |
(x >> (_PyHASH_BITS - PyLong_SHIFT)); (x >> (PyHASH_BITS - PyLong_SHIFT));
x += v->long_value.ob_digit[i]; x += v->long_value.ob_digit[i];
if (x >= _PyHASH_MODULUS) if (x >= PyHASH_MODULUS)
x -= _PyHASH_MODULUS; x -= PyHASH_MODULUS;
} }
x = x * sign; x = x * sign;
if (x == (Py_uhash_t)-1) if (x == (Py_uhash_t)-1)

View file

@ -29,7 +29,7 @@ static Py_ssize_t hashstats[Py_HASH_STATS_MAX + 1] = {0};
#endif #endif
/* For numeric types, the hash of a number x is based on the reduction /* For numeric types, the hash of a number x is based on the reduction
of x modulo the prime P = 2**_PyHASH_BITS - 1. It's designed so that of x modulo the prime P = 2**PyHASH_BITS - 1. It's designed so that
hash(x) == hash(y) whenever x and y are numerically equal, even if hash(x) == hash(y) whenever x and y are numerically equal, even if
x and y have different types. x and y have different types.
@ -52,8 +52,8 @@ static Py_ssize_t hashstats[Py_HASH_STATS_MAX + 1] = {0};
If the result of the reduction is infinity (this is impossible for If the result of the reduction is infinity (this is impossible for
integers, floats and Decimals) then use the predefined hash value integers, floats and Decimals) then use the predefined hash value
_PyHASH_INF for x >= 0, or -_PyHASH_INF for x < 0, instead. PyHASH_INF for x >= 0, or -PyHASH_INF for x < 0, instead.
_PyHASH_INF and -_PyHASH_INF are also used for the PyHASH_INF and -PyHASH_INF are also used for the
hashes of float and Decimal infinities. hashes of float and Decimal infinities.
NaNs hash with a pointer hash. Having distinct hash values prevents NaNs hash with a pointer hash. Having distinct hash values prevents
@ -65,16 +65,16 @@ static Py_ssize_t hashstats[Py_HASH_STATS_MAX + 1] = {0};
efficiently, even if the exponent of the binary or decimal number efficiently, even if the exponent of the binary or decimal number
is large. The key point is that is large. The key point is that
reduce(x * y) == reduce(x) * reduce(y) (modulo _PyHASH_MODULUS) reduce(x * y) == reduce(x) * reduce(y) (modulo PyHASH_MODULUS)
provided that {reduce(x), reduce(y)} != {0, infinity}. The reduction of a provided that {reduce(x), reduce(y)} != {0, infinity}. The reduction of a
binary or decimal float is never infinity, since the denominator is a power binary or decimal float is never infinity, since the denominator is a power
of 2 (for binary) or a divisor of a power of 10 (for decimal). So we have, of 2 (for binary) or a divisor of a power of 10 (for decimal). So we have,
for nonnegative x, for nonnegative x,
reduce(x * 2**e) == reduce(x) * reduce(2**e) % _PyHASH_MODULUS reduce(x * 2**e) == reduce(x) * reduce(2**e) % PyHASH_MODULUS
reduce(x * 10**e) == reduce(x) * reduce(10**e) % _PyHASH_MODULUS reduce(x * 10**e) == reduce(x) * reduce(10**e) % PyHASH_MODULUS
and reduce(10**e) can be computed efficiently by the usual modular and reduce(10**e) can be computed efficiently by the usual modular
exponentiation algorithm. For reduce(2**e) it's even better: since exponentiation algorithm. For reduce(2**e) it's even better: since
@ -92,7 +92,7 @@ _Py_HashDouble(PyObject *inst, double v)
if (!isfinite(v)) { if (!isfinite(v)) {
if (isinf(v)) if (isinf(v))
return v > 0 ? _PyHASH_INF : -_PyHASH_INF; return v > 0 ? PyHASH_INF : -PyHASH_INF;
else else
return PyObject_GenericHash(inst); return PyObject_GenericHash(inst);
} }
@ -109,19 +109,19 @@ _Py_HashDouble(PyObject *inst, double v)
and hexadecimal floating point. */ and hexadecimal floating point. */
x = 0; x = 0;
while (m) { while (m) {
x = ((x << 28) & _PyHASH_MODULUS) | x >> (_PyHASH_BITS - 28); x = ((x << 28) & PyHASH_MODULUS) | x >> (PyHASH_BITS - 28);
m *= 268435456.0; /* 2**28 */ m *= 268435456.0; /* 2**28 */
e -= 28; e -= 28;
y = (Py_uhash_t)m; /* pull out integer part */ y = (Py_uhash_t)m; /* pull out integer part */
m -= y; m -= y;
x += y; x += y;
if (x >= _PyHASH_MODULUS) if (x >= PyHASH_MODULUS)
x -= _PyHASH_MODULUS; x -= PyHASH_MODULUS;
} }
/* adjust for the exponent; first reduce it modulo _PyHASH_BITS */ /* adjust for the exponent; first reduce it modulo PyHASH_BITS */
e = e >= 0 ? e % _PyHASH_BITS : _PyHASH_BITS-1-((-1-e) % _PyHASH_BITS); e = e >= 0 ? e % PyHASH_BITS : PyHASH_BITS-1-((-1-e) % PyHASH_BITS);
x = ((x << e) & _PyHASH_MODULUS) | x >> (_PyHASH_BITS - e); x = ((x << e) & PyHASH_MODULUS) | x >> (PyHASH_BITS - e);
x = x * sign; x = x * sign;
if (x == (Py_uhash_t)-1) if (x == (Py_uhash_t)-1)

View file

@ -1587,10 +1587,10 @@ get_hash_info(PyThreadState *tstate)
} while(0) } while(0)
SET_HASH_INFO_ITEM(PyLong_FromLong(8 * sizeof(Py_hash_t))); SET_HASH_INFO_ITEM(PyLong_FromLong(8 * sizeof(Py_hash_t)));
SET_HASH_INFO_ITEM(PyLong_FromSsize_t(_PyHASH_MODULUS)); SET_HASH_INFO_ITEM(PyLong_FromSsize_t(PyHASH_MODULUS));
SET_HASH_INFO_ITEM(PyLong_FromLong(_PyHASH_INF)); SET_HASH_INFO_ITEM(PyLong_FromLong(PyHASH_INF));
SET_HASH_INFO_ITEM(PyLong_FromLong(0)); // This is no longer used SET_HASH_INFO_ITEM(PyLong_FromLong(0)); // This is no longer used
SET_HASH_INFO_ITEM(PyLong_FromLong(_PyHASH_IMAG)); SET_HASH_INFO_ITEM(PyLong_FromLong(PyHASH_IMAG));
SET_HASH_INFO_ITEM(PyUnicode_FromString(hashfunc->name)); SET_HASH_INFO_ITEM(PyUnicode_FromString(hashfunc->name));
SET_HASH_INFO_ITEM(PyLong_FromLong(hashfunc->hash_bits)); SET_HASH_INFO_ITEM(PyLong_FromLong(hashfunc->hash_bits));
SET_HASH_INFO_ITEM(PyLong_FromLong(hashfunc->seed_bits)); SET_HASH_INFO_ITEM(PyLong_FromLong(hashfunc->seed_bits));