Commit a4768ec2 authored by Christoph Groth's avatar Christoph Groth
Browse files

Merge Stefano's fixes for Python 3.10

parents e6f478e6 f1358fdf
Pipeline #86855 passed with stage
in 1 minute and 28 seconds
......@@ -815,7 +815,7 @@ fail:
// the only documentation for this is in the Python sourcecode
const Py_hash_t HASH_IMAG = _PyHASH_IMAG;
Py_hash_t hash(long x)
Py_hash_t hash(void *inst, long x)
{
// For integers the hash is just the integer itself modulo _PyHASH_MODULUS
// except for the singular case of -1.
......@@ -834,24 +834,30 @@ typedef long Py_hash_t;
typedef unsigned long Py_uhash_t;
const Py_hash_t HASH_IMAG = 1000003L;
Py_hash_t hash(long x)
Py_hash_t hash(void *inst, long x)
{
return x != -1 ? x : -2;
}
#endif
Py_hash_t hash(double x)
// We used to have our own implementation of this, but the extra function
// call is quite negligible compared to the execution time of the function.
#if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 10
Py_hash_t hash(void *inst, double x)
{
return _Py_HashDouble((PyObject *)inst, x);
#else
Py_hash_t hash(void *, double x)
{
// We used to have our own implementation of this, but the extra function
// call is quite negligible compared to the execution time of the function.
return _Py_HashDouble(x);
#endif
}
Py_hash_t hash(Complex x)
Py_hash_t hash(void *inst, Complex x)
{
// x.imag == 0 => hash(x.imag) == 0 => hash(x) == hash(x.real)
return hash(x.real()) + HASH_IMAG * hash(x.imag());
return hash(inst, x.real()) + HASH_IMAG * hash(inst, x.imag());
}
// The following routine calculates the hash of a multi-dimensional array. The
......@@ -875,7 +881,7 @@ Py_hash_t hash(PyObject *obj)
Array<T> *self = reinterpret_cast<Array<T> *>(obj);
self->ndim_shape(&ndim, &shape);
T *p = self->data();
if (ndim == 0) return hash(*p);
if (ndim == 0) return hash(p, *p);
const Py_uhash_t mult_init = 1000003, r_init = 0x345678;
const Py_uhash_t mul_addend = 82520, r_addend = 97531;
......@@ -891,7 +897,8 @@ Py_hash_t hash(PyObject *obj)
--i[d];
if (d == ndim) {
// Innermost loop body.
r[d] = (r[d] ^ hash(*p++)) * mult[d];
r[d] = (r[d] ^ hash(p, *p)) * mult[d];
p++;
mult[d] += mul_addend + 2 * i[d];
} else {
// Entering a loop.
......@@ -958,7 +965,7 @@ Py_hash_t hash(PyObject *obj)
Array<T> *self = reinterpret_cast<Array<T> *>(obj);
self->ndim_shape(&ndim, &shape);
T *p = self->data();
if (ndim == 0) return hash(*p);
if (ndim == 0) return hash(p, *p);
Py_ssize_t i[max_ndim];
Py_uhash_t acc[max_ndim];
......@@ -971,7 +978,8 @@ Py_hash_t hash(PyObject *obj)
if (i[d]) {
--i[d];
if (d == ndim) {
_hash_inner_loop(acc[d], hash(*p++));
_hash_inner_loop(acc[d], hash(p, *p));
p++;
} else {
++d;
i[d] = shape[d];
......
......@@ -323,7 +323,7 @@ def test_hash_equality():
int_bits = (8 * ta.dtype_size[int]) - 1 # 8 bits per byte, minus 1 sign bit
maxint = 2**(int_bits)
special = [float('nan'), float('inf'), float('-inf'),
special = [float('inf'), float('-inf'),
0, -1, -1.0, -1 + 0j,
303, -312424, -0.3, 1.7, 0.4j, -12.3j, 1 - 12.3j, 1.3 - 12.3j,
(), (-1,), (2,),
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment