431431Try writing it without generators, and correctly, and without generating
4324323 internal results for each result output.
433433
434+ XXX Suspect there's memory leaks in this one; definitely in the next
435+ XXX version.
436+
434437>>> def times(n, g):
435438... for i in g:
436439... yield n * i
482485functions can be reused as-is, because they only assume their stream
483486arguments are iterable -- a LazyList is the same as a generator to times().
484487
488+ XXX Massive memory leaks in this; see Python-Iterators.
489+
485490>>> class LazyList:
486491... def __init__(self, g):
487492... self.sofar = []
514519[400, 405, 432, 450, 480, 486, 500, 512, 540, 576, 600, 625, 640, 648, 675]
515520"""
516521
517- # syntax_tests mostly provokes SyntaxErrors.
522+ # syntax_tests mostly provokes SyntaxErrors. Also fiddling with #if 0
523+ # hackery.
518524
519525syntax_tests = """
520526
588594... return
589595>>> list(f())
590596[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]
591710"""
592711
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+ }
598719
599720# Magic test name that regrtest.py invokes *after* importing this module.
600721# This worms around a bootstrap problem.
@@ -605,7 +726,7 @@ def test_main():
605726 if 0 :
606727 # Temporary block to help track down leaks. So far, the blame
607728 # has fallen mostly on doctest.
608- for i in range (1000 ):
729+ for i in range (5000 ):
609730 doctest .master = None
610731 doctest .testmod (test_generators )
611732 else :
0 commit comments