test_deque.py 22 KB
Newer Older
1 2
from collections import deque
import unittest
3
from test import support, seq_tests
4 5
import gc
import weakref
6
import copy
7
import pickle
8
from io import StringIO
9
import random
10
import os
11 12 13

BIG = 100000

14 15 16 17
def fail():
    raise SyntaxError
    yield 1

18 19 20 21 22
class BadCmp:
    def __eq__(self, other):
        raise RuntimeError

class MutateCmp:
23
    def __init__(self, deque, result):
24
        self.deque = deque
25
        self.result = result
26 27
    def __eq__(self, other):
        self.deque.clear()
28
        return self.result
29

30 31 32
class TestBasic(unittest.TestCase):

    def test_basics(self):
33 34
        d = deque(range(-5125, -5000))
        d.__init__(range(200))
35
        for i in range(200, 400):
36
            d.append(i)
37
        for i in reversed(range(-200, 0)):
38
            d.appendleft(i)
39
        self.assertEqual(list(d), list(range(-200, 400)))
40 41
        self.assertEqual(len(d), 600)

42 43 44
        left = [d.popleft() for i in range(250)]
        self.assertEqual(left, list(range(-200, 50)))
        self.assertEqual(list(d), list(range(50, 400)))
45

46
        right = [d.pop() for i in range(250)]
47
        right.reverse()
48 49
        self.assertEqual(right, list(range(150, 400)))
        self.assertEqual(list(d), list(range(50, 150)))
50

51 52 53
    def test_maxlen(self):
        self.assertRaises(ValueError, deque, 'abc', -1)
        self.assertRaises(ValueError, deque, 'abc', -2)
54 55 56
        it = iter(range(10))
        d = deque(it, maxlen=3)
        self.assertEqual(list(it), [])
57 58 59 60 61 62 63 64 65 66 67 68 69
        self.assertEqual(repr(d), 'deque([7, 8, 9], maxlen=3)')
        self.assertEqual(list(d), [7, 8, 9])
        self.assertEqual(d, deque(range(10), 3))
        d.append(10)
        self.assertEqual(list(d), [8, 9, 10])
        d.appendleft(7)
        self.assertEqual(list(d), [7, 8, 9])
        d.extend([10, 11])
        self.assertEqual(list(d), [9, 10, 11])
        d.extendleft([8, 7])
        self.assertEqual(list(d), [7, 8, 9])
        d = deque(range(200), maxlen=10)
        d.append(d)
70 71
        support.unlink(support.TESTFN)
        fo = open(support.TESTFN, "w")
Christian Heimes's avatar
Christian Heimes committed
72 73 74
        try:
            fo.write(str(d))
            fo.close()
75
            fo = open(support.TESTFN, "r")
Christian Heimes's avatar
Christian Heimes committed
76 77 78
            self.assertEqual(fo.read(), repr(d))
        finally:
            fo.close()
79
            support.unlink(support.TESTFN)
Christian Heimes's avatar
Christian Heimes committed
80

81 82
        d = deque(range(10), maxlen=None)
        self.assertEqual(repr(d), 'deque([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])')
83
        fo = open(support.TESTFN, "w")
Christian Heimes's avatar
Christian Heimes committed
84 85 86
        try:
            fo.write(str(d))
            fo.close()
87
            fo = open(support.TESTFN, "r")
Christian Heimes's avatar
Christian Heimes committed
88 89 90
            self.assertEqual(fo.read(), repr(d))
        finally:
            fo.close()
91
            support.unlink(support.TESTFN)
92

93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
    def test_maxlen_zero(self):
        it = iter(range(100))
        deque(it, maxlen=0)
        self.assertEqual(list(it), [])

        it = iter(range(100))
        d = deque(maxlen=0)
        d.extend(it)
        self.assertEqual(list(it), [])

        it = iter(range(100))
        d = deque(maxlen=0)
        d.extendleft(it)
        self.assertEqual(list(it), [])

108 109 110 111 112 113 114 115 116 117
    def test_maxlen_attribute(self):
        self.assertEqual(deque().maxlen, None)
        self.assertEqual(deque('abc').maxlen, None)
        self.assertEqual(deque('abc', maxlen=4).maxlen, 4)
        self.assertEqual(deque('abc', maxlen=2).maxlen, 2)
        self.assertEqual(deque('abc', maxlen=0).maxlen, 0)
        with self.assertRaises(AttributeError):
            d = deque('abc')
            d.maxlen = 10

