|
1 """ |
|
2 Tests common to tuple, list and UserList.UserList |
|
3 """ |
|
4 |
|
5 import unittest |
|
6 from test import test_support |
|
7 |
|
8 # Various iterables |
|
9 # This is used for checking the constructor (here and in test_deque.py) |
|
10 def iterfunc(seqn): |
|
11 'Regular generator' |
|
12 for i in seqn: |
|
13 yield i |
|
14 |
|
15 class Sequence: |
|
16 'Sequence using __getitem__' |
|
17 def __init__(self, seqn): |
|
18 self.seqn = seqn |
|
19 def __getitem__(self, i): |
|
20 return self.seqn[i] |
|
21 |
|
22 class IterFunc: |
|
23 'Sequence using iterator protocol' |
|
24 def __init__(self, seqn): |
|
25 self.seqn = seqn |
|
26 self.i = 0 |
|
27 def __iter__(self): |
|
28 return self |
|
29 def next(self): |
|
30 if self.i >= len(self.seqn): raise StopIteration |
|
31 v = self.seqn[self.i] |
|
32 self.i += 1 |
|
33 return v |
|
34 |
|
35 class IterGen: |
|
36 'Sequence using iterator protocol defined with a generator' |
|
37 def __init__(self, seqn): |
|
38 self.seqn = seqn |
|
39 self.i = 0 |
|
40 def __iter__(self): |
|
41 for val in self.seqn: |
|
42 yield val |
|
43 |
|
44 class IterNextOnly: |
|
45 'Missing __getitem__ and __iter__' |
|
46 def __init__(self, seqn): |
|
47 self.seqn = seqn |
|
48 self.i = 0 |
|
49 def next(self): |
|
50 if self.i >= len(self.seqn): raise StopIteration |
|
51 v = self.seqn[self.i] |
|
52 self.i += 1 |
|
53 return v |
|
54 |
|
55 class IterNoNext: |
|
56 'Iterator missing next()' |
|
57 def __init__(self, seqn): |
|
58 self.seqn = seqn |
|
59 self.i = 0 |
|
60 def __iter__(self): |
|
61 return self |
|
62 |
|
63 class IterGenExc: |
|
64 'Test propagation of exceptions' |
|
65 def __init__(self, seqn): |
|
66 self.seqn = seqn |
|
67 self.i = 0 |
|
68 def __iter__(self): |
|
69 return self |
|
70 def next(self): |
|
71 3 // 0 |
|
72 |
|
73 class IterFuncStop: |
|
74 'Test immediate stop' |
|
75 def __init__(self, seqn): |
|
76 pass |
|
77 def __iter__(self): |
|
78 return self |
|
79 def next(self): |
|
80 raise StopIteration |
|
81 |
|
82 from itertools import chain, imap |
|
83 def itermulti(seqn): |
|
84 'Test multiple tiers of iterators' |
|
85 return chain(imap(lambda x:x, iterfunc(IterGen(Sequence(seqn))))) |
|
86 |
|
87 class CommonTest(unittest.TestCase): |
|
88 # The type to be tested |
|
89 type2test = None |
|
90 |
|
91 def test_constructors(self): |
|
92 l0 = [] |
|
93 l1 = [0] |
|
94 l2 = [0, 1] |
|
95 |
|
96 u = self.type2test() |
|
97 u0 = self.type2test(l0) |
|
98 u1 = self.type2test(l1) |
|
99 u2 = self.type2test(l2) |
|
100 |
|
101 uu = self.type2test(u) |
|
102 uu0 = self.type2test(u0) |
|
103 uu1 = self.type2test(u1) |
|
104 uu2 = self.type2test(u2) |
|
105 |
|
106 v = self.type2test(tuple(u)) |
|
107 class OtherSeq: |
|
108 def __init__(self, initseq): |
|
109 self.__data = initseq |
|
110 def __len__(self): |
|
111 return len(self.__data) |
|
112 def __getitem__(self, i): |
|
113 return self.__data[i] |
|
114 s = OtherSeq(u0) |
|
115 v0 = self.type2test(s) |
|
116 self.assertEqual(len(v0), len(s)) |
|
117 |
|
118 s = "this is also a sequence" |
|
119 vv = self.type2test(s) |
|
120 self.assertEqual(len(vv), len(s)) |
|
121 |
|
122 # Create from various iteratables |
|
123 for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)): |
|
124 for g in (Sequence, IterFunc, IterGen, |
|
125 itermulti, iterfunc): |
|
126 self.assertEqual(self.type2test(g(s)), self.type2test(s)) |
|
127 self.assertEqual(self.type2test(IterFuncStop(s)), self.type2test()) |
|
128 self.assertEqual(self.type2test(c for c in "123"), self.type2test("123")) |
|
129 self.assertRaises(TypeError, self.type2test, IterNextOnly(s)) |
|
130 self.assertRaises(TypeError, self.type2test, IterNoNext(s)) |
|
131 self.assertRaises(ZeroDivisionError, self.type2test, IterGenExc(s)) |
|
132 |
|
133 def test_truth(self): |
|
134 self.assert_(not self.type2test()) |
|
135 self.assert_(self.type2test([42])) |
|
136 |
|
137 def test_getitem(self): |
|
138 u = self.type2test([0, 1, 2, 3, 4]) |
|
139 for i in xrange(len(u)): |
|
140 self.assertEqual(u[i], i) |
|
141 self.assertEqual(u[long(i)], i) |
|
142 for i in xrange(-len(u), -1): |
|
143 self.assertEqual(u[i], len(u)+i) |
|
144 self.assertEqual(u[long(i)], len(u)+i) |
|
145 self.assertRaises(IndexError, u.__getitem__, -len(u)-1) |
|
146 self.assertRaises(IndexError, u.__getitem__, len(u)) |
|
147 self.assertRaises(ValueError, u.__getitem__, slice(0,10,0)) |
|
148 |
|
149 u = self.type2test() |
|
150 self.assertRaises(IndexError, u.__getitem__, 0) |
|
151 self.assertRaises(IndexError, u.__getitem__, -1) |
|
152 |
|
153 self.assertRaises(TypeError, u.__getitem__) |
|
154 |
|
155 a = self.type2test([10, 11]) |
|
156 self.assertEqual(a[0], 10) |
|
157 self.assertEqual(a[1], 11) |
|
158 self.assertEqual(a[-2], 10) |
|
159 self.assertEqual(a[-1], 11) |
|
160 self.assertRaises(IndexError, a.__getitem__, -3) |
|
161 self.assertRaises(IndexError, a.__getitem__, 3) |
|
162 |
|
163 def test_getslice(self): |
|
164 l = [0, 1, 2, 3, 4] |
|
165 u = self.type2test(l) |
|
166 |
|
167 self.assertEqual(u[0:0], self.type2test()) |
|
168 self.assertEqual(u[1:2], self.type2test([1])) |
|
169 self.assertEqual(u[-2:-1], self.type2test([3])) |
|
170 self.assertEqual(u[-1000:1000], u) |
|
171 self.assertEqual(u[1000:-1000], self.type2test([])) |
|
172 self.assertEqual(u[:], u) |
|
173 self.assertEqual(u[1:None], self.type2test([1, 2, 3, 4])) |
|
174 self.assertEqual(u[None:3], self.type2test([0, 1, 2])) |
|
175 |
|
176 # Extended slices |
|
177 self.assertEqual(u[::], u) |
|
178 self.assertEqual(u[::2], self.type2test([0, 2, 4])) |
|
179 self.assertEqual(u[1::2], self.type2test([1, 3])) |
|
180 self.assertEqual(u[::-1], self.type2test([4, 3, 2, 1, 0])) |
|
181 self.assertEqual(u[::-2], self.type2test([4, 2, 0])) |
|
182 self.assertEqual(u[3::-2], self.type2test([3, 1])) |
|
183 self.assertEqual(u[3:3:-2], self.type2test([])) |
|
184 self.assertEqual(u[3:2:-2], self.type2test([3])) |
|
185 self.assertEqual(u[3:1:-2], self.type2test([3])) |
|
186 self.assertEqual(u[3:0:-2], self.type2test([3, 1])) |
|
187 self.assertEqual(u[::-100], self.type2test([4])) |
|
188 self.assertEqual(u[100:-100:], self.type2test([])) |
|
189 self.assertEqual(u[-100:100:], u) |
|
190 self.assertEqual(u[100:-100:-1], u[::-1]) |
|
191 self.assertEqual(u[-100:100:-1], self.type2test([])) |
|
192 self.assertEqual(u[-100L:100L:2L], self.type2test([0, 2, 4])) |
|
193 |
|
194 # Test extreme cases with long ints |
|
195 a = self.type2test([0,1,2,3,4]) |
|
196 self.assertEqual(a[ -pow(2,128L): 3 ], self.type2test([0,1,2])) |
|
197 self.assertEqual(a[ 3: pow(2,145L) ], self.type2test([3,4])) |
|
198 |
|
199 self.assertRaises(TypeError, u.__getslice__) |
|
200 |
|
201 def test_contains(self): |
|
202 u = self.type2test([0, 1, 2]) |
|
203 for i in u: |
|
204 self.assert_(i in u) |
|
205 for i in min(u)-1, max(u)+1: |
|
206 self.assert_(i not in u) |
|
207 |
|
208 self.assertRaises(TypeError, u.__contains__) |
|
209 |
|
210 def test_contains_fake(self): |
|
211 class AllEq: |
|
212 # Sequences must use rich comparison against each item |
|
213 # (unless "is" is true, or an earlier item answered) |
|
214 # So instances of AllEq must be found in all non-empty sequences. |
|
215 def __eq__(self, other): |
|
216 return True |
|
217 def __hash__(self): |
|
218 raise NotImplemented |
|
219 self.assert_(AllEq() not in self.type2test([])) |
|
220 self.assert_(AllEq() in self.type2test([1])) |
|
221 |
|
222 def test_contains_order(self): |
|
223 # Sequences must test in-order. If a rich comparison has side |
|
224 # effects, these will be visible to tests against later members. |
|
225 # In this test, the "side effect" is a short-circuiting raise. |
|
226 class DoNotTestEq(Exception): |
|
227 pass |
|
228 class StopCompares: |
|
229 def __eq__(self, other): |
|
230 raise DoNotTestEq |
|
231 |
|
232 checkfirst = self.type2test([1, StopCompares()]) |
|
233 self.assert_(1 in checkfirst) |
|
234 checklast = self.type2test([StopCompares(), 1]) |
|
235 self.assertRaises(DoNotTestEq, checklast.__contains__, 1) |
|
236 |
|
237 def test_len(self): |
|
238 self.assertEqual(len(self.type2test()), 0) |
|
239 self.assertEqual(len(self.type2test([])), 0) |
|
240 self.assertEqual(len(self.type2test([0])), 1) |
|
241 self.assertEqual(len(self.type2test([0, 1, 2])), 3) |
|
242 |
|
243 def test_minmax(self): |
|
244 u = self.type2test([0, 1, 2]) |
|
245 self.assertEqual(min(u), 0) |
|
246 self.assertEqual(max(u), 2) |
|
247 |
|
248 def test_addmul(self): |
|
249 u1 = self.type2test([0]) |
|
250 u2 = self.type2test([0, 1]) |
|
251 self.assertEqual(u1, u1 + self.type2test()) |
|
252 self.assertEqual(u1, self.type2test() + u1) |
|
253 self.assertEqual(u1 + self.type2test([1]), u2) |
|
254 self.assertEqual(self.type2test([-1]) + u1, self.type2test([-1, 0])) |
|
255 self.assertEqual(self.type2test(), u2*0) |
|
256 self.assertEqual(self.type2test(), 0*u2) |
|
257 self.assertEqual(self.type2test(), u2*0L) |
|
258 self.assertEqual(self.type2test(), 0L*u2) |
|
259 self.assertEqual(u2, u2*1) |
|
260 self.assertEqual(u2, 1*u2) |
|
261 self.assertEqual(u2, u2*1L) |
|
262 self.assertEqual(u2, 1L*u2) |
|
263 self.assertEqual(u2+u2, u2*2) |
|
264 self.assertEqual(u2+u2, 2*u2) |
|
265 self.assertEqual(u2+u2, u2*2L) |
|
266 self.assertEqual(u2+u2, 2L*u2) |
|
267 self.assertEqual(u2+u2+u2, u2*3) |
|
268 self.assertEqual(u2+u2+u2, 3*u2) |
|
269 |
|
270 class subclass(self.type2test): |
|
271 pass |
|
272 u3 = subclass([0, 1]) |
|
273 self.assertEqual(u3, u3*1) |
|
274 self.assert_(u3 is not u3*1) |
|
275 |
|
276 def test_iadd(self): |
|
277 u = self.type2test([0, 1]) |
|
278 u += self.type2test() |
|
279 self.assertEqual(u, self.type2test([0, 1])) |
|
280 u += self.type2test([2, 3]) |
|
281 self.assertEqual(u, self.type2test([0, 1, 2, 3])) |
|
282 u += self.type2test([4, 5]) |
|
283 self.assertEqual(u, self.type2test([0, 1, 2, 3, 4, 5])) |
|
284 |
|
285 u = self.type2test("spam") |
|
286 u += self.type2test("eggs") |
|
287 self.assertEqual(u, self.type2test("spameggs")) |
|
288 |
|
289 def test_imul(self): |
|
290 u = self.type2test([0, 1]) |
|
291 u *= 3 |
|
292 self.assertEqual(u, self.type2test([0, 1, 0, 1, 0, 1])) |
|
293 |
|
294 def test_getitemoverwriteiter(self): |
|
295 # Verify that __getitem__ overrides are not recognized by __iter__ |
|
296 class T(self.type2test): |
|
297 def __getitem__(self, key): |
|
298 return str(key) + '!!!' |
|
299 self.assertEqual(iter(T((1,2))).next(), 1) |
|
300 |
|
301 def test_repeat(self): |
|
302 for m in xrange(4): |
|
303 s = tuple(range(m)) |
|
304 for n in xrange(-3, 5): |
|
305 self.assertEqual(self.type2test(s*n), self.type2test(s)*n) |
|
306 self.assertEqual(self.type2test(s)*(-4), self.type2test([])) |
|
307 self.assertEqual(id(s), id(s*1)) |
|
308 |
|
309 def test_bigrepeat(self): |
|
310 x = self.type2test([0]) |
|
311 x *= 2**16 |
|
312 self.assertRaises(MemoryError, x.__mul__, 2**16) |
|
313 if hasattr(x, '__imul__'): |
|
314 self.assertRaises(MemoryError, x.__imul__, 2**16) |
|
315 |
|
316 def test_subscript(self): |
|
317 a = self.type2test([10, 11]) |
|
318 self.assertEqual(a.__getitem__(0L), 10) |
|
319 self.assertEqual(a.__getitem__(1L), 11) |
|
320 self.assertEqual(a.__getitem__(-2L), 10) |
|
321 self.assertEqual(a.__getitem__(-1L), 11) |
|
322 self.assertRaises(IndexError, a.__getitem__, -3) |
|
323 self.assertRaises(IndexError, a.__getitem__, 3) |
|
324 self.assertEqual(a.__getitem__(slice(0,1)), self.type2test([10])) |
|
325 self.assertEqual(a.__getitem__(slice(1,2)), self.type2test([11])) |
|
326 self.assertEqual(a.__getitem__(slice(0,2)), self.type2test([10, 11])) |
|
327 self.assertEqual(a.__getitem__(slice(0,3)), self.type2test([10, 11])) |
|
328 self.assertEqual(a.__getitem__(slice(3,5)), self.type2test([])) |
|
329 self.assertRaises(ValueError, a.__getitem__, slice(0, 10, 0)) |
|
330 self.assertRaises(TypeError, a.__getitem__, 'x') |