annotate Lib/test/test_generators.py @ 58925:eecf1bef052d 2.6

Merged revisions 78207 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r78207 | ezio.melotti | 2010-02-17 01:26:09 +0200 (Wed, 17 Feb 2010) | 1 line #7930: fix stripid ........
author Ezio Melotti <ezio.melotti@gmail.com>
date Tue, 16 Feb 2010 23:29:44 +0000
parents ed13040ac2e6
children 93da9f14e5b5
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
18250
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
1 tutorial_tests = """
18249
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
2 Let's try a simple generator:
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
3
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
4 >>> def f():
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
5 ... yield 1
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
6 ... yield 2
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
7
18252
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
8 >>> for i in f():
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
9 ... print i
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
10 1
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
11 2
18249
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
12 >>> g = f()
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
13 >>> g.next()
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
14 1
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
15 >>> g.next()
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
16 2
18256
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
17
18265
a46e35acf9c1 Repair indentation in comment.
Tim Peters <tim.peters@gmail.com>
parents: 18257
diff changeset
18 "Falling off the end" stops the generator:
18256
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
19
18249
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
20 >>> g.next()
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
21 Traceback (most recent call last):
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
22 File "<stdin>", line 1, in ?
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
23 File "<stdin>", line 2, in g
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
24 StopIteration
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
25
18256
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
26 "return" also stops the generator:
18249
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
27
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
28 >>> def f():
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
29 ... yield 1
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
30 ... return
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
31 ... yield 2 # never reached
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
32 ...
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
33 >>> g = f()
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
34 >>> g.next()
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
35 1
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
36 >>> g.next()
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
37 Traceback (most recent call last):
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
38 File "<stdin>", line 1, in ?
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
39 File "<stdin>", line 3, in f
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
40 StopIteration
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
41 >>> g.next() # once stopped, can't be resumed
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
42 Traceback (most recent call last):
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
43 File "<stdin>", line 1, in ?
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
44 StopIteration
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
45
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
46 "raise StopIteration" stops the generator too:
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
47
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
48 >>> def f():
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
49 ... yield 1
18525
64fa72a84347 Repair flawed example.
Tim Peters <tim.peters@gmail.com>
parents: 18524
diff changeset
50 ... raise StopIteration
18249
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
51 ... yield 2 # never reached
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
52 ...
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
53 >>> g = f()
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
54 >>> g.next()
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
55 1
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
56 >>> g.next()
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
57 Traceback (most recent call last):
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
58 File "<stdin>", line 1, in ?
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
59 StopIteration
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
60 >>> g.next()
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
61 Traceback (most recent call last):
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
62 File "<stdin>", line 1, in ?
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
63 StopIteration
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
64
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
65 However, they are not exactly equivalent:
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
66
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
67 >>> def g1():
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
68 ... try:
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
69 ... return
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
70 ... except:
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
71 ... yield 1
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
72 ...
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
73 >>> list(g1())
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
74 []
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
75
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
76 >>> def g2():
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
77 ... try:
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
78 ... raise StopIteration
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
79 ... except:
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
80 ... yield 42
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
81 >>> print list(g2())
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
82 [42]
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
83
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
84 This may be surprising at first:
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
85
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
86 >>> def g3():
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
87 ... try:
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
88 ... return
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
89 ... finally:
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
90 ... yield 1
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
91 ...
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
92 >>> list(g3())
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
93 [1]
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
94
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
95 Let's create an alternate range() function implemented as a generator:
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
96
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
97 >>> def yrange(n):
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
98 ... for i in range(n):
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
99 ... yield i
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
100 ...
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
101 >>> list(yrange(5))
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
102 [0, 1, 2, 3, 4]
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
103
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
104 Generators always return to the most recent caller:
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
105
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
106 >>> def creator():
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
107 ... r = yrange(5)
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
108 ... print "creator", r.next()
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
109 ... return r
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
110 ...
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
111 >>> def caller():
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
112 ... r = creator()
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
113 ... for i in r:
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
114 ... print "caller", i
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
115 ...
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
116 >>> caller()
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
117 creator 0
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
118 caller 1
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
119 caller 2
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
120 caller 3
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
121 caller 4
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
122
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
123 Generators can call other generators:
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
124
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
125 >>> def zrange(n):
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
126 ... for i in yrange(n):
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
127 ... yield i
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
128 ...
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
129 >>> list(zrange(5))
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
130 [0, 1, 2, 3, 4]
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
131
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
132 """
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
133
18250
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
134 # The examples from PEP 255.
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
135
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
136 pep_tests = """
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
137
19264
eb5e2b68354f Move one of the tests into the "PEP 255" section, to reflect a change in
Tim Peters <tim.peters@gmail.com>
parents: 19154
diff changeset
138 Specification: Yield
eb5e2b68354f Move one of the tests into the "PEP 255" section, to reflect a change in
Tim Peters <tim.peters@gmail.com>
parents: 19154
diff changeset
139
eb5e2b68354f Move one of the tests into the "PEP 255" section, to reflect a change in
Tim Peters <tim.peters@gmail.com>
parents: 19154
diff changeset
140 Restriction: A generator cannot be resumed while it is actively
eb5e2b68354f Move one of the tests into the "PEP 255" section, to reflect a change in
Tim Peters <tim.peters@gmail.com>
parents: 19154
diff changeset
141 running:
eb5e2b68354f Move one of the tests into the "PEP 255" section, to reflect a change in
Tim Peters <tim.peters@gmail.com>
parents: 19154
diff changeset
142
eb5e2b68354f Move one of the tests into the "PEP 255" section, to reflect a change in
Tim Peters <tim.peters@gmail.com>
parents: 19154
diff changeset
143 >>> def g():
eb5e2b68354f Move one of the tests into the "PEP 255" section, to reflect a change in
Tim Peters <tim.peters@gmail.com>
parents: 19154
diff changeset
144 ... i = me.next()
eb5e2b68354f Move one of the tests into the "PEP 255" section, to reflect a change in
Tim Peters <tim.peters@gmail.com>
parents: 19154
diff changeset
145 ... yield i
eb5e2b68354f Move one of the tests into the "PEP 255" section, to reflect a change in
Tim Peters <tim.peters@gmail.com>
parents: 19154
diff changeset
146 >>> me = g()
eb5e2b68354f Move one of the tests into the "PEP 255" section, to reflect a change in
Tim Peters <tim.peters@gmail.com>
parents: 19154
diff changeset
147 >>> me.next()
eb5e2b68354f Move one of the tests into the "PEP 255" section, to reflect a change in
Tim Peters <tim.peters@gmail.com>
parents: 19154
diff changeset
148 Traceback (most recent call last):
eb5e2b68354f Move one of the tests into the "PEP 255" section, to reflect a change in
Tim Peters <tim.peters@gmail.com>
parents: 19154
diff changeset
149 ...
eb5e2b68354f Move one of the tests into the "PEP 255" section, to reflect a change in
Tim Peters <tim.peters@gmail.com>
parents: 19154
diff changeset
150 File "<string>", line 2, in g
eb5e2b68354f Move one of the tests into the "PEP 255" section, to reflect a change in
Tim Peters <tim.peters@gmail.com>
parents: 19154
diff changeset
151 ValueError: generator already executing
eb5e2b68354f Move one of the tests into the "PEP 255" section, to reflect a change in
Tim Peters <tim.peters@gmail.com>
parents: 19154
diff changeset
152
18250
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
153 Specification: Return
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
154
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
155 Note that return isn't always equivalent to raising StopIteration: the
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
156 difference lies in how enclosing try/except constructs are treated.
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
157 For example,
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
158
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
159 >>> def f1():
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
160 ... try:
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
161 ... return
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
162 ... except:
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
163 ... yield 1
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
164 >>> print list(f1())
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
165 []
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
166
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
167 because, as in any function, return simply exits, but
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
168
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
169 >>> def f2():
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
170 ... try:
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
171 ... raise StopIteration
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
172 ... except:
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
173 ... yield 42
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
174 >>> print list(f2())
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
175 [42]
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
176
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
177 because StopIteration is captured by a bare "except", as is any
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
178 exception.
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
179
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
180 Specification: Generators and Exception Propagation
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
181
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
182 >>> def f():
21251
45e1177424e1 SF bug #488514: -Qnew needs work
Tim Peters <tim.peters@gmail.com>
parents: 19817
diff changeset
183 ... return 1//0
18250
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
184 >>> def g():
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
185 ... yield f() # the zero division exception propagates
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
186 ... yield 42 # and we'll never get here
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
187 >>> k = g()
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
188 >>> k.next()
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
189 Traceback (most recent call last):
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
190 File "<stdin>", line 1, in ?
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
191 File "<stdin>", line 2, in g
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
192 File "<stdin>", line 2, in f
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
193 ZeroDivisionError: integer division or modulo by zero
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
194 >>> k.next() # and the generator cannot be resumed
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
195 Traceback (most recent call last):
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
196 File "<stdin>", line 1, in ?
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
197 StopIteration
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
198 >>>
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
199
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
200 Specification: Try/Except/Finally
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
201
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
202 >>> def f():
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
203 ... try:
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
204 ... yield 1
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
205 ... try:
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
206 ... yield 2
21251
45e1177424e1 SF bug #488514: -Qnew needs work
Tim Peters <tim.peters@gmail.com>
parents: 19817
diff changeset
207 ... 1//0
18250
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
208 ... yield 3 # never get here
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
209 ... except ZeroDivisionError:
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
210 ... yield 4
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
211 ... yield 5
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
212 ... raise
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
213 ... except:
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
214 ... yield 6
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
215 ... yield 7 # the "raise" above stops this
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
216 ... except:
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
217 ... yield 8
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
218 ... yield 9
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
219 ... try:
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
220 ... x = 12
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
221 ... finally:
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
222 ... yield 10
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
223 ... yield 11
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
224 >>> print list(f())
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
225 [1, 2, 4, 5, 8, 9, 10, 11]
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
226 >>>
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
227
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
228 Guido's binary tree example.
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
229
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
230 >>> # A binary tree class.
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
231 >>> class Tree:
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
232 ...
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
233 ... def __init__(self, label, left=None, right=None):
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
234 ... self.label = label
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
235 ... self.left = left
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
236 ... self.right = right
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
237 ...
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
238 ... def __repr__(self, level=0, indent=" "):
31515
71a294bd7950 Replace backticks with repr() or "%r"
Walter Dörwald <walter@livinglogic.de>
parents: 26834
diff changeset
239 ... s = level*indent + repr(self.label)
18250
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
240 ... if self.left:
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
241 ... s = s + "\\n" + self.left.__repr__(level+1, indent)
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
242 ... if self.right:
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
243 ... s = s + "\\n" + self.right.__repr__(level+1, indent)
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
244 ... return s
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
245 ...
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
246 ... def __iter__(self):
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
247 ... return inorder(self)
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
248
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
249 >>> # Create a Tree from a list.
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
250 >>> def tree(list):
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
251 ... n = len(list)
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
252 ... if n == 0:
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
253 ... return []
21251
45e1177424e1 SF bug #488514: -Qnew needs work
Tim Peters <tim.peters@gmail.com>
parents: 19817
diff changeset
254 ... i = n // 2
18250
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
255 ... return Tree(list[i], tree(list[:i]), tree(list[i+1:]))
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
256
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
257 >>> # Show it off: create a tree.
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
258 >>> t = tree("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
259
22207
f0ae37625189 SF patch 499062: Minor typo in test_generators.py.
Tim Peters <tim.peters@gmail.com>
parents: 21251
diff changeset
260 >>> # A recursive generator that generates Tree labels in in-order.
18250
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
261 >>> def inorder(t):
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
262 ... if t:
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
263 ... for x in inorder(t.left):
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
264 ... yield x
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
265 ... yield t.label
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
266 ... for x in inorder(t.right):
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
267 ... yield x
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
268
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
269 >>> # Show it off: create a tree.
33054
27ada25509ff Fixed doctest error (wrong prompts)
Edward Loper <edloper@gradient.cis.upenn.edu>
parents: 31515
diff changeset
270 >>> t = tree("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
27ada25509ff Fixed doctest error (wrong prompts)
Edward Loper <edloper@gradient.cis.upenn.edu>
parents: 31515
diff changeset
271 >>> # Print the nodes of the tree in in-order.
27ada25509ff Fixed doctest error (wrong prompts)
Edward Loper <edloper@gradient.cis.upenn.edu>
parents: 31515
diff changeset
272 >>> for x in t:
18250
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
273 ... print x,
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
274 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
275
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
276 >>> # A non-recursive generator.
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
277 >>> def inorder(node):
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
278 ... stack = []
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
279 ... while node:
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
280 ... while node.left:
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
281 ... stack.append(node)
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
282 ... node = node.left
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
283 ... yield node.label
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
284 ... while not node.right:
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
285 ... try:
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
286 ... node = stack.pop()
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
287 ... except IndexError:
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
288 ... return
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
289 ... yield node.label
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
290 ... node = node.right
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
291
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
292 >>> # Exercise the non-recursive generator.
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
293 >>> for x in t:
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
294 ... print x,
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
295 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
296
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
297 """
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
298
18257
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
299 # Examples from Iterator-List and Python-Dev and c.l.py.
18250
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
300
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
301 email_tests = """
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
302
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
303 The difference between yielding None and returning it.
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
304
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
305 >>> def g():
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
306 ... for i in range(3):
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
307 ... yield None
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
308 ... yield None
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
309 ... return
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
310 >>> list(g())
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
311 [None, None, None, None]
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
312
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
313 Ensure that explicitly raising StopIteration acts like any other exception
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
314 in try/except, not like a return.
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
315
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
316 >>> def g():
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
317 ... yield 1
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
318 ... try:
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
319 ... raise StopIteration
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
320 ... except:
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
321 ... yield 2
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
322 ... yield 3
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
323 >>> list(g())
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
324 [1, 2, 3]
18252
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
325
18257
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
326 Next one was posted to c.l.py.
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
327
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
328 >>> def gcomb(x, k):
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
329 ... "Generate all combinations of k elements from list x."
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
330 ...
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
331 ... if k > len(x):
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
332 ... return
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
333 ... if k == 0:
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
334 ... yield []
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
335 ... else:
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
336 ... first, rest = x[0], x[1:]
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
337 ... # A combination does or doesn't contain first.
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
338 ... # If it does, the remainder is a k-1 comb of rest.
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
339 ... for c in gcomb(rest, k-1):
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
340 ... c.insert(0, first)
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
341 ... yield c
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
342 ... # If it doesn't contain first, it's a k comb of rest.
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
343 ... for c in gcomb(rest, k):
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
344 ... yield c
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
345
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
346 >>> seq = range(1, 5)
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
347 >>> for k in range(len(seq) + 2):
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
348 ... print "%d-combs of %s:" % (k, seq)
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
349 ... for c in gcomb(seq, k):
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
350 ... print " ", c
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
351 0-combs of [1, 2, 3, 4]:
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
352 []
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
353 1-combs of [1, 2, 3, 4]:
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
354 [1]
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
355 [2]
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
356 [3]
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
357 [4]
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
358 2-combs of [1, 2, 3, 4]:
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
359 [1, 2]
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
360 [1, 3]
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
361 [1, 4]
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
362 [2, 3]
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
363 [2, 4]
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
364 [3, 4]
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
365 3-combs of [1, 2, 3, 4]:
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
366 [1, 2, 3]
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
367 [1, 2, 4]
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
368 [1, 3, 4]
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
369 [2, 3, 4]
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
370 4-combs of [1, 2, 3, 4]:
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
371 [1, 2, 3, 4]
358cb74c0864 Added a "generate k-combinations of a list" example posted to c.l.py.
Tim Peters <tim.peters@gmail.com>
parents: 18256
diff changeset
372 5-combs of [1, 2, 3, 4]:
18273
9e326c9e6be5 Teach the types module about generators. Thanks to James Althoff on the
Tim Peters <tim.peters@gmail.com>
parents: 18265
diff changeset
373
18293
0344e4ac70b0 gen_getattr: make the gi_running and gi_frame members discoverable (but
Tim Peters <tim.peters@gmail.com>
parents: 18274
diff changeset
374 From the Iterators list, about the types of these things.
18273
9e326c9e6be5 Teach the types module about generators. Thanks to James Althoff on the
Tim Peters <tim.peters@gmail.com>
parents: 18265
diff changeset
375
9e326c9e6be5 Teach the types module about generators. Thanks to James Althoff on the
Tim Peters <tim.peters@gmail.com>
parents: 18265
diff changeset
376 >>> def g():
9e326c9e6be5 Teach the types module about generators. Thanks to James Althoff on the
Tim Peters <tim.peters@gmail.com>
parents: 18265
diff changeset
377 ... yield 1
9e326c9e6be5 Teach the types module about generators. Thanks to James Althoff on the
Tim Peters <tim.peters@gmail.com>
parents: 18265
diff changeset
378 ...
9e326c9e6be5 Teach the types module about generators. Thanks to James Althoff on the
Tim Peters <tim.peters@gmail.com>
parents: 18265
diff changeset
379 >>> type(g)
9e326c9e6be5 Teach the types module about generators. Thanks to James Althoff on the
Tim Peters <tim.peters@gmail.com>
parents: 18265
diff changeset
380 <type 'function'>
9e326c9e6be5 Teach the types module about generators. Thanks to James Althoff on the
Tim Peters <tim.peters@gmail.com>
parents: 18265
diff changeset
381 >>> i = g()
9e326c9e6be5 Teach the types module about generators. Thanks to James Althoff on the
Tim Peters <tim.peters@gmail.com>
parents: 18265
diff changeset
382 >>> type(i)
9e326c9e6be5 Teach the types module about generators. Thanks to James Althoff on the
Tim Peters <tim.peters@gmail.com>
parents: 18265
diff changeset
383 <type 'generator'>
19665
08c3c9edd99b Make dir() wordier (see the new docstring). The new behavior is a mixed
Tim Peters <tim.peters@gmail.com>
parents: 19298
diff changeset
384 >>> [s for s in dir(i) if not s.startswith('_')]
44976
51bb7b1ae765 #1473257: add generator.gi_code attribute that refers to
Georg Brandl <georg@python.org>
parents: 44127
diff changeset
385 ['close', 'gi_code', 'gi_frame', 'gi_running', 'next', 'send', 'throw']
18273
9e326c9e6be5 Teach the types module about generators. Thanks to James Althoff on the
Tim Peters <tim.peters@gmail.com>
parents: 18265
diff changeset
386 >>> print i.next.__doc__
18933
09df3254b49d Merge of descr-branch back into trunk.
Tim Peters <tim.peters@gmail.com>
parents: 18611
diff changeset
387 x.next() -> the next value, or raise StopIteration
18273
9e326c9e6be5 Teach the types module about generators. Thanks to James Althoff on the
Tim Peters <tim.peters@gmail.com>
parents: 18265
diff changeset
388 >>> iter(i) is i
22785
aa8d59823add Add the 'bool' type and its values 'False' and 'True', as described in
Guido van Rossum <guido@python.org>
parents: 22719
diff changeset
389 True
18273
9e326c9e6be5 Teach the types module about generators. Thanks to James Althoff on the
Tim Peters <tim.peters@gmail.com>
parents: 18265
diff changeset
390 >>> import types
9e326c9e6be5 Teach the types module about generators. Thanks to James Althoff on the
Tim Peters <tim.peters@gmail.com>
parents: 18265
diff changeset
391 >>> isinstance(i, types.GeneratorType)
22785
aa8d59823add Add the 'bool' type and its values 'False' and 'True', as described in
Guido van Rossum <guido@python.org>
parents: 22719
diff changeset
392 True
18293
0344e4ac70b0 gen_getattr: make the gi_running and gi_frame members discoverable (but
Tim Peters <tim.peters@gmail.com>
parents: 18274
diff changeset
393
0344e4ac70b0 gen_getattr: make the gi_running and gi_frame members discoverable (but
Tim Peters <tim.peters@gmail.com>
parents: 18274
diff changeset
394 And more, added later.
0344e4ac70b0 gen_getattr: make the gi_running and gi_frame members discoverable (but
Tim Peters <tim.peters@gmail.com>
parents: 18274
diff changeset
395
0344e4ac70b0 gen_getattr: make the gi_running and gi_frame members discoverable (but
Tim Peters <tim.peters@gmail.com>
parents: 18274
diff changeset
396 >>> i.gi_running
0344e4ac70b0 gen_getattr: make the gi_running and gi_frame members discoverable (but
Tim Peters <tim.peters@gmail.com>
parents: 18274
diff changeset
397 0
0344e4ac70b0 gen_getattr: make the gi_running and gi_frame members discoverable (but
Tim Peters <tim.peters@gmail.com>
parents: 18274
diff changeset
398 >>> type(i.gi_frame)
0344e4ac70b0 gen_getattr: make the gi_running and gi_frame members discoverable (but
Tim Peters <tim.peters@gmail.com>
parents: 18274
diff changeset
399 <type 'frame'>
0344e4ac70b0 gen_getattr: make the gi_running and gi_frame members discoverable (but
Tim Peters <tim.peters@gmail.com>
parents: 18274
diff changeset
400 >>> i.gi_running = 42
0344e4ac70b0 gen_getattr: make the gi_running and gi_frame members discoverable (but
Tim Peters <tim.peters@gmail.com>
parents: 18274
diff changeset
401 Traceback (most recent call last):
0344e4ac70b0 gen_getattr: make the gi_running and gi_frame members discoverable (but
Tim Peters <tim.peters@gmail.com>
parents: 18274
diff changeset
402 ...
19154
7a1ef675d8ac The message accompanying the TypeError exception on a readonly
Guido van Rossum <guido@python.org>
parents: 18933
diff changeset
403 TypeError: readonly attribute
18293
0344e4ac70b0 gen_getattr: make the gi_running and gi_frame members discoverable (but
Tim Peters <tim.peters@gmail.com>
parents: 18274
diff changeset
404 >>> def g():
0344e4ac70b0 gen_getattr: make the gi_running and gi_frame members discoverable (but
Tim Peters <tim.peters@gmail.com>
parents: 18274
diff changeset
405 ... yield me.gi_running
0344e4ac70b0 gen_getattr: make the gi_running and gi_frame members discoverable (but
Tim Peters <tim.peters@gmail.com>
parents: 18274
diff changeset
406 >>> me = g()
0344e4ac70b0 gen_getattr: make the gi_running and gi_frame members discoverable (but
Tim Peters <tim.peters@gmail.com>
parents: 18274
diff changeset
407 >>> me.gi_running
0344e4ac70b0 gen_getattr: make the gi_running and gi_frame members discoverable (but
Tim Peters <tim.peters@gmail.com>
parents: 18274
diff changeset
408 0
0344e4ac70b0 gen_getattr: make the gi_running and gi_frame members discoverable (but
Tim Peters <tim.peters@gmail.com>
parents: 18274
diff changeset
409 >>> me.next()
0344e4ac70b0 gen_getattr: make the gi_running and gi_frame members discoverable (but
Tim Peters <tim.peters@gmail.com>
parents: 18274
diff changeset
410 1
0344e4ac70b0 gen_getattr: make the gi_running and gi_frame members discoverable (but
Tim Peters <tim.peters@gmail.com>
parents: 18274
diff changeset
411 >>> me.gi_running
0344e4ac70b0 gen_getattr: make the gi_running and gi_frame members discoverable (but
Tim Peters <tim.peters@gmail.com>
parents: 18274
diff changeset
412 0
18355
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
413
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
414 A clever union-find implementation from c.l.py, due to David Eppstein.
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
415 Sent: Friday, June 29, 2001 12:16 PM
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
416 To: python-list@python.org
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
417 Subject: Re: PEP 255: Simple Generators
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
418
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
419 >>> class disjointSet:
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
420 ... def __init__(self, name):
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
421 ... self.name = name
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
422 ... self.parent = None
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
423 ... self.generator = self.generate()
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
424 ...
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
425 ... def generate(self):
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
426 ... while not self.parent:
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
427 ... yield self
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
428 ... for x in self.parent.generator:
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
429 ... yield x
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
430 ...
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
431 ... def find(self):
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
432 ... return self.generator.next()
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
433 ...
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
434 ... def union(self, parent):
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
435 ... if self.parent:
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
436 ... raise ValueError("Sorry, I'm not a root!")
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
437 ... self.parent = parent
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
438 ...
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
439 ... def __str__(self):
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
440 ... return self.name
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
441
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
442 >>> names = "ABCDEFGHIJKLM"
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
443 >>> sets = [disjointSet(name) for name in names]
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
444 >>> roots = sets[:]
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
445
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
446 >>> import random
26834
3e1bd137d3c2 This test depends on the exact ordering produced by the WichmannHill
Raymond Hettinger <python@rcn.com>
parents: 24719
diff changeset
447 >>> gen = random.WichmannHill(42)
18355
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
448 >>> while 1:
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
449 ... for s in sets:
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
450 ... print "%s->%s" % (s, s.find()),
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
451 ... print
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
452 ... if len(roots) > 1:
26834
3e1bd137d3c2 This test depends on the exact ordering produced by the WichmannHill
Raymond Hettinger <python@rcn.com>
parents: 24719
diff changeset
453 ... s1 = gen.choice(roots)
18355
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
454 ... roots.remove(s1)
26834
3e1bd137d3c2 This test depends on the exact ordering produced by the WichmannHill
Raymond Hettinger <python@rcn.com>
parents: 24719
diff changeset
455 ... s2 = gen.choice(roots)
18355
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
456 ... s1.union(s2)
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
457 ... print "merged", s1, "into", s2
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
458 ... else:
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
459 ... break
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
460 A->A B->B C->C D->D E->E F->F G->G H->H I->I J->J K->K L->L M->M
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
461 merged D into G
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
462 A->A B->B C->C D->G E->E F->F G->G H->H I->I J->J K->K L->L M->M
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
463 merged C into F
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
464 A->A B->B C->F D->G E->E F->F G->G H->H I->I J->J K->K L->L M->M
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
465 merged L into A
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
466 A->A B->B C->F D->G E->E F->F G->G H->H I->I J->J K->K L->A M->M
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
467 merged H into E
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
468 A->A B->B C->F D->G E->E F->F G->G H->E I->I J->J K->K L->A M->M
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
469 merged B into E
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
470 A->A B->E C->F D->G E->E F->F G->G H->E I->I J->J K->K L->A M->M
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
471 merged J into G
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
472 A->A B->E C->F D->G E->E F->F G->G H->E I->I J->G K->K L->A M->M
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
473 merged E into G
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
474 A->A B->G C->F D->G E->G F->F G->G H->G I->I J->G K->K L->A M->M
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
475 merged M into G
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
476 A->A B->G C->F D->G E->G F->F G->G H->G I->I J->G K->K L->A M->G
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
477 merged I into K
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
478 A->A B->G C->F D->G E->G F->F G->G H->G I->K J->G K->K L->A M->G
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
479 merged K into A
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
480 A->A B->G C->F D->G E->G F->F G->G H->G I->A J->G K->A L->A M->G
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
481 merged F into A
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
482 A->A B->G C->A D->G E->G F->A G->G H->G I->A J->G K->A L->A M->G
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
483 merged A into G
98556cdfe716 A clever union-find implementation from c.l.py, due to David Eppstein.
Tim Peters <tim.peters@gmail.com>
parents: 18352
diff changeset
484 A->G B->G C->G D->G E->G F->G G->G H->G I->G J->G K->G L->G M->G
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
485
18250
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
486 """
24364
aa0d2d51fbde Get rid of relative imports in all unittests. Now anything that
Barry Warsaw <barry@python.org>
parents: 24263
diff changeset
487 # Emacs turd '
18250
45de1ac2a376 Add all the examples from PEP 255, and a few email examples.
Tim Peters <tim.peters@gmail.com>
parents: 18249
diff changeset
488
18251
5d3e7f99cf52 Add a recursive Sieve of Eratosthenes prime generator. Not practical,
Tim Peters <tim.peters@gmail.com>
parents: 18250
diff changeset
489 # Fun tests (for sufficiently warped notions of "fun").
5d3e7f99cf52 Add a recursive Sieve of Eratosthenes prime generator. Not practical,
Tim Peters <tim.peters@gmail.com>
parents: 18250
diff changeset
490
5d3e7f99cf52 Add a recursive Sieve of Eratosthenes prime generator. Not practical,
Tim Peters <tim.peters@gmail.com>
parents: 18250
diff changeset
491 fun_tests = """
5d3e7f99cf52 Add a recursive Sieve of Eratosthenes prime generator. Not practical,
Tim Peters <tim.peters@gmail.com>
parents: 18250
diff changeset
492
5d3e7f99cf52 Add a recursive Sieve of Eratosthenes prime generator. Not practical,
Tim Peters <tim.peters@gmail.com>
parents: 18250
diff changeset
493 Build up to a recursive Sieve of Eratosthenes generator.
5d3e7f99cf52 Add a recursive Sieve of Eratosthenes prime generator. Not practical,
Tim Peters <tim.peters@gmail.com>
parents: 18250
diff changeset
494
5d3e7f99cf52 Add a recursive Sieve of Eratosthenes prime generator. Not practical,
Tim Peters <tim.peters@gmail.com>
parents: 18250
diff changeset
495 >>> def firstn(g, n):
5d3e7f99cf52 Add a recursive Sieve of Eratosthenes prime generator. Not practical,
Tim Peters <tim.peters@gmail.com>
parents: 18250
diff changeset
496 ... return [g.next() for i in range(n)]
5d3e7f99cf52 Add a recursive Sieve of Eratosthenes prime generator. Not practical,
Tim Peters <tim.peters@gmail.com>
parents: 18250
diff changeset
497
5d3e7f99cf52 Add a recursive Sieve of Eratosthenes prime generator. Not practical,
Tim Peters <tim.peters@gmail.com>
parents: 18250
diff changeset
498 >>> def intsfrom(i):
5d3e7f99cf52 Add a recursive Sieve of Eratosthenes prime generator. Not practical,
Tim Peters <tim.peters@gmail.com>
parents: 18250
diff changeset
499 ... while 1:
5d3e7f99cf52 Add a recursive Sieve of Eratosthenes prime generator. Not practical,
Tim Peters <tim.peters@gmail.com>
parents: 18250
diff changeset
500 ... yield i
5d3e7f99cf52 Add a recursive Sieve of Eratosthenes prime generator. Not practical,
Tim Peters <tim.peters@gmail.com>
parents: 18250
diff changeset
501 ... i += 1
5d3e7f99cf52 Add a recursive Sieve of Eratosthenes prime generator. Not practical,
Tim Peters <tim.peters@gmail.com>
parents: 18250
diff changeset
502
5d3e7f99cf52 Add a recursive Sieve of Eratosthenes prime generator. Not practical,
Tim Peters <tim.peters@gmail.com>
parents: 18250
diff changeset
503 >>> firstn(intsfrom(5), 7)
5d3e7f99cf52 Add a recursive Sieve of Eratosthenes prime generator. Not practical,
Tim Peters <tim.peters@gmail.com>
parents: 18250
diff changeset
504 [5, 6, 7, 8, 9, 10, 11]
5d3e7f99cf52 Add a recursive Sieve of Eratosthenes prime generator. Not practical,
Tim Peters <tim.peters@gmail.com>
parents: 18250
diff changeset
505
5d3e7f99cf52 Add a recursive Sieve of Eratosthenes prime generator. Not practical,
Tim Peters <tim.peters@gmail.com>
parents: 18250
diff changeset
506 >>> def exclude_multiples(n, ints):
5d3e7f99cf52 Add a recursive Sieve of Eratosthenes prime generator. Not practical,
Tim Peters <tim.peters@gmail.com>
parents: 18250
diff changeset
507 ... for i in ints:
5d3e7f99cf52 Add a recursive Sieve of Eratosthenes prime generator. Not practical,
Tim Peters <tim.peters@gmail.com>
parents: 18250
diff changeset
508 ... if i % n:
5d3e7f99cf52 Add a recursive Sieve of Eratosthenes prime generator. Not practical,
Tim Peters <tim.peters@gmail.com>
parents: 18250
diff changeset
509 ... yield i
5d3e7f99cf52 Add a recursive Sieve of Eratosthenes prime generator. Not practical,
Tim Peters <tim.peters@gmail.com>
parents: 18250
diff changeset
510
5d3e7f99cf52 Add a recursive Sieve of Eratosthenes prime generator. Not practical,
Tim Peters <tim.peters@gmail.com>
parents: 18250
diff changeset
511 >>> firstn(exclude_multiples(3, intsfrom(1)), 6)
5d3e7f99cf52 Add a recursive Sieve of Eratosthenes prime generator. Not practical,
Tim Peters <tim.peters@gmail.com>
parents: 18250
diff changeset
512 [1, 2, 4, 5, 7, 8]
5d3e7f99cf52 Add a recursive Sieve of Eratosthenes prime generator. Not practical,
Tim Peters <tim.peters@gmail.com>
parents: 18250
diff changeset
513
5d3e7f99cf52 Add a recursive Sieve of Eratosthenes prime generator. Not practical,
Tim Peters <tim.peters@gmail.com>
parents: 18250
diff changeset
514 >>> def sieve(ints):
5d3e7f99cf52 Add a recursive Sieve of Eratosthenes prime generator. Not practical,
Tim Peters <tim.peters@gmail.com>
parents: 18250
diff changeset
515 ... prime = ints.next()
5d3e7f99cf52 Add a recursive Sieve of Eratosthenes prime generator. Not practical,
Tim Peters <tim.peters@gmail.com>
parents: 18250
diff changeset
516 ... yield prime
5d3e7f99cf52 Add a recursive Sieve of Eratosthenes prime generator. Not practical,
Tim Peters <tim.peters@gmail.com>
parents: 18250
diff changeset
517 ... not_divisible_by_prime = exclude_multiples(prime, ints)
5d3e7f99cf52 Add a recursive Sieve of Eratosthenes prime generator. Not practical,
Tim Peters <tim.peters@gmail.com>
parents: 18250
diff changeset
518 ... for p in sieve(not_divisible_by_prime):
5d3e7f99cf52 Add a recursive Sieve of Eratosthenes prime generator. Not practical,
Tim Peters <tim.peters@gmail.com>
parents: 18250
diff changeset
519 ... yield p
5d3e7f99cf52 Add a recursive Sieve of Eratosthenes prime generator. Not practical,
Tim Peters <tim.peters@gmail.com>
parents: 18250
diff changeset
520
5d3e7f99cf52 Add a recursive Sieve of Eratosthenes prime generator. Not practical,
Tim Peters <tim.peters@gmail.com>
parents: 18250
diff changeset
521 >>> primes = sieve(intsfrom(2))
5d3e7f99cf52 Add a recursive Sieve of Eratosthenes prime generator. Not practical,
Tim Peters <tim.peters@gmail.com>
parents: 18250
diff changeset
522 >>> firstn(primes, 20)
5d3e7f99cf52 Add a recursive Sieve of Eratosthenes prime generator. Not practical,
Tim Peters <tim.peters@gmail.com>
parents: 18250
diff changeset
523 [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71]
18252
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
524
18299
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
525
18252
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
526 Another famous problem: generate all integers of the form
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
527 2**i * 3**j * 5**k
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
528 in increasing order, where i,j,k >= 0. Trickier than it may look at first!
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
529 Try writing it without generators, and correctly, and without generating
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
530 3 internal results for each result output.
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
531
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
532 >>> def times(n, g):
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
533 ... for i in g:
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
534 ... yield n * i
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
535 >>> firstn(times(10, intsfrom(1)), 10)
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
536 [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
537
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
538 >>> def merge(g, h):
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
539 ... ng = g.next()
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
540 ... nh = h.next()
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
541 ... while 1:
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
542 ... if ng < nh:
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
543 ... yield ng
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
544 ... ng = g.next()
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
545 ... elif ng > nh:
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
546 ... yield nh
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
547 ... nh = h.next()
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
548 ... else:
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
549 ... yield ng
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
550 ... ng = g.next()
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
551 ... nh = h.next()
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
552
18299
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
553 The following works, but is doing a whale of a lot of redundant work --
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
554 it's not clear how to get the internal uses of m235 to share a single
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
555 generator. Note that me_times2 (etc) each need to see every element in the
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
556 result sequence. So this is an example where lazy lists are more natural
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
557 (you can look at the head of a lazy list any number of times).
18252
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
558
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
559 >>> def m235():
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
560 ... yield 1
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
561 ... me_times2 = times(2, m235())
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
562 ... me_times3 = times(3, m235())
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
563 ... me_times5 = times(5, m235())
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
564 ... for i in merge(merge(me_times2,
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
565 ... me_times3),
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
566 ... me_times5):
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
567 ... yield i
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
568
18299
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
569 Don't print "too many" of these -- the implementation above is extremely
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
570 inefficient: each call of m235() leads to 3 recursive calls, and in
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
571 turn each of those 3 more, and so on, and so on, until we've descended
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
572 enough levels to satisfy the print stmts. Very odd: when I printed 5
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
573 lines of results below, this managed to screw up Win98's malloc in "the
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
574 usual" way, i.e. the heap grew over 4Mb so Win98 started fragmenting
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
575 address space, and it *looked* like a very slow leak.
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
576
18252
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
577 >>> result = m235()
18299
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
578 >>> for i in range(3):
18252
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
579 ... print firstn(result, 15)
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
580 [1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24]
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
581 [25, 27, 30, 32, 36, 40, 45, 48, 50, 54, 60, 64, 72, 75, 80]
065b17fc0d2e More tests.
Tim Peters <tim.peters@gmail.com>
parents: 18251
diff changeset
582 [81, 90, 96, 100, 108, 120, 125, 128, 135, 144, 150, 160, 162, 180, 192]
18254
0514b16c1a68 Another variant of the 2-3-5 test, mixing generators with a LazyList class.
Tim Peters <tim.peters@gmail.com>
parents: 18252
diff changeset
583
0514b16c1a68 Another variant of the 2-3-5 test, mixing generators with a LazyList class.
Tim Peters <tim.peters@gmail.com>
parents: 18252
diff changeset
584 Heh. Here's one way to get a shared list, complete with an excruciating
0514b16c1a68 Another variant of the 2-3-5 test, mixing generators with a LazyList class.
Tim Peters <tim.peters@gmail.com>
parents: 18252
diff changeset
585 namespace renaming trick. The *pretty* part is that the times() and merge()
0514b16c1a68 Another variant of the 2-3-5 test, mixing generators with a LazyList class.
Tim Peters <tim.peters@gmail.com>
parents: 18252
diff changeset
586 functions can be reused as-is, because they only assume their stream
0514b16c1a68 Another variant of the 2-3-5 test, mixing generators with a LazyList class.
Tim Peters <tim.peters@gmail.com>
parents: 18252
diff changeset
587 arguments are iterable -- a LazyList is the same as a generator to times().
0514b16c1a68 Another variant of the 2-3-5 test, mixing generators with a LazyList class.
Tim Peters <tim.peters@gmail.com>
parents: 18252
diff changeset
588
0514b16c1a68 Another variant of the 2-3-5 test, mixing generators with a LazyList class.
Tim Peters <tim.peters@gmail.com>
parents: 18252
diff changeset
589 >>> class LazyList:
0514b16c1a68 Another variant of the 2-3-5 test, mixing generators with a LazyList class.
Tim Peters <tim.peters@gmail.com>
parents: 18252
diff changeset
590 ... def __init__(self, g):
0514b16c1a68 Another variant of the 2-3-5 test, mixing generators with a LazyList class.
Tim Peters <tim.peters@gmail.com>
parents: 18252
diff changeset
591 ... self.sofar = []
0514b16c1a68 Another variant of the 2-3-5 test, mixing generators with a LazyList class.
Tim Peters <tim.peters@gmail.com>
parents: 18252
diff changeset
592 ... self.fetch = g.next
0514b16c1a68 Another variant of the 2-3-5 test, mixing generators with a LazyList class.
Tim Peters <tim.peters@gmail.com>
parents: 18252
diff changeset
593 ...
0514b16c1a68 Another variant of the 2-3-5 test, mixing generators with a LazyList class.
Tim Peters <tim.peters@gmail.com>
parents: 18252
diff changeset
594 ... def __getitem__(self, i):
0514b16c1a68 Another variant of the 2-3-5 test, mixing generators with a LazyList class.
Tim Peters <tim.peters@gmail.com>
parents: 18252
diff changeset
595 ... sofar, fetch = self.sofar, self.fetch
0514b16c1a68 Another variant of the 2-3-5 test, mixing generators with a LazyList class.
Tim Peters <tim.peters@gmail.com>
parents: 18252
diff changeset
596 ... while i >= len(sofar):
0514b16c1a68 Another variant of the 2-3-5 test, mixing generators with a LazyList class.
Tim Peters <tim.peters@gmail.com>
parents: 18252
diff changeset
597 ... sofar.append(fetch())
0514b16c1a68 Another variant of the 2-3-5 test, mixing generators with a LazyList class.
Tim Peters <tim.peters@gmail.com>
parents: 18252
diff changeset
598 ... return sofar[i]
0514b16c1a68 Another variant of the 2-3-5 test, mixing generators with a LazyList class.
Tim Peters <tim.peters@gmail.com>
parents: 18252
diff changeset
599
0514b16c1a68 Another variant of the 2-3-5 test, mixing generators with a LazyList class.
Tim Peters <tim.peters@gmail.com>
parents: 18252
diff changeset
600 >>> def m235():
0514b16c1a68 Another variant of the 2-3-5 test, mixing generators with a LazyList class.
Tim Peters <tim.peters@gmail.com>
parents: 18252
diff changeset
601 ... yield 1
18256
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
602 ... # Gack: m235 below actually refers to a LazyList.
18254
0514b16c1a68 Another variant of the 2-3-5 test, mixing generators with a LazyList class.
Tim Peters <tim.peters@gmail.com>
parents: 18252
diff changeset
603 ... me_times2 = times(2, m235)
0514b16c1a68 Another variant of the 2-3-5 test, mixing generators with a LazyList class.
Tim Peters <tim.peters@gmail.com>
parents: 18252
diff changeset
604 ... me_times3 = times(3, m235)
0514b16c1a68 Another variant of the 2-3-5 test, mixing generators with a LazyList class.
Tim Peters <tim.peters@gmail.com>
parents: 18252
diff changeset
605 ... me_times5 = times(5, m235)
0514b16c1a68 Another variant of the 2-3-5 test, mixing generators with a LazyList class.
Tim Peters <tim.peters@gmail.com>
parents: 18252
diff changeset
606 ... for i in merge(merge(me_times2,
0514b16c1a68 Another variant of the 2-3-5 test, mixing generators with a LazyList class.
Tim Peters <tim.peters@gmail.com>
parents: 18252
diff changeset
607 ... me_times3),
0514b16c1a68 Another variant of the 2-3-5 test, mixing generators with a LazyList class.
Tim Peters <tim.peters@gmail.com>
parents: 18252
diff changeset
608 ... me_times5):
0514b16c1a68 Another variant of the 2-3-5 test, mixing generators with a LazyList class.
Tim Peters <tim.peters@gmail.com>
parents: 18252
diff changeset
609 ... yield i
0514b16c1a68 Another variant of the 2-3-5 test, mixing generators with a LazyList class.
Tim Peters <tim.peters@gmail.com>
parents: 18252
diff changeset
610
18299
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
611 Print as many of these as you like -- *this* implementation is memory-
18509
254a4a9af0fb Remove reference cycle breaking code. The GC now takes care of it.
Neil Schemenauer <nascheme@enme.ucalgary.ca>
parents: 18384
diff changeset
612 efficient.
18299
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
613
18254
0514b16c1a68 Another variant of the 2-3-5 test, mixing generators with a LazyList class.
Tim Peters <tim.peters@gmail.com>
parents: 18252
diff changeset
614 >>> m235 = LazyList(m235())
0514b16c1a68 Another variant of the 2-3-5 test, mixing generators with a LazyList class.
Tim Peters <tim.peters@gmail.com>
parents: 18252
diff changeset
615 >>> for i in range(5):
0514b16c1a68 Another variant of the 2-3-5 test, mixing generators with a LazyList class.
Tim Peters <tim.peters@gmail.com>
parents: 18252
diff changeset
616 ... print [m235[j] for j in range(15*i, 15*(i+1))]
0514b16c1a68 Another variant of the 2-3-5 test, mixing generators with a LazyList class.
Tim Peters <tim.peters@gmail.com>
parents: 18252
diff changeset
617 [1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24]
0514b16c1a68 Another variant of the 2-3-5 test, mixing generators with a LazyList class.
Tim Peters <tim.peters@gmail.com>
parents: 18252
diff changeset
618 [25, 27, 30, 32, 36, 40, 45, 48, 50, 54, 60, 64, 72, 75, 80]
0514b16c1a68 Another variant of the 2-3-5 test, mixing generators with a LazyList class.
Tim Peters <tim.peters@gmail.com>
parents: 18252
diff changeset
619 [81, 90, 96, 100, 108, 120, 125, 128, 135, 144, 150, 160, 162, 180, 192]
0514b16c1a68 Another variant of the 2-3-5 test, mixing generators with a LazyList class.
Tim Peters <tim.peters@gmail.com>
parents: 18252
diff changeset
620 [200, 216, 225, 240, 243, 250, 256, 270, 288, 300, 320, 324, 360, 375, 384]
0514b16c1a68 Another variant of the 2-3-5 test, mixing generators with a LazyList class.
Tim Peters <tim.peters@gmail.com>
parents: 18252
diff changeset
621 [400, 405, 432, 450, 480, 486, 500, 512, 540, 576, 600, 625, 640, 648, 675]
18299
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
622
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
623 Ye olde Fibonacci generator, LazyList style.
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
624
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
625 >>> def fibgen(a, b):
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
626 ...
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
627 ... def sum(g, h):
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
628 ... while 1:
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
629 ... yield g.next() + h.next()
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
630 ...
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
631 ... def tail(g):
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
632 ... g.next() # throw first away
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
633 ... for x in g:
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
634 ... yield x
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
635 ...
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
636 ... yield a
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
637 ... yield b
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
638 ... for s in sum(iter(fib),
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
639 ... tail(iter(fib))):
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
640 ... yield s
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
641
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
642 >>> fib = LazyList(fibgen(1, 2))
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
643 >>> firstn(iter(fib), 17)
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
644 [1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584]
35419
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
645
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
646
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
647 Running after your tail with itertools.tee (new in version 2.4)
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
648
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
649 The algorithms "m235" (Hamming) and Fibonacci presented above are both
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
650 examples of a whole family of FP (functional programming) algorithms
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
651 where a function produces and returns a list while the production algorithm
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
652 suppose the list as already produced by recursively calling itself.
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
653 For these algorithms to work, they must:
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
654
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
655 - produce at least a first element without presupposing the existence of
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
656 the rest of the list
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
657 - produce their elements in a lazy manner
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
658
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
659 To work efficiently, the beginning of the list must not be recomputed over
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
660 and over again. This is ensured in most FP languages as a built-in feature.
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
661 In python, we have to explicitly maintain a list of already computed results
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
662 and abandon genuine recursivity.
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
663
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
664 This is what had been attempted above with the LazyList class. One problem
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
665 with that class is that it keeps a list of all of the generated results and
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
666 therefore continually grows. This partially defeats the goal of the generator
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
667 concept, viz. produce the results only as needed instead of producing them
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
668 all and thereby wasting memory.
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
669
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
670 Thanks to itertools.tee, it is now clear "how to get the internal uses of
37757
e1388aba9896 Add missing PyObject_GC_Track call, causing *some* itertools.tee objects to
Thomas Wouters <thomas@python.org>
parents: 37725
diff changeset
671 m235 to share a single generator".
35419
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
672
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
673 >>> from itertools import tee
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
674 >>> def m235():
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
675 ... def _m235():
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
676 ... yield 1
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
677 ... for n in merge(times(2, m2),
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
678 ... merge(times(3, m3),
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
679 ... times(5, m5))):
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
680 ... yield n
37332
b80b5f84ae54 Fix the reference leak in test_generators, by explicitly breaking the cycle
Thomas Wouters <thomas@python.org>
parents: 37276
diff changeset
681 ... m1 = _m235()
b80b5f84ae54 Fix the reference leak in test_generators, by explicitly breaking the cycle
Thomas Wouters <thomas@python.org>
parents: 37276
diff changeset
682 ... m2, m3, m5, mRes = tee(m1, 4)
37757
e1388aba9896 Add missing PyObject_GC_Track call, causing *some* itertools.tee objects to
Thomas Wouters <thomas@python.org>
parents: 37725
diff changeset
683 ... return mRes
35419
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
684
37757
e1388aba9896 Add missing PyObject_GC_Track call, causing *some* itertools.tee objects to
Thomas Wouters <thomas@python.org>
parents: 37725
diff changeset
685 >>> it = m235()
35419
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
686 >>> for i in range(5):
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
687 ... print firstn(it, 15)
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
688 [1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24]
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
689 [25, 27, 30, 32, 36, 40, 45, 48, 50, 54, 60, 64, 72, 75, 80]
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
690 [81, 90, 96, 100, 108, 120, 125, 128, 135, 144, 150, 160, 162, 180, 192]
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
691 [200, 216, 225, 240, 243, 250, 256, 270, 288, 300, 320, 324, 360, 375, 384]
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
692 [400, 405, 432, 450, 480, 486, 500, 512, 540, 576, 600, 625, 640, 648, 675]
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
693
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
694 The "tee" function does just what we want. It internally keeps a generated
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
695 result for as long as it has not been "consumed" from all of the duplicated
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
696 iterators, whereupon it is deleted. You can therefore print the hamming
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
697 sequence during hours without increasing memory usage, or very little.
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
698
37725
6e9ab87c608c Changed comments to make sense now that the LazyList-based
Tim Peters <tim.peters@gmail.com>
parents: 37724
diff changeset
699 The beauty of it is that recursive running-after-their-tail FP algorithms
37757
e1388aba9896 Add missing PyObject_GC_Track call, causing *some* itertools.tee objects to
Thomas Wouters <thomas@python.org>
parents: 37725
diff changeset
700 are quite straightforwardly expressed with this Python idiom.
35419
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
701
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
702 Ye olde Fibonacci generator, tee style.
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
703
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
704 >>> def fib():
35465
3e5c07faab11 Whitespace normalization (via reindent.py).
Tim Peters <tim.peters@gmail.com>
parents: 35419
diff changeset
705 ...
35419
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
706 ... def _isum(g, h):
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
707 ... while 1:
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
708 ... yield g.next() + h.next()
35465
3e5c07faab11 Whitespace normalization (via reindent.py).
Tim Peters <tim.peters@gmail.com>
parents: 35419
diff changeset
709 ...
35419
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
710 ... def _fib():
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
711 ... yield 1
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
712 ... yield 2
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
713 ... fibTail.next() # throw first away
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
714 ... for res in _isum(fibHead, fibTail):
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
715 ... yield res
35465
3e5c07faab11 Whitespace normalization (via reindent.py).
Tim Peters <tim.peters@gmail.com>
parents: 35419
diff changeset
716 ...
37332
b80b5f84ae54 Fix the reference leak in test_generators, by explicitly breaking the cycle
Thomas Wouters <thomas@python.org>
parents: 37276
diff changeset
717 ... realfib = _fib()
b80b5f84ae54 Fix the reference leak in test_generators, by explicitly breaking the cycle
Thomas Wouters <thomas@python.org>
parents: 37276
diff changeset
718 ... fibHead, fibTail, fibRes = tee(realfib, 3)
37757
e1388aba9896 Add missing PyObject_GC_Track call, causing *some* itertools.tee objects to
Thomas Wouters <thomas@python.org>
parents: 37725
diff changeset
719 ... return fibRes
35419
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
720
37757
e1388aba9896 Add missing PyObject_GC_Track call, causing *some* itertools.tee objects to
Thomas Wouters <thomas@python.org>
parents: 37725
diff changeset
721 >>> firstn(fib(), 17)
35419
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
722 [1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584]
2a6b6942a7f7 [ 1113421 ] New tutorial tests in test_generators.py
Georg Brandl <georg@python.org>
parents: 35320
diff changeset
723
18251
5d3e7f99cf52 Add a recursive Sieve of Eratosthenes prime generator. Not practical,
Tim Peters <tim.peters@gmail.com>
parents: 18250
diff changeset
724 """
5d3e7f99cf52 Add a recursive Sieve of Eratosthenes prime generator. Not practical,
Tim Peters <tim.peters@gmail.com>
parents: 18250
diff changeset
725
18274
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
726 # syntax_tests mostly provokes SyntaxErrors. Also fiddling with #if 0
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
727 # hackery.
18254
0514b16c1a68 Another variant of the 2-3-5 test, mixing generators with a LazyList class.
Tim Peters <tim.peters@gmail.com>
parents: 18252
diff changeset
728
18256
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
729 syntax_tests = """
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
730
33308
f28072e64f81 Don't really need ellipsis doctests for the syntax errors, because
Tim Peters <tim.peters@gmail.com>
parents: 33306
diff changeset
731 >>> def f():
18256
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
732 ... return 22
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
733 ... yield 1
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
734 Traceback (most recent call last):
33306
7f617025565e Fixed 6 failures due to doctest changes.
Tim Peters <tim.peters@gmail.com>
parents: 33054
diff changeset
735 ..
38588
5dfb21a37f19 Patch #1346214: correctly optimize away "if 0"-style stmts
Georg Brandl <georg@python.org>
parents: 37761
diff changeset
736 SyntaxError: 'return' with argument inside generator (<doctest test.test_generators.__test__.syntax[0]>, line 3)
18256
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
737
33308
f28072e64f81 Don't really need ellipsis doctests for the syntax errors, because
Tim Peters <tim.peters@gmail.com>
parents: 33306
diff changeset
738 >>> def f():
18256
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
739 ... yield 1
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
740 ... return 22
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
741 Traceback (most recent call last):
33306
7f617025565e Fixed 6 failures due to doctest changes.
Tim Peters <tim.peters@gmail.com>
parents: 33054
diff changeset
742 ..
33468
a04515a98831 DocTestFinder._find(): for tests derived from a module __test__ global,
Tim Peters <tim.peters@gmail.com>
parents: 33309
diff changeset
743 SyntaxError: 'return' with argument inside generator (<doctest test.test_generators.__test__.syntax[1]>, line 3)
18256
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
744
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
745 "return None" is not the same as "return" in a generator:
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
746
33308
f28072e64f81 Don't really need ellipsis doctests for the syntax errors, because
Tim Peters <tim.peters@gmail.com>
parents: 33306
diff changeset
747 >>> def f():
18256
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
748 ... yield 1
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
749 ... return None
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
750 Traceback (most recent call last):
33306
7f617025565e Fixed 6 failures due to doctest changes.
Tim Peters <tim.peters@gmail.com>
parents: 33054
diff changeset
751 ..
33468
a04515a98831 DocTestFinder._find(): for tests derived from a module __test__ global,
Tim Peters <tim.peters@gmail.com>
parents: 33309
diff changeset
752 SyntaxError: 'return' with argument inside generator (<doctest test.test_generators.__test__.syntax[2]>, line 3)
18256
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
753
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
754 These are fine:
18256
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
755
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
756 >>> def f():
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
757 ... yield 1
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
758 ... return
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
759
33308
f28072e64f81 Don't really need ellipsis doctests for the syntax errors, because
Tim Peters <tim.peters@gmail.com>
parents: 33306
diff changeset
760 >>> def f():
18256
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
761 ... try:
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
762 ... yield 1
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
763 ... finally:
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
764 ... pass
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
765
33308
f28072e64f81 Don't really need ellipsis doctests for the syntax errors, because
Tim Peters <tim.peters@gmail.com>
parents: 33306
diff changeset
766 >>> def f():
18256
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
767 ... try:
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
768 ... try:
21251
45e1177424e1 SF bug #488514: -Qnew needs work
Tim Peters <tim.peters@gmail.com>
parents: 19817
diff changeset
769 ... 1//0
18256
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
770 ... except ZeroDivisionError:
36121
686306a67e9b Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 35959
diff changeset
771 ... yield 666
18256
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
772 ... except:
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
773 ... pass
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
774 ... finally:
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
775 ... pass
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
776
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
777 >>> def f():
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
778 ... try:
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
779 ... try:
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
780 ... yield 12
21251
45e1177424e1 SF bug #488514: -Qnew needs work
Tim Peters <tim.peters@gmail.com>
parents: 19817
diff changeset
781 ... 1//0
18256
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
782 ... except ZeroDivisionError:
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
783 ... yield 666
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
784 ... except:
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
785 ... try:
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
786 ... x = 12
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
787 ... finally:
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
788 ... yield 12
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
789 ... except:
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
790 ... return
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
791 >>> list(f())
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
792 [12, 666]
18274
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
793
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
794 >>> def f():
18333
41243cb4ea05 Another "if 0:" hack, this time to complain about otherwise invisible
Tim Peters <tim.peters@gmail.com>
parents: 18299
diff changeset
795 ... yield
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
796 >>> type(f())
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
797 <type 'generator'>
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
798
18333
41243cb4ea05 Another "if 0:" hack, this time to complain about otherwise invisible
Tim Peters <tim.peters@gmail.com>
parents: 18299
diff changeset
799
41243cb4ea05 Another "if 0:" hack, this time to complain about otherwise invisible
Tim Peters <tim.peters@gmail.com>
parents: 18299
diff changeset
800 >>> def f():
41243cb4ea05 Another "if 0:" hack, this time to complain about otherwise invisible
Tim Peters <tim.peters@gmail.com>
parents: 18299
diff changeset
801 ... if 0:
41243cb4ea05 Another "if 0:" hack, this time to complain about otherwise invisible
Tim Peters <tim.peters@gmail.com>
parents: 18299
diff changeset
802 ... yield
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
803 >>> type(f())
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
804 <type 'generator'>
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
805
18333
41243cb4ea05 Another "if 0:" hack, this time to complain about otherwise invisible
Tim Peters <tim.peters@gmail.com>
parents: 18299
diff changeset
806
41243cb4ea05 Another "if 0:" hack, this time to complain about otherwise invisible
Tim Peters <tim.peters@gmail.com>
parents: 18299
diff changeset
807 >>> def f():
18274
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
808 ... if 0:
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
809 ... yield 1
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
810 >>> type(f())
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
811 <type 'generator'>
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
812
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
813 >>> def f():
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
814 ... if "":
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
815 ... yield None
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
816 >>> type(f())
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
817 <type 'generator'>
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
818
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
819 >>> def f():
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
820 ... return
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
821 ... try:
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
822 ... if x==4:
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
823 ... pass
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
824 ... elif 0:
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
825 ... try:
21251
45e1177424e1 SF bug #488514: -Qnew needs work
Tim Peters <tim.peters@gmail.com>
parents: 19817
diff changeset
826 ... 1//0
18274
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
827 ... except SyntaxError:
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
828 ... pass
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
829 ... else:
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
830 ... if 0:
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
831 ... while 12:
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
832 ... x += 1
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
833 ... yield 2 # don't blink
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
834 ... f(a, b, c, d, e)
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
835 ... else:
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
836 ... pass
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
837 ... except:
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
838 ... x = 1
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
839 ... return
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
840 >>> type(f())
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
841 <type 'generator'>
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
842
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
843 >>> def f():
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
844 ... if 0:
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
845 ... def g():
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
846 ... yield 1
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
847 ...
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
848 >>> type(f())
19298
6c4a8730663a The change of type(None).__name__ from 'None' to 'NoneType' broke this
Guido van Rossum <guido@python.org>
parents: 19264
diff changeset
849 <type 'NoneType'>
18274
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
850
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
851 >>> def f():
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
852 ... if 0:
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
853 ... class C:
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
854 ... def __init__(self):
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
855 ... yield 1
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
856 ... def f(self):
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
857 ... yield 2
86dab0d43b73 SF bug #436207: "if 0: yield x" is ignored.
Tim Peters <tim.peters@gmail.com>
parents: 18273
diff changeset
858 >>> type(f())
19298
6c4a8730663a The change of type(None).__name__ from 'None' to 'NoneType' broke this
Guido van Rossum <guido@python.org>
parents: 19264
diff changeset
859 <type 'NoneType'>
18333
41243cb4ea05 Another "if 0:" hack, this time to complain about otherwise invisible
Tim Peters <tim.peters@gmail.com>
parents: 18299
diff changeset
860
41243cb4ea05 Another "if 0:" hack, this time to complain about otherwise invisible
Tim Peters <tim.peters@gmail.com>
parents: 18299
diff changeset
861 >>> def f():
41243cb4ea05 Another "if 0:" hack, this time to complain about otherwise invisible
Tim Peters <tim.peters@gmail.com>
parents: 18299
diff changeset
862 ... if 0:
41243cb4ea05 Another "if 0:" hack, this time to complain about otherwise invisible
Tim Peters <tim.peters@gmail.com>
parents: 18299
diff changeset
863 ... return
41243cb4ea05 Another "if 0:" hack, this time to complain about otherwise invisible
Tim Peters <tim.peters@gmail.com>
parents: 18299
diff changeset
864 ... if 0:
41243cb4ea05 Another "if 0:" hack, this time to complain about otherwise invisible
Tim Peters <tim.peters@gmail.com>
parents: 18299
diff changeset
865 ... yield 2
41243cb4ea05 Another "if 0:" hack, this time to complain about otherwise invisible
Tim Peters <tim.peters@gmail.com>
parents: 18299
diff changeset
866 >>> type(f())
41243cb4ea05 Another "if 0:" hack, this time to complain about otherwise invisible
Tim Peters <tim.peters@gmail.com>
parents: 18299
diff changeset
867 <type 'generator'>
41243cb4ea05 Another "if 0:" hack, this time to complain about otherwise invisible
Tim Peters <tim.peters@gmail.com>
parents: 18299
diff changeset
868
41243cb4ea05 Another "if 0:" hack, this time to complain about otherwise invisible
Tim Peters <tim.peters@gmail.com>
parents: 18299
diff changeset
869
33308
f28072e64f81 Don't really need ellipsis doctests for the syntax errors, because
Tim Peters <tim.peters@gmail.com>
parents: 33306
diff changeset
870 >>> def f():
18333
41243cb4ea05 Another "if 0:" hack, this time to complain about otherwise invisible
Tim Peters <tim.peters@gmail.com>
parents: 18299
diff changeset
871 ... if 0:
41243cb4ea05 Another "if 0:" hack, this time to complain about otherwise invisible
Tim Peters <tim.peters@gmail.com>
parents: 18299
diff changeset
872 ... lambda x: x # shouldn't trigger here
41243cb4ea05 Another "if 0:" hack, this time to complain about otherwise invisible
Tim Peters <tim.peters@gmail.com>
parents: 18299
diff changeset
873 ... return # or here
41243cb4ea05 Another "if 0:" hack, this time to complain about otherwise invisible
Tim Peters <tim.peters@gmail.com>
parents: 18299
diff changeset
874 ... def f(i):
41243cb4ea05 Another "if 0:" hack, this time to complain about otherwise invisible
Tim Peters <tim.peters@gmail.com>
parents: 18299
diff changeset
875 ... return 2*i # or here
41243cb4ea05 Another "if 0:" hack, this time to complain about otherwise invisible
Tim Peters <tim.peters@gmail.com>
parents: 18299
diff changeset
876 ... if 0:
41243cb4ea05 Another "if 0:" hack, this time to complain about otherwise invisible
Tim Peters <tim.peters@gmail.com>
parents: 18299
diff changeset
877 ... return 3 # but *this* sucks (line 8)
41243cb4ea05 Another "if 0:" hack, this time to complain about otherwise invisible
Tim Peters <tim.peters@gmail.com>
parents: 18299
diff changeset
878 ... if 0:
38588
5dfb21a37f19 Patch #1346214: correctly optimize away "if 0"-style stmts
Georg Brandl <georg@python.org>
parents: 37761
diff changeset
879 ... yield 2 # because it's a generator (line 10)
18333
41243cb4ea05 Another "if 0:" hack, this time to complain about otherwise invisible
Tim Peters <tim.peters@gmail.com>
parents: 18299
diff changeset
880 Traceback (most recent call last):
38588
5dfb21a37f19 Patch #1346214: correctly optimize away "if 0"-style stmts
Georg Brandl <georg@python.org>
parents: 37761
diff changeset
881 SyntaxError: 'return' with argument inside generator (<doctest test.test_generators.__test__.syntax[24]>, line 10)
23785
7a32c2356e56 SF bug 567538: Generator can crash the interpreter (Finn Bock).
Guido van Rossum <guido@python.org>
parents: 22785
diff changeset
882
7a32c2356e56 SF bug 567538: Generator can crash the interpreter (Finn Bock).
Guido van Rossum <guido@python.org>
parents: 22785
diff changeset
883 This one caused a crash (see SF bug 567538):
7a32c2356e56 SF bug 567538: Generator can crash the interpreter (Finn Bock).
Guido van Rossum <guido@python.org>
parents: 22785
diff changeset
884
7a32c2356e56 SF bug 567538: Generator can crash the interpreter (Finn Bock).
Guido van Rossum <guido@python.org>
parents: 22785
diff changeset
885 >>> def f():
7a32c2356e56 SF bug 567538: Generator can crash the interpreter (Finn Bock).
Guido van Rossum <guido@python.org>
parents: 22785
diff changeset
886 ... for i in range(3):
7a32c2356e56 SF bug 567538: Generator can crash the interpreter (Finn Bock).
Guido van Rossum <guido@python.org>
parents: 22785
diff changeset
887 ... try:
7a32c2356e56 SF bug 567538: Generator can crash the interpreter (Finn Bock).
Guido van Rossum <guido@python.org>
parents: 22785
diff changeset
888 ... continue
7a32c2356e56 SF bug 567538: Generator can crash the interpreter (Finn Bock).
Guido van Rossum <guido@python.org>
parents: 22785
diff changeset
889 ... finally:
7a32c2356e56 SF bug 567538: Generator can crash the interpreter (Finn Bock).
Guido van Rossum <guido@python.org>
parents: 22785
diff changeset
890 ... yield i
24263
e6033254df21 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 23785
diff changeset
891 ...
23785
7a32c2356e56 SF bug 567538: Generator can crash the interpreter (Finn Bock).
Guido van Rossum <guido@python.org>
parents: 22785
diff changeset
892 >>> g = f()
7a32c2356e56 SF bug 567538: Generator can crash the interpreter (Finn Bock).
Guido van Rossum <guido@python.org>
parents: 22785
diff changeset
893 >>> print g.next()
7a32c2356e56 SF bug 567538: Generator can crash the interpreter (Finn Bock).
Guido van Rossum <guido@python.org>
parents: 22785
diff changeset
894 0
7a32c2356e56 SF bug 567538: Generator can crash the interpreter (Finn Bock).
Guido van Rossum <guido@python.org>
parents: 22785
diff changeset
895 >>> print g.next()
7a32c2356e56 SF bug 567538: Generator can crash the interpreter (Finn Bock).
Guido van Rossum <guido@python.org>
parents: 22785
diff changeset
896 1
7a32c2356e56 SF bug 567538: Generator can crash the interpreter (Finn Bock).
Guido van Rossum <guido@python.org>
parents: 22785
diff changeset
897 >>> print g.next()
7a32c2356e56 SF bug 567538: Generator can crash the interpreter (Finn Bock).
Guido van Rossum <guido@python.org>
parents: 22785
diff changeset
898 2
7a32c2356e56 SF bug 567538: Generator can crash the interpreter (Finn Bock).
Guido van Rossum <guido@python.org>
parents: 22785
diff changeset
899 >>> print g.next()
7a32c2356e56 SF bug 567538: Generator can crash the interpreter (Finn Bock).
Guido van Rossum <guido@python.org>
parents: 22785
diff changeset
900 Traceback (most recent call last):
7a32c2356e56 SF bug 567538: Generator can crash the interpreter (Finn Bock).
Guido van Rossum <guido@python.org>
parents: 22785
diff changeset
901 StopIteration
44976
51bb7b1ae765 #1473257: add generator.gi_code attribute that refers to
Georg Brandl <georg@python.org>
parents: 44127
diff changeset
902
51bb7b1ae765 #1473257: add generator.gi_code attribute that refers to
Georg Brandl <georg@python.org>
parents: 44127
diff changeset
903
51bb7b1ae765 #1473257: add generator.gi_code attribute that refers to
Georg Brandl <georg@python.org>
parents: 44127
diff changeset
904 Test the gi_code attribute
51bb7b1ae765 #1473257: add generator.gi_code attribute that refers to
Georg Brandl <georg@python.org>
parents: 44127
diff changeset
905
51bb7b1ae765 #1473257: add generator.gi_code attribute that refers to
Georg Brandl <georg@python.org>
parents: 44127
diff changeset
906 >>> def f():
51bb7b1ae765 #1473257: add generator.gi_code attribute that refers to
Georg Brandl <georg@python.org>
parents: 44127
diff changeset
907 ... yield 5
51bb7b1ae765 #1473257: add generator.gi_code attribute that refers to
Georg Brandl <georg@python.org>
parents: 44127
diff changeset
908 ...
51bb7b1ae765 #1473257: add generator.gi_code attribute that refers to
Georg Brandl <georg@python.org>
parents: 44127
diff changeset
909 >>> g = f()
51bb7b1ae765 #1473257: add generator.gi_code attribute that refers to
Georg Brandl <georg@python.org>
parents: 44127
diff changeset
910 >>> g.gi_code is f.func_code
51bb7b1ae765 #1473257: add generator.gi_code attribute that refers to
Georg Brandl <georg@python.org>
parents: 44127
diff changeset
911 True
51bb7b1ae765 #1473257: add generator.gi_code attribute that refers to
Georg Brandl <georg@python.org>
parents: 44127
diff changeset
912 >>> g.next()
51bb7b1ae765 #1473257: add generator.gi_code attribute that refers to
Georg Brandl <georg@python.org>
parents: 44127
diff changeset
913 5
51bb7b1ae765 #1473257: add generator.gi_code attribute that refers to
Georg Brandl <georg@python.org>
parents: 44127
diff changeset
914 >>> g.next()
51bb7b1ae765 #1473257: add generator.gi_code attribute that refers to
Georg Brandl <georg@python.org>
parents: 44127
diff changeset
915 Traceback (most recent call last):
51bb7b1ae765 #1473257: add generator.gi_code attribute that refers to
Georg Brandl <georg@python.org>
parents: 44127
diff changeset
916 StopIteration
51bb7b1ae765 #1473257: add generator.gi_code attribute that refers to
Georg Brandl <georg@python.org>
parents: 44127
diff changeset
917 >>> g.gi_code is f.func_code
51bb7b1ae765 #1473257: add generator.gi_code attribute that refers to
Georg Brandl <georg@python.org>
parents: 44127
diff changeset
918 True
51bb7b1ae765 #1473257: add generator.gi_code attribute that refers to
Georg Brandl <georg@python.org>
parents: 44127
diff changeset
919
47056
1573c776df82 #2863: add gen.__name__ and add this name to generator repr().
Georg Brandl <georg@python.org>
parents: 44976
diff changeset
920
1573c776df82 #2863: add gen.__name__ and add this name to generator repr().
Georg Brandl <georg@python.org>
parents: 44976
diff changeset
921 Test the __name__ attribute and the repr()
1573c776df82 #2863: add gen.__name__ and add this name to generator repr().
Georg Brandl <georg@python.org>
parents: 44976
diff changeset
922
1573c776df82 #2863: add gen.__name__ and add this name to generator repr().
Georg Brandl <georg@python.org>
parents: 44976
diff changeset
923 >>> def f():
1573c776df82 #2863: add gen.__name__ and add this name to generator repr().
Georg Brandl <georg@python.org>
parents: 44976
diff changeset
924 ... yield 5
1573c776df82 #2863: add gen.__name__ and add this name to generator repr().
Georg Brandl <georg@python.org>
parents: 44976
diff changeset
925 ...
1573c776df82 #2863: add gen.__name__ and add this name to generator repr().
Georg Brandl <georg@python.org>
parents: 44976
diff changeset
926 >>> g = f()
1573c776df82 #2863: add gen.__name__ and add this name to generator repr().
Georg Brandl <georg@python.org>
parents: 44976
diff changeset
927 >>> g.__name__
1573c776df82 #2863: add gen.__name__ and add this name to generator repr().
Georg Brandl <georg@python.org>
parents: 44976
diff changeset
928 'f'
1573c776df82 #2863: add gen.__name__ and add this name to generator repr().
Georg Brandl <georg@python.org>
parents: 44976
diff changeset
929 >>> repr(g) # doctest: +ELLIPSIS
47090
ed13040ac2e6 Make generator repr consistent with function and code object repr.
Georg Brandl <georg@python.org>
parents: 47056
diff changeset
930 '<generator object f at ...>'
18256
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
931 """
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
932
18336
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
933 # conjoin is a simple backtracking generator, named in honor of Icon's
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
934 # "conjunction" control structure. Pass a list of no-argument functions
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
935 # that return iterable objects. Easiest to explain by example: assume the
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
936 # function list [x, y, z] is passed. Then conjoin acts like:
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
937 #
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
938 # def g():
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
939 # values = [None] * 3
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
940 # for values[0] in x():
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
941 # for values[1] in y():
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
942 # for values[2] in z():
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
943 # yield values
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
944 #
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
945 # So some 3-lists of values *may* be generated, each time we successfully
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
946 # get into the innermost loop. If an iterator fails (is exhausted) before
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
947 # then, it "backtracks" to get the next value from the nearest enclosing
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
948 # iterator (the one "to the left"), and starts all over again at the next
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
949 # slot (pumps a fresh iterator). Of course this is most useful when the
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
950 # iterators have side-effects, so that which values *can* be generated at
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
951 # each slot depend on the values iterated at previous slots.
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
952
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
953 def conjoin(gs):
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
954
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
955 values = [None] * len(gs)
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
956
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
957 def gen(i, values=values):
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
958 if i >= len(gs):
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
959 yield values
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
960 else:
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
961 for values[i] in gs[i]():
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
962 for x in gen(i+1):
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
963 yield x
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
964
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
965 for x in gen(0):
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
966 yield x
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
967
18352
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
968 # That works fine, but recursing a level and checking i against len(gs) for
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
969 # each item produced is inefficient. By doing manual loop unrolling across
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
970 # generator boundaries, it's possible to eliminate most of that overhead.
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
971 # This isn't worth the bother *in general* for generators, but conjoin() is
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
972 # a core building block for some CPU-intensive generator applications.
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
973
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
974 def conjoin(gs):
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
975
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
976 n = len(gs)
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
977 values = [None] * n
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
978
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
979 # Do one loop nest at time recursively, until the # of loop nests
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
980 # remaining is divisible by 3.
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
981
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
982 def gen(i, values=values):
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
983 if i >= n:
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
984 yield values
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
985
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
986 elif (n-i) % 3:
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
987 ip1 = i+1
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
988 for values[i] in gs[i]():
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
989 for x in gen(ip1):
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
990 yield x
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
991
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
992 else:
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
993 for x in _gen3(i):
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
994 yield x
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
995
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
996 # Do three loop nests at a time, recursing only if at least three more
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
997 # remain. Don't call directly: this is an internal optimization for
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
998 # gen's use.
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
999
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1000 def _gen3(i, values=values):
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1001 assert i < n and (n-i) % 3 == 0
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1002 ip1, ip2, ip3 = i+1, i+2, i+3
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1003 g, g1, g2 = gs[i : ip3]
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1004
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1005 if ip3 >= n:
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1006 # These are the last three, so we can yield values directly.
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1007 for values[i] in g():
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1008 for values[ip1] in g1():
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1009 for values[ip2] in g2():
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1010 yield values
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1011
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1012 else:
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1013 # At least 6 loop nests remain; peel off 3 and recurse for the
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1014 # rest.
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1015 for values[i] in g():
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1016 for values[ip1] in g1():
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1017 for values[ip2] in g2():
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1018 for x in _gen3(ip3):
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1019 yield x
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1020
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1021 for x in gen(0):
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1022 yield x
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1023
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1024 # And one more approach: For backtracking apps like the Knight's Tour
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1025 # solver below, the number of backtracking levels can be enormous (one
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1026 # level per square, for the Knight's Tour, so that e.g. a 100x100 board
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1027 # needs 10,000 levels). In such cases Python is likely to run out of
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1028 # stack space due to recursion. So here's a recursion-free version of
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1029 # conjoin too.
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1030 # NOTE WELL: This allows large problems to be solved with only trivial
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1031 # demands on stack space. Without explicitly resumable generators, this is
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1032 # much harder to achieve. OTOH, this is much slower (up to a factor of 2)
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1033 # than the fancy unrolled recursive conjoin.
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1034
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1035 def flat_conjoin(gs): # rename to conjoin to run tests with this instead
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1036 n = len(gs)
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1037 values = [None] * n
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1038 iters = [None] * n
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1039 _StopIteration = StopIteration # make local because caught a *lot*
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1040 i = 0
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1041 while 1:
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1042 # Descend.
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1043 try:
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1044 while i < n:
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1045 it = iters[i] = gs[i]().next
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1046 values[i] = it()
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1047 i += 1
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1048 except _StopIteration:
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1049 pass
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1050 else:
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1051 assert i == n
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1052 yield values
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1053
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1054 # Backtrack until an older iterator can be resumed.
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1055 i -= 1
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1056 while i >= 0:
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1057 try:
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1058 values[i] = iters[i]()
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1059 # Success! Start fresh at next level.
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1060 i += 1
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1061 break
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1062 except _StopIteration:
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1063 # Continue backtracking.
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1064 i -= 1
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1065 else:
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1066 assert i < 0
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1067 break
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1068
18336
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1069 # A conjoin-based N-Queens solver.
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1070
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1071 class Queens:
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1072 def __init__(self, n):
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1073 self.n = n
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1074 rangen = range(n)
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1075
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1076 # Assign a unique int to each column and diagonal.
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1077 # columns: n of those, range(n).
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1078 # NW-SE diagonals: 2n-1 of these, i-j unique and invariant along
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1079 # each, smallest i-j is 0-(n-1) = 1-n, so add n-1 to shift to 0-
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1080 # based.
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1081 # NE-SW diagonals: 2n-1 of these, i+j unique and invariant along
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1082 # each, smallest i+j is 0, largest is 2n-2.
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1083
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1084 # For each square, compute a bit vector of the columns and
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1085 # diagonals it covers, and for each row compute a function that
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1086 # generates the possiblities for the columns in that row.
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1087 self.rowgenerators = []
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1088 for i in rangen:
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1089 rowuses = [(1L << j) | # column ordinal
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1090 (1L << (n + i-j + n-1)) | # NW-SE ordinal
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1091 (1L << (n + 2*n-1 + i+j)) # NE-SW ordinal
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1092 for j in rangen]
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1093
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1094 def rowgen(rowuses=rowuses):
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1095 for j in rangen:
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1096 uses = rowuses[j]
18352
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1097 if uses & self.used == 0:
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1098 self.used |= uses
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1099 yield j
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1100 self.used &= ~uses
18336
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1101
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1102 self.rowgenerators.append(rowgen)
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1103
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1104 # Generate solutions.
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1105 def solve(self):
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1106 self.used = 0
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1107 for row2col in conjoin(self.rowgenerators):
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1108 yield row2col
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1109
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1110 def printsolution(self, row2col):
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1111 n = self.n
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1112 assert n == len(row2col)
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1113 sep = "+" + "-+" * n
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1114 print sep
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1115 for i in range(n):
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1116 squares = [" " for j in range(n)]
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1117 squares[row2col[i]] = "Q"
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1118 print "|" + "|".join(squares) + "|"
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1119 print sep
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1120
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1121 # A conjoin-based Knight's Tour solver. This is pretty sophisticated
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1122 # (e.g., when used with flat_conjoin above, and passing hard=1 to the
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1123 # constructor, a 200x200 Knight's Tour was found quickly -- note that we're
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1124 # creating 10s of thousands of generators then!), and is lengthy.
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1125
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1126 class Knights:
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1127 def __init__(self, m, n, hard=0):
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1128 self.m, self.n = m, n
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1129
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1130 # solve() will set up succs[i] to be a list of square #i's
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1131 # successors.
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1132 succs = self.succs = []
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1133
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1134 # Remove i0 from each of its successor's successor lists, i.e.
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1135 # successors can't go back to i0 again. Return 0 if we can
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1136 # detect this makes a solution impossible, else return 1.
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1137
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1138 def remove_from_successors(i0, len=len):
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1139 # If we remove all exits from a free square, we're dead:
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1140 # even if we move to it next, we can't leave it again.
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1141 # If we create a square with one exit, we must visit it next;
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1142 # else somebody else will have to visit it, and since there's
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1143 # only one adjacent, there won't be a way to leave it again.
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1144 # Finelly, if we create more than one free square with a
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1145 # single exit, we can only move to one of them next, leaving
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1146 # the other one a dead end.
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1147 ne0 = ne1 = 0
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1148 for i in succs[i0]:
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1149 s = succs[i]
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1150 s.remove(i0)
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1151 e = len(s)
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1152 if e == 0:
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1153 ne0 += 1
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1154 elif e == 1:
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1155 ne1 += 1
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1156 return ne0 == 0 and ne1 < 2
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1157
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1158 # Put i0 back in each of its successor's successor lists.
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1159
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1160 def add_to_successors(i0):
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1161 for i in succs[i0]:
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1162 succs[i].append(i0)
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1163
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1164 # Generate the first move.
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1165 def first():
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1166 if m < 1 or n < 1:
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1167 return
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1168
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1169 # Since we're looking for a cycle, it doesn't matter where we
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1170 # start. Starting in a corner makes the 2nd move easy.
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1171 corner = self.coords2index(0, 0)
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1172 remove_from_successors(corner)
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1173 self.lastij = corner
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1174 yield corner
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1175 add_to_successors(corner)
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1176
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1177 # Generate the second moves.
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1178 def second():
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1179 corner = self.coords2index(0, 0)
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1180 assert self.lastij == corner # i.e., we started in the corner
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1181 if m < 3 or n < 3:
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1182 return
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1183 assert len(succs[corner]) == 2
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1184 assert self.coords2index(1, 2) in succs[corner]
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1185 assert self.coords2index(2, 1) in succs[corner]
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1186 # Only two choices. Whichever we pick, the other must be the
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1187 # square picked on move m*n, as it's the only way to get back
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1188 # to (0, 0). Save its index in self.final so that moves before
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1189 # the last know it must be kept free.
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1190 for i, j in (1, 2), (2, 1):
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1191 this = self.coords2index(i, j)
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1192 final = self.coords2index(3-i, 3-j)
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1193 self.final = final
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1194
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1195 remove_from_successors(this)
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1196 succs[final].append(corner)
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1197 self.lastij = this
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1198 yield this
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1199 succs[final].remove(corner)
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1200 add_to_successors(this)
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1201
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1202 # Generate moves 3 thru m*n-1.
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1203 def advance(len=len):
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1204 # If some successor has only one exit, must take it.
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1205 # Else favor successors with fewer exits.
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1206 candidates = []
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1207 for i in succs[self.lastij]:
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1208 e = len(succs[i])
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1209 assert e > 0, "else remove_from_successors() pruning flawed"
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1210 if e == 1:
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1211 candidates = [(e, i)]
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1212 break
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1213 candidates.append((e, i))
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1214 else:
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1215 candidates.sort()
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1216
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1217 for e, i in candidates:
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1218 if i != self.final:
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1219 if remove_from_successors(i):
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1220 self.lastij = i
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1221 yield i
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1222 add_to_successors(i)
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1223
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1224 # Generate moves 3 thru m*n-1. Alternative version using a
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1225 # stronger (but more expensive) heuristic to order successors.
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1226 # Since the # of backtracking levels is m*n, a poor move early on
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1227 # can take eons to undo. Smallest square board for which this
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1228 # matters a lot is 52x52.
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1229 def advance_hard(vmid=(m-1)/2.0, hmid=(n-1)/2.0, len=len):
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1230 # If some successor has only one exit, must take it.
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1231 # Else favor successors with fewer exits.
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1232 # Break ties via max distance from board centerpoint (favor
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1233 # corners and edges whenever possible).
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1234 candidates = []
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1235 for i in succs[self.lastij]:
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1236 e = len(succs[i])
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1237 assert e > 0, "else remove_from_successors() pruning flawed"
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1238 if e == 1:
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1239 candidates = [(e, 0, i)]
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1240 break
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1241 i1, j1 = self.index2coords(i)
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1242 d = (i1 - vmid)**2 + (j1 - hmid)**2
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1243 candidates.append((e, -d, i))
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1244 else:
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1245 candidates.sort()
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1246
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1247 for e, d, i in candidates:
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1248 if i != self.final:
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1249 if remove_from_successors(i):
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1250 self.lastij = i
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1251 yield i
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1252 add_to_successors(i)
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1253
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1254 # Generate the last move.
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1255 def last():
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1256 assert self.final in succs[self.lastij]
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1257 yield self.final
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1258
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1259 if m*n < 4:
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1260 self.squaregenerators = [first]
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1261 else:
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1262 self.squaregenerators = [first, second] + \
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1263 [hard and advance_hard or advance] * (m*n - 3) + \
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1264 [last]
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1265
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1266 def coords2index(self, i, j):
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1267 assert 0 <= i < self.m
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1268 assert 0 <= j < self.n
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1269 return i * self.n + j
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1270
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1271 def index2coords(self, index):
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1272 assert 0 <= index < self.m * self.n
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1273 return divmod(index, self.n)
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1274
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1275 def _init_board(self):
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1276 succs = self.succs
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1277 del succs[:]
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1278 m, n = self.m, self.n
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1279 c2i = self.coords2index
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1280
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1281 offsets = [( 1, 2), ( 2, 1), ( 2, -1), ( 1, -2),
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1282 (-1, -2), (-2, -1), (-2, 1), (-1, 2)]
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1283 rangen = range(n)
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1284 for i in range(m):
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1285 for j in rangen:
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1286 s = [c2i(i+io, j+jo) for io, jo in offsets
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1287 if 0 <= i+io < m and
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1288 0 <= j+jo < n]
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1289 succs.append(s)
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1290
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1291 # Generate solutions.
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1292 def solve(self):
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1293 self._init_board()
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1294 for x in conjoin(self.squaregenerators):
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1295 yield x
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1296
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1297 def printsolution(self, x):
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1298 m, n = self.m, self.n
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1299 assert len(x) == m*n
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1300 w = len(str(m*n))
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1301 format = "%" + str(w) + "d"
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1302
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1303 squares = [[None] * n for i in range(m)]
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1304 k = 1
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1305 for i in x:
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1306 i1, j1 = self.index2coords(i)
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1307 squares[i1][j1] = format % k
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1308 k += 1
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1309
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1310 sep = "+" + ("-" * w + "+") * n
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1311 print sep
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1312 for i in range(m):
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1313 row = squares[i]
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1314 print "|" + "|".join(row) + "|"
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1315 print sep
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1316
18336
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1317 conjoin_tests = """
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1318
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1319 Generate the 3-bit binary numbers in order. This illustrates dumbest-
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1320 possible use of conjoin, just to generate the full cross-product.
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1321
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1322 >>> for c in conjoin([lambda: iter((0, 1))] * 3):
18336
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1323 ... print c
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1324 [0, 0, 0]
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1325 [0, 0, 1]
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1326 [0, 1, 0]
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1327 [0, 1, 1]
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1328 [1, 0, 0]
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1329 [1, 0, 1]
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1330 [1, 1, 0]
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1331 [1, 1, 1]
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1332
18352
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1333 For efficiency in typical backtracking apps, conjoin() yields the same list
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1334 object each time. So if you want to save away a full account of its
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1335 generated sequence, you need to copy its results.
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1336
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1337 >>> def gencopy(iterator):
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1338 ... for x in iterator:
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1339 ... yield x[:]
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1340
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1341 >>> for n in range(10):
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1342 ... all = list(gencopy(conjoin([lambda: iter((0, 1))] * n)))
18352
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1343 ... print n, len(all), all[0] == [0] * n, all[-1] == [1] * n
22785
aa8d59823add Add the 'bool' type and its values 'False' and 'True', as described in
Guido van Rossum <guido@python.org>
parents: 22719
diff changeset
1344 0 1 True True
aa8d59823add Add the 'bool' type and its values 'False' and 'True', as described in
Guido van Rossum <guido@python.org>
parents: 22719
diff changeset
1345 1 2 True True
aa8d59823add Add the 'bool' type and its values 'False' and 'True', as described in
Guido van Rossum <guido@python.org>
parents: 22719
diff changeset
1346 2 4 True True
aa8d59823add Add the 'bool' type and its values 'False' and 'True', as described in
Guido van Rossum <guido@python.org>
parents: 22719
diff changeset
1347 3 8 True True
aa8d59823add Add the 'bool' type and its values 'False' and 'True', as described in
Guido van Rossum <guido@python.org>
parents: 22719
diff changeset
1348 4 16 True True
aa8d59823add Add the 'bool' type and its values 'False' and 'True', as described in
Guido van Rossum <guido@python.org>
parents: 22719
diff changeset
1349 5 32 True True
aa8d59823add Add the 'bool' type and its values 'False' and 'True', as described in
Guido van Rossum <guido@python.org>
parents: 22719
diff changeset
1350 6 64 True True
aa8d59823add Add the 'bool' type and its values 'False' and 'True', as described in
Guido van Rossum <guido@python.org>
parents: 22719
diff changeset
1351 7 128 True True
aa8d59823add Add the 'bool' type and its values 'False' and 'True', as described in
Guido van Rossum <guido@python.org>
parents: 22719
diff changeset
1352 8 256 True True
aa8d59823add Add the 'bool' type and its values 'False' and 'True', as described in
Guido van Rossum <guido@python.org>
parents: 22719
diff changeset
1353 9 512 True True
18352
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1354
18336
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1355 And run an 8-queens solver.
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1356
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1357 >>> q = Queens(8)
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1358 >>> LIMIT = 2
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1359 >>> count = 0
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1360 >>> for row2col in q.solve():
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1361 ... count += 1
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1362 ... if count <= LIMIT:
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1363 ... print "Solution", count
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1364 ... q.printsolution(row2col)
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1365 Solution 1
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1366 +-+-+-+-+-+-+-+-+
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1367 |Q| | | | | | | |
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1368 +-+-+-+-+-+-+-+-+
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1369 | | | | |Q| | | |
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1370 +-+-+-+-+-+-+-+-+
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1371 | | | | | | | |Q|
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1372 +-+-+-+-+-+-+-+-+
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1373 | | | | | |Q| | |
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1374 +-+-+-+-+-+-+-+-+
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1375 | | |Q| | | | | |
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1376 +-+-+-+-+-+-+-+-+
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1377 | | | | | | |Q| |
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1378 +-+-+-+-+-+-+-+-+
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1379 | |Q| | | | | | |
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1380 +-+-+-+-+-+-+-+-+
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1381 | | | |Q| | | | |
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1382 +-+-+-+-+-+-+-+-+
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1383 Solution 2
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1384 +-+-+-+-+-+-+-+-+
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1385 |Q| | | | | | | |
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1386 +-+-+-+-+-+-+-+-+
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1387 | | | | | |Q| | |
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1388 +-+-+-+-+-+-+-+-+
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1389 | | | | | | | |Q|
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1390 +-+-+-+-+-+-+-+-+
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1391 | | |Q| | | | | |
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1392 +-+-+-+-+-+-+-+-+
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1393 | | | | | | |Q| |
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1394 +-+-+-+-+-+-+-+-+
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1395 | | | |Q| | | | |
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1396 +-+-+-+-+-+-+-+-+
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1397 | |Q| | | | | | |
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1398 +-+-+-+-+-+-+-+-+
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1399 | | | | |Q| | | |
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1400 +-+-+-+-+-+-+-+-+
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1401
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1402 >>> print count, "solutions in all."
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1403 92 solutions in all.
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1404
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1405 And run a Knight's Tour on a 10x10 board. Note that there are about
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1406 20,000 solutions even on a 6x6 board, so don't dare run this to exhaustion.
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1407
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1408 >>> k = Knights(10, 10)
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1409 >>> LIMIT = 2
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1410 >>> count = 0
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1411 >>> for x in k.solve():
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1412 ... count += 1
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1413 ... if count <= LIMIT:
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1414 ... print "Solution", count
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1415 ... k.printsolution(x)
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1416 ... else:
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1417 ... break
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1418 Solution 1
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1419 +---+---+---+---+---+---+---+---+---+---+
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1420 | 1| 58| 27| 34| 3| 40| 29| 10| 5| 8|
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1421 +---+---+---+---+---+---+---+---+---+---+
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1422 | 26| 35| 2| 57| 28| 33| 4| 7| 30| 11|
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1423 +---+---+---+---+---+---+---+---+---+---+
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1424 | 59|100| 73| 36| 41| 56| 39| 32| 9| 6|
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1425 +---+---+---+---+---+---+---+---+---+---+
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1426 | 74| 25| 60| 55| 72| 37| 42| 49| 12| 31|
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1427 +---+---+---+---+---+---+---+---+---+---+
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1428 | 61| 86| 99| 76| 63| 52| 47| 38| 43| 50|
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1429 +---+---+---+---+---+---+---+---+---+---+
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1430 | 24| 75| 62| 85| 54| 71| 64| 51| 48| 13|
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1431 +---+---+---+---+---+---+---+---+---+---+
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1432 | 87| 98| 91| 80| 77| 84| 53| 46| 65| 44|
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1433 +---+---+---+---+---+---+---+---+---+---+
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1434 | 90| 23| 88| 95| 70| 79| 68| 83| 14| 17|
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1435 +---+---+---+---+---+---+---+---+---+---+
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1436 | 97| 92| 21| 78| 81| 94| 19| 16| 45| 66|
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1437 +---+---+---+---+---+---+---+---+---+---+
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1438 | 22| 89| 96| 93| 20| 69| 82| 67| 18| 15|
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1439 +---+---+---+---+---+---+---+---+---+---+
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1440 Solution 2
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1441 +---+---+---+---+---+---+---+---+---+---+
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1442 | 1| 58| 27| 34| 3| 40| 29| 10| 5| 8|
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1443 +---+---+---+---+---+---+---+---+---+---+
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1444 | 26| 35| 2| 57| 28| 33| 4| 7| 30| 11|
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1445 +---+---+---+---+---+---+---+---+---+---+
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1446 | 59|100| 73| 36| 41| 56| 39| 32| 9| 6|
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1447 +---+---+---+---+---+---+---+---+---+---+
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1448 | 74| 25| 60| 55| 72| 37| 42| 49| 12| 31|
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1449 +---+---+---+---+---+---+---+---+---+---+
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1450 | 61| 86| 99| 76| 63| 52| 47| 38| 43| 50|
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1451 +---+---+---+---+---+---+---+---+---+---+
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1452 | 24| 75| 62| 85| 54| 71| 64| 51| 48| 13|
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1453 +---+---+---+---+---+---+---+---+---+---+
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1454 | 87| 98| 89| 80| 77| 84| 53| 46| 65| 44|
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1455 +---+---+---+---+---+---+---+---+---+---+
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1456 | 90| 23| 92| 95| 70| 79| 68| 83| 14| 17|
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1457 +---+---+---+---+---+---+---+---+---+---+
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1458 | 97| 88| 21| 78| 81| 94| 19| 16| 45| 66|
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1459 +---+---+---+---+---+---+---+---+---+---+
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1460 | 22| 91| 96| 93| 20| 69| 82| 67| 18| 15|
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1461 +---+---+---+---+---+---+---+---+---+---+
18336
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1462 """
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1463
24719
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1464 weakref_tests = """\
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1465 Generators are weakly referencable:
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1466
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1467 >>> import weakref
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1468 >>> def gen():
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1469 ... yield 'foo!'
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1470 ...
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1471 >>> wr = weakref.ref(gen)
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1472 >>> wr() is gen
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1473 True
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1474 >>> p = weakref.proxy(gen)
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1475
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1476 Generator-iterators are weakly referencable as well:
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1477
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1478 >>> gi = gen()
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1479 >>> wr = weakref.ref(gi)
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1480 >>> wr() is gi
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1481 True
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1482 >>> p = weakref.proxy(gi)
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1483 >>> list(p)
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1484 ['foo!']
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1485
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1486 """
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1487
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1488 coroutine_tests = """\
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1489 Sending a value into a started generator:
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1490
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1491 >>> def f():
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1492 ... print (yield 1)
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1493 ... yield 2
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1494 >>> g = f()
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1495 >>> g.next()
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1496 1
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1497 >>> g.send(42)
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1498 42
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1499 2
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1500
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1501 Sending a value into a new generator produces a TypeError:
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1502
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1503 >>> f().send("foo")
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1504 Traceback (most recent call last):
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1505 ...
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1506 TypeError: can't send non-None value to a just-started generator
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1507
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1508
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1509 Yield by itself yields None:
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1510
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1511 >>> def f(): yield
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1512 >>> list(f())
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1513 [None]
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1514
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1515
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1516
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1517 An obscene abuse of a yield expression within a generator expression:
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1518
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1519 >>> list((yield 21) for i in range(4))
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1520 [21, None, 21, None, 21, None, 21, None]
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1521
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1522 And a more sane, but still weird usage:
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1523
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1524 >>> def f(): list(i for i in [(yield 26)])
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1525 >>> type(f())
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1526 <type 'generator'>
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1527
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1528
39300
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1529 A yield expression with augmented assignment.
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1530
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1531 >>> def coroutine(seq):
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1532 ... count = 0
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1533 ... while count < 200:
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1534 ... count += yield
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1535 ... seq.append(count)
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1536 >>> seq = []
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1537 >>> c = coroutine(seq)
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1538 >>> c.next()
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1539 >>> print seq
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1540 []
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1541 >>> c.send(10)
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1542 >>> print seq
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1543 [10]
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1544 >>> c.send(10)
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1545 >>> print seq
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1546 [10, 20]
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1547 >>> c.send(10)
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1548 >>> print seq
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1549 [10, 20, 30]
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1550
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1551
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1552 Check some syntax errors for yield expressions:
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1553
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1554 >>> f=lambda: (yield 1),(yield 2)
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1555 Traceback (most recent call last):
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1556 ...
39300
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1557 SyntaxError: 'yield' outside function (<doctest test.test_generators.__test__.coroutine[21]>, line 1)
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1558
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1559 >>> def f(): return lambda x=(yield): 1
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1560 Traceback (most recent call last):
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1561 ...
39300
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1562 SyntaxError: 'return' with argument inside generator (<doctest test.test_generators.__test__.coroutine[22]>, line 1)
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1563
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1564 >>> def f(): x = yield = y
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1565 Traceback (most recent call last):
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1566 ...
39300
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1567 SyntaxError: assignment to yield expression not possible (<doctest test.test_generators.__test__.coroutine[23]>, line 1)
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1568
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1569 >>> def f(): (yield bar) = y
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1570 Traceback (most recent call last):
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1571 ...
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1572 SyntaxError: can't assign to yield expression (<doctest test.test_generators.__test__.coroutine[24]>, line 1)
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1573
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1574 >>> def f(): (yield bar) += y
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1575 Traceback (most recent call last):
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1576 ...
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1577 SyntaxError: augmented assignment to yield expression not possible (<doctest test.test_generators.__test__.coroutine[25]>, line 1)
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1578
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1579
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1580 Now check some throw() conditions:
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1581
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1582 >>> def f():
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1583 ... while True:
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1584 ... try:
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1585 ... print (yield)
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1586 ... except ValueError,v:
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1587 ... print "caught ValueError (%s)" % (v),
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1588 >>> import sys
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1589 >>> g = f()
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1590 >>> g.next()
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1591
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1592 >>> g.throw(ValueError) # type only
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1593 caught ValueError ()
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1594
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1595 >>> g.throw(ValueError("xyz")) # value only
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1596 caught ValueError (xyz)
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1597
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1598 >>> g.throw(ValueError, ValueError(1)) # value+matching type
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1599 caught ValueError (1)
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1600
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1601 >>> g.throw(ValueError, TypeError(1)) # mismatched type, rewrapped
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1602 caught ValueError (1)
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1603
37202
f5cd3091d99f Support throw() of string exceptions.
Phillip J. Eby <pje@telecommunity.com>
parents: 36121
diff changeset
1604 >>> g.throw(ValueError, ValueError(1), None) # explicit None traceback
f5cd3091d99f Support throw() of string exceptions.
Phillip J. Eby <pje@telecommunity.com>
parents: 36121
diff changeset
1605 caught ValueError (1)
f5cd3091d99f Support throw() of string exceptions.
Phillip J. Eby <pje@telecommunity.com>
parents: 36121
diff changeset
1606
35320
fa95fe91cdf7 Whitespace normalization (ran reindent.py over the whole tree).
Tim Peters <tim.peters@gmail.com>
parents: 35298
diff changeset
1607 >>> g.throw(ValueError(1), "foo") # bad args
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1608 Traceback (most recent call last):
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1609 ...
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1610 TypeError: instance exception may not have a separate value
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1611
35320
fa95fe91cdf7 Whitespace normalization (ran reindent.py over the whole tree).
Tim Peters <tim.peters@gmail.com>
parents: 35298
diff changeset
1612 >>> g.throw(ValueError, "foo", 23) # bad args
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1613 Traceback (most recent call last):
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1614 ...
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1615 TypeError: throw() third argument must be a traceback object
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1616
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1617 >>> def throw(g,exc):
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1618 ... try:
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1619 ... raise exc
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1620 ... except:
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1621 ... g.throw(*sys.exc_info())
35320
fa95fe91cdf7 Whitespace normalization (ran reindent.py over the whole tree).
Tim Peters <tim.peters@gmail.com>
parents: 35298
diff changeset
1622 >>> throw(g,ValueError) # do it with traceback included
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1623 caught ValueError ()
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1624
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1625 >>> g.send(1)
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1626 1
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1627
35320
fa95fe91cdf7 Whitespace normalization (ran reindent.py over the whole tree).
Tim Peters <tim.peters@gmail.com>
parents: 35298
diff changeset
1628 >>> throw(g,TypeError) # terminate the generator
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1629 Traceback (most recent call last):
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1630 ...
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1631 TypeError
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1632
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1633 >>> print g.gi_frame
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1634 None
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1635
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1636 >>> g.send(2)
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1637 Traceback (most recent call last):
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1638 ...
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1639 StopIteration
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1640
35320
fa95fe91cdf7 Whitespace normalization (ran reindent.py over the whole tree).
Tim Peters <tim.peters@gmail.com>
parents: 35298
diff changeset
1641 >>> g.throw(ValueError,6) # throw on closed generator
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1642 Traceback (most recent call last):
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1643 ...
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1644 ValueError: 6
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1645
35320
fa95fe91cdf7 Whitespace normalization (ran reindent.py over the whole tree).
Tim Peters <tim.peters@gmail.com>
parents: 35298
diff changeset
1646 >>> f().throw(ValueError,7) # throw on just-opened generator
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1647 Traceback (most recent call last):
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1648 ...
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1649 ValueError: 7
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1650
35959
fca7337710fd Improve test coverage. Hope the test_file changes work the same on windows.
Neal Norwitz <nnorwitz@gmail.com>
parents: 35769
diff changeset
1651 >>> f().throw("abc") # throw on just-opened generator
fca7337710fd Improve test coverage. Hope the test_file changes work the same on windows.
Neal Norwitz <nnorwitz@gmail.com>
parents: 35769
diff changeset
1652 Traceback (most recent call last):
fca7337710fd Improve test coverage. Hope the test_file changes work the same on windows.
Neal Norwitz <nnorwitz@gmail.com>
parents: 35769
diff changeset
1653 ...
43335
c5b6ae9440b5 Generators had their throw() method allowing string exceptions. That's a
Brett Cannon <bcannon@gmail.com>
parents: 40950
diff changeset
1654 TypeError: exceptions must be classes, or instances, not str
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1655
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1656 Now let's try closing a generator:
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1657
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1658 >>> def f():
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1659 ... try: yield
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1660 ... except GeneratorExit:
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1661 ... print "exiting"
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1662
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1663 >>> g = f()
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1664 >>> g.next()
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1665 >>> g.close()
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1666 exiting
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1667 >>> g.close() # should be no-op now
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1668
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1669 >>> f().close() # close on just-opened generator should be fine
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1670
35320
fa95fe91cdf7 Whitespace normalization (ran reindent.py over the whole tree).
Tim Peters <tim.peters@gmail.com>
parents: 35298
diff changeset
1671 >>> def f(): yield # an even simpler generator
fa95fe91cdf7 Whitespace normalization (ran reindent.py over the whole tree).
Tim Peters <tim.peters@gmail.com>
parents: 35298
diff changeset
1672 >>> f().close() # close before opening
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1673 >>> g = f()
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1674 >>> g.next()
35320
fa95fe91cdf7 Whitespace normalization (ran reindent.py over the whole tree).
Tim Peters <tim.peters@gmail.com>
parents: 35298
diff changeset
1675 >>> g.close() # close normally
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1676
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1677 And finalization:
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1678
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1679 >>> def f():
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1680 ... try: yield
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1681 ... finally:
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1682 ... print "exiting"
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1683
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1684 >>> g = f()
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1685 >>> g.next()
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1686 >>> del g
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1687 exiting
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1688
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1689
44127
aa6017a2e8f9 Patch #1537 from Chad Austin
Christian Heimes <christian@cheimes.de>
parents: 43335
diff changeset
1690 GeneratorExit is not caught by except Exception:
aa6017a2e8f9 Patch #1537 from Chad Austin
Christian Heimes <christian@cheimes.de>
parents: 43335
diff changeset
1691
aa6017a2e8f9 Patch #1537 from Chad Austin
Christian Heimes <christian@cheimes.de>
parents: 43335
diff changeset
1692 >>> def f():
aa6017a2e8f9 Patch #1537 from Chad Austin
Christian Heimes <christian@cheimes.de>
parents: 43335
diff changeset
1693 ... try: yield
aa6017a2e8f9 Patch #1537 from Chad Austin
Christian Heimes <christian@cheimes.de>
parents: 43335
diff changeset
1694 ... except Exception: print 'except'
aa6017a2e8f9 Patch #1537 from Chad Austin
Christian Heimes <christian@cheimes.de>
parents: 43335
diff changeset
1695 ... finally: print 'finally'
aa6017a2e8f9 Patch #1537 from Chad Austin
Christian Heimes <christian@cheimes.de>
parents: 43335
diff changeset
1696
aa6017a2e8f9 Patch #1537 from Chad Austin
Christian Heimes <christian@cheimes.de>
parents: 43335
diff changeset
1697 >>> g = f()
aa6017a2e8f9 Patch #1537 from Chad Austin
Christian Heimes <christian@cheimes.de>
parents: 43335
diff changeset
1698 >>> g.next()
aa6017a2e8f9 Patch #1537 from Chad Austin
Christian Heimes <christian@cheimes.de>
parents: 43335
diff changeset
1699 >>> del g
aa6017a2e8f9 Patch #1537 from Chad Austin
Christian Heimes <christian@cheimes.de>
parents: 43335
diff changeset
1700 finally
aa6017a2e8f9 Patch #1537 from Chad Austin
Christian Heimes <christian@cheimes.de>
parents: 43335
diff changeset
1701
aa6017a2e8f9 Patch #1537 from Chad Austin
Christian Heimes <christian@cheimes.de>
parents: 43335
diff changeset
1702
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1703 Now let's try some ill-behaved generators:
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1704
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1705 >>> def f():
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1706 ... try: yield
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1707 ... except GeneratorExit:
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1708 ... yield "foo!"
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1709 >>> g = f()
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1710 >>> g.next()
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1711 >>> g.close()
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1712 Traceback (most recent call last):
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1713 ...
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1714 RuntimeError: generator ignored GeneratorExit
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1715 >>> g.close()
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1716
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1717
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1718 Our ill-behaved code should be invoked during GC:
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1719
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1720 >>> import sys, StringIO
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1721 >>> old, sys.stderr = sys.stderr, StringIO.StringIO()
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1722 >>> g = f()
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1723 >>> g.next()
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1724 >>> del g
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1725 >>> sys.stderr.getvalue().startswith(
40950
f3f0c697aa5b When printing an unraisable error, don't print exceptions. before the name.
Neal Norwitz <nnorwitz@gmail.com>
parents: 39300
diff changeset
1726 ... "Exception RuntimeError: 'generator ignored GeneratorExit' in "
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1727 ... )
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1728 True
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1729 >>> sys.stderr = old
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1730
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1731
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1732 And errors thrown during closing should propagate:
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1733
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1734 >>> def f():
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1735 ... try: yield
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1736 ... except GeneratorExit:
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1737 ... raise TypeError("fie!")
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1738 >>> g = f()
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1739 >>> g.next()
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1740 >>> g.close()
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1741 Traceback (most recent call last):
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1742 ...
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1743 TypeError: fie!
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1744
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1745
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1746 Ensure that various yield expression constructs make their
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1747 enclosing function a generator:
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1748
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1749 >>> def f(): x += yield
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1750 >>> type(f())
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1751 <type 'generator'>
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1752
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1753 >>> def f(): x = yield
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1754 >>> type(f())
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1755 <type 'generator'>
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1756
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1757 >>> def f(): lambda x=(yield): 1
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1758 >>> type(f())
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1759 <type 'generator'>
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1760
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1761 >>> def f(): x=(i for i in (yield) if (yield))
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1762 >>> type(f())
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1763 <type 'generator'>
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1764
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1765 >>> def f(d): d[(yield "a")] = d[(yield "b")] = 27
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1766 >>> data = [1,2]
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1767 >>> g = f(data)
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1768 >>> type(g)
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1769 <type 'generator'>
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1770 >>> g.send(None)
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1771 'a'
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1772 >>> data
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1773 [1, 2]
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1774 >>> g.send(0)
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1775 'b'
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1776 >>> data
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1777 [27, 2]
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1778 >>> try: g.send(1)
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1779 ... except StopIteration: pass
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1780 >>> data
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1781 [27, 27]
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1782
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1783 """
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1784
37276
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1785 refleaks_tests = """
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1786 Prior to adding cycle-GC support to itertools.tee, this code would leak
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1787 references. We add it to the standard suite so the routine refleak-tests
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1788 would trigger if it starts being uncleanable again.
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1789
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1790 >>> import itertools
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1791 >>> def leak():
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1792 ... class gen:
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1793 ... def __iter__(self):
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1794 ... return self
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1795 ... def next(self):
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1796 ... return self.item
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1797 ... g = gen()
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1798 ... head, tail = itertools.tee(g)
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1799 ... g.item = head
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1800 ... return head
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1801 >>> it = leak()
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1802
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1803 Make sure to also test the involvement of the tee-internal teedataobject,
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1804 which stores returned items.
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1805
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1806 >>> item = it.next()
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1807
37758
9b78dc07b170 Consolidate 'leak_test1' and 'refleaks_tests', since they both test for the
Thomas Wouters <thomas@python.org>
parents: 37757
diff changeset
1808
9b78dc07b170 Consolidate 'leak_test1' and 'refleaks_tests', since they both test for the
Thomas Wouters <thomas@python.org>
parents: 37757
diff changeset
1809
9b78dc07b170 Consolidate 'leak_test1' and 'refleaks_tests', since they both test for the
Thomas Wouters <thomas@python.org>
parents: 37757
diff changeset
1810 This test leaked at one point due to generator finalization/destruction.
9b78dc07b170 Consolidate 'leak_test1' and 'refleaks_tests', since they both test for the
Thomas Wouters <thomas@python.org>
parents: 37757
diff changeset
1811 It was copied from Lib/test/leakers/test_generator_cycle.py before the file
9b78dc07b170 Consolidate 'leak_test1' and 'refleaks_tests', since they both test for the
Thomas Wouters <thomas@python.org>
parents: 37757
diff changeset
1812 was removed.
9b78dc07b170 Consolidate 'leak_test1' and 'refleaks_tests', since they both test for the
Thomas Wouters <thomas@python.org>
parents: 37757
diff changeset
1813
9b78dc07b170 Consolidate 'leak_test1' and 'refleaks_tests', since they both test for the
Thomas Wouters <thomas@python.org>
parents: 37757
diff changeset
1814 >>> def leak():
9b78dc07b170 Consolidate 'leak_test1' and 'refleaks_tests', since they both test for the
Thomas Wouters <thomas@python.org>
parents: 37757
diff changeset
1815 ... def gen():
9b78dc07b170 Consolidate 'leak_test1' and 'refleaks_tests', since they both test for the
Thomas Wouters <thomas@python.org>
parents: 37757
diff changeset
1816 ... while True:
9b78dc07b170 Consolidate 'leak_test1' and 'refleaks_tests', since they both test for the
Thomas Wouters <thomas@python.org>
parents: 37757
diff changeset
1817 ... yield g
9b78dc07b170 Consolidate 'leak_test1' and 'refleaks_tests', since they both test for the
Thomas Wouters <thomas@python.org>
parents: 37757
diff changeset
1818 ... g = gen()
9b78dc07b170 Consolidate 'leak_test1' and 'refleaks_tests', since they both test for the
Thomas Wouters <thomas@python.org>
parents: 37757
diff changeset
1819
9b78dc07b170 Consolidate 'leak_test1' and 'refleaks_tests', since they both test for the
Thomas Wouters <thomas@python.org>
parents: 37757
diff changeset
1820 >>> leak()
9b78dc07b170 Consolidate 'leak_test1' and 'refleaks_tests', since they both test for the
Thomas Wouters <thomas@python.org>
parents: 37757
diff changeset
1821
9b78dc07b170 Consolidate 'leak_test1' and 'refleaks_tests', since they both test for the
Thomas Wouters <thomas@python.org>
parents: 37757
diff changeset
1822
37761
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1823
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1824 This test isn't really generator related, but rather exception-in-cleanup
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1825 related. The coroutine tests (above) just happen to cause an exception in
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1826 the generator's __del__ (tp_del) method. We can also test for this
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1827 explicitly, without generators. We do have to redirect stderr to avoid
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1828 printing warnings and to doublecheck that we actually tested what we wanted
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1829 to test.
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1830
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1831 >>> import sys, StringIO
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1832 >>> old = sys.stderr
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1833 >>> try:
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1834 ... sys.stderr = StringIO.StringIO()
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1835 ... class Leaker:
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1836 ... def __del__(self):
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1837 ... raise RuntimeError
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1838 ...
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1839 ... l = Leaker()
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1840 ... del l
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1841 ... err = sys.stderr.getvalue().strip()
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1842 ... err.startswith(
40950
f3f0c697aa5b When printing an unraisable error, don't print exceptions. before the name.
Neal Norwitz <nnorwitz@gmail.com>
parents: 39300
diff changeset
1843 ... "Exception RuntimeError: RuntimeError() in <"
37761
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1844 ... )
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1845 ... err.endswith("> ignored")
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1846 ... len(err.splitlines())
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1847 ... finally:
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1848 ... sys.stderr = old
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1849 True
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1850 True
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1851 1
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1852
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1853
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1854
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1855 These refleak tests should perhaps be in a testfile of their own,
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1856 test_generators just happened to be the test that drew these out.
37276
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1857
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1858 """
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1859
18299
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
1860 __test__ = {"tut": tutorial_tests,
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
1861 "pep": pep_tests,
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
1862 "email": email_tests,
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
1863 "fun": fun_tests,
18336
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1864 "syntax": syntax_tests,
24719
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1865 "conjoin": conjoin_tests,
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1866 "weakref": weakref_tests,
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1867 "coroutine": coroutine_tests,
37276
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1868 "refleaks": refleaks_tests,
24719
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1869 }
18249
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
1870
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
1871 # Magic test name that regrtest.py invokes *after* importing this module.
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
1872 # This worms around a bootstrap problem.
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
1873 # Note that doctest and regrtest both look in sys.argv for a "-v" argument,
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
1874 # so this works as expected in both ways of running regrtest.
19817
b7396287cf65 Teach regrtest how to pass on doctest failure msgs. This is done via a
Tim Peters <tim.peters@gmail.com>
parents: 19665
diff changeset
1875 def test_main(verbose=None):
24364
aa0d2d51fbde Get rid of relative imports in all unittests. Now anything that
Barry Warsaw <barry@python.org>
parents: 24263
diff changeset
1876 from test import test_support, test_generators
33309
598050017b5e Removed old "if 0:" block for leak detection; wouldn't work anymore anyway.
Tim Peters <tim.peters@gmail.com>
parents: 33308
diff changeset
1877 test_support.run_doctest(test_generators, verbose)
18249
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
1878
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
1879 # This part isn't needed for regrtest, but for running the test directly.
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
1880 if __name__ == "__main__":
19817
b7396287cf65 Teach regrtest how to pass on doctest failure msgs. This is done via a
Tim Peters <tim.peters@gmail.com>
parents: 19665
diff changeset
1881 test_main(1)