blob: 13ed5bd4a8b549bb4e0564cb156434caa983a18b [file] [log] [blame]
Guido van Rossum8b48cf92001-04-21 13:33:54 +00001# Test iterators.
2
3import unittest
Martin v. Löwis339d0f72001-08-17 18:39:25 +00004from test_support import run_unittest, TESTFN, unlink, have_unicode
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
25 def next(self):
26 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:
56 val = it.next()
57 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):
71 self.check_iterator(iter(range(10)), range(10))
72
73 # Test that iter(iter(x)) is the same as iter(x)
74 def test_iter_idempotency(self):
75 seq = range(10)
76 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):
82 self.check_for_loop(iter(range(10)), range(10))
83
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):
109 self.check_for_loop(IteratingSequenceClass(10), range(10))
110
111 # Test a class with __iter__ with explicit iter()
112 def test_iter_class_iter(self):
113 self.check_iterator(iter(IteratingSequenceClass(10)), range(10))
114
115 # Test for loop on a sequence class without __iter__
116 def test_seq_class_for(self):
117 self.check_for_loop(SequenceClass(10), range(10))
118
119 # Test iter() on a sequence class without __iter__
120 def test_seq_class_iter(self):
121 self.check_iterator(iter(SequenceClass(10)), range(10))
122
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
134 self.check_iterator(iter(C(), 10), range(10))
135
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
142 self.check_iterator(iter(spam, 10), range(10))
143
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
152 self.check_iterator(iter(spam, 20), range(10))
153
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:
167 self.assertEqual(res, range(10))
168 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:
183 self.assertEqual(res, range(10))
184 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)
194 self.check_for_loop(MySequenceClass(20), range(10))
195
196 # Test a big range
197 def test_iter_big_range(self):
198 self.check_for_loop(iter(range(10000)), range(10000))
199
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):
206 self.check_for_loop(iter((0,1,2,3,4,5,6,7,8,9)), range(10))
207
208 # Test an xrange
209 def test_iter_xrange(self):
210 self.check_for_loop(iter(xrange(10)), range(10))
211
212 # Test a string
213 def test_iter_string(self):
214 self.check_for_loop(iter("abcde"), ["a", "b", "c", "d", "e"])
215
216 # Test a Unicode string
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000217 if have_unicode:
218 def test_iter_unicode(self):
219 self.check_for_loop(iter(unicode("abcde")),
220 [unicode("a"), unicode("b"), unicode("c"),
221 unicode("d"), unicode("e")])
Guido van Rossum8b48cf92001-04-21 13:33:54 +0000222
223 # Test a directory
224 def test_iter_dict(self):
225 dict = {}
226 for i in range(10):
227 dict[i] = None
228 self.check_for_loop(dict, dict.keys())
229
230 # Test a file
231 def test_iter_file(self):
232 f = open(TESTFN, "w")
233 try:
234 for i in range(5):
235 f.write("%d\n" % i)
236 finally:
237 f.close()
238 f = open(TESTFN, "r")
239 try:
240 self.check_for_loop(f, ["0\n", "1\n", "2\n", "3\n", "4\n"])
241 self.check_for_loop(f, [])
242 finally:
243 f.close()
244 try:
245 unlink(TESTFN)
246 except OSError:
247 pass
248
Tim Petersf553f892001-05-01 20:45:31 +0000249 # Test list()'s use of iterators.
250 def test_builtin_list(self):
251 self.assertEqual(list(SequenceClass(5)), range(5))
252 self.assertEqual(list(SequenceClass(0)), [])
253 self.assertEqual(list(()), [])
254 self.assertEqual(list(range(10, -1, -1)), range(10, -1, -1))
255
256 d = {"one": 1, "two": 2, "three": 3}
257 self.assertEqual(list(d), d.keys())
258
259 self.assertRaises(TypeError, list, list)
260 self.assertRaises(TypeError, list, 42)
261
262 f = open(TESTFN, "w")
263 try:
264 for i in range(5):
265 f.write("%d\n" % i)
266 finally:
267 f.close()
268 f = open(TESTFN, "r")
269 try:
270 self.assertEqual(list(f), ["0\n", "1\n", "2\n", "3\n", "4\n"])
271 f.seek(0, 0)
272 self.assertEqual(list(f.xreadlines()),
273 ["0\n", "1\n", "2\n", "3\n", "4\n"])
274 finally:
275 f.close()
276 try:
277 unlink(TESTFN)
278 except OSError:
279 pass
280
Tim Peters6912d4d2001-05-05 03:56:37 +0000281 # Test tuples()'s use of iterators.
282 def test_builtin_tuple(self):
283 self.assertEqual(tuple(SequenceClass(5)), (0, 1, 2, 3, 4))
284 self.assertEqual(tuple(SequenceClass(0)), ())
285 self.assertEqual(tuple([]), ())
286 self.assertEqual(tuple(()), ())
287 self.assertEqual(tuple("abc"), ("a", "b", "c"))
288
289 d = {"one": 1, "two": 2, "three": 3}
290 self.assertEqual(tuple(d), tuple(d.keys()))
291
292 self.assertRaises(TypeError, tuple, list)
293 self.assertRaises(TypeError, tuple, 42)
294
295 f = open(TESTFN, "w")
296 try:
297 for i in range(5):
298 f.write("%d\n" % i)
299 finally:
300 f.close()
301 f = open(TESTFN, "r")
302 try:
303 self.assertEqual(tuple(f), ("0\n", "1\n", "2\n", "3\n", "4\n"))
304 f.seek(0, 0)
305 self.assertEqual(tuple(f.xreadlines()),
306 ("0\n", "1\n", "2\n", "3\n", "4\n"))
307 finally:
308 f.close()
309 try:
310 unlink(TESTFN)
311 except OSError:
312 pass
313
Tim Peters0e57abf2001-05-02 07:39:38 +0000314 # Test filter()'s use of iterators.
315 def test_builtin_filter(self):
316 self.assertEqual(filter(None, SequenceClass(5)), range(1, 5))
317 self.assertEqual(filter(None, SequenceClass(0)), [])
318 self.assertEqual(filter(None, ()), ())
319 self.assertEqual(filter(None, "abc"), "abc")
320
321 d = {"one": 1, "two": 2, "three": 3}
322 self.assertEqual(filter(None, d), d.keys())
323
324 self.assertRaises(TypeError, filter, None, list)
325 self.assertRaises(TypeError, filter, None, 42)
326
327 class Boolean:
328 def __init__(self, truth):
329 self.truth = truth
330 def __nonzero__(self):
331 return self.truth
332 True = Boolean(1)
333 False = Boolean(0)
334
335 class Seq:
336 def __init__(self, *args):
337 self.vals = args
338 def __iter__(self):
339 class SeqIter:
340 def __init__(self, vals):
341 self.vals = vals
342 self.i = 0
343 def __iter__(self):
344 return self
345 def next(self):
346 i = self.i
347 self.i = i + 1
348 if i < len(self.vals):
349 return self.vals[i]
350 else:
351 raise StopIteration
352 return SeqIter(self.vals)
353
354 seq = Seq(*([True, False] * 25))
355 self.assertEqual(filter(lambda x: not x, seq), [False]*25)
356 self.assertEqual(filter(lambda x: not x, iter(seq)), [False]*25)
357
Tim Petersc3074532001-05-03 07:00:32 +0000358 # 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)
364
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.itervalues()), 3)
369 self.assertEqual(min(iter(d.itervalues())), 1)
370
Tim Petersc3074532001-05-03 07:00:32 +0000371 f = open(TESTFN, "w")
372 try:
373 f.write("medium line\n")
374 f.write("xtra large line\n")
375 f.write("itty-bitty line\n")
376 finally:
377 f.close()
378 f = open(TESTFN, "r")
379 try:
380 self.assertEqual(min(f), "itty-bitty line\n")
381 f.seek(0, 0)
382 self.assertEqual(max(f), "xtra large line\n")
383 finally:
384 f.close()
385 try:
386 unlink(TESTFN)
387 except OSError:
388 pass
389
Tim Peters4e9afdc2001-05-03 23:54:49 +0000390 # Test map()'s use of iterators.
391 def test_builtin_map(self):
392 self.assertEqual(map(None, SequenceClass(5)), range(5))
393 self.assertEqual(map(lambda x: x+1, SequenceClass(5)), range(1, 6))
394
395 d = {"one": 1, "two": 2, "three": 3}
396 self.assertEqual(map(None, d), d.keys())
397 self.assertEqual(map(lambda k, d=d: (k, d[k]), d), d.items())
398 dkeys = d.keys()
399 expected = [(i < len(d) and dkeys[i] or None,
400 i,
401 i < len(d) and dkeys[i] or None)
402 for i in range(5)]
403 self.assertEqual(map(None, d,
404 SequenceClass(5),
405 iter(d.iterkeys())),
Tim Peters8bc10b02001-05-03 23:58:47 +0000406 expected)
Tim Peters4e9afdc2001-05-03 23:54:49 +0000407
408 f = open(TESTFN, "w")
409 try:
410 for i in range(10):
411 f.write("xy" * i + "\n") # line i has len 2*i+1
412 finally:
413 f.close()
414 f = open(TESTFN, "r")
415 try:
416 self.assertEqual(map(len, f), range(1, 21, 2))
Tim Peters4e9afdc2001-05-03 23:54:49 +0000417 finally:
418 f.close()
419 try:
420 unlink(TESTFN)
421 except OSError:
422 pass
423
Tim Peters8572b4f2001-05-06 01:05:02 +0000424 # Test zip()'s use of iterators.
425 def test_builtin_zip(self):
426 self.assertRaises(TypeError, zip)
427 self.assertRaises(TypeError, zip, None)
428 self.assertRaises(TypeError, zip, range(10), 42)
429 self.assertRaises(TypeError, zip, range(10), zip)
430
431 self.assertEqual(zip(IteratingSequenceClass(3)),
432 [(0,), (1,), (2,)])
433 self.assertEqual(zip(SequenceClass(3)),
434 [(0,), (1,), (2,)])
435
436 d = {"one": 1, "two": 2, "three": 3}
437 self.assertEqual(d.items(), zip(d, d.itervalues()))
438
439 # Generate all ints starting at constructor arg.
440 class IntsFrom:
441 def __init__(self, start):
442 self.i = start
443
444 def __iter__(self):
445 return self
446
447 def next(self):
448 i = self.i
449 self.i = i+1
450 return i
451
452 f = open(TESTFN, "w")
453 try:
454 f.write("a\n" "bbb\n" "cc\n")
455 finally:
456 f.close()
457 f = open(TESTFN, "r")
458 try:
459 self.assertEqual(zip(IntsFrom(0), f, IntsFrom(-100)),
460 [(0, "a\n", -100),
461 (1, "bbb\n", -99),
462 (2, "cc\n", -98)])
463 finally:
464 f.close()
465 try:
466 unlink(TESTFN)
467 except OSError:
468 pass
469
Tim Peters15d81ef2001-05-04 04:39:21 +0000470 # Test reduces()'s use of iterators.
471 def test_builtin_reduce(self):
472 from operator import add
473 self.assertEqual(reduce(add, SequenceClass(5)), 10)
474 self.assertEqual(reduce(add, SequenceClass(5), 42), 52)
475 self.assertRaises(TypeError, reduce, add, SequenceClass(0))
476 self.assertEqual(reduce(add, SequenceClass(0), 42), 42)
477 self.assertEqual(reduce(add, SequenceClass(1)), 0)
478 self.assertEqual(reduce(add, SequenceClass(1), 42), 42)
479
480 d = {"one": 1, "two": 2, "three": 3}
481 self.assertEqual(reduce(add, d), "".join(d.keys()))
482
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000483 # This test case will be removed if we don't have Unicode
Tim Peters2cfe3682001-05-05 05:36:48 +0000484 def test_unicode_join_endcase(self):
485
486 # This class inserts a Unicode object into its argument's natural
487 # iteration, in the 3rd position.
488 class OhPhooey:
489 def __init__(self, seq):
490 self.it = iter(seq)
491 self.i = 0
492
493 def __iter__(self):
494 return self
495
496 def next(self):
497 i = self.i
498 self.i = i+1
499 if i == 2:
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000500 return unicode("fooled you!")
Tim Peters2cfe3682001-05-05 05:36:48 +0000501 return self.it.next()
502
503 f = open(TESTFN, "w")
504 try:
505 f.write("a\n" + "b\n" + "c\n")
506 finally:
507 f.close()
508
509 f = open(TESTFN, "r")
510 # Nasty: string.join(s) can't know whether unicode.join() is needed
511 # until it's seen all of s's elements. But in this case, f's
512 # iterator cannot be restarted. So what we're testing here is
513 # whether string.join() can manage to remember everything it's seen
514 # and pass that on to unicode.join().
515 try:
516 got = " - ".join(OhPhooey(f))
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000517 self.assertEqual(got, unicode("a\n - b\n - fooled you! - c\n"))
Tim Peters2cfe3682001-05-05 05:36:48 +0000518 finally:
519 f.close()
520 try:
521 unlink(TESTFN)
522 except OSError:
523 pass
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000524 if not have_unicode:
525 def test_unicode_join_endcase(self): pass
Tim Peters2cfe3682001-05-05 05:36:48 +0000526
Tim Petersde9725f2001-05-05 10:06:17 +0000527 # Test iterators with 'x in y' and 'x not in y'.
528 def test_in_and_not_in(self):
Tim Peterscb8d3682001-05-05 21:05:01 +0000529 for sc5 in IteratingSequenceClass(5), SequenceClass(5):
530 for i in range(5):
531 self.assert_(i in sc5)
532 for i in "abc", -1, 5, 42.42, (3, 4), [], {1: 1}, 3-12j, sc5:
533 self.assert_(i not in sc5)
Tim Petersde9725f2001-05-05 10:06:17 +0000534
535 self.assertRaises(TypeError, lambda: 3 in 12)
536 self.assertRaises(TypeError, lambda: 3 not in map)
537
538 d = {"one": 1, "two": 2, "three": 3, 1j: 2j}
539 for k in d:
540 self.assert_(k in d)
541 self.assert_(k not in d.itervalues())
542 for v in d.values():
543 self.assert_(v in d.itervalues())
544 self.assert_(v not in d)
545 for k, v in d.iteritems():
546 self.assert_((k, v) in d.iteritems())
547 self.assert_((v, k) not in d.iteritems())
Tim Petersde9725f2001-05-05 10:06:17 +0000548
549 f = open(TESTFN, "w")
550 try:
551 f.write("a\n" "b\n" "c\n")
552 finally:
553 f.close()
554 f = open(TESTFN, "r")
555 try:
556 for chunk in "abc":
557 f.seek(0, 0)
558 self.assert_(chunk not in f)
559 f.seek(0, 0)
560 self.assert_((chunk + "\n") in f)
561 finally:
562 f.close()
563 try:
564 unlink(TESTFN)
565 except OSError:
566 pass
567
Tim Peters75f8e352001-05-05 11:33:43 +0000568 # Test iterators with operator.countOf (PySequence_Count).
569 def test_countOf(self):
570 from operator import countOf
571 self.assertEqual(countOf([1,2,2,3,2,5], 2), 3)
572 self.assertEqual(countOf((1,2,2,3,2,5), 2), 3)
573 self.assertEqual(countOf("122325", "2"), 3)
574 self.assertEqual(countOf("122325", "6"), 0)
575
576 self.assertRaises(TypeError, countOf, 42, 1)
577 self.assertRaises(TypeError, countOf, countOf, countOf)
578
579 d = {"one": 3, "two": 3, "three": 3, 1j: 2j}
580 for k in d:
581 self.assertEqual(countOf(d, k), 1)
582 self.assertEqual(countOf(d.itervalues(), 3), 3)
583 self.assertEqual(countOf(d.itervalues(), 2j), 1)
584 self.assertEqual(countOf(d.itervalues(), 1j), 0)
585
586 f = open(TESTFN, "w")
587 try:
588 f.write("a\n" "b\n" "c\n" "b\n")
589 finally:
590 f.close()
591 f = open(TESTFN, "r")
592 try:
593 for letter, count in ("a", 1), ("b", 2), ("c", 1), ("d", 0):
594 f.seek(0, 0)
595 self.assertEqual(countOf(f, letter + "\n"), count)
596 finally:
597 f.close()
598 try:
599 unlink(TESTFN)
600 except OSError:
601 pass
602
Tim Peters16a77ad2001-09-08 04:00:12 +0000603 # Test iterators with operator.indexOf (PySequence_Index).
604 def test_indexOf(self):
605 from operator import indexOf
606 self.assertEqual(indexOf([1,2,2,3,2,5], 1), 0)
607 self.assertEqual(indexOf((1,2,2,3,2,5), 2), 1)
608 self.assertEqual(indexOf((1,2,2,3,2,5), 3), 3)
609 self.assertEqual(indexOf((1,2,2,3,2,5), 5), 5)
610 self.assertRaises(ValueError, indexOf, (1,2,2,3,2,5), 0)
611 self.assertRaises(ValueError, indexOf, (1,2,2,3,2,5), 6)
612
613 self.assertEqual(indexOf("122325", "2"), 1)
614 self.assertEqual(indexOf("122325", "5"), 5)
615 self.assertRaises(ValueError, indexOf, "122325", "6")
616
617 self.assertRaises(TypeError, indexOf, 42, 1)
618 self.assertRaises(TypeError, indexOf, indexOf, indexOf)
619
620 f = open(TESTFN, "w")
621 try:
622 f.write("a\n" "b\n" "c\n" "d\n" "e\n")
623 finally:
624 f.close()
625 f = open(TESTFN, "r")
626 try:
627 fiter = iter(f)
628 self.assertEqual(indexOf(fiter, "b\n"), 1)
629 self.assertEqual(indexOf(fiter, "d\n"), 1)
630 self.assertEqual(indexOf(fiter, "e\n"), 0)
631 self.assertRaises(ValueError, indexOf, fiter, "a\n")
632 finally:
633 f.close()
634 try:
635 unlink(TESTFN)
636 except OSError:
637 pass
638
639 iclass = IteratingSequenceClass(3)
640 for i in range(3):
641 self.assertEqual(indexOf(iclass, i), i)
642 self.assertRaises(ValueError, indexOf, iclass, -1)
643
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000644 # Test iterators with file.writelines().
645 def test_writelines(self):
646 f = file(TESTFN, "w")
647
648 try:
649 self.assertRaises(TypeError, f.writelines, None)
650 self.assertRaises(TypeError, f.writelines, 42)
Tim Peters527e64f2001-10-04 05:36:56 +0000651
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000652 f.writelines(["1\n", "2\n"])
653 f.writelines(("3\n", "4\n"))
654 f.writelines({'5\n': None})
655 f.writelines({})
656
657 # Try a big chunk too.
658 class Iterator:
659 def __init__(self, start, finish):
660 self.start = start
661 self.finish = finish
662 self.i = self.start
663
664 def next(self):
665 if self.i >= self.finish:
666 raise StopIteration
667 result = str(self.i) + '\n'
668 self.i += 1
669 return result
670
671 def __iter__(self):
672 return self
673
674 class Whatever:
675 def __init__(self, start, finish):
676 self.start = start
677 self.finish = finish
678
679 def __iter__(self):
680 return Iterator(self.start, self.finish)
Tim Peters527e64f2001-10-04 05:36:56 +0000681
682 f.writelines(Whatever(6, 6+2000))
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000683 f.close()
684
685 f = file(TESTFN)
686 expected = [str(i) + "\n" for i in range(1, 2006)]
687 self.assertEqual(list(f), expected)
Tim Peters527e64f2001-10-04 05:36:56 +0000688
Tim Peters2c9aa5e2001-09-23 04:06:05 +0000689 finally:
690 f.close()
691 try:
692 unlink(TESTFN)
693 except OSError:
694 pass
695
696
Tim Petersd6d010b2001-06-21 02:49:55 +0000697 # Test iterators on RHS of unpacking assignments.
698 def test_unpack_iter(self):
699 a, b = 1, 2
700 self.assertEqual((a, b), (1, 2))
701
702 a, b, c = IteratingSequenceClass(3)
703 self.assertEqual((a, b, c), (0, 1, 2))
704
705 try: # too many values
706 a, b = IteratingSequenceClass(3)
707 except ValueError:
708 pass
709 else:
710 self.fail("should have raised ValueError")
711
712 try: # not enough values
713 a, b, c = IteratingSequenceClass(2)
714 except ValueError:
715 pass
716 else:
717 self.fail("should have raised ValueError")
718
719 try: # not iterable
720 a, b, c = len
721 except TypeError:
722 pass
723 else:
724 self.fail("should have raised TypeError")
725
726 a, b, c = {1: 42, 2: 42, 3: 42}.itervalues()
727 self.assertEqual((a, b, c), (42, 42, 42))
728
729 f = open(TESTFN, "w")
730 lines = ("a\n", "bb\n", "ccc\n")
731 try:
732 for line in lines:
733 f.write(line)
734 finally:
735 f.close()
736 f = open(TESTFN, "r")
737 try:
738 a, b, c = f
739 self.assertEqual((a, b, c), lines)
740 finally:
741 f.close()
742 try:
743 unlink(TESTFN)
744 except OSError:
745 pass
746
747 (a, b), (c,) = IteratingSequenceClass(2), {42: 24}
748 self.assertEqual((a, b, c), (0, 1, 42))
749
Guido van Rossumbb8f59a2001-12-03 19:33:25 +0000750 # Test reference count behavior
751
752 class C(object):
753 count = 0
754 def __new__(cls):
755 cls.count += 1
756 return object.__new__(cls)
757 def __del__(self):
758 cls = self.__class__
759 assert cls.count > 0
760 cls.count -= 1
761 x = C()
762 self.assertEqual(C.count, 1)
763 del x
764 self.assertEqual(C.count, 0)
765 l = [C(), C(), C()]
766 self.assertEqual(C.count, 3)
767 try:
768 a, b = iter(l)
769 except ValueError:
770 pass
771 del l
772 self.assertEqual(C.count, 0)
Fred Drake2e2be372001-09-20 21:33:42 +0000773
774def test_main():
775 run_unittest(TestCase)
776
777
778if __name__ == "__main__":
779 test_main()