118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
    def test_comparisons(self):
        d = deque('xabc'); d.popleft()
        for e in [d, deque('abc'), deque('ab'), deque(), list(d)]:
            self.assertEqual(d==e, type(d)==type(e) and list(d)==list(e))
            self.assertEqual(d!=e, not(type(d)==type(e) and list(d)==list(e)))

        args = map(deque, ('', 'a', 'b', 'ab', 'ba', 'abc', 'xba', 'xabc', 'cba'))
        for x in args:
            for y in args:
                self.assertEqual(x == y, list(x) == list(y), (x,y))
                self.assertEqual(x != y, list(x) != list(y), (x,y))
                self.assertEqual(x <  y, list(x) <  list(y), (x,y))
                self.assertEqual(x <= y, list(x) <= list(y), (x,y))
                self.assertEqual(x >  y, list(x) >  list(y), (x,y))
                self.assertEqual(x >= y, list(x) >= list(y), (x,y))

134 135 136 137 138 139 140 141 142 143 144
    def test_extend(self):
        d = deque('a')
        self.assertRaises(TypeError, d.extend, 1)
        d.extend('bcd')
        self.assertEqual(list(d), list('abcd'))

    def test_extendleft(self):
        d = deque('a')
        self.assertRaises(TypeError, d.extendleft, 1)
        d.extendleft('bcd')
        self.assertEqual(list(d), list(reversed('abcd')))
145 146 147 148
        d = deque()
        d.extendleft(range(1000))
        self.assertEqual(list(d), list(reversed(range(1000))))
        self.assertRaises(SyntaxError, d.extendleft, fail())
149

150 151
    def test_getitem(self):
        n = 200
152 153 154
        d = deque(range(n))
        l = list(range(n))
        for i in range(n):
155 156 157 158 159
            d.popleft()
            l.pop(0)
            if random.random() < 0.5:
                d.append(i)
                l.append(i)
160
            for j in range(1-len(l), len(l)):
161 162
                assert d[j] == l[j]

163
        d = deque('superman')
164 165
        self.assertEqual(d[0], 's')
        self.assertEqual(d[-1], 'n')
166
        d = deque()
167 168 169 170 171
        self.assertRaises(IndexError, d.__getitem__, 0)
        self.assertRaises(IndexError, d.__getitem__, -1)

    def test_setitem(self):
        n = 200
172 173
        d = deque(range(n))
        for i in range(n):
174
            d[i] = 10 * i
175
        self.assertEqual(list(d), [10*i for i in range(n)])
176
        l = list(d)
177
        for i in range(1-n, 0, -1):
178 179 180
            d[i] = 7*i
            l[i] = 7*i
        self.assertEqual(list(d), l)
181

182 183
    def test_delitem(self):
        n = 500         # O(n**2) test, don't make this too big
184
        d = deque(range(n))
185 186
        self.assertRaises(IndexError, d.__delitem__, -n-1)
        self.assertRaises(IndexError, d.__delitem__, n)
187
        for i in range(n):
188 189 190 191 192 193 194 195
            self.assertEqual(len(d), n-i)
            j = random.randrange(-len(d), len(d))
            val = d[j]
            self.assert_(val in d)
            del d[j]
            self.assert_(val not in d)
        self.assertEqual(len(d), 0)

196
    def test_rotate(self):
197 198 199 200 201 202 203 204 205 206 207 208 209
        s = tuple('abcde')
        n = len(s)

        d = deque(s)
        d.rotate(1)             # verify rot(1)
        self.assertEqual(''.join(d), 'eabcd')

        d = deque(s)
        d.rotate(-1)            # verify rot(-1)
        self.assertEqual(''.join(d), 'bcdea')
        d.rotate()              # check default to 1
        self.assertEqual(tuple(d), s)

210
        for i in range(n*3):
211 212 213
            d = deque(s)
            e = deque(d)
            d.rotate(i)         # check vs. rot(1) n times
214
            for j in range(i):
215 216 217 218 219 220 221
                e.rotate(1)
            self.assertEqual(tuple(d), tuple(e))
            d.rotate(-i)        # check that it works in reverse
            self.assertEqual(tuple(d), s)
            e.rotate(n-i)       # check that it wraps forward
            self.assertEqual(tuple(e), s)

222
        for i in range(n*3):
223 224 225
            d = deque(s)
            e = deque(d)
            d.rotate(-i)
226
            for j in range(i):
