1 from collections
import deque
3 from test
import test_support
, seq_tests
4 from weakref
import proxy
6 import cPickle
as pickle
7 from cStringIO
import StringIO
18 def __eq__(self
, other
):
22 def __init__(self
, deque
, result
):
25 def __eq__(self
, other
):
29 class TestBasic(unittest
.TestCase
):
31 def test_basics(self
):
32 d
= deque(xrange(100))
33 d
.__init
__(xrange(100, 200))
34 for i
in xrange(200, 400):
36 for i
in reversed(xrange(-200, 0)):
38 self
.assertEqual(list(d
), range(-200, 400))
39 self
.assertEqual(len(d
), 600)
41 left
= [d
.popleft() for i
in xrange(250)]
42 self
.assertEqual(left
, range(-200, 50))
43 self
.assertEqual(list(d
), range(50, 400))
45 right
= [d
.pop() for i
in xrange(250)]
47 self
.assertEqual(right
, range(150, 400))
48 self
.assertEqual(list(d
), range(50, 150))
50 def test_comparisons(self
):
51 d
= deque('xabc'); d
.popleft()
52 for e
in [d
, deque('abc'), deque('ab'), deque(), list(d
)]:
53 self
.assertEqual(d
==e
, type(d
)==type(e
) and list(d
)==list(e
))
54 self
.assertEqual(d
!=e
, not(type(d
)==type(e
) and list(d
)==list(e
)))
56 args
= map(deque
, ('', 'a', 'b', 'ab', 'ba', 'abc', 'xba', 'xabc', 'cba'))
59 self
.assertEqual(x
== y
, list(x
) == list(y
), (x
,y
))
60 self
.assertEqual(x
!= y
, list(x
) != list(y
), (x
,y
))
61 self
.assertEqual(x
< y
, list(x
) < list(y
), (x
,y
))
62 self
.assertEqual(x
<= y
, list(x
) <= list(y
), (x
,y
))
63 self
.assertEqual(x
> y
, list(x
) > list(y
), (x
,y
))
64 self
.assertEqual(x
>= y
, list(x
) >= list(y
), (x
,y
))
65 self
.assertEqual(cmp(x
,y
), cmp(list(x
),list(y
)), (x
,y
))
67 def test_extend(self
):
69 self
.assertRaises(TypeError, d
.extend
, 1)
71 self
.assertEqual(list(d
), list('abcd'))
73 def test_extendleft(self
):
75 self
.assertRaises(TypeError, d
.extendleft
, 1)
77 self
.assertEqual(list(d
), list(reversed('abcd')))
79 d
.extendleft(range(1000))
80 self
.assertEqual(list(d
), list(reversed(range(1000))))
81 self
.assertRaises(SyntaxError, d
.extendleft
, fail())
83 def test_getitem(self
):
90 if random
.random() < 0.5:
93 for j
in xrange(1-len(l
), len(l
)):
97 self
.assertEqual(d
[0], 's')
98 self
.assertEqual(d
[-1], 'n')
100 self
.assertRaises(IndexError, d
.__getitem
__, 0)
101 self
.assertRaises(IndexError, d
.__getitem
__, -1)
103 def test_setitem(self
):
108 self
.assertEqual(list(d
), [10*i
for i
in xrange(n
)])
110 for i
in xrange(1-n
, 0, -1):
113 self
.assertEqual(list(d
), l
)
115 def test_delitem(self
):
116 n
= 500 # O(n**2) test, don't make this too big
118 self
.assertRaises(IndexError, d
.__delitem
__, -n
-1)
119 self
.assertRaises(IndexError, d
.__delitem
__, n
)
121 self
.assertEqual(len(d
), n
-i
)
122 j
= random
.randrange(-len(d
), len(d
))
124 self
.assert_(val
in d
)
126 self
.assert_(val
not in d
)
127 self
.assertEqual(len(d
), 0)
129 def test_rotate(self
):
134 d
.rotate(1) # verify rot(1)
135 self
.assertEqual(''.join(d
), 'eabcd')
138 d
.rotate(-1) # verify rot(-1)
139 self
.assertEqual(''.join(d
), 'bcdea')
140 d
.rotate() # check default to 1
141 self
.assertEqual(tuple(d
), s
)
143 for i
in xrange(n
*3):
146 d
.rotate(i
) # check vs. rot(1) n times
149 self
.assertEqual(tuple(d
), tuple(e
))
150 d
.rotate(-i
) # check that it works in reverse
151 self
.assertEqual(tuple(d
), s
)
152 e
.rotate(n
-i
) # check that it wraps forward
153 self
.assertEqual(tuple(e
), s
)
155 for i
in xrange(n
*3):
160 e
.rotate(-1) # check vs. rot(-1) n times
161 self
.assertEqual(tuple(d
), tuple(e
))
162 d
.rotate(i
) # check that it works in reverse
163 self
.assertEqual(tuple(d
), s
)
164 e
.rotate(i
-n
) # check that it wraps backaround
165 self
.assertEqual(tuple(e
), s
)
169 e
.rotate(BIG
+17) # verify on long series of rotates
171 for i
in xrange(BIG
+17):
173 self
.assertEqual(tuple(d
), tuple(e
))
175 self
.assertRaises(TypeError, d
.rotate
, 'x') # Wrong arg type
176 self
.assertRaises(TypeError, d
.rotate
, 1, 10) # Too many args
179 d
.rotate() # rotate an empty deque
180 self
.assertEqual(d
, deque())
184 self
.assertEqual(len(d
), 2)
186 self
.assertEqual(len(d
), 1)
188 self
.assertEqual(len(d
), 0)
189 self
.assertRaises(IndexError, d
.pop
)
190 self
.assertEqual(len(d
), 0)
192 self
.assertEqual(len(d
), 1)
194 self
.assertEqual(len(d
), 2)
196 self
.assertEqual(len(d
), 0)
198 def test_underflow(self
):
200 self
.assertRaises(IndexError, d
.pop
)
201 self
.assertRaises(IndexError, d
.popleft
)
203 def test_clear(self
):
204 d
= deque(xrange(100))
205 self
.assertEqual(len(d
), 100)
207 self
.assertEqual(len(d
), 0)
208 self
.assertEqual(list(d
), [])
209 d
.clear() # clear an emtpy deque
210 self
.assertEqual(list(d
), [])
212 def test_remove(self
):
213 d
= deque('abcdefghcij')
215 self
.assertEqual(d
, deque('abdefghcij'))
217 self
.assertEqual(d
, deque('abdefghij'))
218 self
.assertRaises(ValueError, d
.remove
, 'c')
219 self
.assertEqual(d
, deque('abdefghij'))
221 # Handle comparison errors
222 d
= deque(['a', 'b', BadCmp(), 'c'])
224 self
.assertRaises(RuntimeError, d
.remove
, 'c')
225 for x
, y
in zip(d
, e
):
226 # verify that original order and values are retained.
229 # Handle evil mutator
230 for match
in (True, False):
232 d
.extend([MutateCmp(d
, match
), 'c'])
233 self
.assertRaises(IndexError, d
.remove
, 'c')
234 self
.assertEqual(d
, deque())
237 d
= deque(xrange(200))
239 self
.assertEqual(list(d
), list(e
))
241 self
.assert_('...' in repr(d
))
243 def test_print(self
):
244 d
= deque(xrange(200))
247 fo
= open(test_support
.TESTFN
, "wb")
250 fo
= open(test_support
.TESTFN
, "rb")
251 self
.assertEqual(fo
.read(), repr(d
))
254 os
.remove(test_support
.TESTFN
)
257 self
.assertRaises(TypeError, deque
, 'abc', 2);
258 self
.assertRaises(TypeError, deque
, 1);
261 self
.assertRaises(TypeError, hash, deque('abc'))
263 def test_long_steadystate_queue_popleft(self
):
264 for size
in (0, 1, 2, 100, 1000):
265 d
= deque(xrange(size
))
266 append
, pop
= d
.append
, d
.popleft
267 for i
in xrange(size
, BIG
):
271 self
.assertEqual(x
, i
-size
)
272 self
.assertEqual(list(d
), range(BIG
-size
, BIG
))
274 def test_long_steadystate_queue_popright(self
):
275 for size
in (0, 1, 2, 100, 1000):
276 d
= deque(reversed(xrange(size
)))
277 append
, pop
= d
.appendleft
, d
.pop
278 for i
in xrange(size
, BIG
):
282 self
.assertEqual(x
, i
-size
)
283 self
.assertEqual(list(reversed(list(d
))), range(BIG
-size
, BIG
))
285 def test_big_queue_popleft(self
):
288 append
, pop
= d
.append
, d
.popleft
289 for i
in xrange(BIG
):
291 for i
in xrange(BIG
):
294 self
.assertEqual(x
, i
)
296 def test_big_queue_popright(self
):
298 append
, pop
= d
.appendleft
, d
.pop
299 for i
in xrange(BIG
):
301 for i
in xrange(BIG
):
304 self
.assertEqual(x
, i
)
306 def test_big_stack_right(self
):
308 append
, pop
= d
.append
, d
.pop
309 for i
in xrange(BIG
):
311 for i
in reversed(xrange(BIG
)):
314 self
.assertEqual(x
, i
)
315 self
.assertEqual(len(d
), 0)
317 def test_big_stack_left(self
):
319 append
, pop
= d
.appendleft
, d
.popleft
320 for i
in xrange(BIG
):
322 for i
in reversed(xrange(BIG
)):
325 self
.assertEqual(x
, i
)
326 self
.assertEqual(len(d
), 0)
328 def test_roundtrip_iter_init(self
):
329 d
= deque(xrange(200))
331 self
.assertNotEqual(id(d
), id(e
))
332 self
.assertEqual(list(d
), list(e
))
334 def test_pickle(self
):
335 d
= deque(xrange(200))
337 s
= pickle
.dumps(d
, i
)
339 self
.assertNotEqual(id(d
), id(e
))
340 self
.assertEqual(list(d
), list(e
))
342 def test_pickle_recursive(self
):
346 e
= pickle
.loads(pickle
.dumps(d
, i
))
347 self
.assertNotEqual(id(d
), id(e
))
348 self
.assertEqual(id(e
), id(e
[-1]))
350 def test_deepcopy(self
):
354 self
.assertEqual(list(d
), list(e
))
356 self
.assertNotEqual(id(d
), id(e
))
357 self
.assertNotEqual(list(d
), list(e
))
363 self
.assertEqual(list(d
), list(e
))
365 self
.assertNotEqual(id(d
), id(e
))
366 self
.assertEqual(list(d
), list(e
))
368 def test_reversed(self
):
369 for s
in ('abcd', xrange(2000)):
370 self
.assertEqual(list(reversed(deque(s
))), list(reversed(s
)))
372 def test_gc_doesnt_blowup(self
):
374 # This used to assert-fail in deque_traverse() under a debug
375 # build, or run wild with a NULL pointer in a release build.
377 for i
in xrange(100):
381 class TestVariousIteratorArgs(unittest
.TestCase
):
383 def test_constructor(self
):
384 for s
in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)):
385 for g
in (seq_tests
.Sequence
, seq_tests
.IterFunc
,
386 seq_tests
.IterGen
, seq_tests
.IterFuncStop
,
387 seq_tests
.itermulti
, seq_tests
.iterfunc
):
388 self
.assertEqual(list(deque(g(s
))), list(g(s
)))
389 self
.assertRaises(TypeError, deque
, seq_tests
.IterNextOnly(s
))
390 self
.assertRaises(TypeError, deque
, seq_tests
.IterNoNext(s
))
391 self
.assertRaises(ZeroDivisionError, deque
, seq_tests
.IterGenExc(s
))
393 def test_iter_with_altered_data(self
):
397 self
.assertRaises(RuntimeError, it
.next
)
402 class DequeWithBadIter(deque
):
406 class TestSubclass(unittest
.TestCase
):
408 def test_basics(self
):
409 d
= Deque(xrange(100))
410 d
.__init
__(xrange(100, 200))
411 for i
in xrange(200, 400):
413 for i
in reversed(xrange(-200, 0)):
415 self
.assertEqual(list(d
), range(-200, 400))
416 self
.assertEqual(len(d
), 600)
418 left
= [d
.popleft() for i
in xrange(250)]
419 self
.assertEqual(left
, range(-200, 50))
420 self
.assertEqual(list(d
), range(50, 400))
422 right
= [d
.pop() for i
in xrange(250)]
424 self
.assertEqual(right
, range(150, 400))
425 self
.assertEqual(list(d
), range(50, 150))
428 self
.assertEqual(len(d
), 0)
430 def test_copy_pickle(self
):
435 self
.assertEqual(type(d
), type(e
))
436 self
.assertEqual(list(d
), list(e
))
439 self
.assertEqual(type(d
), type(e
))
440 self
.assertEqual(list(d
), list(e
))
444 self
.assertNotEqual(id(d
), id(e
))
445 self
.assertEqual(type(d
), type(e
))
446 self
.assertEqual(list(d
), list(e
))
448 def test_pickle(self
):
452 e
= pickle
.loads(pickle
.dumps(d
))
453 self
.assertNotEqual(id(d
), id(e
))
454 self
.assertEqual(type(d
), type(e
))
457 self
.assertEqual(id(e
), id(ee
))
458 self
.assertEqual(d
, e
)
461 e
= pickle
.loads(pickle
.dumps(d
))
462 self
.assertEqual(id(e
), id(e
.x
))
464 d
= DequeWithBadIter('abc')
465 self
.assertRaises(TypeError, pickle
.dumps
, d
)
467 def test_weakref(self
):
468 d
= deque('gallahad')
470 self
.assertEqual(str(p
), str(d
))
472 self
.assertRaises(ReferenceError, str, p
)
474 def test_strange_subclass(self
):
480 d1
== d2
# not clear if this is supposed to be True or False,
481 # but it used to give a SystemError
483 #==============================================================================
486 Example from the Library Reference: Doc/lib/libcollections.tex
488 >>> from collections import deque
489 >>> d = deque('ghi') # make a new deque with three items
490 >>> for elem in d: # iterate over the deque's elements
491 ... print elem.upper()
495 >>> d.append('j') # add a new entry to the right side
496 >>> d.appendleft('f') # add a new entry to the left side
497 >>> d # show the representation of the deque
498 deque(['f', 'g', 'h', 'i', 'j'])
499 >>> d.pop() # return and remove the rightmost item
501 >>> d.popleft() # return and remove the leftmost item
503 >>> list(d) # list the contents of the deque
505 >>> d[0] # peek at leftmost item
507 >>> d[-1] # peek at rightmost item
509 >>> list(reversed(d)) # list the contents of a deque in reverse
511 >>> 'h' in d # search the deque
513 >>> d.extend('jkl') # add multiple elements at once
515 deque(['g', 'h', 'i', 'j', 'k', 'l'])
516 >>> d.rotate(1) # right rotation
518 deque(['l', 'g', 'h', 'i', 'j', 'k'])
519 >>> d.rotate(-1) # left rotation
521 deque(['g', 'h', 'i', 'j', 'k', 'l'])
522 >>> deque(reversed(d)) # make a new deque in reverse order
523 deque(['l', 'k', 'j', 'i', 'h', 'g'])
524 >>> d.clear() # empty the deque
525 >>> d.pop() # cannot pop from an empty deque
526 Traceback (most recent call last):
527 File "<pyshell#6>", line 1, in -toplevel-
529 IndexError: pop from an empty deque
531 >>> d.extendleft('abc') # extendleft() reverses the input order
533 deque(['c', 'b', 'a'])
537 >>> def delete_nth(d, n):
542 >>> d = deque('abcdef')
543 >>> delete_nth(d, 2) # remove the entry at d[2]
545 deque(['a', 'b', 'd', 'e', 'f'])
549 >>> def roundrobin(*iterables):
550 ... pending = deque(iter(i) for i in iterables)
552 ... task = pending.popleft()
554 ... yield task.next()
555 ... except StopIteration:
557 ... pending.append(task)
560 >>> for value in roundrobin('abc', 'd', 'efgh'):
573 >>> def maketree(iterable):
574 ... d = deque(iterable)
575 ... while len(d) > 1:
576 ... pair = [d.popleft(), d.popleft()]
580 >>> print maketree('abcdefgh')
581 [[[['a', 'b'], ['c', 'd']], [['e', 'f'], ['g', 'h']]]]
586 #==============================================================================
588 __test__
= {'libreftest' : libreftest
}
590 def test_main(verbose
=None):
594 TestVariousIteratorArgs
,
598 test_support
.run_unittest(*test_classes
)
600 # verify reference counting
601 if verbose
and hasattr(sys
, "gettotalrefcount"):
604 for i
in xrange(len(counts
)):
605 test_support
.run_unittest(*test_classes
)
607 counts
[i
] = sys
.gettotalrefcount()
611 from test
import test_deque
612 test_support
.run_doctest(test_deque
, verbose
)
614 if __name__
== "__main__":
615 test_main(verbose
=True)