1 from collections import deque 2 import unittest 3 from test import test_support, seq_tests 4 import gc 5 import weakref 6 import copy 7 import cPickle as pickle 8 import random 9 import struct 10 11 BIG = 100000 12 13 def fail(): 14 raise SyntaxError 15 yield 1 16 17 class BadCmp: 18 def __eq__(self, other): 19 raise RuntimeError 20 21 class MutateCmp: 22 def __init__(self, deque, result): 23 self.deque = deque 24 self.result = result 25 def __eq__(self, other): 26 self.deque.clear() 27 return self.result 28 29 class TestBasic(unittest.TestCase): 30 31 def test_basics(self): 32 d = deque(xrange(-5125, -5000)) 33 d.__init__(xrange(200)) 34 for i in xrange(200, 400): 35 d.append(i) 36 for i in reversed(xrange(-200, 0)): 37 d.appendleft(i) 38 self.assertEqual(list(d), range(-200, 400)) 39 self.assertEqual(len(d), 600) 40 41 left = [d.popleft() for i in xrange(250)] 42 self.assertEqual(left, range(-200, 50)) 43 self.assertEqual(list(d), range(50, 400)) 44 45 right = [d.pop() for i in xrange(250)] 46 right.reverse() 47 self.assertEqual(right, range(150, 400)) 48 self.assertEqual(list(d), range(50, 150)) 49 50 def test_maxlen(self): 51 self.assertRaises(ValueError, deque, 'abc', -1) 52 self.assertRaises(ValueError, deque, 'abc', -2) 53 it = iter(range(10)) 54 d = deque(it, maxlen=3) 55 self.assertEqual(list(it), []) 56 self.assertEqual(repr(d), 'deque([7, 8, 9], maxlen=3)') 57 self.assertEqual(list(d), range(7, 10)) 58 self.assertEqual(d, deque(range(10), 3)) 59 d.append(10) 60 self.assertEqual(list(d), range(8, 11)) 61 d.appendleft(7) 62 self.assertEqual(list(d), range(7, 10)) 63 d.extend([10, 11]) 64 self.assertEqual(list(d), range(9, 12)) 65 d.extendleft([8, 7]) 66 self.assertEqual(list(d), range(7, 10)) 67 d = deque(xrange(200), maxlen=10) 68 d.append(d) 69 test_support.unlink(test_support.TESTFN) 70 fo = open(test_support.TESTFN, "wb") 71 try: 72 print >> fo, d, 73 fo.close() 74 fo = open(test_support.TESTFN, "rb") 75 self.assertEqual(fo.read(), repr(d)) 76 finally: 77 fo.close() 78 test_support.unlink(test_support.TESTFN) 79 80 d = deque(range(10), maxlen=None) 81 self.assertEqual(repr(d), 'deque([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])') 82 fo = open(test_support.TESTFN, "wb") 83 try: 84 print >> fo, d, 85 fo.close() 86 fo = open(test_support.TESTFN, "rb") 87 self.assertEqual(fo.read(), repr(d)) 88 finally: 89 fo.close() 90 test_support.unlink(test_support.TESTFN) 91 92 def test_maxlen_zero(self): 93 it = iter(range(100)) 94 deque(it, maxlen=0) 95 self.assertEqual(list(it), []) 96 97 it = iter(range(100)) 98 d = deque(maxlen=0) 99 d.extend(it) 100 self.assertEqual(list(it), []) 101 102 it = iter(range(100)) 103 d = deque(maxlen=0) 104 d.extendleft(it) 105 self.assertEqual(list(it), []) 106 107 def test_maxlen_attribute(self): 108 self.assertEqual(deque().maxlen, None) 109 self.assertEqual(deque('abc').maxlen, None) 110 self.assertEqual(deque('abc', maxlen=4).maxlen, 4) 111 self.assertEqual(deque('abc', maxlen=2).maxlen, 2) 112 self.assertEqual(deque('abc', maxlen=0).maxlen, 0) 113 with self.assertRaises(AttributeError): 114 d = deque('abc') 115 d.maxlen = 10 116 117 def test_count(self): 118 for s in ('', 'abracadabra', 'simsalabim'*500+'abc'): 119 s = list(s) 120 d = deque(s) 121 for letter in 'abcdefghijklmnopqrstuvwxyz': 122 self.assertEqual(s.count(letter), d.count(letter), (s, d, letter)) 123 self.assertRaises(TypeError, d.count) # too few args 124 self.assertRaises(TypeError, d.count, 1, 2) # too many args 125 class BadCompare: 126 def __eq__(self, other): 127 raise ArithmeticError 128 d = deque([1, 2, BadCompare(), 3]) 129 self.assertRaises(ArithmeticError, d.count, 2) 130 d = deque([1, 2, 3]) 131 self.assertRaises(ArithmeticError, d.count, BadCompare()) 132 class MutatingCompare: 133 def __eq__(self, other): 134 self.d.pop() 135 return True 136 m = MutatingCompare() 137 d = deque([1, 2, 3, m, 4, 5]) 138 m.d = d 139 self.assertRaises(RuntimeError, d.count, 3) 140 141 # test issue11004 142 # block advance failed after rotation aligned elements on right side of block 143 d = deque([None]*16) 144 for i in range(len(d)): 145 d.rotate(-1) 146 d.rotate(1) 147 self.assertEqual(d.count(1), 0) 148 self.assertEqual(d.count(None), 16) 149 150 def test_comparisons(self): 151 d = deque('xabc'); d.popleft() 152 for e in [d, deque('abc'), deque('ab'), deque(), list(d)]: 153 self.assertEqual(d==e, type(d)==type(e) and list(d)==list(e)) 154 self.assertEqual(d!=e, not(type(d)==type(e) and list(d)==list(e))) 155 156 args = map(deque, ('', 'a', 'b', 'ab', 'ba', 'abc', 'xba', 'xabc', 'cba')) 157 for x in args: 158 for y in args: 159 self.assertEqual(x == y, list(x) == list(y), (x,y)) 160 self.assertEqual(x != y, list(x) != list(y), (x,y)) 161 self.assertEqual(x < y, list(x) < list(y), (x,y)) 162 self.assertEqual(x <= y, list(x) <= list(y), (x,y)) 163 self.assertEqual(x > y, list(x) > list(y), (x,y)) 164 self.assertEqual(x >= y, list(x) >= list(y), (x,y)) 165 self.assertEqual(cmp(x,y), cmp(list(x),list(y)), (x,y)) 166 167 def test_extend(self): 168 d = deque('a') 169 self.assertRaises(TypeError, d.extend, 1) 170 d.extend('bcd') 171 self.assertEqual(list(d), list('abcd')) 172 d.extend(d) 173 self.assertEqual(list(d), list('abcdabcd')) 174 175 def test_iadd(self): 176 d = deque('a') 177 d += 'bcd' 178 self.assertEqual(list(d), list('abcd')) 179 d += d 180 self.assertEqual(list(d), list('abcdabcd')) 181 182 def test_extendleft(self): 183 d = deque('a') 184 self.assertRaises(TypeError, d.extendleft, 1) 185 d.extendleft('bcd') 186 self.assertEqual(list(d), list(reversed('abcd'))) 187 d.extendleft(d) 188 self.assertEqual(list(d), list('abcddcba')) 189 d = deque() 190 d.extendleft(range(1000)) 191 self.assertEqual(list(d), list(reversed(range(1000)))) 192 self.assertRaises(SyntaxError, d.extendleft, fail()) 193 194 def test_getitem(self): 195 n = 200 196 d = deque(xrange(n)) 197 l = range(n) 198 for i in xrange(n): 199 d.popleft() 200 l.pop(0) 201 if random.random() < 0.5: 202 d.append(i) 203 l.append(i) 204 for j in xrange(1-len(l), len(l)): 205 assert d[j] == l[j] 206 207 d = deque('superman') 208 self.assertEqual(d[0], 's') 209 self.assertEqual(d[-1], 'n') 210 d = deque() 211 self.assertRaises(IndexError, d.__getitem__, 0) 212 self.assertRaises(IndexError, d.__getitem__, -1) 213 214 def test_setitem(self): 215 n = 200 216 d = deque(xrange(n)) 217 for i in xrange(n): 218 d[i] = 10 * i 219 self.assertEqual(list(d), [10*i for i in xrange(n)]) 220 l = list(d) 221 for i in xrange(1-n, 0, -1): 222 d[i] = 7*i 223 l[i] = 7*i 224 self.assertEqual(list(d), l) 225 226 def test_delitem(self): 227 n = 500 # O(n**2) test, don't make this too big 228 d = deque(xrange(n)) 229 self.assertRaises(IndexError, d.__delitem__, -n-1) 230 self.assertRaises(IndexError, d.__delitem__, n) 231 for i in xrange(n): 232 self.assertEqual(len(d), n-i) 233 j = random.randrange(-len(d), len(d)) 234 val = d[j] 235 self.assertIn(val, d) 236 del d[j] 237 self.assertNotIn(val, d) 238 self.assertEqual(len(d), 0) 239 240 def test_reverse(self): 241 n = 500 # O(n**2) test, don't make this too big 242 data = [random.random() for i in range(n)] 243 for i in range(n): 244 d = deque(data[:i]) 245 r = d.reverse() 246 self.assertEqual(list(d), list(reversed(data[:i]))) 247 self.assertIs(r, None) 248 d.reverse() 249 self.assertEqual(list(d), data[:i]) 250 self.assertRaises(TypeError, d.reverse, 1) # Arity is zero 251 252 def test_rotate(self): 253 s = tuple('abcde') 254 n = len(s) 255 256 d = deque(s) 257 d.rotate(1) # verify rot(1) 258 self.assertEqual(''.join(d), 'eabcd') 259 260 d = deque(s) 261 d.rotate(-1) # verify rot(-1) 262 self.assertEqual(''.join(d), 'bcdea') 263 d.rotate() # check default to 1 264 self.assertEqual(tuple(d), s) 265 266 for i in xrange(n*3): 267 d = deque(s) 268 e = deque(d) 269 d.rotate(i) # check vs. rot(1) n times 270 for j in xrange(i): 271 e.rotate(1) 272 self.assertEqual(tuple(d), tuple(e)) 273 d.rotate(-i) # check that it works in reverse 274 self.assertEqual(tuple(d), s) 275 e.rotate(n-i) # check that it wraps forward 276 self.assertEqual(tuple(e), s) 277 278 for i in xrange(n*3): 279 d = deque(s) 280 e = deque(d) 281 d.rotate(-i) 282 for j in xrange(i): 283 e.rotate(-1) # check vs. rot(-1) n times 284 self.assertEqual(tuple(d), tuple(e)) 285 d.rotate(i) # check that it works in reverse 286 self.assertEqual(tuple(d), s) 287 e.rotate(i-n) # check that it wraps backaround 288 self.assertEqual(tuple(e), s) 289 290 d = deque(s) 291 e = deque(s) 292 e.rotate(BIG+17) # verify on long series of rotates 293 dr = d.rotate 294 for i in xrange(BIG+17): 295 dr() 296 self.assertEqual(tuple(d), tuple(e)) 297 298 self.assertRaises(TypeError, d.rotate, 'x') # Wrong arg type 299 self.assertRaises(TypeError, d.rotate, 1, 10) # Too many args 300 301 d = deque() 302 d.rotate() # rotate an empty deque 303 self.assertEqual(d, deque()) 304 305 def test_len(self): 306 d = deque('ab') 307 self.assertEqual(len(d), 2) 308 d.popleft() 309 self.assertEqual(len(d), 1) 310 d.pop() 311 self.assertEqual(len(d), 0) 312 self.assertRaises(IndexError, d.pop) 313 self.assertEqual(len(d), 0) 314 d.append('c') 315 self.assertEqual(len(d), 1) 316 d.appendleft('d') 317 self.assertEqual(len(d), 2) 318 d.clear() 319 self.assertEqual(len(d), 0) 320 321 def test_underflow(self): 322 d = deque() 323 self.assertRaises(IndexError, d.pop) 324 self.assertRaises(IndexError, d.popleft) 325 326 def test_clear(self): 327 d = deque(xrange(100)) 328 self.assertEqual(len(d), 100) 329 d.clear() 330 self.assertEqual(len(d), 0) 331 self.assertEqual(list(d), []) 332 d.clear() # clear an emtpy deque 333 self.assertEqual(list(d), []) 334 335 def test_remove(self): 336 d = deque('abcdefghcij') 337 d.remove('c') 338 self.assertEqual(d, deque('abdefghcij')) 339 d.remove('c') 340 self.assertEqual(d, deque('abdefghij')) 341 self.assertRaises(ValueError, d.remove, 'c') 342 self.assertEqual(d, deque('abdefghij')) 343 344 # Handle comparison errors 345 d = deque(['a', 'b', BadCmp(), 'c']) 346 e = deque(d) 347 self.assertRaises(RuntimeError, d.remove, 'c') 348 for x, y in zip(d, e): 349 # verify that original order and values are retained. 350 self.assertTrue(x is y) 351 352 # Handle evil mutator 353 for match in (True, False): 354 d = deque(['ab']) 355 d.extend([MutateCmp(d, match), 'c']) 356 self.assertRaises(IndexError, d.remove, 'c') 357 self.assertEqual(d, deque()) 358 359 def test_repr(self): 360 d = deque(xrange(200)) 361 e = eval(repr(d)) 362 self.assertEqual(list(d), list(e)) 363 d.append(d) 364 self.assertIn('...', repr(d)) 365 366 def test_print(self): 367 d = deque(xrange(200)) 368 d.append(d) 369 test_support.unlink(test_support.TESTFN) 370 fo = open(test_support.TESTFN, "wb") 371 try: 372 print >> fo, d, 373 fo.close() 374 fo = open(test_support.TESTFN, "rb") 375 self.assertEqual(fo.read(), repr(d)) 376 finally: 377 fo.close() 378 test_support.unlink(test_support.TESTFN) 379 380 def test_init(self): 381 self.assertRaises(TypeError, deque, 'abc', 2, 3); 382 self.assertRaises(TypeError, deque, 1); 383 384 def test_hash(self): 385 self.assertRaises(TypeError, hash, deque('abc')) 386 387 def test_long_steadystate_queue_popleft(self): 388 for size in (0, 1, 2, 100, 1000): 389 d = deque(xrange(size)) 390 append, pop = d.append, d.popleft 391 for i in xrange(size, BIG): 392 append(i) 393 x = pop() 394 if x != i - size: 395 self.assertEqual(x, i-size) 396 self.assertEqual(list(d), range(BIG-size, BIG)) 397 398 def test_long_steadystate_queue_popright(self): 399 for size in (0, 1, 2, 100, 1000): 400 d = deque(reversed(xrange(size))) 401 append, pop = d.appendleft, d.pop 402 for i in xrange(size, BIG): 403 append(i) 404 x = pop() 405 if x != i - size: 406 self.assertEqual(x, i-size) 407 self.assertEqual(list(reversed(list(d))), range(BIG-size, BIG)) 408 409 def test_big_queue_popleft(self): 410 pass 411 d = deque() 412 append, pop = d.append, d.popleft 413 for i in xrange(BIG): 414 append(i) 415 for i in xrange(BIG): 416 x = pop() 417 if x != i: 418 self.assertEqual(x, i) 419 420 def test_big_queue_popright(self): 421 d = deque() 422 append, pop = d.appendleft, d.pop 423 for i in xrange(BIG): 424 append(i) 425 for i in xrange(BIG): 426 x = pop() 427 if x != i: 428 self.assertEqual(x, i) 429 430 def test_big_stack_right(self): 431 d = deque() 432 append, pop = d.append, d.pop 433 for i in xrange(BIG): 434 append(i) 435 for i in reversed(xrange(BIG)): 436 x = pop() 437 if x != i: 438 self.assertEqual(x, i) 439 self.assertEqual(len(d), 0) 440 441 def test_big_stack_left(self): 442 d = deque() 443 append, pop = d.appendleft, d.popleft 444 for i in xrange(BIG): 445 append(i) 446 for i in reversed(xrange(BIG)): 447 x = pop() 448 if x != i: 449 self.assertEqual(x, i) 450 self.assertEqual(len(d), 0) 451 452 def test_roundtrip_iter_init(self): 453 d = deque(xrange(200)) 454 e = deque(d) 455 self.assertNotEqual(id(d), id(e)) 456 self.assertEqual(list(d), list(e)) 457 458 def test_pickle(self): 459 d = deque(xrange(200)) 460 for i in range(pickle.HIGHEST_PROTOCOL + 1): 461 s = pickle.dumps(d, i) 462 e = pickle.loads(s) 463 self.assertNotEqual(id(d), id(e)) 464 self.assertEqual(list(d), list(e)) 465 466 ## def test_pickle_recursive(self): 467 ## d = deque('abc') 468 ## d.append(d) 469 ## for i in range(pickle.HIGHEST_PROTOCOL + 1): 470 ## e = pickle.loads(pickle.dumps(d, i)) 471 ## self.assertNotEqual(id(d), id(e)) 472 ## self.assertEqual(id(e), id(e[-1])) 473 474 def test_deepcopy(self): 475 mut = [10] 476 d = deque([mut]) 477 e = copy.deepcopy(d) 478 self.assertEqual(list(d), list(e)) 479 mut[0] = 11 480 self.assertNotEqual(id(d), id(e)) 481 self.assertNotEqual(list(d), list(e)) 482 483 def test_copy(self): 484 mut = [10] 485 d = deque([mut]) 486 e = copy.copy(d) 487 self.assertEqual(list(d), list(e)) 488 mut[0] = 11 489 self.assertNotEqual(id(d), id(e)) 490 self.assertEqual(list(d), list(e)) 491 492 def test_reversed(self): 493 for s in ('abcd', xrange(2000)): 494 self.assertEqual(list(reversed(deque(s))), list(reversed(s))) 495 496 def test_gc_doesnt_blowup(self): 497 import gc 498 # This used to assert-fail in deque_traverse() under a debug 499 # build, or run wild with a NULL pointer in a release build. 500 d = deque() 501 for i in xrange(100): 502 d.append(1) 503 gc.collect() 504 505 def test_container_iterator(self): 506 # Bug #3680: tp_traverse was not implemented for deque iterator objects 507 class C(object): 508 pass 509 for i in range(2): 510 obj = C() 511 ref = weakref.ref(obj) 512 if i == 0: 513 container = deque([obj, 1]) 514 else: 515 container = reversed(deque([obj, 1])) 516 obj.x = iter(container) 517 del obj, container 518 gc.collect() 519 self.assertTrue(ref() is None, "Cycle was not collected") 520 521 check_sizeof = test_support.check_sizeof 522 523 @test_support.cpython_only 524 def test_sizeof(self): 525 BLOCKLEN = 62 526 basesize = test_support.calcobjsize('2P4PlP') 527 blocksize = struct.calcsize('2P%dP' % BLOCKLEN) 528 self.assertEqual(object.__sizeof__(deque()), basesize) 529 check = self.check_sizeof 530 check(deque(), basesize + blocksize) 531 check(deque('a'), basesize + blocksize) 532 check(deque('a' * (BLOCKLEN // 2)), basesize + blocksize) 533 check(deque('a' * (BLOCKLEN // 2 + 1)), basesize + 2 * blocksize) 534 check(deque('a' * (42 * BLOCKLEN)), basesize + 43 * blocksize) 535 536 class TestVariousIteratorArgs(unittest.TestCase): 537 538 def test_constructor(self): 539 for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)): 540 for g in (seq_tests.Sequence, seq_tests.IterFunc, 541 seq_tests.IterGen, seq_tests.IterFuncStop, 542 seq_tests.itermulti, seq_tests.iterfunc): 543 self.assertEqual(list(deque(g(s))), list(g(s))) 544 self.assertRaises(TypeError, deque, seq_tests.IterNextOnly(s)) 545 self.assertRaises(TypeError, deque, seq_tests.IterNoNext(s)) 546 self.assertRaises(ZeroDivisionError, deque, seq_tests.IterGenExc(s)) 547 548 def test_iter_with_altered_data(self): 549 d = deque('abcdefg') 550 it = iter(d) 551 d.pop() 552 self.assertRaises(RuntimeError, it.next) 553 554 def test_runtime_error_on_empty_deque(self): 555 d = deque() 556 it = iter(d) 557 d.append(10) 558 self.assertRaises(RuntimeError, it.next) 559 560 class Deque(deque): 561 pass 562 563 class DequeWithBadIter(deque): 564 def __iter__(self): 565 raise TypeError 566 567 class TestSubclass(unittest.TestCase): 568 569 def test_basics(self): 570 d = Deque(xrange(25)) 571 d.__init__(xrange(200)) 572 for i in xrange(200, 400): 573 d.append(i) 574 for i in reversed(xrange(-200, 0)): 575 d.appendleft(i) 576 self.assertEqual(list(d), range(-200, 400)) 577 self.assertEqual(len(d), 600) 578 579 left = [d.popleft() for i in xrange(250)] 580 self.assertEqual(left, range(-200, 50)) 581 self.assertEqual(list(d), range(50, 400)) 582 583 right = [d.pop() for i in xrange(250)] 584 right.reverse() 585 self.assertEqual(right, range(150, 400)) 586 self.assertEqual(list(d), range(50, 150)) 587 588 d.clear() 589 self.assertEqual(len(d), 0) 590 591 def test_copy_pickle(self): 592 593 d = Deque('abc') 594 595 e = d.__copy__() 596 self.assertEqual(type(d), type(e)) 597 self.assertEqual(list(d), list(e)) 598 599 e = Deque(d) 600 self.assertEqual(type(d), type(e)) 601 self.assertEqual(list(d), list(e)) 602 603 s = pickle.dumps(d) 604 e = pickle.loads(s) 605 self.assertNotEqual(id(d), id(e)) 606 self.assertEqual(type(d), type(e)) 607 self.assertEqual(list(d), list(e)) 608 609 d = Deque('abcde', maxlen=4) 610 611 e = d.__copy__() 612 self.assertEqual(type(d), type(e)) 613 self.assertEqual(list(d), list(e)) 614 615 e = Deque(d) 616 self.assertEqual(type(d), type(e)) 617 self.assertEqual(list(d), list(e)) 618 619 s = pickle.dumps(d) 620 e = pickle.loads(s) 621 self.assertNotEqual(id(d), id(e)) 622 self.assertEqual(type(d), type(e)) 623 self.assertEqual(list(d), list(e)) 624 625 ## def test_pickle(self): 626 ## d = Deque('abc') 627 ## d.append(d) 628 ## 629 ## e = pickle.loads(pickle.dumps(d)) 630 ## self.assertNotEqual(id(d), id(e)) 631 ## self.assertEqual(type(d), type(e)) 632 ## dd = d.pop() 633 ## ee = e.pop() 634 ## self.assertEqual(id(e), id(ee)) 635 ## self.assertEqual(d, e) 636 ## 637 ## d.x = d 638 ## e = pickle.loads(pickle.dumps(d)) 639 ## self.assertEqual(id(e), id(e.x)) 640 ## 641 ## d = DequeWithBadIter('abc') 642 ## self.assertRaises(TypeError, pickle.dumps, d) 643 644 def test_weakref(self): 645 d = deque('gallahad') 646 p = weakref.proxy(d) 647 self.assertEqual(str(p), str(d)) 648 d = None 649 self.assertRaises(ReferenceError, str, p) 650 651 def test_strange_subclass(self): 652 class X(deque): 653 def __iter__(self): 654 return iter([]) 655 d1 = X([1,2,3]) 656 d2 = X([4,5,6]) 657 d1 == d2 # not clear if this is supposed to be True or False, 658 # but it used to give a SystemError 659 660 661 class SubclassWithKwargs(deque): 662 def __init__(self, newarg=1): 663 deque.__init__(self) 664 665 class TestSubclassWithKwargs(unittest.TestCase): 666 def test_subclass_with_kwargs(self): 667 # SF bug #1486663 -- this used to erroneously raise a TypeError 668 SubclassWithKwargs(newarg=1) 669 670 #============================================================================== 671 672 libreftest = """ 673 Example from the Library Reference: Doc/lib/libcollections.tex 674 675 >>> from collections import deque 676 >>> d = deque('ghi') # make a new deque with three items 677 >>> for elem in d: # iterate over the deque's elements 678 ... print elem.upper() 679 G 680 H 681 I 682 >>> d.append('j') # add a new entry to the right side 683 >>> d.appendleft('f') # add a new entry to the left side 684 >>> d # show the representation of the deque 685 deque(['f', 'g', 'h', 'i', 'j']) 686 >>> d.pop() # return and remove the rightmost item 687 'j' 688 >>> d.popleft() # return and remove the leftmost item 689 'f' 690 >>> list(d) # list the contents of the deque 691 ['g', 'h', 'i'] 692 >>> d[0] # peek at leftmost item 693 'g' 694 >>> d[-1] # peek at rightmost item 695 'i' 696 >>> list(reversed(d)) # list the contents of a deque in reverse 697 ['i', 'h', 'g'] 698 >>> 'h' in d # search the deque 699 True 700 >>> d.extend('jkl') # add multiple elements at once 701 >>> d 702 deque(['g', 'h', 'i', 'j', 'k', 'l']) 703 >>> d.rotate(1) # right rotation 704 >>> d 705 deque(['l', 'g', 'h', 'i', 'j', 'k']) 706 >>> d.rotate(-1) # left rotation 707 >>> d 708 deque(['g', 'h', 'i', 'j', 'k', 'l']) 709 >>> deque(reversed(d)) # make a new deque in reverse order 710 deque(['l', 'k', 'j', 'i', 'h', 'g']) 711 >>> d.clear() # empty the deque 712 >>> d.pop() # cannot pop from an empty deque 713 Traceback (most recent call last): 714 File "<pyshell#6>", line 1, in -toplevel- 715 d.pop() 716 IndexError: pop from an empty deque 717 718 >>> d.extendleft('abc') # extendleft() reverses the input order 719 >>> d 720 deque(['c', 'b', 'a']) 721 722 723 724 >>> def delete_nth(d, n): 725 ... d.rotate(-n) 726 ... d.popleft() 727 ... d.rotate(n) 728 ... 729 >>> d = deque('abcdef') 730 >>> delete_nth(d, 2) # remove the entry at d[2] 731 >>> d 732 deque(['a', 'b', 'd', 'e', 'f']) 733 734 735 736 >>> def roundrobin(*iterables): 737 ... pending = deque(iter(i) for i in iterables) 738 ... while pending: 739 ... task = pending.popleft() 740 ... try: 741 ... yield task.next() 742 ... except StopIteration: 743 ... continue 744 ... pending.append(task) 745 ... 746 747 >>> for value in roundrobin('abc', 'd', 'efgh'): 748 ... print value 749 ... 750 a 751 d 752 e 753 b 754 f 755 c 756 g 757 h 758 759 760 >>> def maketree(iterable): 761 ... d = deque(iterable) 762 ... while len(d) > 1: 763 ... pair = [d.popleft(), d.popleft()] 764 ... d.append(pair) 765 ... return list(d) 766 ... 767 >>> print maketree('abcdefgh') 768 [[[['a', 'b'], ['c', 'd']], [['e', 'f'], ['g', 'h']]]] 769 770 """ 771 772 773 #============================================================================== 774 775 __test__ = {'libreftest' : libreftest} 776 777 def test_main(verbose=None): 778 import sys 779 test_classes = ( 780 TestBasic, 781 TestVariousIteratorArgs, 782 TestSubclass, 783 TestSubclassWithKwargs, 784 ) 785 786 test_support.run_unittest(*test_classes) 787 788 # verify reference counting 789 if verbose and hasattr(sys, "gettotalrefcount"): 790 import gc 791 counts = [None] * 5 792 for i in xrange(len(counts)): 793 test_support.run_unittest(*test_classes) 794 gc.collect() 795 counts[i] = sys.gettotalrefcount() 796 print counts 797 798 # doctests 799 from test import test_deque 800 test_support.run_doctest(test_deque, verbose) 801 802 if __name__ == "__main__": 803 test_main(verbose=True) 804