431
431
Try writing it without generators, and correctly, and without generating
432
432
3 internal results for each result output.
433
433
434
+ XXX Suspect there's memory leaks in this one; definitely in the next
435
+ XXX version.
436
+
434
437
>>> def times(n, g):
435
438
... for i in g:
436
439
... yield n * i
482
485
functions can be reused as-is, because they only assume their stream
483
486
arguments are iterable -- a LazyList is the same as a generator to times().
484
487
488
+ XXX Massive memory leaks in this; see Python-Iterators.
489
+
485
490
>>> class LazyList:
486
491
... def __init__(self, g):
487
492
... self.sofar = []
514
519
[400, 405, 432, 450, 480, 486, 500, 512, 540, 576, 600, 625, 640, 648, 675]
515
520
"""
516
521
517
- # syntax_tests mostly provokes SyntaxErrors.
522
+ # syntax_tests mostly provokes SyntaxErrors. Also fiddling with #if 0
523
+ # hackery.
518
524
519
525
syntax_tests = """
520
526
588
594
... return
589
595
>>> list(f())
590
596
[12, 666]
597
+
598
+ >>> def f():
599
+ ... if 0:
600
+ ... yield 1
601
+ >>> type(f())
602
+ <type 'generator'>
603
+
604
+ >>> def f():
605
+ ... if "":
606
+ ... yield None
607
+ >>> type(f())
608
+ <type 'generator'>
609
+
610
+ >>> def f():
611
+ ... return
612
+ ... try:
613
+ ... if x==4:
614
+ ... pass
615
+ ... elif 0:
616
+ ... try:
617
+ ... 1/0
618
+ ... except SyntaxError:
619
+ ... pass
620
+ ... else:
621
+ ... if 0:
622
+ ... while 12:
623
+ ... x += 1
624
+ ... yield 2 # don't blink
625
+ ... f(a, b, c, d, e)
626
+ ... else:
627
+ ... pass
628
+ ... except:
629
+ ... x = 1
630
+ ... return
631
+ >>> type(f())
632
+ <type 'generator'>
633
+
634
+ >>> def f():
635
+ ... if 0:
636
+ ... def g():
637
+ ... yield 1
638
+ ...
639
+ >>> type(f())
640
+ <type 'None'>
641
+
642
+ >>> def f():
643
+ ... if 0:
644
+ ... class C:
645
+ ... def __init__(self):
646
+ ... yield 1
647
+ ... def f(self):
648
+ ... yield 2
649
+ >>> type(f())
650
+ <type 'None'>
651
+ """
652
+
653
+
654
+ x_tests = """
655
+
656
+ >>> def firstn(g, n):
657
+ ... return [g.next() for i in range(n)]
658
+
659
+ >>> def times(n, g):
660
+ ... for i in g:
661
+ ... yield n * i
662
+
663
+ >>> def merge(g, h):
664
+ ... ng = g.next()
665
+ ... nh = h.next()
666
+ ... while 1:
667
+ ... if ng < nh:
668
+ ... yield ng
669
+ ... ng = g.next()
670
+ ... elif ng > nh:
671
+ ... yield nh
672
+ ... nh = h.next()
673
+ ... else:
674
+ ... yield ng
675
+ ... ng = g.next()
676
+ ... nh = h.next()
677
+
678
+ >>> class LazyList:
679
+ ... def __init__(self, g):
680
+ ... self.sofar = []
681
+ ... self.fetch = g.next
682
+ ...
683
+ ... def __getitem__(self, i):
684
+ ... sofar, fetch = self.sofar, self.fetch
685
+ ... while i >= len(sofar):
686
+ ... sofar.append(fetch())
687
+ ... return sofar[i]
688
+
689
+ >>> def m235():
690
+ ... yield 1
691
+ ... # Gack: m235 below actually refers to a LazyList.
692
+ ... me_times2 = times(2, m235)
693
+ ... me_times3 = times(3, m235)
694
+ ... me_times5 = times(5, m235)
695
+ ... for i in merge(merge(me_times2,
696
+ ... me_times3),
697
+ ... me_times5):
698
+ ... yield i
699
+
700
+ >>> m235 = LazyList(m235())
701
+ >>> for i in range(5):
702
+ ... x = [m235[j] for j in range(15*i, 15*(i+1))]
703
+
704
+
705
+ [1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24]
706
+ [25, 27, 30, 32, 36, 40, 45, 48, 50, 54, 60, 64, 72, 75, 80]
707
+ [81, 90, 96, 100, 108, 120, 125, 128, 135, 144, 150, 160, 162, 180, 192]
708
+ [200, 216, 225, 240, 243, 250, 256, 270, 288, 300, 320, 324, 360, 375, 384]
709
+ [400, 405, 432, 450, 480, 486, 500, 512, 540, 576, 600, 625, 640, 648, 675]
591
710
"""
592
711
593
- __test__ = {"tut" : tutorial_tests ,
594
- "pep" : pep_tests ,
595
- "email" : email_tests ,
596
- "fun" : fun_tests ,
597
- "syntax" : syntax_tests }
712
+ __test__ = {"tut" : tutorial_tests , # clean
713
+ "pep" : pep_tests , # clean
714
+ "email" : email_tests , # clean
715
+ "fun" : fun_tests , # leaks
716
+ "syntax" : syntax_tests # clean
717
+ #"x": x_tests
718
+ }
598
719
599
720
# Magic test name that regrtest.py invokes *after* importing this module.
600
721
# This worms around a bootstrap problem.
@@ -605,7 +726,7 @@ def test_main():
605
726
if 0 :
606
727
# Temporary block to help track down leaks. So far, the blame
607
728
# has fallen mostly on doctest.
608
- for i in range (1000 ):
729
+ for i in range (5000 ):
609
730
doctest .master = None
610
731
doctest .testmod (test_generators )
611
732
else :
0 commit comments