@@ -628,6 +628,42 @@ slice_traverse(PySliceObject *v, visitproc visit, void *arg)
628628 return 0 ;
629629}
630630
631+ /* code based on tuplehash() of Objects/tupleobject.c */
632+ #if SIZEOF_PY_UHASH_T > 4
633+ #define _PyHASH_XXPRIME_1 ((Py_uhash_t)11400714785074694791ULL)
634+ #define _PyHASH_XXPRIME_2 ((Py_uhash_t)14029467366897019727ULL)
635+ #define _PyHASH_XXPRIME_5 ((Py_uhash_t)2870177450012600261ULL)
636+ #define _PyHASH_XXROTATE (x ) ((x << 31) | (x >> 33)) /* Rotate left 31 bits */
637+ #else
638+ #define _PyHASH_XXPRIME_1 ((Py_uhash_t)2654435761UL)
639+ #define _PyHASH_XXPRIME_2 ((Py_uhash_t)2246822519UL)
640+ #define _PyHASH_XXPRIME_5 ((Py_uhash_t)374761393UL)
641+ #define _PyHASH_XXROTATE (x ) ((x << 13) | (x >> 19)) /* Rotate left 13 bits */
642+ #endif
643+
644+ static Py_hash_t
645+ slicehash (PySliceObject * v )
646+ {
647+ Py_uhash_t acc = _PyHASH_XXPRIME_5 ;
648+ #define _PyHASH_SLICE_PART (com ) { \
649+ Py_uhash_t lane = PyObject_Hash(v->com); \
650+ if(lane == (Py_uhash_t)-1) { \
651+ return -1; \
652+ } \
653+ acc += lane * _PyHASH_XXPRIME_2; \
654+ acc = _PyHASH_XXROTATE(acc); \
655+ acc *= _PyHASH_XXPRIME_1; \
656+ }
657+ _PyHASH_SLICE_PART (start );
658+ _PyHASH_SLICE_PART (stop );
659+ _PyHASH_SLICE_PART (step );
660+ #undef _PyHASH_SLICE_PART
661+ if (acc == (Py_uhash_t )- 1 ) {
662+ return 1546275796 ;
663+ }
664+ return acc ;
665+ }
666+
631667PyTypeObject PySlice_Type = {
632668 PyVarObject_HEAD_INIT (& PyType_Type , 0 )
633669 "slice" , /* Name of this type */
@@ -642,7 +678,7 @@ PyTypeObject PySlice_Type = {
642678 0 , /* tp_as_number */
643679 0 , /* tp_as_sequence */
644680 0 , /* tp_as_mapping */
645- PyObject_HashNotImplemented , /* tp_hash */
681+ ( hashfunc ) slicehash , /* tp_hash */
646682 0 , /* tp_call */
647683 0 , /* tp_str */
648684 PyObject_GenericGetAttr , /* tp_getattro */
0 commit comments