annotate Lib/test/test_generators.py @ 79675:c0a2294de787 2.7

Issue #16199: Backport 2to3 typo fix from 3.2.
author Chris Jerdonek <chris.jerdonek@gmail.com>
date Thu, 11 Oct 2012 16:15:46 -0700
parents 76cf60e2d005
children df9f8feb7444
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 ...>'
50308
93da9f14e5b5 #4748 lambda generators shouldn't return values
Benjamin Peterson <benjamin@python.org>
parents: 47090
diff changeset
931
93da9f14e5b5 #4748 lambda generators shouldn't return values
Benjamin Peterson <benjamin@python.org>
parents: 47090
diff changeset
932 Lambdas shouldn't have their usual return behavior.
93da9f14e5b5 #4748 lambda generators shouldn't return values
Benjamin Peterson <benjamin@python.org>
parents: 47090
diff changeset
933
93da9f14e5b5 #4748 lambda generators shouldn't return values
Benjamin Peterson <benjamin@python.org>
parents: 47090
diff changeset
934 >>> x = lambda: (yield 1)
93da9f14e5b5 #4748 lambda generators shouldn't return values
Benjamin Peterson <benjamin@python.org>
parents: 47090
diff changeset
935 >>> list(x())
93da9f14e5b5 #4748 lambda generators shouldn't return values
Benjamin Peterson <benjamin@python.org>
parents: 47090
diff changeset
936 [1]
93da9f14e5b5 #4748 lambda generators shouldn't return values
Benjamin Peterson <benjamin@python.org>
parents: 47090
diff changeset
937
93da9f14e5b5 #4748 lambda generators shouldn't return values
Benjamin Peterson <benjamin@python.org>
parents: 47090
diff changeset
938 >>> x = lambda: ((yield 1), (yield 2))
93da9f14e5b5 #4748 lambda generators shouldn't return values
Benjamin Peterson <benjamin@python.org>
parents: 47090
diff changeset
939 >>> list(x())
93da9f14e5b5 #4748 lambda generators shouldn't return values
Benjamin Peterson <benjamin@python.org>
parents: 47090
diff changeset
940 [1, 2]
18256
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
941 """
d50d4f81aa4c New tests to provoke SyntaxErrors unique to generators. Minor fiddling
Tim Peters <tim.peters@gmail.com>
parents: 18254
diff changeset
942
18336
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
943 # 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
944 # "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
945 # 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
946 # 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
947 #
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
948 # def g():
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
949 # 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
950 # 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
951 # 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
952 # 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
953 # yield values
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 # 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
956 # 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
957 # 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
958 # 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
959 # 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
960 # 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
961 # 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
962
54800
e1c230f02feb show that this one isn't used
Benjamin Peterson <benjamin@python.org>
parents: 54639
diff changeset
963 def simple_conjoin(gs):
18336
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 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
966
54801
913c9bf98d60 use closures
Benjamin Peterson <benjamin@python.org>
parents: 54800
diff changeset
967 def gen(i):
18336
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
968 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
969 yield values
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
970 else:
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
971 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
972 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
973 yield x
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
974
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
975 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
976 yield x
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
977
18352
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
978 # 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
979 # 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
980 # 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
981 # 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
982 # 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
983
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
984 def conjoin(gs):
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 n = len(gs)
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
987 values = [None] * n
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
988
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
989 # 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
990 # 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
991
54801
913c9bf98d60 use closures
Benjamin Peterson <benjamin@python.org>
parents: 54800
diff changeset
992 def gen(i):
18352
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
993 if i >= n:
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
994 yield values
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 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
997 ip1 = i+1
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
998 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
999 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
1000 yield x
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1001
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1002 else:
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1003 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
1004 yield x
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1005
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1006 # 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
1007 # 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
1008 # gen's use.
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1009
54801
913c9bf98d60 use closures
Benjamin Peterson <benjamin@python.org>
parents: 54800
diff changeset
1010 def _gen3(i):
18352
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1011 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
1012 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
1013 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
1014
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1015 if ip3 >= n:
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1016 # 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
1017 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
1018 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
1019 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
1020 yield values
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1021
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1022 else:
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1023 # 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
1024 # rest.
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1025 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
1026 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
1027 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
1028 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
1029 yield x
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1030
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1031 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
1032 yield x
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1033
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1034 # 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
1035 # 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
1036 # 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
1037 # 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
1038 # 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
1039 # conjoin too.
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1040 # 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
1041 # 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
1042 # 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
1043 # 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
1044
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1045 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
1046 n = len(gs)
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1047 values = [None] * n
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1048 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
1049 _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
1050 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
1051 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
1052 # Descend.
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1053 try:
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1054 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
1055 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
1056 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
1057 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
1058 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
1059 pass
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1060 else:
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1061 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
1062 yield values
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1063
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1064 # 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
1065 i -= 1
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1066 while i >= 0:
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1067 try:
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1068 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
1069 # 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
1070 i += 1
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1071 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
1072 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
1073 # 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
1074 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
1075 else:
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1076 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
1077 break
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1078
18336
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1079 # 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
1080
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1081 class Queens:
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1082 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
1083 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
1084 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
1085
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1086 # 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
1087 # 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
1088 # 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
1089 # 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
1090 # based.
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1091 # 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
1092 # 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
1093
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1094 # 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
1095 # 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
1096 # 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
1097 self.rowgenerators = []
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1098 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
1099 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
1100 (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
1101 (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
1102 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
1103
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1104 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
1105 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
1106 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
1107 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
1108 self.used |= uses
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1109 yield j
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1110 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
1111
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1112 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
1113
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1114 # Generate solutions.
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1115 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
1116 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
1117 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
1118 yield row2col
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1119
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1120 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
1121 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
1122 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
1123 sep = "+" + "-+" * n
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1124 print sep
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1125 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
1126 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
1127 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
1128 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
1129 print sep
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1130
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1131 # 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
1132 # (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
1133 # 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
1134 # 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
1135
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1136 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
1137 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
1138 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
1139
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1140 # 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
1141 # successors.
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1142 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
1143
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1144 # 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
1145 # 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
1146 # 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
1147
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1148 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
1149 # 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
1150 # 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
1151 # 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
1152 # 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
1153 # 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
1154 # 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
1155 # 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
1156 # 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
1157 ne0 = ne1 = 0
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1158 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
1159 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
1160 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
1161 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
1162 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
1163 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
1164 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
1165 ne1 += 1
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1166 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
1167
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1168 # 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
1169
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1170 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
1171 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
1172 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
1173
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1174 # 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
1175 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
1176 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
1177 return
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1178
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1179 # 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
1180 # 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
1181 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
1182 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
1183 self.lastij = corner
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1184 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
1185 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
1186
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1187 # 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
1188 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
1189 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
1190 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
1191 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
1192 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
1193 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
1194 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
1195 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
1196 # 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
1197 # 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
1198 # 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
1199 # 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
1200 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
1201 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
1202 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
1203 self.final = final
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1204
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1205 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
1206 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
1207 self.lastij = this
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1208 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
1209 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
1210 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
1211
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1212 # 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
1213 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
1214 # 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
1215 # 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
1216 candidates = []
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1217 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
1218 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
1219 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
1220 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
1221 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
1222 break
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1223 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
1224 else:
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1225 candidates.sort()
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1226
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1227 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
1228 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
1229 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
1230 self.lastij = i
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1231 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
1232 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
1233
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1234 # 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
1235 # 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
1236 # 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
1237 # 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
1238 # 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
1239 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
1240 # 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
1241 # 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
1242 # 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
1243 # 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
1244 candidates = []
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1245 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
1246 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
1247 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
1248 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
1249 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
1250 break
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1251 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
1252 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
1253 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
1254 else:
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1255 candidates.sort()
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1256
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1257 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
1258 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
1259 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
1260 self.lastij = i
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1261 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
1262 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
1263
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1264 # 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
1265 def last():
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1266 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
1267 yield self.final
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1268
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1269 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
1270 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
1271 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
1272 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
1273 [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
1274 [last]
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1275
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1276 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
1277 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
1278 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
1279 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
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 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
1282 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
1283 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
1284
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1285 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
1286 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
1287 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
1288 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
1289 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
1290
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1291 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
1292 (-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
1293 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
1294 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
1295 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
1296 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
1297 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
1298 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
1299 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
1300
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1301 # Generate solutions.
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1302 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
1303 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
1304 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
1305 yield x
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1306
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1307 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
1308 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
1309 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
1310 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
1311 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
1312
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1313 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
1314 k = 1
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1315 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
1316 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
1317 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
1318 k += 1
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1319
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1320 sep = "+" + ("-" * w + "+") * n
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1321 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
1322 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
1323 row = squares[i]
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1324 print "|" + "|".join(row) + "|"
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1325 print sep
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1326
18336
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1327 conjoin_tests = """
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1328
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1329 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
1330 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
1331
18384
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1332 >>> 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
1333 ... print c
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1334 [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
1335 [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
1336 [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
1337 [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
1338 [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
1339 [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
1340 [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
1341 [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
1342
18352
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1343 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
1344 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
1345 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
1346
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1347 >>> def gencopy(iterator):
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1348 ... 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
1349 ... yield x[:]
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1350
3eda6231e1c2 Derive an industrial-strength conjoin() via cross-recursion loop unrolling,
Tim Peters <tim.peters@gmail.com>
parents: 18336
diff changeset
1351 >>> 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
1352 ... 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
1353 ... 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
1354 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
1355 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
1356 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
1357 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
1358 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
1359 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
1360 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
1361 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
1362 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
1363 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
1364
18336
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1365 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
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 = Queens(8)
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1368 >>> LIMIT = 2
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1369 >>> count = 0
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1370 >>> 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
1371 ... count += 1
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1372 ... 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
1373 ... 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
1374 ... 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
1375 Solution 1
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 | | | | | |Q| | |
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 Solution 2
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 | | |Q| | | | | |
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1402 +-+-+-+-+-+-+-+-+
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1403 | | | | | | |Q| |
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1404 +-+-+-+-+-+-+-+-+
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1405 | | | |Q| | | | |
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1406 +-+-+-+-+-+-+-+-+
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1407 | |Q| | | | | | |
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1408 +-+-+-+-+-+-+-+-+
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1409 | | | | |Q| | | |
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1410 +-+-+-+-+-+-+-+-+
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1411
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1412 >>> 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
1413 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
1414
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1415 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
1416 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
1417
18541
70461f2d2109 Having fun on my own time: quicker flat_conjoin; Knights Tour solver
Tim Peters <tim.peters@gmail.com>
parents: 18526
diff changeset
1418 >>> 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
1419 >>> LIMIT = 2
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1420 >>> count = 0
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1421 >>> 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
1422 ... count += 1
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1423 ... if count <= LIMIT:
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1424 ... print "Solution", count
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1425 ... k.printsolution(x)
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1426 ... else:
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1427 ... break
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1428 Solution 1
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 | 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
1431 +---+---+---+---+---+---+---+---+---+---+
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1432 | 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
1433 +---+---+---+---+---+---+---+---+---+---+
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1434 | 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
1435 +---+---+---+---+---+---+---+---+---+---+
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1436 | 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
1437 +---+---+---+---+---+---+---+---+---+---+
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1438 | 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
1439 +---+---+---+---+---+---+---+---+---+---+
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1440 | 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
1441 +---+---+---+---+---+---+---+---+---+---+
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1442 | 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
1443 +---+---+---+---+---+---+---+---+---+---+
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1444 | 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
1445 +---+---+---+---+---+---+---+---+---+---+
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1446 | 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
1447 +---+---+---+---+---+---+---+---+---+---+
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1448 | 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
1449 +---+---+---+---+---+---+---+---+---+---+
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1450 Solution 2
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 | 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
1453 +---+---+---+---+---+---+---+---+---+---+
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1454 | 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
1455 +---+---+---+---+---+---+---+---+---+---+
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1456 | 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
1457 +---+---+---+---+---+---+---+---+---+---+
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1458 | 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
1459 +---+---+---+---+---+---+---+---+---+---+
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1460 | 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
1461 +---+---+---+---+---+---+---+---+---+---+
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1462 | 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
1463 +---+---+---+---+---+---+---+---+---+---+
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1464 | 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
1465 +---+---+---+---+---+---+---+---+---+---+
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1466 | 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
1467 +---+---+---+---+---+---+---+---+---+---+
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1468 | 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
1469 +---+---+---+---+---+---+---+---+---+---+
95e3947ca3ce Added a non-recursive implementation of conjoin(), and a Knight's Tour
unknown <tools@python.org>
parents: 18355
diff changeset
1470 | 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
1471 +---+---+---+---+---+---+---+---+---+---+
18336
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1472 """
794582fc0623 Added a simple but general backtracking generator (conjoin), and a couple
Tim Peters <tim.peters@gmail.com>
parents: 18333
diff changeset
1473
24719
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1474 weakref_tests = """\
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1475 Generators are weakly referencable:
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1476
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1477 >>> import weakref
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1478 >>> def gen():
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1479 ... yield 'foo!'
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1480 ...
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1481 >>> wr = weakref.ref(gen)
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1482 >>> wr() is gen
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1483 True
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1484 >>> p = weakref.proxy(gen)
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 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
1487
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1488 >>> gi = gen()
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1489 >>> wr = weakref.ref(gi)
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1490 >>> wr() is gi
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1491 True
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1492 >>> p = weakref.proxy(gi)
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1493 >>> list(p)
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1494 ['foo!']
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1495
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1496 """
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1497
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1498 coroutine_tests = """\
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1499 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
1500
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1501 >>> def f():
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1502 ... print (yield 1)
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1503 ... yield 2
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1504 >>> g = f()
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1505 >>> g.next()
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1506 1
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1507 >>> g.send(42)
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1508 42
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1509 2
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 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
1512
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1513 >>> f().send("foo")
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1514 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
1515 ...
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1516 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
1517
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 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
1520
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1521 >>> def f(): yield
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1522 >>> list(f())
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1523 [None]
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1524
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1525
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1526
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1527 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
1528
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1529 >>> 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
1530 [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
1531
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1532 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
1533
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1534 >>> 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
1535 >>> type(f())
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1536 <type 'generator'>
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1537
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1538
39300
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1539 A yield expression with augmented assignment.
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 >>> def coroutine(seq):
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1542 ... count = 0
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1543 ... while count < 200:
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1544 ... count += yield
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1545 ... seq.append(count)
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1546 >>> seq = []
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1547 >>> c = coroutine(seq)
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1548 >>> c.next()
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1549 >>> print seq
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 >>> c.send(10)
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1552 >>> print seq
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1553 [10]
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1554 >>> c.send(10)
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1555 >>> print seq
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1556 [10, 20]
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1557 >>> c.send(10)
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1558 >>> print seq
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1559 [10, 20, 30]
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1560
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1561
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1562 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
1563
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1564 >>> 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
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 ...
52960
5e8c3e7451ff fix since difference formating of SyntaxErrors
Benjamin Peterson <benjamin@python.org>
parents: 50308
diff changeset
1567 File "<doctest test.test_generators.__test__.coroutine[21]>", line 1
5e8c3e7451ff fix since difference formating of SyntaxErrors
Benjamin Peterson <benjamin@python.org>
parents: 50308
diff changeset
1568 SyntaxError: 'yield' outside function
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1569
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1570 >>> 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
1571 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
1572 ...
39300
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1573 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
1574
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1575 >>> 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
1576 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
1577 ...
52960
5e8c3e7451ff fix since difference formating of SyntaxErrors
Benjamin Peterson <benjamin@python.org>
parents: 50308
diff changeset
1578 File "<doctest test.test_generators.__test__.coroutine[23]>", line 1
5e8c3e7451ff fix since difference formating of SyntaxErrors
Benjamin Peterson <benjamin@python.org>
parents: 50308
diff changeset
1579 SyntaxError: assignment to yield expression not possible
39300
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1580
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1581 >>> def f(): (yield bar) = y
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1582 Traceback (most recent call last):
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1583 ...
52960
5e8c3e7451ff fix since difference formating of SyntaxErrors
Benjamin Peterson <benjamin@python.org>
parents: 50308
diff changeset
1584 File "<doctest test.test_generators.__test__.coroutine[24]>", line 1
5e8c3e7451ff fix since difference formating of SyntaxErrors
Benjamin Peterson <benjamin@python.org>
parents: 50308
diff changeset
1585 SyntaxError: can't assign to yield expression
39300
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1586
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1587 >>> def f(): (yield bar) += y
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1588 Traceback (most recent call last):
b745b3fd66a6 Patch #1531113: Fix augmented assignment with yield expressions.
Neal Norwitz <nnorwitz@gmail.com>
parents: 38588
diff changeset
1589 ...
52960
5e8c3e7451ff fix since difference formating of SyntaxErrors
Benjamin Peterson <benjamin@python.org>
parents: 50308
diff changeset
1590 File "<doctest test.test_generators.__test__.coroutine[25]>", line 1
54639
1b8602c38fd0 remove error checks already done in set_context()
Benjamin Peterson <benjamin@python.org>
parents: 52960
diff changeset
1591 SyntaxError: can't assign to yield expression
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1592
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1593
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1594 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
1595
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1596 >>> def f():
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1597 ... while True:
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1598 ... try:
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1599 ... print (yield)
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1600 ... except ValueError,v:
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1601 ... 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
1602 >>> import sys
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1603 >>> g = f()
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1604 >>> g.next()
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1605
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1606 >>> 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
1607 caught ValueError ()
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1608
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1609 >>> 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
1610 caught ValueError (xyz)
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1611
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1612 >>> 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
1613 caught ValueError (1)
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 >>> 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
1616 caught ValueError (1)
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1617
37202
f5cd3091d99f Support throw() of string exceptions.
Phillip J. Eby <pje@telecommunity.com>
parents: 36121
diff changeset
1618 >>> 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
1619 caught ValueError (1)
f5cd3091d99f Support throw() of string exceptions.
Phillip J. Eby <pje@telecommunity.com>
parents: 36121
diff changeset
1620
35320
fa95fe91cdf7 Whitespace normalization (ran reindent.py over the whole tree).
Tim Peters <tim.peters@gmail.com>
parents: 35298
diff changeset
1621 >>> 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
1622 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
1623 ...
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1624 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
1625
35320
fa95fe91cdf7 Whitespace normalization (ran reindent.py over the whole tree).
Tim Peters <tim.peters@gmail.com>
parents: 35298
diff changeset
1626 >>> 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
1627 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
1628 ...
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1629 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
1630
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1631 >>> 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
1632 ... try:
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1633 ... raise exc
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1634 ... except:
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1635 ... 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
1636 >>> 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
1637 caught ValueError ()
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 >>> g.send(1)
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1640 1
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1641
35320
fa95fe91cdf7 Whitespace normalization (ran reindent.py over the whole tree).
Tim Peters <tim.peters@gmail.com>
parents: 35298
diff changeset
1642 >>> 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
1643 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
1644 ...
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1645 TypeError
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1646
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1647 >>> 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
1648 None
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1649
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1650 >>> g.send(2)
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1651 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
1652 ...
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1653 StopIteration
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1654
35320
fa95fe91cdf7 Whitespace normalization (ran reindent.py over the whole tree).
Tim Peters <tim.peters@gmail.com>
parents: 35298
diff changeset
1655 >>> 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
1656 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
1657 ...
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1658 ValueError: 6
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1659
35320
fa95fe91cdf7 Whitespace normalization (ran reindent.py over the whole tree).
Tim Peters <tim.peters@gmail.com>
parents: 35298
diff changeset
1660 >>> 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
1661 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
1662 ...
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1663 ValueError: 7
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1664
35959
fca7337710fd Improve test coverage. Hope the test_file changes work the same on windows.
Neal Norwitz <nnorwitz@gmail.com>
parents: 35769
diff changeset
1665 >>> 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
1666 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
1667 ...
43335
c5b6ae9440b5 Generators had their throw() method allowing string exceptions. That's a
Brett Cannon <bcannon@gmail.com>
parents: 40950
diff changeset
1668 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
1669
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1670 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
1671
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1672 >>> def f():
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1673 ... try: yield
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1674 ... except GeneratorExit:
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1675 ... print "exiting"
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 >>> g = f()
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1678 >>> g.next()
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1679 >>> g.close()
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1680 exiting
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1681 >>> 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
1682
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1683 >>> 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
1684
35320
fa95fe91cdf7 Whitespace normalization (ran reindent.py over the whole tree).
Tim Peters <tim.peters@gmail.com>
parents: 35298
diff changeset
1685 >>> 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
1686 >>> 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
1687 >>> g = f()
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1688 >>> g.next()
35320
fa95fe91cdf7 Whitespace normalization (ran reindent.py over the whole tree).
Tim Peters <tim.peters@gmail.com>
parents: 35298
diff changeset
1689 >>> 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
1690
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1691 And finalization:
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1692
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1693 >>> def f():
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1694 ... try: yield
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1695 ... finally:
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1696 ... print "exiting"
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1697
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1698 >>> g = f()
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1699 >>> g.next()
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1700 >>> del g
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1701 exiting
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1702
58707
76cf60e2d005 normalize exceptions passed to the __exit__ method #7853
Benjamin Peterson <benjamin@python.org>
parents: 54801
diff changeset
1703 >>> class context(object):
76cf60e2d005 normalize exceptions passed to the __exit__ method #7853
Benjamin Peterson <benjamin@python.org>
parents: 54801
diff changeset
1704 ... def __enter__(self): pass
76cf60e2d005 normalize exceptions passed to the __exit__ method #7853
Benjamin Peterson <benjamin@python.org>
parents: 54801
diff changeset
1705 ... def __exit__(self, *args): print 'exiting'
76cf60e2d005 normalize exceptions passed to the __exit__ method #7853
Benjamin Peterson <benjamin@python.org>
parents: 54801
diff changeset
1706 >>> def f():
76cf60e2d005 normalize exceptions passed to the __exit__ method #7853
Benjamin Peterson <benjamin@python.org>
parents: 54801
diff changeset
1707 ... with context():
76cf60e2d005 normalize exceptions passed to the __exit__ method #7853
Benjamin Peterson <benjamin@python.org>
parents: 54801
diff changeset
1708 ... yield
76cf60e2d005 normalize exceptions passed to the __exit__ method #7853
Benjamin Peterson <benjamin@python.org>
parents: 54801
diff changeset
1709 >>> g = f()
76cf60e2d005 normalize exceptions passed to the __exit__ method #7853
Benjamin Peterson <benjamin@python.org>
parents: 54801
diff changeset
1710 >>> g.next()
76cf60e2d005 normalize exceptions passed to the __exit__ method #7853
Benjamin Peterson <benjamin@python.org>
parents: 54801
diff changeset
1711 >>> del g
76cf60e2d005 normalize exceptions passed to the __exit__ method #7853
Benjamin Peterson <benjamin@python.org>
parents: 54801
diff changeset
1712 exiting
76cf60e2d005 normalize exceptions passed to the __exit__ method #7853
Benjamin Peterson <benjamin@python.org>
parents: 54801
diff changeset
1713
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1714
44127
aa6017a2e8f9 Patch #1537 from Chad Austin
Christian Heimes <christian@cheimes.de>
parents: 43335
diff changeset
1715 GeneratorExit is not caught by except Exception:
aa6017a2e8f9 Patch #1537 from Chad Austin
Christian Heimes <christian@cheimes.de>
parents: 43335
diff changeset
1716
aa6017a2e8f9 Patch #1537 from Chad Austin
Christian Heimes <christian@cheimes.de>
parents: 43335
diff changeset
1717 >>> def f():
aa6017a2e8f9 Patch #1537 from Chad Austin
Christian Heimes <christian@cheimes.de>
parents: 43335
diff changeset
1718 ... try: yield
aa6017a2e8f9 Patch #1537 from Chad Austin
Christian Heimes <christian@cheimes.de>
parents: 43335
diff changeset
1719 ... except Exception: print 'except'
aa6017a2e8f9 Patch #1537 from Chad Austin
Christian Heimes <christian@cheimes.de>
parents: 43335
diff changeset
1720 ... finally: print 'finally'
aa6017a2e8f9 Patch #1537 from Chad Austin
Christian Heimes <christian@cheimes.de>
parents: 43335
diff changeset
1721
aa6017a2e8f9 Patch #1537 from Chad Austin
Christian Heimes <christian@cheimes.de>
parents: 43335
diff changeset
1722 >>> g = f()
aa6017a2e8f9 Patch #1537 from Chad Austin
Christian Heimes <christian@cheimes.de>
parents: 43335
diff changeset
1723 >>> g.next()
aa6017a2e8f9 Patch #1537 from Chad Austin
Christian Heimes <christian@cheimes.de>
parents: 43335
diff changeset
1724 >>> del g
aa6017a2e8f9 Patch #1537 from Chad Austin
Christian Heimes <christian@cheimes.de>
parents: 43335
diff changeset
1725 finally
aa6017a2e8f9 Patch #1537 from Chad Austin
Christian Heimes <christian@cheimes.de>
parents: 43335
diff changeset
1726
aa6017a2e8f9 Patch #1537 from Chad Austin
Christian Heimes <christian@cheimes.de>
parents: 43335
diff changeset
1727
35298
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1728 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
1729
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1730 >>> def f():
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1731 ... try: yield
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1732 ... except GeneratorExit:
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1733 ... yield "foo!"
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1734 >>> g = f()
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1735 >>> g.next()
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1736 >>> g.close()
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1737 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
1738 ...
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1739 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
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
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 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
1744
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1745 >>> import sys, StringIO
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1746 >>> 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
1747 >>> g = f()
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1748 >>> g.next()
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1749 >>> del g
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1750 >>> 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
1751 ... "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
1752 ... )
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1753 True
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1754 >>> sys.stderr = old
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1755
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 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
1758
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1759 >>> def f():
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1760 ... try: yield
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1761 ... except GeneratorExit:
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1762 ... raise TypeError("fie!")
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1763 >>> g = f()
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1764 >>> g.next()
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1765 >>> g.close()
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1766 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
1767 ...
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1768 TypeError: fie!
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1769
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1770
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1771 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
1772 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
1773
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1774 >>> 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
1775 >>> type(f())
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1776 <type 'generator'>
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1777
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1778 >>> 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
1779 >>> type(f())
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1780 <type 'generator'>
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1781
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1782 >>> 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
1783 >>> type(f())
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1784 <type 'generator'>
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1785
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1786 >>> 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
1787 >>> type(f())
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1788 <type 'generator'>
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1789
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1790 >>> 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
1791 >>> data = [1,2]
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1792 >>> g = f(data)
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1793 >>> type(g)
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1794 <type 'generator'>
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1795 >>> g.send(None)
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1796 'a'
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1797 >>> data
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1798 [1, 2]
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1799 >>> g.send(0)
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1800 'b'
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1801 >>> data
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1802 [27, 2]
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1803 >>> 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
1804 ... except StopIteration: pass
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1805 >>> data
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1806 [27, 27]
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1807
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1808 """
b2fe5f8fcfdd PEP 342 implementation. Per Guido's comments, the generator throw()
Phillip J. Eby <pje@telecommunity.com>
parents: 33468
diff changeset
1809
37276
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1810 refleaks_tests = """
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1811 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
1812 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
1813 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
1814
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1815 >>> import itertools
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1816 >>> def leak():
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1817 ... class gen:
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1818 ... def __iter__(self):
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1819 ... return self
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1820 ... def next(self):
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1821 ... return self.item
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1822 ... g = gen()
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1823 ... head, tail = itertools.tee(g)
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1824 ... g.item = head
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1825 ... return head
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1826 >>> it = leak()
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1827
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1828 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
1829 which stores returned items.
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1830
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1831 >>> item = it.next()
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1832
37758
9b78dc07b170 Consolidate 'leak_test1' and 'refleaks_tests', since they both test for the
Thomas Wouters <thomas@python.org>
parents: 37757
diff changeset
1833
9b78dc07b170 Consolidate 'leak_test1' and 'refleaks_tests', since they both test for the
Thomas Wouters <thomas@python.org>
parents: 37757
diff changeset
1834
9b78dc07b170 Consolidate 'leak_test1' and 'refleaks_tests', since they both test for the
Thomas Wouters <thomas@python.org>
parents: 37757
diff changeset
1835 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
1836 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
1837 was removed.
9b78dc07b170 Consolidate 'leak_test1' and 'refleaks_tests', since they both test for the
Thomas Wouters <thomas@python.org>
parents: 37757
diff changeset
1838
9b78dc07b170 Consolidate 'leak_test1' and 'refleaks_tests', since they both test for the
Thomas Wouters <thomas@python.org>
parents: 37757
diff changeset
1839 >>> def leak():
9b78dc07b170 Consolidate 'leak_test1' and 'refleaks_tests', since they both test for the
Thomas Wouters <thomas@python.org>
parents: 37757
diff changeset
1840 ... def gen():
9b78dc07b170 Consolidate 'leak_test1' and 'refleaks_tests', since they both test for the
Thomas Wouters <thomas@python.org>
parents: 37757
diff changeset
1841 ... while True:
9b78dc07b170 Consolidate 'leak_test1' and 'refleaks_tests', since they both test for the
Thomas Wouters <thomas@python.org>
parents: 37757
diff changeset
1842 ... yield g
9b78dc07b170 Consolidate 'leak_test1' and 'refleaks_tests', since they both test for the
Thomas Wouters <thomas@python.org>
parents: 37757
diff changeset
1843 ... g = gen()
9b78dc07b170 Consolidate 'leak_test1' and 'refleaks_tests', since they both test for the
Thomas Wouters <thomas@python.org>
parents: 37757
diff changeset
1844
9b78dc07b170 Consolidate 'leak_test1' and 'refleaks_tests', since they both test for the
Thomas Wouters <thomas@python.org>
parents: 37757
diff changeset
1845 >>> leak()
9b78dc07b170 Consolidate 'leak_test1' and 'refleaks_tests', since they both test for the
Thomas Wouters <thomas@python.org>
parents: 37757
diff changeset
1846
9b78dc07b170 Consolidate 'leak_test1' and 'refleaks_tests', since they both test for the
Thomas Wouters <thomas@python.org>
parents: 37757
diff changeset
1847
37761
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1848
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1849 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
1850 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
1851 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
1852 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
1853 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
1854 to test.
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1855
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1856 >>> import sys, StringIO
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1857 >>> old = sys.stderr
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1858 >>> try:
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1859 ... sys.stderr = StringIO.StringIO()
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1860 ... class Leaker:
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1861 ... def __del__(self):
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1862 ... raise RuntimeError
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1863 ...
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1864 ... l = Leaker()
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1865 ... del l
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1866 ... err = sys.stderr.getvalue().strip()
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1867 ... 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
1868 ... "Exception RuntimeError: RuntimeError() in <"
37761
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1869 ... )
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1870 ... err.endswith("> ignored")
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1871 ... len(err.splitlines())
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1872 ... finally:
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1873 ... sys.stderr = old
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1874 True
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1875 True
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1876 1
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1877
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1878
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1879
833f384ebd41 Add missing DECREF to PyErr_WriteUnraisable(). That function reports
Thomas Wouters <thomas@python.org>
parents: 37758
diff changeset
1880 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
1881 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
1882
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1883 """
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1884
18299
68c12d5556df This no longer leaks memory when run in an infinite loop. However,
Tim Peters <tim.peters@gmail.com>
parents: 18293
diff changeset
1885 __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
1886 "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
1887 "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
1888 "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
1889 "syntax": syntax_tests,
24719
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1890 "conjoin": conjoin_tests,
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1891 "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
1892 "coroutine": coroutine_tests,
37276
762e5b8d189d In true regression-test spirit, make sure the
Thomas Wouters <thomas@python.org>
parents: 37202
diff changeset
1893 "refleaks": refleaks_tests,
24719
5c77316b21f7 Add tests for weakref support for generator-iterators.
Fred Drake <fdrake@acm.org>
parents: 24364
diff changeset
1894 }
18249
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
1895
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
1896 # 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
1897 # 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
1898 # 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
1899 # 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
1900 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
1901 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
1902 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
1903
4826a6cdafc4 New std test for generators, initially populated with doctests NeilS put
Tim Peters <tim.peters@gmail.com>
parents:
diff changeset
1904 # 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
1905 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
1906 test_main(1)