2
>>> index_object(100, 100) # doctest: +ELLIPSIS
3
Traceback (most recent call last):
5
TypeError: 'int' object ...
9
cdef Py_ssize_t maxsize = sys.maxsize
15
def index_tuple(tuple t, int i):
17
(minor PyPy error formatting bug here, hence ELLIPSIS)
19
>>> index_tuple((1,1,2,3,5), 0)
21
>>> index_tuple((1,1,2,3,5), 3)
23
>>> index_tuple((1,1,2,3,5), -1)
25
>>> index_tuple((1,1,2,3,5), 100) # doctest: +ELLIPSIS
26
Traceback (most recent call last):
27
IndexError: ... index out of range
28
>>> index_tuple((1,1,2,3,5), -7) # doctest: +ELLIPSIS
29
Traceback (most recent call last):
30
IndexError: ... index out of range
31
>>> index_tuple(None, 0)
32
Traceback (most recent call last):
33
TypeError: 'NoneType' object is not subscriptable
37
def index_list(list L, int i):
39
>>> index_list([2,3,5,7,11,13,17,19], 0)
41
>>> index_list([2,3,5,7,11,13,17,19], 5)
43
>>> index_list([2,3,5,7,11,13,17,19], -1)
45
>>> index_list([2,3,5,7,11,13,17,19], 100) # doctest: +ELLIPSIS
46
Traceback (most recent call last):
47
IndexError: ... index out of range
48
>>> index_list([2,3,5,7,11,13,17,19], -10) # doctest: +ELLIPSIS
49
Traceback (most recent call last):
50
IndexError: ... index out of range
51
>>> index_list(None, 0)
52
Traceback (most recent call last):
53
TypeError: 'NoneType' object is not subscriptable
57
def index_object(object o, int i):
59
(minor PyPy error formatting bug here, hence ELLIPSIS)
61
>>> index_object([2,3,5,7,11,13,17,19], 1)
63
>>> index_object([2,3,5,7,11,13,17,19], -1)
65
>>> index_object((1,1,2,3,5), 2)
67
>>> index_object((1,1,2,3,5), -2)
69
>>> index_object("abcdef...z", 0)
71
>>> index_object("abcdef...z", -1)
73
>>> index_object("abcdef...z", 100)
74
Traceback (most recent call last):
75
IndexError: string index out of range
76
>>> try: index_object(None, 0)
77
... except TypeError: pass
82
def del_index_list(list L, Py_ssize_t index):
84
>>> del_index_list(list(range(4)), 0)
86
>>> del_index_list(list(range(4)), 1)
88
>>> del_index_list(list(range(4)), -1)
90
>>> del_index_list(list(range(4)), py_maxsize) # doctest: +ELLIPSIS
91
Traceback (most recent call last):
92
IndexError: list... index out of range
93
>>> del_index_list(list(range(4)), -py_maxsize) # doctest: +ELLIPSIS
94
Traceback (most recent call last):
95
IndexError: list... index out of range
101
def set_index_list(list L, Py_ssize_t index):
103
>>> set_index_list(list(range(4)), 0)
105
>>> set_index_list(list(range(4)), 1)
107
>>> set_index_list(list(range(4)), -1)
109
>>> set_index_list(list(range(4)), py_maxsize) # doctest: +ELLIPSIS
110
Traceback (most recent call last):
111
IndexError: list... index out of range
112
>>> set_index_list(list(range(4)), -py_maxsize) # doctest: +ELLIPSIS
113
Traceback (most recent call last):
114
IndexError: list... index out of range
120
# These make sure that our fast indexing works with large and unsigned types.
122
def test_unsigned_long():
124
>>> test_unsigned_long()
127
cdef unsigned long ix
129
for i from 0 <= i < <int>sizeof(unsigned long) * 8:
130
ix = (<unsigned long>1) << i
132
for i from 0 <= i < <int>sizeof(unsigned long) * 8:
133
ix = (<unsigned long>1) << i
138
def test_unsigned_short():
140
>>> test_unsigned_short()
143
cdef unsigned short ix
145
for i from 0 <= i < <int>sizeof(unsigned short) * 8:
146
ix = (<unsigned short>1) << i
148
for i from 0 <= i < <int>sizeof(unsigned short) * 8:
149
ix = (<unsigned short>1) << i
161
for i from 0 <= i < <int>sizeof(long long) * 8:
162
ix = (<long long>1) << i
164
for i from 0 <= i < <int>sizeof(long long) * 8:
165
ix = (<long long>1) << i
172
except OverflowError:
173
pass # can't test this here
176
except IndexError: pass
177
else: assert False, "setting large index failed to raise IndexError"
180
except IndexError: pass
181
else: assert False, "deleting large index failed to raise IndexError"
185
except OverflowError:
186
pass # can't test this here
189
except IndexError: pass
190
else: assert False, "setting large index failed to raise IndexError"
193
except IndexError: pass
194
else: assert False, "deleting large index failed to raise IndexError"
199
def test_ulong_long():
201
>>> test_ulong_long()
203
cdef unsigned long long ix
208
except OverflowError:
209
pass # can't test this here
212
except IndexError: pass
213
else: assert False, "setting large index failed to raise IndexError"
216
except IndexError: pass
217
else: assert False, "deleting large index failed to raise IndexError"
220
@cython.boundscheck(False)
221
def test_boundscheck_unsigned(list L, tuple t, object o, unsigned long ix):
223
>>> test_boundscheck_unsigned([1, 2, 4], (1, 2, 4), [1, 2, 4], 2)
225
>>> test_boundscheck_unsigned([1, 2, 4], (1, 2, 4), "", 2)
226
Traceback (most recent call last):
228
IndexError: string index out of range
230
return L[ix], t[ix], o[ix]
232
@cython.boundscheck(False)
233
def test_boundscheck_signed(list L, tuple t, object o, long ix):
235
>>> test_boundscheck_signed([1, 2, 4], (1, 2, 4), [1, 2, 4], 2)
237
>>> test_boundscheck_signed([1, 2, 4], (1, 2, 4), "", 2)
238
Traceback (most recent call last):
240
IndexError: string index out of range
242
return L[ix], t[ix], o[ix]
244
@cython.wraparound(False)
245
def test_wraparound_signed(list L, tuple t, object o, long ix):
247
>>> test_wraparound_signed([1, 2, 4], (1, 2, 4), [1, 2, 4], 2)
249
>>> test_wraparound_signed([1, 2, 4], (1, 2, 4), "", 2)
250
Traceback (most recent call last):
252
IndexError: string index out of range
254
return L[ix], t[ix], o[ix]
256
def large_literal_index(object o):
258
>>> large_literal_index({1000000000000000000000000000000: True})
261
return o[1000000000000000000000000000000]
264
class LargeIndexable(object):
270
def __getitem__(self, index):
273
def __setitem__(self, index, value):
274
assert index == value == self.expected
277
def __delitem__(self, index):
278
assert self.expected == index
282
def test_large_indexing(obj):
284
>>> obj = LargeIndexable()
285
>>> zero, pone, none, pmaxsize, nmaxsize = test_large_indexing(obj)
286
>>> # , p2maxsize, n2maxsize
293
>>> pmaxsize == py_maxsize
295
>>> nmaxsize == -py_maxsize
298
#>>> p2maxsize == py_maxsize*2
300
#>>> n2maxsize == -py_maxsize*2
304
obj[0], obj[1], obj[-1],
305
obj[maxsize], obj[-maxsize],
306
#obj[maxsize*2], obj[-maxsize*2] # FIXME!
310
def del_large_index(obj, Py_ssize_t index):
312
>>> obj = LargeIndexable()
313
>>> del_large_index(obj, 0)
314
>>> del_large_index(obj, 1)
315
>>> del_large_index(obj, -1)
316
>>> del_large_index(obj, py_maxsize)
317
>>> del_large_index(obj, -py_maxsize)
321
assert obj.expected is None
324
def set_large_index(obj, Py_ssize_t index):
326
>>> obj = LargeIndexable()
327
>>> set_large_index(obj, 0)
328
>>> set_large_index(obj, 1)
329
>>> set_large_index(obj, -1)
330
>>> set_large_index(obj, py_maxsize)
331
>>> set_large_index(obj, -py_maxsize)
335
assert obj.expected is None
338
class DoesntLikePositiveIndices(object):
339
def __getitem__(self, idx):
341
raise RuntimeError("Positive index")
344
def __setitem__(self, idx, value):
346
raise RuntimeError("Positive index")
348
def __delitem__(self, idx):
350
raise RuntimeError("Positive index")
355
def test_call_with_negative_numbers():
357
The key point is that Cython shouldn't default to PySequence_*Item
358
since that invisibly adjusts negative numbers to be len(o)-idx.
359
>>> test_call_with_negative_numbers()
363
indexme = DoesntLikePositiveIndices()
365
indexme[idx] = "something"