4
from test.support import run_unittest, TESTFN, unlink
6
# Test result of triple loop (too big to inline)
7
TRIPLETS = [(0, 0, 0), (0, 0, 1), (0, 0, 2),
8
(0, 1, 0), (0, 1, 1), (0, 1, 2),
9
(0, 2, 0), (0, 2, 1), (0, 2, 2),
11
(1, 0, 0), (1, 0, 1), (1, 0, 2),
12
(1, 1, 0), (1, 1, 1), (1, 1, 2),
13
(1, 2, 0), (1, 2, 1), (1, 2, 2),
15
(2, 0, 0), (2, 0, 1), (2, 0, 2),
16
(2, 1, 0), (2, 1, 1), (2, 1, 2),
17
(2, 2, 0), (2, 2, 1), (2, 2, 2)]
22
def __init__(self, n):
32
class IteratingSequenceClass:
33
def __init__(self, n):
36
return BasicIterClass(self.n)
39
def __init__(self, n):
41
def __getitem__(self, i):
49
class TestCase(unittest.TestCase):
51
# Helper to check that an iterator returns a given sequence
52
def check_iterator(self, it, seq):
60
self.assertEqual(res, seq)
62
# Helper to check that a for loop generates a given sequence
63
def check_for_loop(self, expr, seq):
67
self.assertEqual(res, seq)
69
# Test basic use of iter() function
70
def test_iter_basic(self):
71
self.check_iterator(iter(range(10)), list(range(10)))
73
# Test that iter(iter(x)) is the same as iter(x)
74
def test_iter_idempotency(self):
78
self.assert_(it is it2)
80
# Test that for loops over iterators work
81
def test_iter_for_loop(self):
82
self.check_for_loop(iter(range(10)), list(range(10)))
84
# Test several independent iterators over the same list
85
def test_iter_independence(self):
92
self.assertEqual(res, TRIPLETS)
94
# Test triple list comprehension using iterators
95
def test_nested_comprehensions_iter(self):
98
for i in iter(seq) for j in iter(seq) for k in iter(seq)]
99
self.assertEqual(res, TRIPLETS)
101
# Test triple list comprehension without iterators
102
def test_nested_comprehensions_for(self):
104
res = [(i, j, k) for i in seq for j in seq for k in seq]
105
self.assertEqual(res, TRIPLETS)
107
# Test a class with __iter__ in a for loop
108
def test_iter_class_for(self):
109
self.check_for_loop(IteratingSequenceClass(10), list(range(10)))
111
# Test a class with __iter__ with explicit iter()
112
def test_iter_class_iter(self):
113
self.check_iterator(iter(IteratingSequenceClass(10)), list(range(10)))
115
# Test for loop on a sequence class without __iter__
116
def test_seq_class_for(self):
117
self.check_for_loop(SequenceClass(10), list(range(10)))
119
# Test iter() on a sequence class without __iter__
120
def test_seq_class_iter(self):
121
self.check_iterator(iter(SequenceClass(10)), list(range(10)))
123
# Test a new_style class with __iter__ but no next() method
124
def test_new_style_iter_class(self):
125
class IterClass(object):
128
self.assertRaises(TypeError, iter, IterClass())
130
# Test two-argument iter() with callable instance
131
def test_iter_callable(self):
139
raise IndexError # Emergency stop
141
self.check_iterator(iter(C(), 10), list(range(10)))
143
# Test two-argument iter() with function
144
def test_iter_function(self):
149
self.check_iterator(iter(spam, 10), list(range(10)))
151
# Test two-argument iter() with function that raises StopIteration
152
def test_iter_function_stop(self):
159
self.check_iterator(iter(spam, 20), list(range(10)))
161
# Test exception propagation through function iterator
162
def test_exception_function(self):
171
for x in iter(spam, 20):
174
self.assertEqual(res, list(range(10)))
176
self.fail("should have raised RuntimeError")
178
# Test exception propagation through sequence iterator
179
def test_exception_sequence(self):
180
class MySequenceClass(SequenceClass):
181
def __getitem__(self, i):
184
return SequenceClass.__getitem__(self, i)
187
for x in MySequenceClass(20):
190
self.assertEqual(res, list(range(10)))
192
self.fail("should have raised RuntimeError")
194
# Test for StopIteration from __getitem__
195
def test_stop_sequence(self):
196
class MySequenceClass(SequenceClass):
197
def __getitem__(self, i):
200
return SequenceClass.__getitem__(self, i)
201
self.check_for_loop(MySequenceClass(20), list(range(10)))
204
def test_iter_big_range(self):
205
self.check_for_loop(iter(range(10000)), list(range(10000)))
208
def test_iter_empty(self):
209
self.check_for_loop(iter([]), [])
212
def test_iter_tuple(self):
213
self.check_for_loop(iter((0,1,2,3,4,5,6,7,8,9)), list(range(10)))
216
def test_iter_range(self):
217
self.check_for_loop(iter(range(10)), list(range(10)))
220
def test_iter_string(self):
221
self.check_for_loop(iter("abcde"), ["a", "b", "c", "d", "e"])
224
def test_iter_dict(self):
228
self.check_for_loop(dict, list(dict.keys()))
231
def test_iter_file(self):
232
f = open(TESTFN, "w")
238
f = open(TESTFN, "r")
240
self.check_for_loop(f, ["0\n", "1\n", "2\n", "3\n", "4\n"])
241
self.check_for_loop(f, [])
249
# Test list()'s use of iterators.
250
def test_builtin_list(self):
251
self.assertEqual(list(SequenceClass(5)), list(range(5)))
252
self.assertEqual(list(SequenceClass(0)), [])
253
self.assertEqual(list(()), [])
255
d = {"one": 1, "two": 2, "three": 3}
256
self.assertEqual(list(d), list(d.keys()))
258
self.assertRaises(TypeError, list, list)
259
self.assertRaises(TypeError, list, 42)
261
f = open(TESTFN, "w")
267
f = open(TESTFN, "r")
269
self.assertEqual(list(f), ["0\n", "1\n", "2\n", "3\n", "4\n"])
271
self.assertEqual(list(f),
272
["0\n", "1\n", "2\n", "3\n", "4\n"])
280
# Test tuples()'s use of iterators.
281
def test_builtin_tuple(self):
282
self.assertEqual(tuple(SequenceClass(5)), (0, 1, 2, 3, 4))
283
self.assertEqual(tuple(SequenceClass(0)), ())
284
self.assertEqual(tuple([]), ())
285
self.assertEqual(tuple(()), ())
286
self.assertEqual(tuple("abc"), ("a", "b", "c"))
288
d = {"one": 1, "two": 2, "three": 3}
289
self.assertEqual(tuple(d), tuple(d.keys()))
291
self.assertRaises(TypeError, tuple, list)
292
self.assertRaises(TypeError, tuple, 42)
294
f = open(TESTFN, "w")
300
f = open(TESTFN, "r")
302
self.assertEqual(tuple(f), ("0\n", "1\n", "2\n", "3\n", "4\n"))
304
self.assertEqual(tuple(f),
305
("0\n", "1\n", "2\n", "3\n", "4\n"))
313
# Test filter()'s use of iterators.
314
def test_builtin_filter(self):
315
self.assertEqual(list(filter(None, SequenceClass(5))),
317
self.assertEqual(list(filter(None, SequenceClass(0))), [])
318
self.assertEqual(list(filter(None, ())), [])
319
self.assertEqual(list(filter(None, "abc")), ["a", "b", "c"])
321
d = {"one": 1, "two": 2, "three": 3}
322
self.assertEqual(list(filter(None, d)), list(d.keys()))
324
self.assertRaises(TypeError, filter, None, list)
325
self.assertRaises(TypeError, filter, None, 42)
328
def __init__(self, truth):
332
bTrue = Boolean(True)
333
bFalse = Boolean(False)
336
def __init__(self, *args):
340
def __init__(self, vals):
348
if i < len(self.vals):
352
return SeqIter(self.vals)
354
seq = Seq(*([bTrue, bFalse] * 25))
355
self.assertEqual(list(filter(lambda x: not x, seq)), [bFalse]*25)
356
self.assertEqual(list(filter(lambda x: not x, iter(seq))), [bFalse]*25)
358
# Test max() and min()'s use of iterators.
359
def test_builtin_max_min(self):
360
self.assertEqual(max(SequenceClass(5)), 4)
361
self.assertEqual(min(SequenceClass(5)), 0)
362
self.assertEqual(max(8, -1), 8)
363
self.assertEqual(min(8, -1), -1)
365
d = {"one": 1, "two": 2, "three": 3}
366
self.assertEqual(max(d), "two")
367
self.assertEqual(min(d), "one")
368
self.assertEqual(max(d.values()), 3)
369
self.assertEqual(min(iter(d.values())), 1)
371
f = open(TESTFN, "w")
373
f.write("medium line\n")
374
f.write("xtra large line\n")
375
f.write("itty-bitty line\n")
378
f = open(TESTFN, "r")
380
self.assertEqual(min(f), "itty-bitty line\n")
382
self.assertEqual(max(f), "xtra large line\n")
390
# Test map()'s use of iterators.
391
def test_builtin_map(self):
392
self.assertEqual(list(map(lambda x: x+1, SequenceClass(5))),
395
d = {"one": 1, "two": 2, "three": 3}
396
self.assertEqual(list(map(lambda k, d=d: (k, d[k]), d)),
398
dkeys = list(d.keys())
399
expected = [(i < len(d) and dkeys[i] or None,
401
i < len(d) and dkeys[i] or None)
404
f = open(TESTFN, "w")
407
f.write("xy" * i + "\n") # line i has len 2*i+1
410
f = open(TESTFN, "r")
412
self.assertEqual(list(map(len, f)), list(range(1, 21, 2)))
420
# Test zip()'s use of iterators.
421
def test_builtin_zip(self):
422
self.assertEqual(list(zip()), [])
423
self.assertEqual(list(zip(*[])), [])
424
self.assertEqual(list(zip(*[(1, 2), 'ab'])), [(1, 'a'), (2, 'b')])
426
self.assertRaises(TypeError, zip, None)
427
self.assertRaises(TypeError, zip, range(10), 42)
428
self.assertRaises(TypeError, zip, range(10), zip)
430
self.assertEqual(list(zip(IteratingSequenceClass(3))),
432
self.assertEqual(list(zip(SequenceClass(3))),
435
d = {"one": 1, "two": 2, "three": 3}
436
self.assertEqual(list(d.items()), list(zip(d, d.values())))
438
# Generate all ints starting at constructor arg.
440
def __init__(self, start):
451
f = open(TESTFN, "w")
453
f.write("a\n" "bbb\n" "cc\n")
456
f = open(TESTFN, "r")
458
self.assertEqual(list(zip(IntsFrom(0), f, IntsFrom(-100))),
469
self.assertEqual(list(zip(range(5))), [(i,) for i in range(5)])
471
# Classes that lie about their lengths.
473
def __getitem__(self, i):
478
class Guess3Len5(NoGuessLen5):
482
class Guess30Len5(NoGuessLen5):
487
return list(zip(*args))
489
self.assertEqual(len(Guess3Len5()), 3)
490
self.assertEqual(len(Guess30Len5()), 30)
491
self.assertEqual(lzip(NoGuessLen5()), lzip(range(5)))
492
self.assertEqual(lzip(Guess3Len5()), lzip(range(5)))
493
self.assertEqual(lzip(Guess30Len5()), lzip(range(5)))
495
expected = [(i, i) for i in range(5)]
496
for x in NoGuessLen5(), Guess3Len5(), Guess30Len5():
497
for y in NoGuessLen5(), Guess3Len5(), Guess30Len5():
498
self.assertEqual(lzip(x, y), expected)
500
def test_unicode_join_endcase(self):
502
# This class inserts a Unicode object into its argument's natural
503
# iteration, in the 3rd position.
505
def __init__(self, seq):
519
f = open(TESTFN, "w")
521
f.write("a\n" + "b\n" + "c\n")
525
f = open(TESTFN, "r")
526
# Nasty: string.join(s) can't know whether unicode.join() is needed
527
# until it's seen all of s's elements. But in this case, f's
528
# iterator cannot be restarted. So what we're testing here is
529
# whether string.join() can manage to remember everything it's seen
530
# and pass that on to unicode.join().
532
got = " - ".join(OhPhooey(f))
533
self.assertEqual(got, "a\n - b\n - fooled you! - c\n")
541
# Test iterators with 'x in y' and 'x not in y'.
542
def test_in_and_not_in(self):
543
for sc5 in IteratingSequenceClass(5), SequenceClass(5):
545
self.assert_(i in sc5)
546
for i in "abc", -1, 5, 42.42, (3, 4), [], {1: 1}, 3-12j, sc5:
547
self.assert_(i not in sc5)
549
self.assertRaises(TypeError, lambda: 3 in 12)
550
self.assertRaises(TypeError, lambda: 3 not in map)
552
d = {"one": 1, "two": 2, "three": 3, 1j: 2j}
555
self.assert_(k not in d.values())
557
self.assert_(v in d.values())
558
self.assert_(v not in d)
559
for k, v in d.items():
560
self.assert_((k, v) in d.items())
561
self.assert_((v, k) not in d.items())
563
f = open(TESTFN, "w")
565
f.write("a\n" "b\n" "c\n")
568
f = open(TESTFN, "r")
572
self.assert_(chunk not in f)
574
self.assert_((chunk + "\n") in f)
582
# Test iterators with operator.countOf (PySequence_Count).
583
def test_countOf(self):
584
from operator import countOf
585
self.assertEqual(countOf([1,2,2,3,2,5], 2), 3)
586
self.assertEqual(countOf((1,2,2,3,2,5), 2), 3)
587
self.assertEqual(countOf("122325", "2"), 3)
588
self.assertEqual(countOf("122325", "6"), 0)
590
self.assertRaises(TypeError, countOf, 42, 1)
591
self.assertRaises(TypeError, countOf, countOf, countOf)
593
d = {"one": 3, "two": 3, "three": 3, 1j: 2j}
595
self.assertEqual(countOf(d, k), 1)
596
self.assertEqual(countOf(d.values(), 3), 3)
597
self.assertEqual(countOf(d.values(), 2j), 1)
598
self.assertEqual(countOf(d.values(), 1j), 0)
600
f = open(TESTFN, "w")
602
f.write("a\n" "b\n" "c\n" "b\n")
605
f = open(TESTFN, "r")
607
for letter, count in ("a", 1), ("b", 2), ("c", 1), ("d", 0):
609
self.assertEqual(countOf(f, letter + "\n"), count)
617
# Test iterators with operator.indexOf (PySequence_Index).
618
def test_indexOf(self):
619
from operator import indexOf
620
self.assertEqual(indexOf([1,2,2,3,2,5], 1), 0)
621
self.assertEqual(indexOf((1,2,2,3,2,5), 2), 1)
622
self.assertEqual(indexOf((1,2,2,3,2,5), 3), 3)
623
self.assertEqual(indexOf((1,2,2,3,2,5), 5), 5)
624
self.assertRaises(ValueError, indexOf, (1,2,2,3,2,5), 0)
625
self.assertRaises(ValueError, indexOf, (1,2,2,3,2,5), 6)
627
self.assertEqual(indexOf("122325", "2"), 1)
628
self.assertEqual(indexOf("122325", "5"), 5)
629
self.assertRaises(ValueError, indexOf, "122325", "6")
631
self.assertRaises(TypeError, indexOf, 42, 1)
632
self.assertRaises(TypeError, indexOf, indexOf, indexOf)
634
f = open(TESTFN, "w")
636
f.write("a\n" "b\n" "c\n" "d\n" "e\n")
639
f = open(TESTFN, "r")
642
self.assertEqual(indexOf(fiter, "b\n"), 1)
643
self.assertEqual(indexOf(fiter, "d\n"), 1)
644
self.assertEqual(indexOf(fiter, "e\n"), 0)
645
self.assertRaises(ValueError, indexOf, fiter, "a\n")
653
iclass = IteratingSequenceClass(3)
655
self.assertEqual(indexOf(iclass, i), i)
656
self.assertRaises(ValueError, indexOf, iclass, -1)
658
# Test iterators with file.writelines().
659
def test_writelines(self):
660
f = open(TESTFN, "w")
663
self.assertRaises(TypeError, f.writelines, None)
664
self.assertRaises(TypeError, f.writelines, 42)
666
f.writelines(["1\n", "2\n"])
667
f.writelines(("3\n", "4\n"))
668
f.writelines({'5\n': None})
671
# Try a big chunk too.
673
def __init__(self, start, finish):
679
if self.i >= self.finish:
681
result = str(self.i) + '\n'
689
def __init__(self, start, finish):
694
return Iterator(self.start, self.finish)
696
f.writelines(Whatever(6, 6+2000))
700
expected = [str(i) + "\n" for i in range(1, 2006)]
701
self.assertEqual(list(f), expected)
711
# Test iterators on RHS of unpacking assignments.
712
def test_unpack_iter(self):
714
self.assertEqual((a, b), (1, 2))
716
a, b, c = IteratingSequenceClass(3)
717
self.assertEqual((a, b, c), (0, 1, 2))
719
try: # too many values
720
a, b = IteratingSequenceClass(3)
724
self.fail("should have raised ValueError")
726
try: # not enough values
727
a, b, c = IteratingSequenceClass(2)
731
self.fail("should have raised ValueError")
738
self.fail("should have raised TypeError")
740
a, b, c = {1: 42, 2: 42, 3: 42}.values()
741
self.assertEqual((a, b, c), (42, 42, 42))
743
f = open(TESTFN, "w")
744
lines = ("a\n", "bb\n", "ccc\n")
750
f = open(TESTFN, "r")
753
self.assertEqual((a, b, c), lines)
761
(a, b), (c,) = IteratingSequenceClass(2), {42: 24}
762
self.assertEqual((a, b, c), (0, 1, 42))
764
# Test reference count behavior
770
return object.__new__(cls)
776
self.assertEqual(C.count, 1)
778
self.assertEqual(C.count, 0)
780
self.assertEqual(C.count, 3)
786
self.assertEqual(C.count, 0)
789
# Make sure StopIteration is a "sink state".
790
# This tests various things that weren't sink states in Python 2.2.1,
791
# plus various things that always were fine.
793
def test_sinkstate_list(self):
797
self.assertEqual(list(b), list(range(5)))
798
a.extend(range(5, 10))
799
self.assertEqual(list(b), [])
801
def test_sinkstate_tuple(self):
804
self.assertEqual(list(b), list(range(5)))
805
self.assertEqual(list(b), [])
807
def test_sinkstate_string(self):
810
self.assertEqual(list(b), ['a', 'b', 'c', 'd', 'e'])
811
self.assertEqual(list(b), [])
813
def test_sinkstate_sequence(self):
817
self.assertEqual(list(b), list(range(5)))
819
self.assertEqual(list(b), [])
821
def test_sinkstate_callable(self):
827
raise AssertionError("shouldn't have gotten this far")
830
self.assertEqual(list(b), list(range(5)))
831
self.assertEqual(list(b), [])
833
def test_sinkstate_dict(self):
834
# XXX For a more thorough test, see towards the end of:
835
# http://mail.python.org/pipermail/python-dev/2002-July/026512.html
836
a = {1:1, 2:2, 0:0, 4:4, 3:3}
837
for b in iter(a), a.keys(), a.items(), a.values():
839
self.assertEqual(len(list(b)), 5)
840
self.assertEqual(list(b), [])
842
def test_sinkstate_yield(self):
847
self.assertEqual(list(b), list(range(5)))
848
self.assertEqual(list(b), [])
850
def test_sinkstate_range(self):
853
self.assertEqual(list(b), list(range(5)))
854
self.assertEqual(list(b), [])
856
def test_sinkstate_enumerate(self):
860
self.assertEqual(list(b), list(zip(range(5), range(5))))
861
self.assertEqual(list(b), [])
864
# Avoid a crash, when an iterator deletes its next() method.
865
class BadIterator(object):
869
del BadIterator.__next__
873
for i in BadIterator() :
880
run_unittest(TestCase)
883
if __name__ == "__main__":