/////////////// GetItemInt.proto ///////////////
+#define __Pyx_GetItemInt(o, i, size, to_py_func, is_list, wraparound, boundscheck) \
+ (((size) <= sizeof(Py_ssize_t)) ? \
+ __Pyx_GetItemInt_Fast(o, i, is_list, wraparound, boundscheck) : \
+ __Pyx_GetItemInt_Generic(o, to_py_func(i)))
+
+{{for type in ['List', 'Tuple']}}
+#define __Pyx_GetItemInt_{{type}}(o, i, size, to_py_func, is_list, wraparound, boundscheck) \
+ (((size) <= sizeof(Py_ssize_t)) ? \
+ __Pyx_GetItemInt_{{type}}_Fast(o, i, wraparound, boundscheck) : \
+ __Pyx_GetItemInt_Generic(o, to_py_func(i)))
+
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_{{type}}_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck);
+{{endfor}}
+
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j);
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
+ int is_list, int wraparound, int boundscheck);
+
+/////////////// GetItemInt ///////////////
+
static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
PyObject *r;
if (!j) return NULL;
}
{{for type in ['List', 'Tuple']}}
-#define __Pyx_GetItemInt_{{type}}(o, i, size, to_py_func, is_list, wraparound, boundscheck) \
- (((size) <= sizeof(Py_ssize_t)) ? \
- __Pyx_GetItemInt_{{type}}_Fast(o, i, wraparound, boundscheck) : \
- __Pyx_GetItemInt_Generic(o, to_py_func(i)))
-
static CYTHON_INLINE PyObject *__Pyx_GetItemInt_{{type}}_Fast(PyObject *o, Py_ssize_t i,
int wraparound, int boundscheck) {
#if CYTHON_COMPILING_IN_CPYTHON
}
{{endfor}}
-#define __Pyx_GetItemInt(o, i, size, to_py_func, is_list, wraparound, boundscheck) \
- (((size) <= sizeof(Py_ssize_t)) ? \
- __Pyx_GetItemInt_Fast(o, i, is_list, wraparound, boundscheck) : \
- __Pyx_GetItemInt_Generic(o, to_py_func(i)))
-
static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
int is_list, int wraparound, int boundscheck) {
#if CYTHON_COMPILING_IN_CPYTHON
Py_INCREF(r);
return r;
}
- } else { /* inlined PySequence_GetItem() */
+ } else { /* inlined PySequence_GetItem() + special cased length overflow */
PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
if (likely(m && m->sq_item)) {
if (wraparound && unlikely(i < 0) && likely(m->sq_length)) {
Py_ssize_t l = m->sq_length(o);
- if (unlikely(l < 0)) return NULL;
- i += l;
+ if (likely(l >= 0)) {
+ i += l;
+ } else {
+ // if length > max(Py_ssize_t), maybe the object can wrap around itself?
+ if (PyErr_ExceptionMatches(PyExc_OverflowError))
+ PyErr_Clear();
+ else
+ return NULL;
+ }
}
return m->sq_item(o, i);
}
if sys.version_info < (2,5):
__doc__ = __doc__.replace(u"'int' object ...", u'unsubscriptable object')
+cdef Py_ssize_t maxsize = getattr(sys, 'maxsize', getattr(sys, 'maxint', None))
+py_maxsize = maxsize
+
import cython
def index_tuple(tuple t, int i):
True
"""
return o[1000000000000000000000000000000]
+
+
+class LargeIndexable(object):
+ def __len__(self):
+ raise OverflowError
+
+ def __getitem__(self, index):
+ return index
+
+
+def test_large_indexing(obj):
+ """
+ >>> obj = LargeIndexable()
+ >>> zero, pone, none, pmaxsize, nmaxsize = test_large_indexing(obj)
+ >>> # , p2maxsize, n2maxsize
+ >>> zero
+ 0
+ >>> pone
+ 1
+ >>> none
+ -1
+ >>> pmaxsize == py_maxsize
+ True
+ >>> nmaxsize == -py_maxsize
+ True
+
+ #>>> p2maxsize == py_maxsize*2
+ #True
+ #>>> n2maxsize == -py_maxsize*2
+ #True
+ """
+ return (
+ obj[0], obj[1], obj[-1],
+ obj[maxsize], obj[-maxsize],
+ #obj[maxsize*2], obj[-maxsize*2] # FIXME!
+ )