227 228 229 230 231 232 233
                e.rotate(-1)    # check vs. rot(-1) n times
            self.assertEqual(tuple(d), tuple(e))
            d.rotate(i)         # check that it works in reverse
            self.assertEqual(tuple(d), s)
            e.rotate(i-n)       # check that it wraps backaround
            self.assertEqual(tuple(e), s)

234
        d = deque(s)
235 236 237
        e = deque(s)
        e.rotate(BIG+17)        # verify on long series of rotates
        dr = d.rotate
238
        for i in range(BIG+17):
239 240
            dr()
        self.assertEqual(tuple(d), tuple(e))
241

242 243 244 245 246 247 248
        self.assertRaises(TypeError, d.rotate, 'x')   # Wrong arg type
        self.assertRaises(TypeError, d.rotate, 1, 10) # Too many args

        d = deque()
        d.rotate()              # rotate an empty deque
        self.assertEqual(d, deque())

249 250 251 252 253 254 255
    def test_len(self):
        d = deque('ab')
        self.assertEqual(len(d), 2)
        d.popleft()
        self.assertEqual(len(d), 1)
        d.pop()
        self.assertEqual(len(d), 0)
256
        self.assertRaises(IndexError, d.pop)
257 258 259 260 261 262 263 264 265 266
        self.assertEqual(len(d), 0)
        d.append('c')
        self.assertEqual(len(d), 1)
        d.appendleft('d')
        self.assertEqual(len(d), 2)
        d.clear()
        self.assertEqual(len(d), 0)

    def test_underflow(self):
        d = deque()
267 268
        self.assertRaises(IndexError, d.pop)
        self.assertRaises(IndexError, d.popleft)
269 270

    def test_clear(self):
271
        d = deque(range(100))
272 273 274 275
        self.assertEqual(len(d), 100)
        d.clear()
        self.assertEqual(len(d), 0)
        self.assertEqual(list(d), [])
276 277
        d.clear()               # clear an emtpy deque
        self.assertEqual(list(d), [])
278

279 280 281 282 283 284 285 286 287
    def test_remove(self):
        d = deque('abcdefghcij')
        d.remove('c')
        self.assertEqual(d, deque('abdefghcij'))
        d.remove('c')
        self.assertEqual(d, deque('abdefghij'))
        self.assertRaises(ValueError, d.remove, 'c')
        self.assertEqual(d, deque('abdefghij'))

Walter Dörwald's avatar
Walter Dörwald committed
288
        # Handle comparison errors
289 290 291 292 293 294 295 296
        d = deque(['a', 'b', BadCmp(), 'c'])
        e = deque(d)
        self.assertRaises(RuntimeError, d.remove, 'c')
        for x, y in zip(d, e):
            # verify that original order and values are retained.
            self.assert_(x is y)

        # Handle evil mutator
297 298 299 300 301
        for match in (True, False):
            d = deque(['ab'])
            d.extend([MutateCmp(d, match), 'c'])
            self.assertRaises(IndexError, d.remove, 'c')
            self.assertEqual(d, deque())
302

303
    def test_repr(self):
304
        d = deque(range(200))
305 306 307 308 309 310
        e = eval(repr(d))
        self.assertEqual(list(d), list(e))
        d.append(d)
        self.assert_('...' in repr(d))

    def test_print(self):
311
        d = deque(range(200))
312
        d.append(d)
313
        try:
314 315
            support.unlink(support.TESTFN)
            fo = open(support.TESTFN, "w")
Christian Heimes's avatar
Christian Heimes committed
316
            print(d, file=fo, end='')
317
            fo.close()
318
            fo = open(support.TESTFN, "r")
319 320 321
            self.assertEqual(fo.read(), repr(d))
        finally:
            fo.close()
322
            support.unlink(support.TESTFN)
323 324

    def test_init(self):
325
        self.assertRaises(TypeError, deque, 'abc', 2, 3);
326
        self.assertRaises(TypeError, deque, 1);
327 328 329 330 331 332

    def test_hash(self):
        self.assertRaises(TypeError, hash, deque('abc'))

    def test_long_steadystate_queue_popleft(self):
        for size in (0, 1, 2, 100, 1000):
333
            d = deque(range(size))
334
            append, pop = d.append, d.popleft
335
            for i in range(size, BIG):
336 337 338 339
                append(i)
                x = pop()
                if x != i - size:
                    self.assertEqual(x, i-size)
340
            self.assertEqual(list(d), list(range(BIG-size, BIG)))
