@@ -8228,6 +8228,40 @@ _shuffle_bits(Py_uhash_t h)
82288228 return ((h ^ 89869747UL ) ^ (h << 16 )) * 3644798167UL ;
82298229}
82308230
8231+ // Compute hash((key, value)).
8232+ // Code copied from tuple_hash().
8233+ static Py_hash_t
8234+ frozendict_pair_hash (PyObject * key , PyObject * value )
8235+ {
8236+ Py_ssize_t len = 2 ;
8237+ Py_uhash_t acc = _PyTuple_HASH_XXPRIME_5 ;
8238+
8239+ Py_uhash_t lane = PyObject_Hash (key );
8240+ if (lane == (Py_uhash_t )- 1 ) {
8241+ return -1 ;
8242+ }
8243+ acc += lane * _PyTuple_HASH_XXPRIME_2 ;
8244+ acc = _PyTuple_HASH_XXROTATE (acc );
8245+ acc *= _PyTuple_HASH_XXPRIME_1 ;
8246+
8247+ lane = PyObject_Hash (value );
8248+ if (lane == (Py_uhash_t )- 1 ) {
8249+ return -1 ;
8250+ }
8251+ acc += lane * _PyTuple_HASH_XXPRIME_2 ;
8252+ acc = _PyTuple_HASH_XXROTATE (acc );
8253+ acc *= _PyTuple_HASH_XXPRIME_1 ;
8254+
8255+ /* Add input length, mangled to keep the historical value of hash(()). */
8256+ acc += len ^ (_PyTuple_HASH_XXPRIME_5 ^ 3527539UL );
8257+
8258+ if (acc == (Py_uhash_t )- 1 ) {
8259+ acc = 1546275796 ;
8260+ }
8261+ return acc ;
8262+ }
8263+
8264+
82318265// Code copied from frozenset_hash()
82328266static Py_hash_t
82338267frozendict_hash (PyObject * op )
@@ -8244,17 +8278,11 @@ frozendict_hash(PyObject *op)
82448278 PyObject * key , * value ; // borrowed refs
82458279 Py_ssize_t pos = 0 ;
82468280 while (PyDict_Next (op , & pos , & key , & value )) {
8247- Py_hash_t key_hash = PyObject_Hash (key );
8248- if (key_hash == -1 ) {
8249- return -1 ;
8250- }
8251- hash ^= _shuffle_bits (key_hash );
8252-
8253- Py_hash_t value_hash = PyObject_Hash (value );
8254- if (value_hash == -1 ) {
8281+ Py_hash_t pair_hash = frozendict_pair_hash (key , value );
8282+ if (pair_hash == -1 ) {
82558283 return -1 ;
82568284 }
8257- hash ^= _shuffle_bits (value_hash );
8285+ hash ^= _shuffle_bits (pair_hash );
82588286 }
82598287
82608288 /* Factor in the number of active entries */
0 commit comments