blob: 7de016f66fac3e60c6315221a9c262424f92ba61 [file] [log] [blame]
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001from collections import deque
2import unittest
Walter Dörwald09a3f2c2005-03-22 22:43:28 +00003from test import test_support, seq_tests
Antoine Pitrouaa687902009-01-01 14:11:22 +00004import gc
5import weakref
Raymond Hettinger756b3f32004-01-29 06:37:52 +00006import copy
7import cPickle as pickle
Raymond Hettinger0a4977c2004-03-01 23:16:22 +00008import random
Raymond Hettinger756b3f32004-01-29 06:37:52 +00009
10BIG = 100000
11
Raymond Hettingera435c532004-07-09 04:10:20 +000012def fail():
13 raise SyntaxError
14 yield 1
15
Raymond Hettinger4aec61e2005-03-18 21:20:23 +000016class BadCmp:
17 def __eq__(self, other):
18 raise RuntimeError
19
20class MutateCmp:
Raymond Hettingerd73202c2005-03-19 00:00:51 +000021 def __init__(self, deque, result):
Raymond Hettinger4aec61e2005-03-18 21:20:23 +000022 self.deque = deque
Raymond Hettingerd73202c2005-03-19 00:00:51 +000023 self.result = result
Raymond Hettinger4aec61e2005-03-18 21:20:23 +000024 def __eq__(self, other):
25 self.deque.clear()
Raymond Hettingerd73202c2005-03-19 00:00:51 +000026 return self.result
Raymond Hettinger4aec61e2005-03-18 21:20:23 +000027
Raymond Hettinger756b3f32004-01-29 06:37:52 +000028class TestBasic(unittest.TestCase):
29
30 def test_basics(self):
Raymond Hettingeradf9ffd2007-12-13 00:08:37 +000031 d = deque(xrange(-5125, -5000))
32 d.__init__(xrange(200))
Raymond Hettinger756b3f32004-01-29 06:37:52 +000033 for i in xrange(200, 400):
34 d.append(i)
35 for i in reversed(xrange(-200, 0)):
36 d.appendleft(i)
37 self.assertEqual(list(d), range(-200, 400))
38 self.assertEqual(len(d), 600)
39
40 left = [d.popleft() for i in xrange(250)]
41 self.assertEqual(left, range(-200, 50))
42 self.assertEqual(list(d), range(50, 400))
43
44 right = [d.pop() for i in xrange(250)]
45 right.reverse()
46 self.assertEqual(right, range(150, 400))
47 self.assertEqual(list(d), range(50, 150))
48
Raymond Hettingera7fc4b12007-10-05 02:47:07 +000049 def test_maxlen(self):
Raymond Hettinger68995862007-10-10 00:26:46 +000050 self.assertRaises(ValueError, deque, 'abc', -1)
Raymond Hettingera7fc4b12007-10-05 02:47:07 +000051 self.assertRaises(ValueError, deque, 'abc', -2)
Raymond Hettingerbac769b2009-03-10 09:31:48 +000052 it = iter(range(10))
53 d = deque(it, maxlen=3)
54 self.assertEqual(list(it), [])
Raymond Hettingera7fc4b12007-10-05 02:47:07 +000055 self.assertEqual(repr(d), 'deque([7, 8, 9], maxlen=3)')
56 self.assertEqual(list(d), range(7, 10))
57 self.assertEqual(d, deque(range(10), 3))
58 d.append(10)
59 self.assertEqual(list(d), range(8, 11))
60 d.appendleft(7)
61 self.assertEqual(list(d), range(7, 10))
62 d.extend([10, 11])
63 self.assertEqual(list(d), range(9, 12))
64 d.extendleft([8, 7])
65 self.assertEqual(list(d), range(7, 10))
66 d = deque(xrange(200), maxlen=10)
67 d.append(d)
Neal Norwitz36a59b42008-04-10 05:46:39 +000068 test_support.unlink(test_support.TESTFN)
Neal Norwitz40f5e4c2008-03-25 04:17:38 +000069 fo = open(test_support.TESTFN, "wb")
Raymond Hettingera7fc4b12007-10-05 02:47:07 +000070 try:
Raymond Hettingera7fc4b12007-10-05 02:47:07 +000071 print >> fo, d,
72 fo.close()
73 fo = open(test_support.TESTFN, "rb")
74 self.assertEqual(fo.read(), repr(d))
75 finally:
76 fo.close()
Neal Norwitz40f5e4c2008-03-25 04:17:38 +000077 test_support.unlink(test_support.TESTFN)
Raymond Hettingera7fc4b12007-10-05 02:47:07 +000078
Raymond Hettinger68995862007-10-10 00:26:46 +000079 d = deque(range(10), maxlen=None)
Raymond Hettingera7fc4b12007-10-05 02:47:07 +000080 self.assertEqual(repr(d), 'deque([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])')
Neal Norwitz40f5e4c2008-03-25 04:17:38 +000081 fo = open(test_support.TESTFN, "wb")
Raymond Hettingera7fc4b12007-10-05 02:47:07 +000082 try:
Raymond Hettingera7fc4b12007-10-05 02:47:07 +000083 print >> fo, d,
84 fo.close()
85 fo = open(test_support.TESTFN, "rb")
86 self.assertEqual(fo.read(), repr(d))
87 finally:
88 fo.close()
Neal Norwitz40f5e4c2008-03-25 04:17:38 +000089 test_support.unlink(test_support.TESTFN)
Raymond Hettingera7fc4b12007-10-05 02:47:07 +000090
Raymond Hettingerbac769b2009-03-10 09:31:48 +000091 def test_maxlen_zero(self):
92 it = iter(range(100))
93 deque(it, maxlen=0)
94 self.assertEqual(list(it), [])
95
96 it = iter(range(100))
97 d = deque(maxlen=0)
98 d.extend(it)
99 self.assertEqual(list(it), [])
100
101 it = iter(range(100))
102 d = deque(maxlen=0)
103 d.extendleft(it)
104 self.assertEqual(list(it), [])
105
Raymond Hettinger56411aa2009-03-10 12:50:59 +0000106 def test_maxlen_attribute(self):
107 self.assertEqual(deque().maxlen, None)
108 self.assertEqual(deque('abc').maxlen, None)
109 self.assertEqual(deque('abc', maxlen=4).maxlen, 4)
110 self.assertEqual(deque('abc', maxlen=2).maxlen, 2)
111 self.assertEqual(deque('abc', maxlen=0).maxlen, 0)
112 with self.assertRaises(AttributeError):
113 d = deque('abc')
114 d.maxlen = 10
115
Raymond Hettinger738ec902004-02-29 02:15:56 +0000116 def test_comparisons(self):
117 d = deque('xabc'); d.popleft()
118 for e in [d, deque('abc'), deque('ab'), deque(), list(d)]:
119 self.assertEqual(d==e, type(d)==type(e) and list(d)==list(e))
120 self.assertEqual(d!=e, not(type(d)==type(e) and list(d)==list(e)))
121
122 args = map(deque, ('', 'a', 'b', 'ab', 'ba', 'abc', 'xba', 'xabc', 'cba'))
123 for x in args:
124 for y in args:
125 self.assertEqual(x == y, list(x) == list(y), (x,y))
126 self.assertEqual(x != y, list(x) != list(y), (x,y))
127 self.assertEqual(x < y, list(x) < list(y), (x,y))
128 self.assertEqual(x <= y, list(x) <= list(y), (x,y))
129 self.assertEqual(x > y, list(x) > list(y), (x,y))
130 self.assertEqual(x >= y, list(x) >= list(y), (x,y))
131 self.assertEqual(cmp(x,y), cmp(list(x),list(y)), (x,y))
132
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000133 def test_extend(self):
134 d = deque('a')
135 self.assertRaises(TypeError, d.extend, 1)
136 d.extend('bcd')
137 self.assertEqual(list(d), list('abcd'))
Raymond Hettinger0b3263b2009-12-10 06:00:33 +0000138 d.extend(d)
139 self.assertEqual(list(d), list('abcdabcd'))
140
141 def test_iadd(self):
142 d = deque('a')
143 d += 'bcd'
144 self.assertEqual(list(d), list('abcd'))
145 d += d
146 self.assertEqual(list(d), list('abcdabcd'))
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000147
148 def test_extendleft(self):
149 d = deque('a')
150 self.assertRaises(TypeError, d.extendleft, 1)
151 d.extendleft('bcd')
152 self.assertEqual(list(d), list(reversed('abcd')))
Raymond Hettinger0b3263b2009-12-10 06:00:33 +0000153 d.extendleft(d)
154 self.assertEqual(list(d), list('abcddcba'))
Raymond Hettingera435c532004-07-09 04:10:20 +0000155 d = deque()
156 d.extendleft(range(1000))
157 self.assertEqual(list(d), list(reversed(range(1000))))
158 self.assertRaises(SyntaxError, d.extendleft, fail())
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000159
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000160 def test_getitem(self):
161 n = 200
162 d = deque(xrange(n))
163 l = range(n)
164 for i in xrange(n):
165 d.popleft()
166 l.pop(0)
167 if random.random() < 0.5:
168 d.append(i)
169 l.append(i)
170 for j in xrange(1-len(l), len(l)):
171 assert d[j] == l[j]
172
Raymond Hettinger738ec902004-02-29 02:15:56 +0000173 d = deque('superman')
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000174 self.assertEqual(d[0], 's')
175 self.assertEqual(d[-1], 'n')
Raymond Hettinger738ec902004-02-29 02:15:56 +0000176 d = deque()
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000177 self.assertRaises(IndexError, d.__getitem__, 0)
178 self.assertRaises(IndexError, d.__getitem__, -1)
179
180 def test_setitem(self):
181 n = 200
182 d = deque(xrange(n))
183 for i in xrange(n):
184 d[i] = 10 * i
185 self.assertEqual(list(d), [10*i for i in xrange(n)])
186 l = list(d)
187 for i in xrange(1-n, 0, -1):
188 d[i] = 7*i
189 l[i] = 7*i
190 self.assertEqual(list(d), l)
Raymond Hettinger738ec902004-02-29 02:15:56 +0000191
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000192 def test_delitem(self):
193 n = 500 # O(n**2) test, don't make this too big
194 d = deque(xrange(n))
195 self.assertRaises(IndexError, d.__delitem__, -n-1)
196 self.assertRaises(IndexError, d.__delitem__, n)
197 for i in xrange(n):
198 self.assertEqual(len(d), n-i)
199 j = random.randrange(-len(d), len(d))
200 val = d[j]
Ezio Melottiaa980582010-01-23 23:04:36 +0000201 self.assertIn(val, d)
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000202 del d[j]
Ezio Melottiaa980582010-01-23 23:04:36 +0000203 self.assertNotIn(val, d)
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000204 self.assertEqual(len(d), 0)
205
Raymond Hettingera5fd24e2009-12-10 06:42:54 +0000206 def test_reverse(self):
207 n = 500 # O(n**2) test, don't make this too big
208 data = [random.random() for i in range(n)]
209 for i in range(n):
210 d = deque(data[:i])
211 r = d.reverse()
212 self.assertEqual(list(d), list(reversed(data[:i])))
213 self.assert_(r is None)
214 d.reverse()
215 self.assertEqual(list(d), data[:i])
216 self.assertRaises(TypeError, d.reverse, 1) # Arity is zero
217
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000218 def test_rotate(self):
Raymond Hettingeree33b272004-02-08 04:05:26 +0000219 s = tuple('abcde')
220 n = len(s)
221
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000222 d = deque(s)
Raymond Hettingeree33b272004-02-08 04:05:26 +0000223 d.rotate(1) # verify rot(1)
224 self.assertEqual(''.join(d), 'eabcd')
225
226 d = deque(s)
227 d.rotate(-1) # verify rot(-1)
228 self.assertEqual(''.join(d), 'bcdea')
229 d.rotate() # check default to 1
230 self.assertEqual(tuple(d), s)
231
232 for i in xrange(n*3):
233 d = deque(s)
234 e = deque(d)
235 d.rotate(i) # check vs. rot(1) n times
236 for j in xrange(i):
237 e.rotate(1)
238 self.assertEqual(tuple(d), tuple(e))
239 d.rotate(-i) # check that it works in reverse
240 self.assertEqual(tuple(d), s)
241 e.rotate(n-i) # check that it wraps forward
242 self.assertEqual(tuple(e), s)
243
244 for i in xrange(n*3):
245 d = deque(s)
246 e = deque(d)
247 d.rotate(-i)
248 for j in xrange(i):
249 e.rotate(-1) # check vs. rot(-1) n times
250 self.assertEqual(tuple(d), tuple(e))
251 d.rotate(i) # check that it works in reverse
252 self.assertEqual(tuple(d), s)
253 e.rotate(i-n) # check that it wraps backaround
254 self.assertEqual(tuple(e), s)
255
256 d = deque(s)
257 e = deque(s)
258 e.rotate(BIG+17) # verify on long series of rotates
259 dr = d.rotate
260 for i in xrange(BIG+17):
261 dr()
262 self.assertEqual(tuple(d), tuple(e))
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000263
Raymond Hettingera435c532004-07-09 04:10:20 +0000264 self.assertRaises(TypeError, d.rotate, 'x') # Wrong arg type
265 self.assertRaises(TypeError, d.rotate, 1, 10) # Too many args
266
267 d = deque()
268 d.rotate() # rotate an empty deque
269 self.assertEqual(d, deque())
270
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000271 def test_len(self):
272 d = deque('ab')
273 self.assertEqual(len(d), 2)
274 d.popleft()
275 self.assertEqual(len(d), 1)
276 d.pop()
277 self.assertEqual(len(d), 0)
Raymond Hettinger738ec902004-02-29 02:15:56 +0000278 self.assertRaises(IndexError, d.pop)
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000279 self.assertEqual(len(d), 0)
280 d.append('c')
281 self.assertEqual(len(d), 1)
282 d.appendleft('d')
283 self.assertEqual(len(d), 2)
284 d.clear()
285 self.assertEqual(len(d), 0)
286
287 def test_underflow(self):
288 d = deque()
Raymond Hettinger738ec902004-02-29 02:15:56 +0000289 self.assertRaises(IndexError, d.pop)
290 self.assertRaises(IndexError, d.popleft)
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000291
292 def test_clear(self):
293 d = deque(xrange(100))
294 self.assertEqual(len(d), 100)
295 d.clear()
296 self.assertEqual(len(d), 0)
297 self.assertEqual(list(d), [])
Raymond Hettingera435c532004-07-09 04:10:20 +0000298 d.clear() # clear an emtpy deque
299 self.assertEqual(list(d), [])
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000300
Raymond Hettinger4aec61e2005-03-18 21:20:23 +0000301 def test_remove(self):
302 d = deque('abcdefghcij')
303 d.remove('c')
304 self.assertEqual(d, deque('abdefghcij'))
305 d.remove('c')
306 self.assertEqual(d, deque('abdefghij'))
307 self.assertRaises(ValueError, d.remove, 'c')
308 self.assertEqual(d, deque('abdefghij'))
309
Walter Dörwaldc448a912005-03-22 11:22:38 +0000310 # Handle comparison errors
Raymond Hettinger4aec61e2005-03-18 21:20:23 +0000311 d = deque(['a', 'b', BadCmp(), 'c'])
312 e = deque(d)
313 self.assertRaises(RuntimeError, d.remove, 'c')
314 for x, y in zip(d, e):
315 # verify that original order and values are retained.
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000316 self.assertTrue(x is y)
Raymond Hettinger4aec61e2005-03-18 21:20:23 +0000317
318 # Handle evil mutator
Raymond Hettingerd73202c2005-03-19 00:00:51 +0000319 for match in (True, False):
320 d = deque(['ab'])
321 d.extend([MutateCmp(d, match), 'c'])
322 self.assertRaises(IndexError, d.remove, 'c')
323 self.assertEqual(d, deque())
Raymond Hettinger4aec61e2005-03-18 21:20:23 +0000324
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000325 def test_repr(self):
326 d = deque(xrange(200))
327 e = eval(repr(d))
328 self.assertEqual(list(d), list(e))
329 d.append(d)
Ezio Melottiaa980582010-01-23 23:04:36 +0000330 self.assertIn('...', repr(d))
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000331
332 def test_print(self):
333 d = deque(xrange(200))
334 d.append(d)
Neal Norwitz36a59b42008-04-10 05:46:39 +0000335 test_support.unlink(test_support.TESTFN)
Neal Norwitz40f5e4c2008-03-25 04:17:38 +0000336 fo = open(test_support.TESTFN, "wb")
Raymond Hettingera435c532004-07-09 04:10:20 +0000337 try:
Raymond Hettingera435c532004-07-09 04:10:20 +0000338 print >> fo, d,
339 fo.close()
340 fo = open(test_support.TESTFN, "rb")
341 self.assertEqual(fo.read(), repr(d))
342 finally:
343 fo.close()
Neal Norwitz40f5e4c2008-03-25 04:17:38 +0000344 test_support.unlink(test_support.TESTFN)
Raymond Hettingera435c532004-07-09 04:10:20 +0000345
346 def test_init(self):
Raymond Hettingera7fc4b12007-10-05 02:47:07 +0000347 self.assertRaises(TypeError, deque, 'abc', 2, 3);
Raymond Hettingera435c532004-07-09 04:10:20 +0000348 self.assertRaises(TypeError, deque, 1);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000349
350 def test_hash(self):
351 self.assertRaises(TypeError, hash, deque('abc'))
352
353 def test_long_steadystate_queue_popleft(self):
354 for size in (0, 1, 2, 100, 1000):
355 d = deque(xrange(size))
356 append, pop = d.append, d.popleft
357 for i in xrange(size, BIG):
358 append(i)
359 x = pop()
360 if x != i - size:
361 self.assertEqual(x, i-size)
362 self.assertEqual(list(d), range(BIG-size, BIG))
363
364 def test_long_steadystate_queue_popright(self):
365 for size in (0, 1, 2, 100, 1000):
366 d = deque(reversed(xrange(size)))
367 append, pop = d.appendleft, d.pop
368 for i in xrange(size, BIG):
369 append(i)
370 x = pop()
371 if x != i - size:
372 self.assertEqual(x, i-size)
373 self.assertEqual(list(reversed(list(d))), range(BIG-size, BIG))
374
375 def test_big_queue_popleft(self):
376 pass
377 d = deque()
378 append, pop = d.append, d.popleft
379 for i in xrange(BIG):
380 append(i)
381 for i in xrange(BIG):
382 x = pop()
383 if x != i:
384 self.assertEqual(x, i)
385
386 def test_big_queue_popright(self):
387 d = deque()
388 append, pop = d.appendleft, d.pop
389 for i in xrange(BIG):
390 append(i)
391 for i in xrange(BIG):
392 x = pop()
393 if x != i:
394 self.assertEqual(x, i)
395
396 def test_big_stack_right(self):
397 d = deque()
398 append, pop = d.append, d.pop
399 for i in xrange(BIG):
400 append(i)
401 for i in reversed(xrange(BIG)):
402 x = pop()
403 if x != i:
404 self.assertEqual(x, i)
405 self.assertEqual(len(d), 0)
406
407 def test_big_stack_left(self):
408 d = deque()
409 append, pop = d.appendleft, d.popleft
410 for i in xrange(BIG):
411 append(i)
412 for i in reversed(xrange(BIG)):
413 x = pop()
414 if x != i:
415 self.assertEqual(x, i)
416 self.assertEqual(len(d), 0)
417
418 def test_roundtrip_iter_init(self):
419 d = deque(xrange(200))
420 e = deque(d)
421 self.assertNotEqual(id(d), id(e))
422 self.assertEqual(list(d), list(e))
423
424 def test_pickle(self):
425 d = deque(xrange(200))
Hirokazu Yamamoto0fc07472008-12-27 04:19:48 +0000426 for i in range(pickle.HIGHEST_PROTOCOL + 1):
Raymond Hettinger952f8802004-11-09 07:27:35 +0000427 s = pickle.dumps(d, i)
428 e = pickle.loads(s)
429 self.assertNotEqual(id(d), id(e))
430 self.assertEqual(list(d), list(e))
431
Raymond Hettingera7fc4b12007-10-05 02:47:07 +0000432## def test_pickle_recursive(self):
433## d = deque('abc')
434## d.append(d)
Hirokazu Yamamoto0fc07472008-12-27 04:19:48 +0000435## for i in range(pickle.HIGHEST_PROTOCOL + 1):
Raymond Hettingera7fc4b12007-10-05 02:47:07 +0000436## e = pickle.loads(pickle.dumps(d, i))
437## self.assertNotEqual(id(d), id(e))
438## self.assertEqual(id(e), id(e[-1]))
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000439
440 def test_deepcopy(self):
441 mut = [10]
442 d = deque([mut])
443 e = copy.deepcopy(d)
444 self.assertEqual(list(d), list(e))
445 mut[0] = 11
446 self.assertNotEqual(id(d), id(e))
447 self.assertNotEqual(list(d), list(e))
448
449 def test_copy(self):
450 mut = [10]
451 d = deque([mut])
452 e = copy.copy(d)
453 self.assertEqual(list(d), list(e))
454 mut[0] = 11
455 self.assertNotEqual(id(d), id(e))
456 self.assertEqual(list(d), list(e))
457
Raymond Hettingerc058fd12004-02-07 02:45:22 +0000458 def test_reversed(self):
459 for s in ('abcd', xrange(2000)):
460 self.assertEqual(list(reversed(deque(s))), list(reversed(s)))
461
Tim Peters10c7e862004-10-01 02:01:04 +0000462 def test_gc_doesnt_blowup(self):
463 import gc
464 # This used to assert-fail in deque_traverse() under a debug
465 # build, or run wild with a NULL pointer in a release build.
466 d = deque()
467 for i in xrange(100):
468 d.append(1)
469 gc.collect()
470
Antoine Pitrouaa687902009-01-01 14:11:22 +0000471 def test_container_iterator(self):
Antoine Pitrou733dc742009-01-01 15:38:03 +0000472 # Bug #3680: tp_traverse was not implemented for deque iterator objects
Antoine Pitrouaa687902009-01-01 14:11:22 +0000473 class C(object):
474 pass
475 for i in range(2):
476 obj = C()
477 ref = weakref.ref(obj)
478 if i == 0:
479 container = deque([obj, 1])
480 else:
481 container = reversed(deque([obj, 1]))
482 obj.x = iter(container)
483 del obj, container
484 gc.collect()
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000485 self.assertTrue(ref() is None, "Cycle was not collected")
Antoine Pitrouaa687902009-01-01 14:11:22 +0000486
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000487class TestVariousIteratorArgs(unittest.TestCase):
488
489 def test_constructor(self):
490 for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):
Walter Dörwald09a3f2c2005-03-22 22:43:28 +0000491 for g in (seq_tests.Sequence, seq_tests.IterFunc,
492 seq_tests.IterGen, seq_tests.IterFuncStop,
493 seq_tests.itermulti, seq_tests.iterfunc):
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000494 self.assertEqual(list(deque(g(s))), list(g(s)))
Walter Dörwald09a3f2c2005-03-22 22:43:28 +0000495 self.assertRaises(TypeError, deque, seq_tests.IterNextOnly(s))
496 self.assertRaises(TypeError, deque, seq_tests.IterNoNext(s))
497 self.assertRaises(ZeroDivisionError, deque, seq_tests.IterGenExc(s))
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000498
499 def test_iter_with_altered_data(self):
500 d = deque('abcdefg')
501 it = iter(d)
502 d.pop()
503 self.assertRaises(RuntimeError, it.next)
504
Raymond Hettinger51c2f6c2007-01-08 18:09:20 +0000505 def test_runtime_error_on_empty_deque(self):
506 d = deque()
507 it = iter(d)
508 d.append(10)
509 self.assertRaises(RuntimeError, it.next)
510
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000511class Deque(deque):
512 pass
513
Raymond Hettinger952f8802004-11-09 07:27:35 +0000514class DequeWithBadIter(deque):
515 def __iter__(self):
516 raise TypeError
517
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000518class TestSubclass(unittest.TestCase):
519
520 def test_basics(self):
Raymond Hettingeradf9ffd2007-12-13 00:08:37 +0000521 d = Deque(xrange(25))
522 d.__init__(xrange(200))
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000523 for i in xrange(200, 400):
524 d.append(i)
525 for i in reversed(xrange(-200, 0)):
526 d.appendleft(i)
527 self.assertEqual(list(d), range(-200, 400))
528 self.assertEqual(len(d), 600)
529
530 left = [d.popleft() for i in xrange(250)]
531 self.assertEqual(left, range(-200, 50))
532 self.assertEqual(list(d), range(50, 400))
533
534 right = [d.pop() for i in xrange(250)]
535 right.reverse()
536 self.assertEqual(right, range(150, 400))
537 self.assertEqual(list(d), range(50, 150))
538
539 d.clear()
540 self.assertEqual(len(d), 0)
541
542 def test_copy_pickle(self):
543
544 d = Deque('abc')
545
546 e = d.__copy__()
547 self.assertEqual(type(d), type(e))
548 self.assertEqual(list(d), list(e))
549
550 e = Deque(d)
551 self.assertEqual(type(d), type(e))
552 self.assertEqual(list(d), list(e))
553
554 s = pickle.dumps(d)
555 e = pickle.loads(s)
556 self.assertNotEqual(id(d), id(e))
557 self.assertEqual(type(d), type(e))
558 self.assertEqual(list(d), list(e))
559
Raymond Hettinger68995862007-10-10 00:26:46 +0000560 d = Deque('abcde', maxlen=4)
561
562 e = d.__copy__()
563 self.assertEqual(type(d), type(e))
564 self.assertEqual(list(d), list(e))
565
566 e = Deque(d)
567 self.assertEqual(type(d), type(e))
568 self.assertEqual(list(d), list(e))
569
570 s = pickle.dumps(d)
571 e = pickle.loads(s)
572 self.assertNotEqual(id(d), id(e))
573 self.assertEqual(type(d), type(e))
574 self.assertEqual(list(d), list(e))
575
Raymond Hettingera7fc4b12007-10-05 02:47:07 +0000576## def test_pickle(self):
577## d = Deque('abc')
578## d.append(d)
579##
580## e = pickle.loads(pickle.dumps(d))
581## self.assertNotEqual(id(d), id(e))
582## self.assertEqual(type(d), type(e))
583## dd = d.pop()
584## ee = e.pop()
585## self.assertEqual(id(e), id(ee))
586## self.assertEqual(d, e)
587##
588## d.x = d
589## e = pickle.loads(pickle.dumps(d))
590## self.assertEqual(id(e), id(e.x))
591##
592## d = DequeWithBadIter('abc')
593## self.assertRaises(TypeError, pickle.dumps, d)
Raymond Hettinger952f8802004-11-09 07:27:35 +0000594
Raymond Hettinger691d8052004-05-30 07:26:47 +0000595 def test_weakref(self):
596 d = deque('gallahad')
Antoine Pitrouaa687902009-01-01 14:11:22 +0000597 p = weakref.proxy(d)
Raymond Hettinger691d8052004-05-30 07:26:47 +0000598 self.assertEqual(str(p), str(d))
599 d = None
600 self.assertRaises(ReferenceError, str, p)
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000601
Armin Rigo974d7572004-10-02 13:59:34 +0000602 def test_strange_subclass(self):
603 class X(deque):
604 def __iter__(self):
605 return iter([])
606 d1 = X([1,2,3])
607 d2 = X([4,5,6])
608 d1 == d2 # not clear if this is supposed to be True or False,
609 # but it used to give a SystemError
610
Georg Brandlb84c1372007-01-21 10:28:43 +0000611
612class SubclassWithKwargs(deque):
613 def __init__(self, newarg=1):
614 deque.__init__(self)
615
616class TestSubclassWithKwargs(unittest.TestCase):
617 def test_subclass_with_kwargs(self):
618 # SF bug #1486663 -- this used to erroneously raise a TypeError
619 SubclassWithKwargs(newarg=1)
620
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000621#==============================================================================
622
Raymond Hettinger738ec902004-02-29 02:15:56 +0000623libreftest = """
624Example from the Library Reference: Doc/lib/libcollections.tex
625
626>>> from collections import deque
627>>> d = deque('ghi') # make a new deque with three items
628>>> for elem in d: # iterate over the deque's elements
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000629... print elem.upper()
Raymond Hettinger738ec902004-02-29 02:15:56 +0000630G
631H
632I
633>>> d.append('j') # add a new entry to the right side
634>>> d.appendleft('f') # add a new entry to the left side
635>>> d # show the representation of the deque
636deque(['f', 'g', 'h', 'i', 'j'])
637>>> d.pop() # return and remove the rightmost item
638'j'
639>>> d.popleft() # return and remove the leftmost item
640'f'
641>>> list(d) # list the contents of the deque
642['g', 'h', 'i']
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000643>>> d[0] # peek at leftmost item
Raymond Hettinger738ec902004-02-29 02:15:56 +0000644'g'
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000645>>> d[-1] # peek at rightmost item
Raymond Hettinger738ec902004-02-29 02:15:56 +0000646'i'
647>>> list(reversed(d)) # list the contents of a deque in reverse
648['i', 'h', 'g']
649>>> 'h' in d # search the deque
650True
651>>> d.extend('jkl') # add multiple elements at once
652>>> d
653deque(['g', 'h', 'i', 'j', 'k', 'l'])
654>>> d.rotate(1) # right rotation
655>>> d
656deque(['l', 'g', 'h', 'i', 'j', 'k'])
657>>> d.rotate(-1) # left rotation
658>>> d
659deque(['g', 'h', 'i', 'j', 'k', 'l'])
660>>> deque(reversed(d)) # make a new deque in reverse order
661deque(['l', 'k', 'j', 'i', 'h', 'g'])
662>>> d.clear() # empty the deque
663>>> d.pop() # cannot pop from an empty deque
664Traceback (most recent call last):
665 File "<pyshell#6>", line 1, in -toplevel-
666 d.pop()
667IndexError: pop from an empty deque
668
669>>> d.extendleft('abc') # extendleft() reverses the input order
670>>> d
671deque(['c', 'b', 'a'])
672
Raymond Hettingere7169eb2004-05-09 01:15:01 +0000673
674
Raymond Hettingere7169eb2004-05-09 01:15:01 +0000675>>> def delete_nth(d, n):
Raymond Hettingere7169eb2004-05-09 01:15:01 +0000676... d.rotate(-n)
677... d.popleft()
678... d.rotate(n)
679...
680>>> d = deque('abcdef')
681>>> delete_nth(d, 2) # remove the entry at d[2]
682>>> d
683deque(['a', 'b', 'd', 'e', 'f'])
684
685
686
687>>> def roundrobin(*iterables):
688... pending = deque(iter(i) for i in iterables)
689... while pending:
690... task = pending.popleft()
691... try:
692... yield task.next()
693... except StopIteration:
694... continue
695... pending.append(task)
696...
697
698>>> for value in roundrobin('abc', 'd', 'efgh'):
699... print value
700...
701a
702d
703e
704b
705f
706c
707g
708h
709
710
711>>> def maketree(iterable):
712... d = deque(iterable)
713... while len(d) > 1:
714... pair = [d.popleft(), d.popleft()]
715... d.append(pair)
716... return list(d)
717...
718>>> print maketree('abcdefgh')
719[[[['a', 'b'], ['c', 'd']], [['e', 'f'], ['g', 'h']]]]
720
Raymond Hettinger738ec902004-02-29 02:15:56 +0000721"""
722
723
724#==============================================================================
725
726__test__ = {'libreftest' : libreftest}
727
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000728def test_main(verbose=None):
729 import sys
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000730 test_classes = (
731 TestBasic,
732 TestVariousIteratorArgs,
733 TestSubclass,
Georg Brandlb84c1372007-01-21 10:28:43 +0000734 TestSubclassWithKwargs,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000735 )
736
737 test_support.run_unittest(*test_classes)
738
739 # verify reference counting
740 if verbose and hasattr(sys, "gettotalrefcount"):
741 import gc
742 counts = [None] * 5
743 for i in xrange(len(counts)):
744 test_support.run_unittest(*test_classes)
745 gc.collect()
746 counts[i] = sys.gettotalrefcount()
747 print counts
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000748
Raymond Hettinger738ec902004-02-29 02:15:56 +0000749 # doctests
750 from test import test_deque
Raymond Hettinger354433a2004-05-19 08:20:33 +0000751 test_support.run_doctest(test_deque, verbose)
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000752
753if __name__ == "__main__":
754 test_main(verbose=True)