341 342 343

    def test_long_steadystate_queue_popright(self):
        for size in (0, 1, 2, 100, 1000):
344
            d = deque(reversed(range(size)))
345
            append, pop = d.appendleft, d.pop
346
            for i in range(size, BIG):
347 348 349 350
                append(i)
                x = pop()
                if x != i - size:
                    self.assertEqual(x, i-size)
351 352
            self.assertEqual(list(reversed(list(d))),
                             list(range(BIG-size, BIG)))
353 354 355 356 357

    def test_big_queue_popleft(self):
        pass
        d = deque()
        append, pop = d.append, d.popleft
358
        for i in range(BIG):
359
            append(i)
360
        for i in range(BIG):
361 362 363 364 365 366 367
            x = pop()
            if x != i:
                self.assertEqual(x, i)

    def test_big_queue_popright(self):
        d = deque()
        append, pop = d.appendleft, d.pop
368
        for i in range(BIG):
369
            append(i)
370
        for i in range(BIG):
371 372 373 374 375 376 377
            x = pop()
            if x != i:
                self.assertEqual(x, i)

    def test_big_stack_right(self):
        d = deque()
        append, pop = d.append, d.pop
378
        for i in range(BIG):
379
            append(i)
380
        for i in reversed(range(BIG)):
381 382 383 384 385 386 387 388
            x = pop()
            if x != i:
                self.assertEqual(x, i)
        self.assertEqual(len(d), 0)

    def test_big_stack_left(self):
        d = deque()
        append, pop = d.appendleft, d.popleft
389
        for i in range(BIG):
390
            append(i)
391
        for i in reversed(range(BIG)):
392 393 394 395 396 397
            x = pop()
            if x != i:
                self.assertEqual(x, i)
        self.assertEqual(len(d), 0)

    def test_roundtrip_iter_init(self):
398
        d = deque(range(200))
399 400 401 402 403
        e = deque(d)
        self.assertNotEqual(id(d), id(e))
        self.assertEqual(list(d), list(e))

    def test_pickle(self):
404
        d = deque(range(200))
405
        for i in range(pickle.HIGHEST_PROTOCOL + 1):
406 407 408 409 410
            s = pickle.dumps(d, i)
            e = pickle.loads(s)
            self.assertNotEqual(id(d), id(e))
            self.assertEqual(list(d), list(e))

411 412 413
##    def test_pickle_recursive(self):
##        d = deque('abc')
##        d.append(d)
414
##        for i in range(pickle.HIGHEST_PROTOCOL + 1):
415 416 417
##            e = pickle.loads(pickle.dumps(d, i))
##            self.assertNotEqual(id(d), id(e))
##            self.assertEqual(id(e), id(e[-1]))
418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436

    def test_deepcopy(self):
        mut = [10]
        d = deque([mut])
        e = copy.deepcopy(d)
        self.assertEqual(list(d), list(e))
        mut[0] = 11
        self.assertNotEqual(id(d), id(e))
        self.assertNotEqual(list(d), list(e))

    def test_copy(self):
        mut = [10]
        d = deque([mut])
        e = copy.copy(d)
        self.assertEqual(list(d), list(e))
        mut[0] = 11
        self.assertNotEqual(id(d), id(e))
        self.assertEqual(list(d), list(e))

437
    def test_reversed(self):
438
        for s in ('abcd', range(2000)):
439 440
            self.assertEqual(list(reversed(deque(s))), list(reversed(s)))

441 442 443 444 445
    def test_gc_doesnt_blowup(self):
        import gc
        # This used to assert-fail in deque_traverse() under a debug
        # build, or run wild with a NULL pointer in a release build.
        d = deque()
446
        for i in range(100):
447 448 449
            d.append(1)
            gc.collect()

450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465
    def test_container_iterator(self):
        # Bug #3680: tp_traverse was not implemented for deque iterator objects
        class C(object):
            pass
        for i in range(2):
            obj = C()
            ref = weakref.ref(obj)
            if i == 0:
                container = deque([obj, 1])
            else:
                container = reversed(deque([obj, 1]))
            obj.x = iter(container)
            del obj, container
            gc.collect()
            self.assert_(ref() is None, "Cycle was not collected")

466 467 468
class TestVariousIteratorArgs(unittest.TestCase):

    def test_constructor(self):
469
        for s in ("123", "", range(1000), ('do', 1.2), range(2000,2200,5)):
