blob: d861dcdd66d55d9897f7ff2ff823850523ee5fcf [file] [log] [blame]
Guido van Rossum8b48cf92001-04-21 13:33:54 +00001# Test iterators.
2
3import unittest
Walter Dörwald1f5947b2007-05-22 16:52:54 +00004from test.test_support import run_unittest, TESTFN, unlink
Guido van Rossum8b48cf92001-04-21 13:33:54 +00005
6# Test result of triple loop (too big to inline)
7TRIPLETS = [(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),
10
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),
14
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)]
18
19# Helper classes
20
21class BasicIterClass:
22 def __init__(self, n):
23 self.n = n
24 self.i = 0
Georg Brandla18af4e2007-04-21 15:47:16 +000025 def __next__(self):
Guido van Rossum8b48cf92001-04-21 13:33:54 +000026 res = self.i
27 if res >= self.n:
28 raise StopIteration
29 self.i = res + 1
30 return res
31
32class IteratingSequenceClass:
33 def __init__(self, n):
34 self.n = n
35 def __iter__(self):
36 return BasicIterClass(self.n)
37
38class SequenceClass:
39 def __init__(self, n):
40 self.n = n
41 def __getitem__(self, i):
42 if 0 <= i < self.n:
43 return i
44 else:
45 raise IndexError
46
47# Main test suite
48
49class TestCase(unittest.TestCase):
50
51 # Helper to check that an iterator returns a given sequence
52 def check_iterator(self, it, seq):
53 res = []
54 while 1:
55 try:
Georg Brandla18af4e2007-04-21 15:47:16 +000056 val = next(it)
Guido van Rossum8b48cf92001-04-21 13:33:54 +000057 except StopIteration:
58 break
59 res.append(val)
60 self.assertEqual(res, seq)
61
62 # Helper to check that a for loop generates a given sequence
63 def check_for_loop(self, expr, seq):
64 res = []
65 for val in expr:
66 res.append(val)
67 self.assertEqual(res, seq)
68
69 # Test basic use of iter() function
70 def test_iter_basic(self):
Guido van Rossum805365e2007-05-07 22:24:25 +000071 self.check_iterator(iter(range(10)), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +000072
73 # Test that iter(iter(x)) is the same as iter(x)
74 def test_iter_idempotency(self):
Guido van Rossum805365e2007-05-07 22:24:25 +000075 seq = list(range(10))
Guido van Rossum8b48cf92001-04-21 13:33:54 +000076 it = iter(seq)
77 it2 = iter(it)
78 self.assert_(it is it2)
79
80 # Test that for loops over iterators work
81 def test_iter_for_loop(self):
Guido van Rossum805365e2007-05-07 22:24:25 +000082 self.check_for_loop(iter(range(10)), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +000083
84 # Test several independent iterators over the same list
85 def test_iter_independence(self):
86 seq = range(3)
87 res = []
88 for i in iter(seq):
89 for j in iter(seq):
90 for k in iter(seq):
91 res.append((i, j, k))
92 self.assertEqual(res, TRIPLETS)
93
94 # Test triple list comprehension using iterators
95 def test_nested_comprehensions_iter(self):
96 seq = range(3)
97 res = [(i, j, k)
98 for i in iter(seq) for j in iter(seq) for k in iter(seq)]
99 self.assertEqual(res, TRIPLETS)
100
101 # Test triple list comprehension without iterators
102 def test_nested_comprehensions_for(self):
103 seq = range(3)
104 res = [(i, j, k) for i in seq for j in seq for k in seq]
105 self.assertEqual(res, TRIPLETS)
106
107 # Test a class with __iter__ in a for loop
108 def test_iter_class_for(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000109 self.check_for_loop(IteratingSequenceClass(10), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000110
111 # Test a class with __iter__ with explicit iter()
112 def test_iter_class_iter(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000113 self.check_iterator(iter(IteratingSequenceClass(10)), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000114
115 # Test for loop on a sequence class without __iter__
116 def test_seq_class_for(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000117 self.check_for_loop(SequenceClass(10), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000118
119 # Test iter() on a sequence class without __iter__
120 def test_seq_class_iter(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000121 self.check_iterator(iter(SequenceClass(10)), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000122
123 # Test two-argument iter() with callable instance
124 def test_iter_callable(self):
125 class C:
126 def __init__(self):
127 self.i = 0
128 def __call__(self):
129 i = self.i
130 self.i = i + 1
131 if i > 100:
132 raise IndexError # Emergency stop
133 return i
Guido van Rossum805365e2007-05-07 22:24:25 +0000134 self.check_iterator(iter(C(), 10), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000135
136 # Test two-argument iter() with function
137 def test_iter_function(self):
138 def spam(state=[0]):
139 i = state[0]
140 state[0] = i+1
141 return i
Guido van Rossum805365e2007-05-07 22:24:25 +0000142 self.check_iterator(iter(spam, 10), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000143
144 # Test two-argument iter() with function that raises StopIteration
145 def test_iter_function_stop(self):
146 def spam(state=[0]):
147 i = state[0]
148 if i == 10:
149 raise StopIteration
150 state[0] = i+1
151 return i
Guido van Rossum805365e2007-05-07 22:24:25 +0000152 self.check_iterator(iter(spam, 20), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000153
154 # Test exception propagation through function iterator
155 def test_exception_function(self):
156 def spam(state=[0]):
157 i = state[0]
158 state[0] = i+1
159 if i == 10:
160 raise RuntimeError
161 return i
162 res = []
163 try:
164 for x in iter(spam, 20):
165 res.append(x)
166 except RuntimeError:
Guido van Rossum805365e2007-05-07 22:24:25 +0000167 self.assertEqual(res, list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000168 else:
169 self.fail("should have raised RuntimeError")
170
171 # Test exception propagation through sequence iterator
172 def test_exception_sequence(self):
173 class MySequenceClass(SequenceClass):
174 def __getitem__(self, i):
175 if i == 10:
176 raise RuntimeError
177 return SequenceClass.__getitem__(self, i)
178 res = []
179 try:
180 for x in MySequenceClass(20):
181 res.append(x)
182 except RuntimeError:
Guido van Rossum805365e2007-05-07 22:24:25 +0000183 self.assertEqual(res, list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000184 else:
185 self.fail("should have raised RuntimeError")
186
187 # Test for StopIteration from __getitem__
188 def test_stop_sequence(self):
189 class MySequenceClass(SequenceClass):
190 def __getitem__(self, i):
191 if i == 10:
192 raise StopIteration
193 return SequenceClass.__getitem__(self, i)
Guido van Rossum805365e2007-05-07 22:24:25 +0000194 self.check_for_loop(MySequenceClass(20), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000195
196 # Test a big range
197 def test_iter_big_range(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000198 self.check_for_loop(iter(range(10000)), list(range(10000)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000199
200 # Test an empty list
201 def test_iter_empty(self):
202 self.check_for_loop(iter([]), [])
203
204 # Test a tuple
205 def test_iter_tuple(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000206 self.check_for_loop(iter((0,1,2,3,4,5,6,7,8,9)), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000207
Guido van Rossum805365e2007-05-07 22:24:25 +0000208 # Test a range
209 def test_iter_range(self):
210 self.check_for_loop(iter(range(10)), list(range(10)))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000211
212 # Test a string
213 def test_iter_string(self):
214 self.check_for_loop(iter("abcde"), ["a", "b", "c", "d", "e"])
215
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000216 # Test a directory
217 def test_iter_dict(self):
218 dict = {}
219 for i in range(10):
220 dict[i] = None
Brett Cannon0caf6d82007-02-22 04:49:03 +0000221 self.check_for_loop(dict, list(dict.keys()))
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000222
223 # Test a file
224 def test_iter_file(self):
225 f = open(TESTFN, "w")
226 try:
227 for i in range(5):
228 f.write("%d\n" % i)
229 finally:
230 f.close()
231 f = open(TESTFN, "r")
232 try:
233 self.check_for_loop(f, ["0\n", "1\n", "2\n", "3\n", "4\n"])
234 self.check_for_loop(f, [])
235 finally:
236 f.close()
237 try:
238 unlink(TESTFN)
239 except OSError:
240 pass
241
Tim Petersf553f892001-05-01 20:45:31 +0000242 # Test list()'s use of iterators.
243 def test_builtin_list(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000244 self.assertEqual(list(SequenceClass(5)), list(range(5)))
Tim Petersf553f892001-05-01 20:45:31 +0000245 self.assertEqual(list(SequenceClass(0)), [])
246 self.assertEqual(list(()), [])
Tim Petersf553f892001-05-01 20:45:31 +0000247
248 d = {"one": 1, "two": 2, "three": 3}
Brett Cannon0caf6d82007-02-22 04:49:03 +0000249 self.assertEqual(list(d), list(d.keys()))
Tim Petersf553f892001-05-01 20:45:31 +0000250
251 self.assertRaises(TypeError, list, list)
252 self.assertRaises(TypeError, list, 42)
253
254 f = open(TESTFN, "w")
255 try:
256 for i in range(5):
257 f.write("%d\n" % i)
258 finally:
259 f.close()
260 f = open(TESTFN, "r")
261 try:
262 self.assertEqual(list(f), ["0\n", "1\n", "2\n", "3\n", "4\n"])
263 f.seek(0, 0)
Guido van Rossum8ee52432002-08-06 17:14:04 +0000264 self.assertEqual(list(f),
Tim Petersf553f892001-05-01 20:45:31 +0000265 ["0\n", "1\n", "2\n", "3\n", "4\n"])
266 finally:
267 f.close()
268 try:
269 unlink(TESTFN)
270 except OSError:
271 pass
272
Tim Peters6912d4d2001-05-05 03:56:37 +0000273 # Test tuples()'s use of iterators.
274 def test_builtin_tuple(self):
275 self.assertEqual(tuple(SequenceClass(5)), (0, 1, 2, 3, 4))
276 self.assertEqual(tuple(SequenceClass(0)), ())
277 self.assertEqual(tuple([]), ())
278 self.assertEqual(tuple(()), ())
279 self.assertEqual(tuple("abc"), ("a", "b", "c"))
280
281 d = {"one": 1, "two": 2, "three": 3}
282 self.assertEqual(tuple(d), tuple(d.keys()))
283
284 self.assertRaises(TypeError, tuple, list)
285 self.assertRaises(TypeError, tuple, 42)
286
287 f = open(TESTFN, "w")
288 try:
289 for i in range(5):
290 f.write("%d\n" % i)
291 finally:
292 f.close()
293 f = open(TESTFN, "r")
294 try:
295 self.assertEqual(tuple(f), ("0\n", "1\n", "2\n", "3\n", "4\n"))
296 f.seek(0, 0)
Guido van Rossum8ee52432002-08-06 17:14:04 +0000297 self.assertEqual(tuple(f),
Tim Peters6912d4d2001-05-05 03:56:37 +0000298 ("0\n", "1\n", "2\n", "3\n", "4\n"))
299 finally:
300 f.close()
301 try:
302 unlink(TESTFN)
303 except OSError:
304 pass
305
Tim Peters0e57abf2001-05-02 07:39:38 +0000306 # Test filter()'s use of iterators.
307 def test_builtin_filter(self):
Guido van Rossumc1f779c2007-07-03 08:25:58 +0000308 self.assertEqual(list(filter(None, SequenceClass(5))),
309 list(range(1, 5)))
310 self.assertEqual(list(filter(None, SequenceClass(0))), [])
311 self.assertEqual(list(filter(None, ())), [])
312 self.assertEqual(list(filter(None, "abc")), ["a", "b", "c"])
Tim Peters0e57abf2001-05-02 07:39:38 +0000313
314 d = {"one": 1, "two": 2, "three": 3}
Guido van Rossumc1f779c2007-07-03 08:25:58 +0000315 self.assertEqual(list(filter(None, d)), list(d.keys()))
Tim Peters0e57abf2001-05-02 07:39:38 +0000316
317 self.assertRaises(TypeError, filter, None, list)
318 self.assertRaises(TypeError, filter, None, 42)
319
320 class Boolean:
321 def __init__(self, truth):
322 self.truth = truth
Jack Diederich4dafcc42006-11-28 19:15:13 +0000323 def __bool__(self):
Tim Peters0e57abf2001-05-02 07:39:38 +0000324 return self.truth
Jack Diederich4dafcc42006-11-28 19:15:13 +0000325 bTrue = Boolean(True)
326 bFalse = Boolean(False)
Tim Peters0e57abf2001-05-02 07:39:38 +0000327
328 class Seq:
329 def __init__(self, *args):
330 self.vals = args
331 def __iter__(self):
332 class SeqIter:
333 def __init__(self, vals):
334 self.vals = vals
335 self.i = 0
336 def __iter__(self):
337 return self
Georg Brandla18af4e2007-04-21 15:47:16 +0000338 def __next__(self):
Tim Peters0e57abf2001-05-02 07:39:38 +0000339 i = self.i
340 self.i = i + 1
341 if i < len(self.vals):
342 return self.vals[i]
343 else:
344 raise StopIteration
345 return SeqIter(self.vals)
346
Tim Peterscae330e2002-12-23 16:50:58 +0000347 seq = Seq(*([bTrue, bFalse] * 25))
Guido van Rossumc1f779c2007-07-03 08:25:58 +0000348 self.assertEqual(list(filter(lambda x: not x, seq)), [bFalse]*25)
349 self.assertEqual(list(filter(lambda x: not x, iter(seq))), [bFalse]*25)
Tim Peters0e57abf2001-05-02 07:39:38 +0000350
Tim Petersc3074532001-05-03 07:00:32 +0000351 # Test max() and min()'s use of iterators.
352 def test_builtin_max_min(self):
353 self.assertEqual(max(SequenceClass(5)), 4)
354 self.assertEqual(min(SequenceClass(5)), 0)
355 self.assertEqual(max(8, -1), 8)
356 self.assertEqual(min(8, -1), -1)
357
358 d = {"one": 1, "two": 2, "three": 3}
359 self.assertEqual(max(d), "two")
360 self.assertEqual(min(d), "one")
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000361 self.assertEqual(max(d.values()), 3)
362 self.assertEqual(min(iter(d.values())), 1)
Tim Petersc3074532001-05-03 07:00:32 +0000363
Tim Petersc3074532001-05-03 07:00:32 +0000364 f = open(TESTFN, "w")
365 try:
366 f.write("medium line\n")
367 f.write("xtra large line\n")
368 f.write("itty-bitty line\n")
369 finally:
370 f.close()
371 f = open(TESTFN, "r")
372 try:
373 self.assertEqual(min(f), "itty-bitty line\n")
374 f.seek(0, 0)
375 self.assertEqual(max(f), "xtra large line\n")
376 finally:
377 f.close()
378 try:
379 unlink(TESTFN)
380 except OSError:
381 pass
382
Tim Peters4e9afdc2001-05-03 23:54:49 +0000383 # Test map()'s use of iterators.
384 def test_builtin_map(self):
Guido van Rossumc1f779c2007-07-03 08:25:58 +0000385 self.assertEqual(list(map(lambda x: x+1, SequenceClass(5))),
386 list(range(1, 6)))
Tim Peters4e9afdc2001-05-03 23:54:49 +0000387
388 d = {"one": 1, "two": 2, "three": 3}
Guido van Rossumc1f779c2007-07-03 08:25:58 +0000389 self.assertEqual(list(map(lambda k, d=d: (k, d[k]), d)),
390 list(d.items()))
Brett Cannon0caf6d82007-02-22 04:49:03 +0000391 dkeys = list(d.keys())
Tim Peters4e9afdc2001-05-03 23:54:49 +0000392 expected = [(i < len(d) and dkeys[i] or None,
393 i,
394 i < len(d) and dkeys[i] or None)
Guido van Rossumc1f779c2007-07-03 08:25:58 +0000395 for i in range(3)]
Tim Peters4e9afdc2001-05-03 23:54:49 +0000396
397 f = open(TESTFN, "w")
398 try:
399 for i in range(10):
400 f.write("xy" * i + "\n") # line i has len 2*i+1
401 finally:
402 f.close()
403 f = open(TESTFN, "r")
404 try:
Guido van Rossumc1f779c2007-07-03 08:25:58 +0000405 self.assertEqual(list(map(len, f)), list(range(1, 21, 2)))
Tim Peters4e9afdc2001-05-03 23:54:49 +0000406 finally:
407 f.close()
408 try:
409 unlink(TESTFN)
410 except OSError:
411 pass
412
Tim Peters8572b4f2001-05-06 01:05:02 +0000413 # Test zip()'s use of iterators.
414 def test_builtin_zip(self):
Guido van Rossum801f0d72006-08-24 19:48:10 +0000415 self.assertEqual(list(zip()), [])
416 self.assertEqual(list(zip(*[])), [])
417 self.assertEqual(list(zip(*[(1, 2), 'ab'])), [(1, 'a'), (2, 'b')])
Raymond Hettingereaef6152003-08-02 07:42:57 +0000418
Tim Peters8572b4f2001-05-06 01:05:02 +0000419 self.assertRaises(TypeError, zip, None)
420 self.assertRaises(TypeError, zip, range(10), 42)
421 self.assertRaises(TypeError, zip, range(10), zip)
422
Guido van Rossum801f0d72006-08-24 19:48:10 +0000423 self.assertEqual(list(zip(IteratingSequenceClass(3))),
Tim Peters8572b4f2001-05-06 01:05:02 +0000424 [(0,), (1,), (2,)])
Guido van Rossum801f0d72006-08-24 19:48:10 +0000425 self.assertEqual(list(zip(SequenceClass(3))),
Tim Peters8572b4f2001-05-06 01:05:02 +0000426 [(0,), (1,), (2,)])
427
428 d = {"one": 1, "two": 2, "three": 3}
Brett Cannon0caf6d82007-02-22 04:49:03 +0000429 self.assertEqual(list(d.items()), list(zip(d, d.values())))
Tim Peters8572b4f2001-05-06 01:05:02 +0000430
431 # Generate all ints starting at constructor arg.
432 class IntsFrom:
433 def __init__(self, start):
434 self.i = start
435
436 def __iter__(self):
437 return self
438
Georg Brandla18af4e2007-04-21 15:47:16 +0000439 def __next__(self):
Tim Peters8572b4f2001-05-06 01:05:02 +0000440 i = self.i
441 self.i = i+1
442 return i
443
444 f = open(TESTFN, "w")
445 try:
446 f.write("a\n" "bbb\n" "cc\n")
447 finally:
448 f.close()
449 f = open(TESTFN, "r")
450 try:
Guido van Rossum801f0d72006-08-24 19:48:10 +0000451 self.assertEqual(list(zip(IntsFrom(0), f, IntsFrom(-100))),
Tim Peters8572b4f2001-05-06 01:05:02 +0000452 [(0, "a\n", -100),
453 (1, "bbb\n", -99),
454 (2, "cc\n", -98)])
455 finally:
456 f.close()
457 try:
458 unlink(TESTFN)
459 except OSError:
460 pass
461
Guido van Rossum805365e2007-05-07 22:24:25 +0000462 self.assertEqual(list(zip(range(5))), [(i,) for i in range(5)])
Tim Peters67d687a2002-04-29 21:27:32 +0000463
464 # Classes that lie about their lengths.
465 class NoGuessLen5:
466 def __getitem__(self, i):
467 if i >= 5:
468 raise IndexError
469 return i
470
471 class Guess3Len5(NoGuessLen5):
472 def __len__(self):
473 return 3
474
475 class Guess30Len5(NoGuessLen5):
476 def __len__(self):
477 return 30
478
Guido van Rossum801f0d72006-08-24 19:48:10 +0000479 def lzip(*args):
480 return list(zip(*args))
481
Tim Peters67d687a2002-04-29 21:27:32 +0000482 self.assertEqual(len(Guess3Len5()), 3)
483 self.assertEqual(len(Guess30Len5()), 30)
Guido van Rossum801f0d72006-08-24 19:48:10 +0000484 self.assertEqual(lzip(NoGuessLen5()), lzip(range(5)))
485 self.assertEqual(lzip(Guess3Len5()), lzip(range(5)))
486 self.assertEqual(lzip(Guess30Len5()), lzip(range(5)))
Tim Peters67d687a2002-04-29 21:27:32 +0000487
488 expected = [(i, i) for i in range(5)]
489 for x in NoGuessLen5(), Guess3Len5(), Guess30Len5():
490 for y in NoGuessLen5(), Guess3Len5(), Guess30Len5():
Guido van Rossum801f0d72006-08-24 19:48:10 +0000491 self.assertEqual(lzip(x, y), expected)
Tim Peters67d687a2002-04-29 21:27:32 +0000492
Tim Peters2cfe3682001-05-05 05:36:48 +0000493 def test_unicode_join_endcase(self):
494
495 # This class inserts a Unicode object into its argument's natural
496 # iteration, in the 3rd position.
497 class OhPhooey:
498 def __init__(self, seq):
499 self.it = iter(seq)
500 self.i = 0
501
502 def __iter__(self):
503 return self
504
Georg Brandla18af4e2007-04-21 15:47:16 +0000505 def __next__(self):
Tim Peters2cfe3682001-05-05 05:36:48 +0000506 i = self.i
507 self.i = i+1
508 if i == 2:
Walter Dörwald1f5947b2007-05-22 16:52:54 +0000509 return "fooled you!"
Georg Brandla18af4e2007-04-21 15:47:16 +0000510 return next(self.it)
Tim Peters2cfe3682001-05-05 05:36:48 +0000511
512 f = open(TESTFN, "w")
513 try:
514 f.write("a\n" + "b\n" + "c\n")
515 finally:
516 f.close()
517
518 f = open(TESTFN, "r")
519 # Nasty: string.join(s) can't know whether unicode.join() is needed
520 # until it's seen all of s's elements. But in this case, f's
521 # iterator cannot be restarted. So what we're testing here is
522 # whether string.join() can manage to remember everything it's seen
523 # and pass that on to unicode.join().
524 try:
525 got = " - ".join(OhPhooey(f))
Walter Dörwald5de48bd2007-06-11 21:38:39 +0000526 self.assertEqual(got, "a\n - b\n - fooled you! - c\n")
Tim Peters2cfe3682001-05-05 05:36:48 +0000527 finally:
528 f.close()
529 try:
530 unlink(TESTFN)
531 except OSError:
532 pass
533
Tim Petersde9725f2001-05-05 10:06:17 +0000534 # Test iterators with 'x in y' and 'x not in y'.
535 def test_in_and_not_in(self):
Tim Peterscb8d3682001-05-05 21:05:01 +0000536 for sc5 in IteratingSequenceClass(5), SequenceClass(5):
537 for i in range(5):
538 self.assert_(i in sc5)
539 for i in "abc", -1, 5, 42.42, (3, 4), [], {1: 1}, 3-12j, sc5:
540 self.assert_(i not in sc5)
Tim Petersde9725f2001-05-05 10:06:17 +0000541
542 self.assertRaises(TypeError, lambda: 3 in 12)
543 self.assertRaises(TypeError, lambda: 3 not in map)
544
545 d = {"one": 1, "two": 2, "three": 3, 1j: 2j}
546 for k in d:
547 self.assert_(k in d)
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000548 self.assert_(k not in d.values())
Tim Petersde9725f2001-05-05 10:06:17 +0000549 for v in d.values():
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000550 self.assert_(v in d.values())
Tim Petersde9725f2001-05-05 10:06:17 +0000551 self.assert_(v not in d)
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000552 for k, v in d.items():
553 self.assert_((k, v) in d.items())
554 self.assert_((v, k) not in d.items())
Tim Petersde9725f2001-05-05 10:06:17 +0000555
556 f = open(TESTFN, "w")
557 try:
558 f.write("a\n" "b\n" "c\n")
559 finally:
560 f.close()
561 f = open(TESTFN, "r")
562 try:
563 for chunk in "abc":
564 f.seek(0, 0)
565 self.assert_(chunk not in f)
566 f.seek(0, 0)
567 self.assert_((chunk + "\n") in f)
568 finally:
569 f.close()
570 try:
571 unlink(TESTFN)
572 except OSError:
573 pass
574
Tim Peters75f8e352001-05-05 11:33:43 +0000575 # Test iterators with operator.countOf (PySequence_Count).
576 def test_countOf(self):
577 from operator import countOf
578 self.assertEqual(countOf([1,2,2,3,2,5], 2), 3)
579 self.assertEqual(countOf((1,2,2,3,2,5), 2), 3)
580 self.assertEqual(countOf("122325", "2"), 3)
581 self.assertEqual(countOf("122325", "6"), 0)
582
583 self.assertRaises(TypeError, countOf, 42, 1)
584 self.assertRaises(TypeError, countOf, countOf, countOf)
585
586 d = {"one": 3, "two": 3, "three": 3, 1j: 2j}
587 for k in d:
588 self.assertEqual(countOf(d, k), 1)
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000589 self.assertEqual(countOf(d.values(), 3), 3)
590 self.assertEqual(countOf(d.values(), 2j), 1)
591 self.assertEqual(countOf(d.values(), 1j), 0)
Tim Peters75f8e352001-05-05 11:33:43 +0000592
593 f = open(TESTFN, "w")
594 try:
595 f.write("a\n" "b\n" "c\n" "b\n")
596 finally:
597 f.close()
598 f = open(TESTFN, "r")
599 try:
600 for letter, count in ("a", 1), ("b", 2), ("c", 1), ("d", 0):
601 f.seek(0, 0)
602 self.assertEqual(countOf(f, letter + "\n"), count)
603 finally:
604 f.close()
605 try:
606 unlink(TESTFN)
607 except OSError:
608 pass
609
Tim Peters16a77ad2001-09-08 04:00:12 +0000610 # Test iterators with operator.indexOf (PySequence_Index).
611 def test_indexOf(self):
612 from operator import indexOf
613 self.assertEqual(indexOf([1,2,2,3,2,5], 1), 0)
614 self.assertEqual(indexOf((1,2,2,3,2,5), 2), 1)
615 self.assertEqual(indexOf((1,2,2,3,2,5), 3), 3)
616 self.assertEqual(indexOf((1,2,2,3,2,5), 5), 5)
617 self.assertRaises(ValueError, indexOf, (1,2,2,3,2,5), 0)
618 self.assertRaises(ValueError, indexOf, (1,2,2,3,2,5), 6)
619
620 self.assertEqual(indexOf("122325", "2"), 1)
621 self.assertEqual(indexOf("122325", "5"), 5)
622 self.assertRaises(ValueError, indexOf, "122325", "6")
623
624 self.assertRaises(TypeError, indexOf, 42, 1)
625 self.assertRaises(TypeError, indexOf, indexOf, indexOf)
626
627 f = open(TESTFN, "w")
628 try:
629 f.write("a\n" "b\n" "c\n" "d\n" "e\n")
630 finally:
631 f.close()
632 f = open(TESTFN, "r")
633 try:
634 fiter = iter(f)
635 self.assertEqual(indexOf(fiter, "b\n"), 1)
636 self.assertEqual(indexOf(fiter, "d\n"), 1)
637 self.assertEqual(indexOf(fiter, "e\n"), 0)
638 self.assertRaises(ValueError, indexOf, fiter, "a\n")
639 finally:
640 f.close()
641 try:
642 unlink(TESTFN)
643 except OSError:
644 pass
645
646 iclass = IteratingSequenceClass(3)
647 for i in range(3):
648 self.assertEqual(indexOf(iclass, i), i)
649 self.assertRaises(ValueError, indexOf, iclass, -1)
650
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000651 # Test iterators with file.writelines().
652 def test_writelines(self):
Alex Martelli01c77c62006-08-24 02:58:11 +0000653 f = open(TESTFN, "w")
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000654
655 try:
656 self.assertRaises(TypeError, f.writelines, None)
657 self.assertRaises(TypeError, f.writelines, 42)
Tim Peters527e64f2001-10-04 05:36:56 +0000658
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000659 f.writelines(["1\n", "2\n"])
660 f.writelines(("3\n", "4\n"))
661 f.writelines({'5\n': None})
662 f.writelines({})
663
664 # Try a big chunk too.
665 class Iterator:
666 def __init__(self, start, finish):
667 self.start = start
668 self.finish = finish
669 self.i = self.start
670
Georg Brandla18af4e2007-04-21 15:47:16 +0000671 def __next__(self):
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000672 if self.i >= self.finish:
673 raise StopIteration
674 result = str(self.i) + '\n'
675 self.i += 1
676 return result
677
678 def __iter__(self):
679 return self
680
681 class Whatever:
682 def __init__(self, start, finish):
683 self.start = start
684 self.finish = finish
685
686 def __iter__(self):
687 return Iterator(self.start, self.finish)
Tim Peters527e64f2001-10-04 05:36:56 +0000688
689 f.writelines(Whatever(6, 6+2000))
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000690 f.close()
691
Alex Martelli01c77c62006-08-24 02:58:11 +0000692 f = open(TESTFN)
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000693 expected = [str(i) + "\n" for i in range(1, 2006)]
694 self.assertEqual(list(f), expected)
Tim Peters527e64f2001-10-04 05:36:56 +0000695
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000696 finally:
697 f.close()
698 try:
699 unlink(TESTFN)
700 except OSError:
701 pass
702
703
Tim Petersd6d010b2001-06-21 02:49:55 +0000704 # Test iterators on RHS of unpacking assignments.
705 def test_unpack_iter(self):
706 a, b = 1, 2
707 self.assertEqual((a, b), (1, 2))
708
709 a, b, c = IteratingSequenceClass(3)
710 self.assertEqual((a, b, c), (0, 1, 2))
711
712 try: # too many values
713 a, b = IteratingSequenceClass(3)
714 except ValueError:
715 pass
716 else:
717 self.fail("should have raised ValueError")
718
719 try: # not enough values
720 a, b, c = IteratingSequenceClass(2)
721 except ValueError:
722 pass
723 else:
724 self.fail("should have raised ValueError")
725
726 try: # not iterable
727 a, b, c = len
728 except TypeError:
729 pass
730 else:
731 self.fail("should have raised TypeError")
732
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000733 a, b, c = {1: 42, 2: 42, 3: 42}.values()
Tim Petersd6d010b2001-06-21 02:49:55 +0000734 self.assertEqual((a, b, c), (42, 42, 42))
735
736 f = open(TESTFN, "w")
737 lines = ("a\n", "bb\n", "ccc\n")
738 try:
739 for line in lines:
740 f.write(line)
741 finally:
742 f.close()
743 f = open(TESTFN, "r")
744 try:
745 a, b, c = f
746 self.assertEqual((a, b, c), lines)
747 finally:
748 f.close()
749 try:
750 unlink(TESTFN)
751 except OSError:
752 pass
753
754 (a, b), (c,) = IteratingSequenceClass(2), {42: 24}
755 self.assertEqual((a, b, c), (0, 1, 42))
756
Guido van Rossumbb8f59a2001-12-03 19:33:25 +0000757 # Test reference count behavior
758
759 class C(object):
760 count = 0
761 def __new__(cls):
762 cls.count += 1
763 return object.__new__(cls)
764 def __del__(self):
765 cls = self.__class__
766 assert cls.count > 0
767 cls.count -= 1
768 x = C()
769 self.assertEqual(C.count, 1)
770 del x
771 self.assertEqual(C.count, 0)
772 l = [C(), C(), C()]
773 self.assertEqual(C.count, 3)
774 try:
775 a, b = iter(l)
776 except ValueError:
777 pass
778 del l
779 self.assertEqual(C.count, 0)
Fred Drake2e2be372001-09-20 21:33:42 +0000780
Guido van Rossum674eae62002-07-16 21:48:11 +0000781
782 # Make sure StopIteration is a "sink state".
783 # This tests various things that weren't sink states in Python 2.2.1,
784 # plus various things that always were fine.
785
786 def test_sinkstate_list(self):
787 # This used to fail
Guido van Rossum805365e2007-05-07 22:24:25 +0000788 a = list(range(5))
Guido van Rossum674eae62002-07-16 21:48:11 +0000789 b = iter(a)
Guido van Rossum805365e2007-05-07 22:24:25 +0000790 self.assertEqual(list(b), list(range(5)))
Guido van Rossum674eae62002-07-16 21:48:11 +0000791 a.extend(range(5, 10))
792 self.assertEqual(list(b), [])
793
794 def test_sinkstate_tuple(self):
795 a = (0, 1, 2, 3, 4)
796 b = iter(a)
Guido van Rossum805365e2007-05-07 22:24:25 +0000797 self.assertEqual(list(b), list(range(5)))
Guido van Rossum674eae62002-07-16 21:48:11 +0000798 self.assertEqual(list(b), [])
799
800 def test_sinkstate_string(self):
801 a = "abcde"
802 b = iter(a)
803 self.assertEqual(list(b), ['a', 'b', 'c', 'd', 'e'])
804 self.assertEqual(list(b), [])
805
806 def test_sinkstate_sequence(self):
807 # This used to fail
808 a = SequenceClass(5)
809 b = iter(a)
Guido van Rossum805365e2007-05-07 22:24:25 +0000810 self.assertEqual(list(b), list(range(5)))
Guido van Rossum674eae62002-07-16 21:48:11 +0000811 a.n = 10
812 self.assertEqual(list(b), [])
813
814 def test_sinkstate_callable(self):
815 # This used to fail
816 def spam(state=[0]):
817 i = state[0]
818 state[0] = i+1
819 if i == 10:
Collin Winter3add4d72007-08-29 23:37:32 +0000820 raise AssertionError("shouldn't have gotten this far")
Guido van Rossum674eae62002-07-16 21:48:11 +0000821 return i
822 b = iter(spam, 5)
Guido van Rossum805365e2007-05-07 22:24:25 +0000823 self.assertEqual(list(b), list(range(5)))
Guido van Rossum674eae62002-07-16 21:48:11 +0000824 self.assertEqual(list(b), [])
825
826 def test_sinkstate_dict(self):
827 # XXX For a more thorough test, see towards the end of:
828 # http://mail.python.org/pipermail/python-dev/2002-July/026512.html
829 a = {1:1, 2:2, 0:0, 4:4, 3:3}
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000830 for b in iter(a), a.keys(), a.items(), a.values():
Guido van Rossum674eae62002-07-16 21:48:11 +0000831 b = iter(a)
832 self.assertEqual(len(list(b)), 5)
833 self.assertEqual(list(b), [])
834
835 def test_sinkstate_yield(self):
836 def gen():
837 for i in range(5):
838 yield i
839 b = gen()
Guido van Rossum805365e2007-05-07 22:24:25 +0000840 self.assertEqual(list(b), list(range(5)))
Guido van Rossum674eae62002-07-16 21:48:11 +0000841 self.assertEqual(list(b), [])
842
843 def test_sinkstate_range(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000844 a = range(5)
Guido van Rossum674eae62002-07-16 21:48:11 +0000845 b = iter(a)
Guido van Rossum805365e2007-05-07 22:24:25 +0000846 self.assertEqual(list(b), list(range(5)))
Guido van Rossum674eae62002-07-16 21:48:11 +0000847 self.assertEqual(list(b), [])
848
849 def test_sinkstate_enumerate(self):
850 a = range(5)
851 e = enumerate(a)
852 b = iter(e)
Guido van Rossum801f0d72006-08-24 19:48:10 +0000853 self.assertEqual(list(b), list(zip(range(5), range(5))))
Guido van Rossum674eae62002-07-16 21:48:11 +0000854 self.assertEqual(list(b), [])
855
856
Fred Drake2e2be372001-09-20 21:33:42 +0000857def test_main():
858 run_unittest(TestCase)
859
860
861if __name__ == "__main__":
862 test_main()