blob: 42d4e3ee0a2e5c02e95a5d5a212e205e7a941263 [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 Rossum805365e2007-05-07 22:24:25 +0000308 self.assertEqual(filter(None, SequenceClass(5)), list(range(1, 5)))
Tim Peters0e57abf2001-05-02 07:39:38 +0000309 self.assertEqual(filter(None, SequenceClass(0)), [])
310 self.assertEqual(filter(None, ()), ())
311 self.assertEqual(filter(None, "abc"), "abc")
312
313 d = {"one": 1, "two": 2, "three": 3}
Brett Cannon0caf6d82007-02-22 04:49:03 +0000314 self.assertEqual(filter(None, d), list(d.keys()))
Tim Peters0e57abf2001-05-02 07:39:38 +0000315
316 self.assertRaises(TypeError, filter, None, list)
317 self.assertRaises(TypeError, filter, None, 42)
318
319 class Boolean:
320 def __init__(self, truth):
321 self.truth = truth
Jack Diederich4dafcc42006-11-28 19:15:13 +0000322 def __bool__(self):
Tim Peters0e57abf2001-05-02 07:39:38 +0000323 return self.truth
Jack Diederich4dafcc42006-11-28 19:15:13 +0000324 bTrue = Boolean(True)
325 bFalse = Boolean(False)
Tim Peters0e57abf2001-05-02 07:39:38 +0000326
327 class Seq:
328 def __init__(self, *args):
329 self.vals = args
330 def __iter__(self):
331 class SeqIter:
332 def __init__(self, vals):
333 self.vals = vals
334 self.i = 0
335 def __iter__(self):
336 return self
Georg Brandla18af4e2007-04-21 15:47:16 +0000337 def __next__(self):
Tim Peters0e57abf2001-05-02 07:39:38 +0000338 i = self.i
339 self.i = i + 1
340 if i < len(self.vals):
341 return self.vals[i]
342 else:
343 raise StopIteration
344 return SeqIter(self.vals)
345
Tim Peterscae330e2002-12-23 16:50:58 +0000346 seq = Seq(*([bTrue, bFalse] * 25))
347 self.assertEqual(filter(lambda x: not x, seq), [bFalse]*25)
348 self.assertEqual(filter(lambda x: not x, iter(seq)), [bFalse]*25)
Tim Peters0e57abf2001-05-02 07:39:38 +0000349
Tim Petersc3074532001-05-03 07:00:32 +0000350 # Test max() and min()'s use of iterators.
351 def test_builtin_max_min(self):
352 self.assertEqual(max(SequenceClass(5)), 4)
353 self.assertEqual(min(SequenceClass(5)), 0)
354 self.assertEqual(max(8, -1), 8)
355 self.assertEqual(min(8, -1), -1)
356
357 d = {"one": 1, "two": 2, "three": 3}
358 self.assertEqual(max(d), "two")
359 self.assertEqual(min(d), "one")
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000360 self.assertEqual(max(d.values()), 3)
361 self.assertEqual(min(iter(d.values())), 1)
Tim Petersc3074532001-05-03 07:00:32 +0000362
Tim Petersc3074532001-05-03 07:00:32 +0000363 f = open(TESTFN, "w")
364 try:
365 f.write("medium line\n")
366 f.write("xtra large line\n")
367 f.write("itty-bitty line\n")
368 finally:
369 f.close()
370 f = open(TESTFN, "r")
371 try:
372 self.assertEqual(min(f), "itty-bitty line\n")
373 f.seek(0, 0)
374 self.assertEqual(max(f), "xtra large line\n")
375 finally:
376 f.close()
377 try:
378 unlink(TESTFN)
379 except OSError:
380 pass
381
Tim Peters4e9afdc2001-05-03 23:54:49 +0000382 # Test map()'s use of iterators.
383 def test_builtin_map(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000384 self.assertEqual(map(None, SequenceClass(5)), list(range(5)))
385 self.assertEqual(map(lambda x: x+1, SequenceClass(5)), list(range(1, 6)))
Tim Peters4e9afdc2001-05-03 23:54:49 +0000386
387 d = {"one": 1, "two": 2, "three": 3}
Brett Cannon0caf6d82007-02-22 04:49:03 +0000388 self.assertEqual(map(None, d), list(d.keys()))
389 self.assertEqual(map(lambda k, d=d: (k, d[k]), d), list(d.items()))
390 dkeys = list(d.keys())
Tim Peters4e9afdc2001-05-03 23:54:49 +0000391 expected = [(i < len(d) and dkeys[i] or None,
392 i,
393 i < len(d) and dkeys[i] or None)
394 for i in range(5)]
395 self.assertEqual(map(None, d,
396 SequenceClass(5),
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000397 iter(d.keys())),
Tim Peters8bc10b02001-05-03 23:58:47 +0000398 expected)
Tim Peters4e9afdc2001-05-03 23:54:49 +0000399
400 f = open(TESTFN, "w")
401 try:
402 for i in range(10):
403 f.write("xy" * i + "\n") # line i has len 2*i+1
404 finally:
405 f.close()
406 f = open(TESTFN, "r")
407 try:
Guido van Rossum805365e2007-05-07 22:24:25 +0000408 self.assertEqual(map(len, f), list(range(1, 21, 2)))
Tim Peters4e9afdc2001-05-03 23:54:49 +0000409 finally:
410 f.close()
411 try:
412 unlink(TESTFN)
413 except OSError:
414 pass
415
Tim Peters8572b4f2001-05-06 01:05:02 +0000416 # Test zip()'s use of iterators.
417 def test_builtin_zip(self):
Guido van Rossum801f0d72006-08-24 19:48:10 +0000418 self.assertEqual(list(zip()), [])
419 self.assertEqual(list(zip(*[])), [])
420 self.assertEqual(list(zip(*[(1, 2), 'ab'])), [(1, 'a'), (2, 'b')])
Raymond Hettingereaef6152003-08-02 07:42:57 +0000421
Tim Peters8572b4f2001-05-06 01:05:02 +0000422 self.assertRaises(TypeError, zip, None)
423 self.assertRaises(TypeError, zip, range(10), 42)
424 self.assertRaises(TypeError, zip, range(10), zip)
425
Guido van Rossum801f0d72006-08-24 19:48:10 +0000426 self.assertEqual(list(zip(IteratingSequenceClass(3))),
Tim Peters8572b4f2001-05-06 01:05:02 +0000427 [(0,), (1,), (2,)])
Guido van Rossum801f0d72006-08-24 19:48:10 +0000428 self.assertEqual(list(zip(SequenceClass(3))),
Tim Peters8572b4f2001-05-06 01:05:02 +0000429 [(0,), (1,), (2,)])
430
431 d = {"one": 1, "two": 2, "three": 3}
Brett Cannon0caf6d82007-02-22 04:49:03 +0000432 self.assertEqual(list(d.items()), list(zip(d, d.values())))
Tim Peters8572b4f2001-05-06 01:05:02 +0000433
434 # Generate all ints starting at constructor arg.
435 class IntsFrom:
436 def __init__(self, start):
437 self.i = start
438
439 def __iter__(self):
440 return self
441
Georg Brandla18af4e2007-04-21 15:47:16 +0000442 def __next__(self):
Tim Peters8572b4f2001-05-06 01:05:02 +0000443 i = self.i
444 self.i = i+1
445 return i
446
447 f = open(TESTFN, "w")
448 try:
449 f.write("a\n" "bbb\n" "cc\n")
450 finally:
451 f.close()
452 f = open(TESTFN, "r")
453 try:
Guido van Rossum801f0d72006-08-24 19:48:10 +0000454 self.assertEqual(list(zip(IntsFrom(0), f, IntsFrom(-100))),
Tim Peters8572b4f2001-05-06 01:05:02 +0000455 [(0, "a\n", -100),
456 (1, "bbb\n", -99),
457 (2, "cc\n", -98)])
458 finally:
459 f.close()
460 try:
461 unlink(TESTFN)
462 except OSError:
463 pass
464
Guido van Rossum805365e2007-05-07 22:24:25 +0000465 self.assertEqual(list(zip(range(5))), [(i,) for i in range(5)])
Tim Peters67d687a2002-04-29 21:27:32 +0000466
467 # Classes that lie about their lengths.
468 class NoGuessLen5:
469 def __getitem__(self, i):
470 if i >= 5:
471 raise IndexError
472 return i
473
474 class Guess3Len5(NoGuessLen5):
475 def __len__(self):
476 return 3
477
478 class Guess30Len5(NoGuessLen5):
479 def __len__(self):
480 return 30
481
Guido van Rossum801f0d72006-08-24 19:48:10 +0000482 def lzip(*args):
483 return list(zip(*args))
484
Tim Peters67d687a2002-04-29 21:27:32 +0000485 self.assertEqual(len(Guess3Len5()), 3)
486 self.assertEqual(len(Guess30Len5()), 30)
Guido van Rossum801f0d72006-08-24 19:48:10 +0000487 self.assertEqual(lzip(NoGuessLen5()), lzip(range(5)))
488 self.assertEqual(lzip(Guess3Len5()), lzip(range(5)))
489 self.assertEqual(lzip(Guess30Len5()), lzip(range(5)))
Tim Peters67d687a2002-04-29 21:27:32 +0000490
491 expected = [(i, i) for i in range(5)]
492 for x in NoGuessLen5(), Guess3Len5(), Guess30Len5():
493 for y in NoGuessLen5(), Guess3Len5(), Guess30Len5():
Guido van Rossum801f0d72006-08-24 19:48:10 +0000494 self.assertEqual(lzip(x, y), expected)
Tim Peters67d687a2002-04-29 21:27:32 +0000495
Tim Peters2cfe3682001-05-05 05:36:48 +0000496 def test_unicode_join_endcase(self):
497
498 # This class inserts a Unicode object into its argument's natural
499 # iteration, in the 3rd position.
500 class OhPhooey:
501 def __init__(self, seq):
502 self.it = iter(seq)
503 self.i = 0
504
505 def __iter__(self):
506 return self
507
Georg Brandla18af4e2007-04-21 15:47:16 +0000508 def __next__(self):
Tim Peters2cfe3682001-05-05 05:36:48 +0000509 i = self.i
510 self.i = i+1
511 if i == 2:
Walter Dörwald1f5947b2007-05-22 16:52:54 +0000512 return "fooled you!"
Georg Brandla18af4e2007-04-21 15:47:16 +0000513 return next(self.it)
Tim Peters2cfe3682001-05-05 05:36:48 +0000514
515 f = open(TESTFN, "w")
516 try:
517 f.write("a\n" + "b\n" + "c\n")
518 finally:
519 f.close()
520
521 f = open(TESTFN, "r")
522 # Nasty: string.join(s) can't know whether unicode.join() is needed
523 # until it's seen all of s's elements. But in this case, f's
524 # iterator cannot be restarted. So what we're testing here is
525 # whether string.join() can manage to remember everything it's seen
526 # and pass that on to unicode.join().
527 try:
528 got = " - ".join(OhPhooey(f))
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000529 self.assertEqual(got, str("a\n - b\n - fooled you! - c\n"))
Tim Peters2cfe3682001-05-05 05:36:48 +0000530 finally:
531 f.close()
532 try:
533 unlink(TESTFN)
534 except OSError:
535 pass
536
Tim Petersde9725f2001-05-05 10:06:17 +0000537 # Test iterators with 'x in y' and 'x not in y'.
538 def test_in_and_not_in(self):
Tim Peterscb8d3682001-05-05 21:05:01 +0000539 for sc5 in IteratingSequenceClass(5), SequenceClass(5):
540 for i in range(5):
541 self.assert_(i in sc5)
542 for i in "abc", -1, 5, 42.42, (3, 4), [], {1: 1}, 3-12j, sc5:
543 self.assert_(i not in sc5)
Tim Petersde9725f2001-05-05 10:06:17 +0000544
545 self.assertRaises(TypeError, lambda: 3 in 12)
546 self.assertRaises(TypeError, lambda: 3 not in map)
547
548 d = {"one": 1, "two": 2, "three": 3, 1j: 2j}
549 for k in d:
550 self.assert_(k in d)
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000551 self.assert_(k not in d.values())
Tim Petersde9725f2001-05-05 10:06:17 +0000552 for v in d.values():
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000553 self.assert_(v in d.values())
Tim Petersde9725f2001-05-05 10:06:17 +0000554 self.assert_(v not in d)
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000555 for k, v in d.items():
556 self.assert_((k, v) in d.items())
557 self.assert_((v, k) not in d.items())
Tim Petersde9725f2001-05-05 10:06:17 +0000558
559 f = open(TESTFN, "w")
560 try:
561 f.write("a\n" "b\n" "c\n")
562 finally:
563 f.close()
564 f = open(TESTFN, "r")
565 try:
566 for chunk in "abc":
567 f.seek(0, 0)
568 self.assert_(chunk not in f)
569 f.seek(0, 0)
570 self.assert_((chunk + "\n") in f)
571 finally:
572 f.close()
573 try:
574 unlink(TESTFN)
575 except OSError:
576 pass
577
Tim Peters75f8e352001-05-05 11:33:43 +0000578 # Test iterators with operator.countOf (PySequence_Count).
579 def test_countOf(self):
580 from operator import countOf
581 self.assertEqual(countOf([1,2,2,3,2,5], 2), 3)
582 self.assertEqual(countOf((1,2,2,3,2,5), 2), 3)
583 self.assertEqual(countOf("122325", "2"), 3)
584 self.assertEqual(countOf("122325", "6"), 0)
585
586 self.assertRaises(TypeError, countOf, 42, 1)
587 self.assertRaises(TypeError, countOf, countOf, countOf)
588
589 d = {"one": 3, "two": 3, "three": 3, 1j: 2j}
590 for k in d:
591 self.assertEqual(countOf(d, k), 1)
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000592 self.assertEqual(countOf(d.values(), 3), 3)
593 self.assertEqual(countOf(d.values(), 2j), 1)
594 self.assertEqual(countOf(d.values(), 1j), 0)
Tim Peters75f8e352001-05-05 11:33:43 +0000595
596 f = open(TESTFN, "w")
597 try:
598 f.write("a\n" "b\n" "c\n" "b\n")
599 finally:
600 f.close()
601 f = open(TESTFN, "r")
602 try:
603 for letter, count in ("a", 1), ("b", 2), ("c", 1), ("d", 0):
604 f.seek(0, 0)
605 self.assertEqual(countOf(f, letter + "\n"), count)
606 finally:
607 f.close()
608 try:
609 unlink(TESTFN)
610 except OSError:
611 pass
612
Tim Peters16a77ad2001-09-08 04:00:12 +0000613 # Test iterators with operator.indexOf (PySequence_Index).
614 def test_indexOf(self):
615 from operator import indexOf
616 self.assertEqual(indexOf([1,2,2,3,2,5], 1), 0)
617 self.assertEqual(indexOf((1,2,2,3,2,5), 2), 1)
618 self.assertEqual(indexOf((1,2,2,3,2,5), 3), 3)
619 self.assertEqual(indexOf((1,2,2,3,2,5), 5), 5)
620 self.assertRaises(ValueError, indexOf, (1,2,2,3,2,5), 0)
621 self.assertRaises(ValueError, indexOf, (1,2,2,3,2,5), 6)
622
623 self.assertEqual(indexOf("122325", "2"), 1)
624 self.assertEqual(indexOf("122325", "5"), 5)
625 self.assertRaises(ValueError, indexOf, "122325", "6")
626
627 self.assertRaises(TypeError, indexOf, 42, 1)
628 self.assertRaises(TypeError, indexOf, indexOf, indexOf)
629
630 f = open(TESTFN, "w")
631 try:
632 f.write("a\n" "b\n" "c\n" "d\n" "e\n")
633 finally:
634 f.close()
635 f = open(TESTFN, "r")
636 try:
637 fiter = iter(f)
638 self.assertEqual(indexOf(fiter, "b\n"), 1)
639 self.assertEqual(indexOf(fiter, "d\n"), 1)
640 self.assertEqual(indexOf(fiter, "e\n"), 0)
641 self.assertRaises(ValueError, indexOf, fiter, "a\n")
642 finally:
643 f.close()
644 try:
645 unlink(TESTFN)
646 except OSError:
647 pass
648
649 iclass = IteratingSequenceClass(3)
650 for i in range(3):
651 self.assertEqual(indexOf(iclass, i), i)
652 self.assertRaises(ValueError, indexOf, iclass, -1)
653
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000654 # Test iterators with file.writelines().
655 def test_writelines(self):
Alex Martelli01c77c62006-08-24 02:58:11 +0000656 f = open(TESTFN, "w")
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000657
658 try:
659 self.assertRaises(TypeError, f.writelines, None)
660 self.assertRaises(TypeError, f.writelines, 42)
Tim Peters527e64f2001-10-04 05:36:56 +0000661
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000662 f.writelines(["1\n", "2\n"])
663 f.writelines(("3\n", "4\n"))
664 f.writelines({'5\n': None})
665 f.writelines({})
666
667 # Try a big chunk too.
668 class Iterator:
669 def __init__(self, start, finish):
670 self.start = start
671 self.finish = finish
672 self.i = self.start
673
Georg Brandla18af4e2007-04-21 15:47:16 +0000674 def __next__(self):
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000675 if self.i >= self.finish:
676 raise StopIteration
677 result = str(self.i) + '\n'
678 self.i += 1
679 return result
680
681 def __iter__(self):
682 return self
683
684 class Whatever:
685 def __init__(self, start, finish):
686 self.start = start
687 self.finish = finish
688
689 def __iter__(self):
690 return Iterator(self.start, self.finish)
Tim Peters527e64f2001-10-04 05:36:56 +0000691
692 f.writelines(Whatever(6, 6+2000))
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000693 f.close()
694
Alex Martelli01c77c62006-08-24 02:58:11 +0000695 f = open(TESTFN)
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000696 expected = [str(i) + "\n" for i in range(1, 2006)]
697 self.assertEqual(list(f), expected)
Tim Peters527e64f2001-10-04 05:36:56 +0000698
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000699 finally:
700 f.close()
701 try:
702 unlink(TESTFN)
703 except OSError:
704 pass
705
706
Tim Petersd6d010b2001-06-21 02:49:55 +0000707 # Test iterators on RHS of unpacking assignments.
708 def test_unpack_iter(self):
709 a, b = 1, 2
710 self.assertEqual((a, b), (1, 2))
711
712 a, b, c = IteratingSequenceClass(3)
713 self.assertEqual((a, b, c), (0, 1, 2))
714
715 try: # too many values
716 a, b = IteratingSequenceClass(3)
717 except ValueError:
718 pass
719 else:
720 self.fail("should have raised ValueError")
721
722 try: # not enough values
723 a, b, c = IteratingSequenceClass(2)
724 except ValueError:
725 pass
726 else:
727 self.fail("should have raised ValueError")
728
729 try: # not iterable
730 a, b, c = len
731 except TypeError:
732 pass
733 else:
734 self.fail("should have raised TypeError")
735
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000736 a, b, c = {1: 42, 2: 42, 3: 42}.values()
Tim Petersd6d010b2001-06-21 02:49:55 +0000737 self.assertEqual((a, b, c), (42, 42, 42))
738
739 f = open(TESTFN, "w")
740 lines = ("a\n", "bb\n", "ccc\n")
741 try:
742 for line in lines:
743 f.write(line)
744 finally:
745 f.close()
746 f = open(TESTFN, "r")
747 try:
748 a, b, c = f
749 self.assertEqual((a, b, c), lines)
750 finally:
751 f.close()
752 try:
753 unlink(TESTFN)
754 except OSError:
755 pass
756
757 (a, b), (c,) = IteratingSequenceClass(2), {42: 24}
758 self.assertEqual((a, b, c), (0, 1, 42))
759
Guido van Rossumbb8f59a2001-12-03 19:33:25 +0000760 # Test reference count behavior
761
762 class C(object):
763 count = 0
764 def __new__(cls):
765 cls.count += 1
766 return object.__new__(cls)
767 def __del__(self):
768 cls = self.__class__
769 assert cls.count > 0
770 cls.count -= 1
771 x = C()
772 self.assertEqual(C.count, 1)
773 del x
774 self.assertEqual(C.count, 0)
775 l = [C(), C(), C()]
776 self.assertEqual(C.count, 3)
777 try:
778 a, b = iter(l)
779 except ValueError:
780 pass
781 del l
782 self.assertEqual(C.count, 0)
Fred Drake2e2be372001-09-20 21:33:42 +0000783
Guido van Rossum674eae62002-07-16 21:48:11 +0000784
785 # Make sure StopIteration is a "sink state".
786 # This tests various things that weren't sink states in Python 2.2.1,
787 # plus various things that always were fine.
788
789 def test_sinkstate_list(self):
790 # This used to fail
Guido van Rossum805365e2007-05-07 22:24:25 +0000791 a = list(range(5))
Guido van Rossum674eae62002-07-16 21:48:11 +0000792 b = iter(a)
Guido van Rossum805365e2007-05-07 22:24:25 +0000793 self.assertEqual(list(b), list(range(5)))
Guido van Rossum674eae62002-07-16 21:48:11 +0000794 a.extend(range(5, 10))
795 self.assertEqual(list(b), [])
796
797 def test_sinkstate_tuple(self):
798 a = (0, 1, 2, 3, 4)
799 b = iter(a)
Guido van Rossum805365e2007-05-07 22:24:25 +0000800 self.assertEqual(list(b), list(range(5)))
Guido van Rossum674eae62002-07-16 21:48:11 +0000801 self.assertEqual(list(b), [])
802
803 def test_sinkstate_string(self):
804 a = "abcde"
805 b = iter(a)
806 self.assertEqual(list(b), ['a', 'b', 'c', 'd', 'e'])
807 self.assertEqual(list(b), [])
808
809 def test_sinkstate_sequence(self):
810 # This used to fail
811 a = SequenceClass(5)
812 b = iter(a)
Guido van Rossum805365e2007-05-07 22:24:25 +0000813 self.assertEqual(list(b), list(range(5)))
Guido van Rossum674eae62002-07-16 21:48:11 +0000814 a.n = 10
815 self.assertEqual(list(b), [])
816
817 def test_sinkstate_callable(self):
818 # This used to fail
819 def spam(state=[0]):
820 i = state[0]
821 state[0] = i+1
822 if i == 10:
823 raise AssertionError, "shouldn't have gotten this far"
824 return i
825 b = iter(spam, 5)
Guido van Rossum805365e2007-05-07 22:24:25 +0000826 self.assertEqual(list(b), list(range(5)))
Guido van Rossum674eae62002-07-16 21:48:11 +0000827 self.assertEqual(list(b), [])
828
829 def test_sinkstate_dict(self):
830 # XXX For a more thorough test, see towards the end of:
831 # http://mail.python.org/pipermail/python-dev/2002-July/026512.html
832 a = {1:1, 2:2, 0:0, 4:4, 3:3}
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000833 for b in iter(a), a.keys(), a.items(), a.values():
Guido van Rossum674eae62002-07-16 21:48:11 +0000834 b = iter(a)
835 self.assertEqual(len(list(b)), 5)
836 self.assertEqual(list(b), [])
837
838 def test_sinkstate_yield(self):
839 def gen():
840 for i in range(5):
841 yield i
842 b = gen()
Guido van Rossum805365e2007-05-07 22:24:25 +0000843 self.assertEqual(list(b), list(range(5)))
Guido van Rossum674eae62002-07-16 21:48:11 +0000844 self.assertEqual(list(b), [])
845
846 def test_sinkstate_range(self):
Guido van Rossum805365e2007-05-07 22:24:25 +0000847 a = range(5)
Guido van Rossum674eae62002-07-16 21:48:11 +0000848 b = iter(a)
Guido van Rossum805365e2007-05-07 22:24:25 +0000849 self.assertEqual(list(b), list(range(5)))
Guido van Rossum674eae62002-07-16 21:48:11 +0000850 self.assertEqual(list(b), [])
851
852 def test_sinkstate_enumerate(self):
853 a = range(5)
854 e = enumerate(a)
855 b = iter(e)
Guido van Rossum801f0d72006-08-24 19:48:10 +0000856 self.assertEqual(list(b), list(zip(range(5), range(5))))
Guido van Rossum674eae62002-07-16 21:48:11 +0000857 self.assertEqual(list(b), [])
858
859
Fred Drake2e2be372001-09-20 21:33:42 +0000860def test_main():
861 run_unittest(TestCase)
862
863
864if __name__ == "__main__":
865 test_main()