470 471 472
            for g in (seq_tests.Sequence, seq_tests.IterFunc,
                      seq_tests.IterGen, seq_tests.IterFuncStop,
                      seq_tests.itermulti, seq_tests.iterfunc):
473
                self.assertEqual(list(deque(g(s))), list(g(s)))
474 475 476
            self.assertRaises(TypeError, deque, seq_tests.IterNextOnly(s))
            self.assertRaises(TypeError, deque, seq_tests.IterNoNext(s))
            self.assertRaises(ZeroDivisionError, deque, seq_tests.IterGenExc(s))
477 478 479 480 481

    def test_iter_with_altered_data(self):
        d = deque('abcdefg')
        it = iter(d)
        d.pop()
482
        self.assertRaises(RuntimeError, next, it)
483

484 485 486 487
    def test_runtime_error_on_empty_deque(self):
        d = deque()
        it = iter(d)
        d.append(10)
488
        self.assertRaises(RuntimeError, next, it)
489

490 491 492
class Deque(deque):
    pass

493 494 495 496
class DequeWithBadIter(deque):
    def __iter__(self):
        raise TypeError

497 498 499
class TestSubclass(unittest.TestCase):

    def test_basics(self):
500 501
        d = Deque(range(25))
        d.__init__(range(200))
502
        for i in range(200, 400):
503
            d.append(i)
504
        for i in reversed(range(-200, 0)):
505
            d.appendleft(i)
506
        self.assertEqual(list(d), list(range(-200, 400)))
507 508
        self.assertEqual(len(d), 600)

509 510 511
        left = [d.popleft() for i in range(250)]
        self.assertEqual(left, list(range(-200, 50)))
        self.assertEqual(list(d), list(range(50, 400)))
512

513
        right = [d.pop() for i in range(250)]
514
        right.reverse()
515 516
        self.assertEqual(right, list(range(150, 400)))
        self.assertEqual(list(d), list(range(50, 150)))
517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538

        d.clear()
        self.assertEqual(len(d), 0)

    def test_copy_pickle(self):

        d = Deque('abc')

        e = d.__copy__()
        self.assertEqual(type(d), type(e))
        self.assertEqual(list(d), list(e))

        e = Deque(d)
        self.assertEqual(type(d), type(e))
        self.assertEqual(list(d), list(e))

        s = pickle.dumps(d)
        e = pickle.loads(s)
        self.assertNotEqual(id(d), id(e))
        self.assertEqual(type(d), type(e))
        self.assertEqual(list(d), list(e))

539
        d = Deque('abcde', maxlen=4)
540

541
        e = d.__copy__()
542
        self.assertEqual(type(d), type(e))
543 544 545 546 547
        self.assertEqual(list(d), list(e))

        e = Deque(d)
        self.assertEqual(type(d), type(e))
        self.assertEqual(list(d), list(e))
548

549 550 551 552 553
        s = pickle.dumps(d)
        e = pickle.loads(s)
        self.assertNotEqual(id(d), id(e))
        self.assertEqual(type(d), type(e))
        self.assertEqual(list(d), list(e))
554

555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572
##    def test_pickle(self):
##        d = Deque('abc')
##        d.append(d)
##
##        e = pickle.loads(pickle.dumps(d))
##        self.assertNotEqual(id(d), id(e))
##        self.assertEqual(type(d), type(e))
##        dd = d.pop()
##        ee = e.pop()
##        self.assertEqual(id(e), id(ee))
##        self.assertEqual(d, e)
##
##        d.x = d
##        e = pickle.loads(pickle.dumps(d))
##        self.assertEqual(id(e), id(e.x))
##
##        d = DequeWithBadIter('abc')
##        self.assertRaises(TypeError, pickle.dumps, d)
573

574 575
    def test_weakref(self):
        d = deque('gallahad')
576
        p = weakref.proxy(d)
577 578 579
        self.assertEqual(str(p), str(d))
        d = None
        self.assertRaises(ReferenceError, str, p)
580

581 582 583 584 585 586 587 588 589
    def test_strange_subclass(self):
        class X(deque):
            def __iter__(self):
                return iter([])
        d1 = X([1,2,3])
        d2 = X([4,5,6])
        d1 == d2   # not clear if this is supposed to be True or False,
                   # but it used to give a SystemError

590 591 592 593 594 595 596 597 598 599

class SubclassWithKwargs(deque):
    def __init__(self, newarg=1):
        deque.__init__(self)

