@@ -862,11 +862,44 @@ bool CPySet_Remove(PyObject *set, PyObject *key);
862862
863863// Tuple operations
864864
865-
866- PyObject * CPySequenceTuple_GetItem (PyObject * tuple , CPyTagged index );
867865PyObject * CPySequenceTuple_GetSlice (PyObject * obj , CPyTagged start , CPyTagged end );
868- PyObject * CPySequenceTuple_GetItemUnsafe (PyObject * tuple , Py_ssize_t index );
869- void CPySequenceTuple_SetItemUnsafe (PyObject * tuple , Py_ssize_t index , PyObject * value );
866+
867+ static inline bool CPySequenceTuple_IsValidIndex (Py_ssize_t n , Py_ssize_t size ) {
868+ return (0 <= n && n < size ) || (- size <= n && n < 0 );
869+ }
870+
871+ static inline PyObject * CPySequenceTuple_GetItem (PyObject * tuple , CPyTagged index )
872+ {
873+ if (likely (CPyTagged_CheckShort (index ))) {
874+ Py_ssize_t n = CPyTagged_ShortAsSsize_t (index );
875+ Py_ssize_t size = PyTuple_GET_SIZE (tuple );
876+ if (unlikely (!CPySequenceTuple_IsValidIndex (n , size )))
877+ {
878+ PyErr_SetString (PyExc_IndexError , "tuple index out of range" );
879+ return NULL ;
880+ }
881+ if (n < 0 )
882+ n += size ;
883+ PyObject * result = PyTuple_GET_ITEM (tuple , n );
884+ Py_INCREF (result );
885+ return result ;
886+ } else {
887+ PyErr_SetString (PyExc_OverflowError , CPYTHON_LARGE_INT_ERRMSG );
888+ return NULL ;
889+ }
890+ }
891+
892+ static inline PyObject * CPySequenceTuple_GetItemUnsafe (PyObject * tuple , Py_ssize_t index )
893+ {
894+ PyObject * result = PyTuple_GET_ITEM (tuple , index );
895+ Py_INCREF (result );
896+ return result ;
897+ }
898+
899+ static inline void CPySequenceTuple_SetItemUnsafe (PyObject * tuple , Py_ssize_t index , PyObject * value )
900+ {
901+ PyTuple_SET_ITEM (tuple , index , value );
902+ }
870903
871904
872905// Exception operations
0 commit comments