1 | import unittest
|
---|
2 | from test import test_support
|
---|
3 | import operator
|
---|
4 | from sys import maxint
|
---|
5 | maxsize = test_support.MAX_Py_ssize_t
|
---|
6 | minsize = -maxsize-1
|
---|
7 |
|
---|
8 | class oldstyle:
|
---|
9 | def __index__(self):
|
---|
10 | return self.ind
|
---|
11 |
|
---|
12 | class newstyle(object):
|
---|
13 | def __index__(self):
|
---|
14 | return self.ind
|
---|
15 |
|
---|
16 | class TrapInt(int):
|
---|
17 | def __index__(self):
|
---|
18 | return self
|
---|
19 |
|
---|
20 | class TrapLong(long):
|
---|
21 | def __index__(self):
|
---|
22 | return self
|
---|
23 |
|
---|
24 | class BaseTestCase(unittest.TestCase):
|
---|
25 | def setUp(self):
|
---|
26 | self.o = oldstyle()
|
---|
27 | self.n = newstyle()
|
---|
28 |
|
---|
29 | def test_basic(self):
|
---|
30 | self.o.ind = -2
|
---|
31 | self.n.ind = 2
|
---|
32 | self.assertEqual(operator.index(self.o), -2)
|
---|
33 | self.assertEqual(operator.index(self.n), 2)
|
---|
34 |
|
---|
35 | def test_slice(self):
|
---|
36 | self.o.ind = 1
|
---|
37 | self.n.ind = 2
|
---|
38 | slc = slice(self.o, self.o, self.o)
|
---|
39 | check_slc = slice(1, 1, 1)
|
---|
40 | self.assertEqual(slc.indices(self.o), check_slc.indices(1))
|
---|
41 | slc = slice(self.n, self.n, self.n)
|
---|
42 | check_slc = slice(2, 2, 2)
|
---|
43 | self.assertEqual(slc.indices(self.n), check_slc.indices(2))
|
---|
44 |
|
---|
45 | def test_wrappers(self):
|
---|
46 | self.o.ind = 4
|
---|
47 | self.n.ind = 5
|
---|
48 | self.assertEqual(6 .__index__(), 6)
|
---|
49 | self.assertEqual(-7L.__index__(), -7)
|
---|
50 | self.assertEqual(self.o.__index__(), 4)
|
---|
51 | self.assertEqual(self.n.__index__(), 5)
|
---|
52 | self.assertEqual(True.__index__(), 1)
|
---|
53 | self.assertEqual(False.__index__(), 0)
|
---|
54 |
|
---|
55 | def test_subclasses(self):
|
---|
56 | r = range(10)
|
---|
57 | self.assertEqual(r[TrapInt(5):TrapInt(10)], r[5:10])
|
---|
58 | self.assertEqual(r[TrapLong(5):TrapLong(10)], r[5:10])
|
---|
59 | self.assertEqual(slice(TrapInt()).indices(0), (0,0,1))
|
---|
60 | self.assertEqual(slice(TrapLong(0)).indices(0), (0,0,1))
|
---|
61 |
|
---|
62 | def test_error(self):
|
---|
63 | self.o.ind = 'dumb'
|
---|
64 | self.n.ind = 'bad'
|
---|
65 | self.assertRaises(TypeError, operator.index, self.o)
|
---|
66 | self.assertRaises(TypeError, operator.index, self.n)
|
---|
67 | self.assertRaises(TypeError, slice(self.o).indices, 0)
|
---|
68 | self.assertRaises(TypeError, slice(self.n).indices, 0)
|
---|
69 |
|
---|
70 |
|
---|
71 | class SeqTestCase(unittest.TestCase):
|
---|
72 | # This test case isn't run directly. It just defines common tests
|
---|
73 | # to the different sequence types below
|
---|
74 | def setUp(self):
|
---|
75 | self.o = oldstyle()
|
---|
76 | self.n = newstyle()
|
---|
77 | self.o2 = oldstyle()
|
---|
78 | self.n2 = newstyle()
|
---|
79 |
|
---|
80 | def test_index(self):
|
---|
81 | self.o.ind = -2
|
---|
82 | self.n.ind = 2
|
---|
83 | self.assertEqual(self.seq[self.n], self.seq[2])
|
---|
84 | self.assertEqual(self.seq[self.o], self.seq[-2])
|
---|
85 |
|
---|
86 | def test_slice(self):
|
---|
87 | self.o.ind = 1
|
---|
88 | self.o2.ind = 3
|
---|
89 | self.n.ind = 2
|
---|
90 | self.n2.ind = 4
|
---|
91 | self.assertEqual(self.seq[self.o:self.o2], self.seq[1:3])
|
---|
92 | self.assertEqual(self.seq[self.n:self.n2], self.seq[2:4])
|
---|
93 |
|
---|
94 | def test_slice_bug7532(self):
|
---|
95 | seqlen = len(self.seq)
|
---|
96 | self.o.ind = int(seqlen * 1.5)
|
---|
97 | self.n.ind = seqlen + 2
|
---|
98 | self.assertEqual(self.seq[self.o:], self.seq[0:0])
|
---|
99 | self.assertEqual(self.seq[:self.o], self.seq)
|
---|
100 | self.assertEqual(self.seq[self.n:], self.seq[0:0])
|
---|
101 | self.assertEqual(self.seq[:self.n], self.seq)
|
---|
102 | if isinstance(self.seq, ClassicSeq):
|
---|
103 | return
|
---|
104 | # These tests fail for ClassicSeq (see bug #7532)
|
---|
105 | self.o2.ind = -seqlen - 2
|
---|
106 | self.n2.ind = -int(seqlen * 1.5)
|
---|
107 | self.assertEqual(self.seq[self.o2:], self.seq)
|
---|
108 | self.assertEqual(self.seq[:self.o2], self.seq[0:0])
|
---|
109 | self.assertEqual(self.seq[self.n2:], self.seq)
|
---|
110 | self.assertEqual(self.seq[:self.n2], self.seq[0:0])
|
---|
111 |
|
---|
112 | def test_repeat(self):
|
---|
113 | self.o.ind = 3
|
---|
114 | self.n.ind = 2
|
---|
115 | self.assertEqual(self.seq * self.o, self.seq * 3)
|
---|
116 | self.assertEqual(self.seq * self.n, self.seq * 2)
|
---|
117 | self.assertEqual(self.o * self.seq, self.seq * 3)
|
---|
118 | self.assertEqual(self.n * self.seq, self.seq * 2)
|
---|
119 |
|
---|
120 | def test_wrappers(self):
|
---|
121 | self.o.ind = 4
|
---|
122 | self.n.ind = 5
|
---|
123 | self.assertEqual(self.seq.__getitem__(self.o), self.seq[4])
|
---|
124 | self.assertEqual(self.seq.__mul__(self.o), self.seq * 4)
|
---|
125 | self.assertEqual(self.seq.__rmul__(self.o), self.seq * 4)
|
---|
126 | self.assertEqual(self.seq.__getitem__(self.n), self.seq[5])
|
---|
127 | self.assertEqual(self.seq.__mul__(self.n), self.seq * 5)
|
---|
128 | self.assertEqual(self.seq.__rmul__(self.n), self.seq * 5)
|
---|
129 |
|
---|
130 | def test_subclasses(self):
|
---|
131 | self.assertEqual(self.seq[TrapInt()], self.seq[0])
|
---|
132 | self.assertEqual(self.seq[TrapLong()], self.seq[0])
|
---|
133 |
|
---|
134 | def test_error(self):
|
---|
135 | self.o.ind = 'dumb'
|
---|
136 | self.n.ind = 'bad'
|
---|
137 | indexobj = lambda x, obj: obj.seq[x]
|
---|
138 | self.assertRaises(TypeError, indexobj, self.o, self)
|
---|
139 | self.assertRaises(TypeError, indexobj, self.n, self)
|
---|
140 | sliceobj = lambda x, obj: obj.seq[x:]
|
---|
141 | self.assertRaises(TypeError, sliceobj, self.o, self)
|
---|
142 | self.assertRaises(TypeError, sliceobj, self.n, self)
|
---|
143 |
|
---|
144 |
|
---|
145 | class ListTestCase(SeqTestCase):
|
---|
146 | seq = [0,10,20,30,40,50]
|
---|
147 |
|
---|
148 | def test_setdelitem(self):
|
---|
149 | self.o.ind = -2
|
---|
150 | self.n.ind = 2
|
---|
151 | lst = list('ab!cdefghi!j')
|
---|
152 | del lst[self.o]
|
---|
153 | del lst[self.n]
|
---|
154 | lst[self.o] = 'X'
|
---|
155 | lst[self.n] = 'Y'
|
---|
156 | self.assertEqual(lst, list('abYdefghXj'))
|
---|
157 |
|
---|
158 | lst = [5, 6, 7, 8, 9, 10, 11]
|
---|
159 | lst.__setitem__(self.n, "here")
|
---|
160 | self.assertEqual(lst, [5, 6, "here", 8, 9, 10, 11])
|
---|
161 | lst.__delitem__(self.n)
|
---|
162 | self.assertEqual(lst, [5, 6, 8, 9, 10, 11])
|
---|
163 |
|
---|
164 | def test_inplace_repeat(self):
|
---|
165 | self.o.ind = 2
|
---|
166 | self.n.ind = 3
|
---|
167 | lst = [6, 4]
|
---|
168 | lst *= self.o
|
---|
169 | self.assertEqual(lst, [6, 4, 6, 4])
|
---|
170 | lst *= self.n
|
---|
171 | self.assertEqual(lst, [6, 4, 6, 4] * 3)
|
---|
172 |
|
---|
173 | lst = [5, 6, 7, 8, 9, 11]
|
---|
174 | l2 = lst.__imul__(self.n)
|
---|
175 | self.assertIs(l2, lst)
|
---|
176 | self.assertEqual(lst, [5, 6, 7, 8, 9, 11] * 3)
|
---|
177 |
|
---|
178 |
|
---|
179 | class _BaseSeq:
|
---|
180 |
|
---|
181 | def __init__(self, iterable):
|
---|
182 | self._list = list(iterable)
|
---|
183 |
|
---|
184 | def __repr__(self):
|
---|
185 | return repr(self._list)
|
---|
186 |
|
---|
187 | def __eq__(self, other):
|
---|
188 | return self._list == other
|
---|
189 |
|
---|
190 | def __len__(self):
|
---|
191 | return len(self._list)
|
---|
192 |
|
---|
193 | def __mul__(self, n):
|
---|
194 | return self.__class__(self._list*n)
|
---|
195 | __rmul__ = __mul__
|
---|
196 |
|
---|
197 | def __getitem__(self, index):
|
---|
198 | return self._list[index]
|
---|
199 |
|
---|
200 |
|
---|
201 | class _GetSliceMixin:
|
---|
202 |
|
---|
203 | def __getslice__(self, i, j):
|
---|
204 | return self._list.__getslice__(i, j)
|
---|
205 |
|
---|
206 |
|
---|
207 | class ClassicSeq(_BaseSeq): pass
|
---|
208 | class NewSeq(_BaseSeq, object): pass
|
---|
209 | class ClassicSeqDeprecated(_GetSliceMixin, ClassicSeq): pass
|
---|
210 | class NewSeqDeprecated(_GetSliceMixin, NewSeq): pass
|
---|
211 |
|
---|
212 |
|
---|
213 | class TupleTestCase(SeqTestCase):
|
---|
214 | seq = (0,10,20,30,40,50)
|
---|
215 |
|
---|
216 | class StringTestCase(SeqTestCase):
|
---|
217 | seq = "this is a test"
|
---|
218 |
|
---|
219 | class ByteArrayTestCase(SeqTestCase):
|
---|
220 | seq = bytearray("this is a test")
|
---|
221 |
|
---|
222 | class UnicodeTestCase(SeqTestCase):
|
---|
223 | seq = u"this is a test"
|
---|
224 |
|
---|
225 | class ClassicSeqTestCase(SeqTestCase):
|
---|
226 | seq = ClassicSeq((0,10,20,30,40,50))
|
---|
227 |
|
---|
228 | class NewSeqTestCase(SeqTestCase):
|
---|
229 | seq = NewSeq((0,10,20,30,40,50))
|
---|
230 |
|
---|
231 | class ClassicSeqDeprecatedTestCase(SeqTestCase):
|
---|
232 | seq = ClassicSeqDeprecated((0,10,20,30,40,50))
|
---|
233 |
|
---|
234 | class NewSeqDeprecatedTestCase(SeqTestCase):
|
---|
235 | seq = NewSeqDeprecated((0,10,20,30,40,50))
|
---|
236 |
|
---|
237 |
|
---|
238 | class XRangeTestCase(unittest.TestCase):
|
---|
239 |
|
---|
240 | def test_xrange(self):
|
---|
241 | n = newstyle()
|
---|
242 | n.ind = 5
|
---|
243 | self.assertEqual(xrange(1, 20)[n], 6)
|
---|
244 | self.assertEqual(xrange(1, 20).__getitem__(n), 6)
|
---|
245 |
|
---|
246 | class OverflowTestCase(unittest.TestCase):
|
---|
247 |
|
---|
248 | def setUp(self):
|
---|
249 | self.pos = 2**100
|
---|
250 | self.neg = -self.pos
|
---|
251 |
|
---|
252 | def test_large_longs(self):
|
---|
253 | self.assertEqual(self.pos.__index__(), self.pos)
|
---|
254 | self.assertEqual(self.neg.__index__(), self.neg)
|
---|
255 |
|
---|
256 | def _getitem_helper(self, base):
|
---|
257 | class GetItem(base):
|
---|
258 | def __len__(self):
|
---|
259 | return maxint # cannot return long here
|
---|
260 | def __getitem__(self, key):
|
---|
261 | return key
|
---|
262 | x = GetItem()
|
---|
263 | self.assertEqual(x[self.pos], self.pos)
|
---|
264 | self.assertEqual(x[self.neg], self.neg)
|
---|
265 | self.assertEqual(x[self.neg:self.pos].indices(maxsize),
|
---|
266 | (0, maxsize, 1))
|
---|
267 | self.assertEqual(x[self.neg:self.pos:1].indices(maxsize),
|
---|
268 | (0, maxsize, 1))
|
---|
269 |
|
---|
270 | def _getslice_helper_deprecated(self, base):
|
---|
271 | class GetItem(base):
|
---|
272 | def __len__(self):
|
---|
273 | return maxint # cannot return long here
|
---|
274 | def __getitem__(self, key):
|
---|
275 | return key
|
---|
276 | def __getslice__(self, i, j):
|
---|
277 | return i, j
|
---|
278 | x = GetItem()
|
---|
279 | self.assertEqual(x[self.pos], self.pos)
|
---|
280 | self.assertEqual(x[self.neg], self.neg)
|
---|
281 | self.assertEqual(x[self.neg:self.pos], (maxint+minsize, maxsize))
|
---|
282 | self.assertEqual(x[self.neg:self.pos:1].indices(maxsize),
|
---|
283 | (0, maxsize, 1))
|
---|
284 |
|
---|
285 | def test_getitem(self):
|
---|
286 | self._getitem_helper(object)
|
---|
287 | with test_support.check_py3k_warnings():
|
---|
288 | self._getslice_helper_deprecated(object)
|
---|
289 |
|
---|
290 | def test_getitem_classic(self):
|
---|
291 | class Empty: pass
|
---|
292 | # XXX This test fails (see bug #7532)
|
---|
293 | #self._getitem_helper(Empty)
|
---|
294 | with test_support.check_py3k_warnings():
|
---|
295 | self._getslice_helper_deprecated(Empty)
|
---|
296 |
|
---|
297 | def test_sequence_repeat(self):
|
---|
298 | self.assertRaises(OverflowError, lambda: "a" * self.pos)
|
---|
299 | self.assertRaises(OverflowError, lambda: "a" * self.neg)
|
---|
300 |
|
---|
301 |
|
---|
302 | def test_main():
|
---|
303 | test_support.run_unittest(
|
---|
304 | BaseTestCase,
|
---|
305 | ListTestCase,
|
---|
306 | TupleTestCase,
|
---|
307 | ByteArrayTestCase,
|
---|
308 | StringTestCase,
|
---|
309 | UnicodeTestCase,
|
---|
310 | ClassicSeqTestCase,
|
---|
311 | NewSeqTestCase,
|
---|
312 | XRangeTestCase,
|
---|
313 | OverflowTestCase,
|
---|
314 | )
|
---|
315 | with test_support.check_py3k_warnings():
|
---|
316 | test_support.run_unittest(
|
---|
317 | ClassicSeqDeprecatedTestCase,
|
---|
318 | NewSeqDeprecatedTestCase,
|
---|
319 | )
|
---|
320 |
|
---|
321 |
|
---|
322 | if __name__ == "__main__":
|
---|
323 | test_main()
|
---|