class TestSubclassWithKwargs(unittest.TestCase):
    def test_subclass_with_kwargs(self):
        # SF bug #1486663 -- this used to erroneously raise a TypeError
        SubclassWithKwargs(newarg=1)

600 601
#==============================================================================

602 603 604 605 606 607
libreftest = """
Example from the Library Reference:  Doc/lib/libcollections.tex

>>> from collections import deque
>>> d = deque('ghi')                 # make a new deque with three items
>>> for elem in d:                   # iterate over the deque's elements
608
...     print(elem.upper())
609 610 611 612 613 614 615 616 617 618 619 620 621
G
H
I
>>> d.append('j')                    # add a new entry to the right side
>>> d.appendleft('f')                # add a new entry to the left side
>>> d                                # show the representation of the deque
deque(['f', 'g', 'h', 'i', 'j'])
>>> d.pop()                          # return and remove the rightmost item
'j'
>>> d.popleft()                      # return and remove the leftmost item
'f'
>>> list(d)                          # list the contents of the deque
['g', 'h', 'i']
622
>>> d[0]                             # peek at leftmost item
623
'g'
624
>>> d[-1]                            # peek at rightmost item
625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651
'i'
>>> list(reversed(d))                # list the contents of a deque in reverse
['i', 'h', 'g']
>>> 'h' in d                         # search the deque
True
>>> d.extend('jkl')                  # add multiple elements at once
>>> d
deque(['g', 'h', 'i', 'j', 'k', 'l'])
>>> d.rotate(1)                      # right rotation
>>> d
deque(['l', 'g', 'h', 'i', 'j', 'k'])
>>> d.rotate(-1)                     # left rotation
>>> d
deque(['g', 'h', 'i', 'j', 'k', 'l'])
>>> deque(reversed(d))               # make a new deque in reverse order
deque(['l', 'k', 'j', 'i', 'h', 'g'])
>>> d.clear()                        # empty the deque
>>> d.pop()                          # cannot pop from an empty deque
Traceback (most recent call last):
  File "<pyshell#6>", line 1, in -toplevel-
    d.pop()
IndexError: pop from an empty deque

>>> d.extendleft('abc')              # extendleft() reverses the input order
>>> d
deque(['c', 'b', 'a'])

Raymond Hettinger's avatar
Raymond Hettinger committed
652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670


>>> def delete_nth(d, n):
...     d.rotate(-n)
...     d.popleft()
...     d.rotate(n)
...
>>> d = deque('abcdef')
>>> delete_nth(d, 2)   # remove the entry at d[2]
>>> d
deque(['a', 'b', 'd', 'e', 'f'])



>>> def roundrobin(*iterables):
...     pending = deque(iter(i) for i in iterables)
...     while pending:
...         task = pending.popleft()
...         try:
671
...             yield next(task)
Raymond Hettinger's avatar
Raymond Hettinger committed
672 673 674 675 676 677
...         except StopIteration:
...             continue
...         pending.append(task)
...

>>> for value in roundrobin('abc', 'd', 'efgh'):
678
...     print(value)
679
...
Raymond Hettinger's avatar
Raymond Hettinger committed
680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696
a
d
e
b
f
c
g
h


>>> def maketree(iterable):
...     d = deque(iterable)
...     while len(d) > 1:
...         pair = [d.popleft(), d.popleft()]
...         d.append(pair)
...     return list(d)
...
697
>>> print(maketree('abcdefgh'))
Raymond Hettinger's avatar
Raymond Hettinger committed
698 699
[[[['a', 'b'], ['c', 'd']], [['e', 'f'], ['g', 'h']]]]

700 701 702 703 704 705 706
"""


#==============================================================================

__test__ = {'libreftest' : libreftest}

707 708 709 710 711 712
def test_main(verbose=None):
    import sys
    test_classes = (
        TestBasic,
        TestVariousIteratorArgs,
        TestSubclass,
713
        TestSubclassWithKwargs,
714 715
    )

716
    support.run_unittest(*test_classes)
717 718 719 720 721

    # verify reference counting
    if verbose and hasattr(sys, "gettotalrefcount"):
        import gc
        counts = [None] * 5
722
        for i in range(len(counts)):
723
            support.run_unittest(*test_classes)
724 725
            gc.collect()
            counts[i] = sys.gettotalrefcount()
726
        print(counts)
727

728 729
    # doctests
    from test import test_deque
730
    support.run_doctest(test_deque, verbose)
731 732 733

if __name__ == "__main__":
    test_main(verbose=True)