Files for 2.1b1 distribution.
[python/dscho.git] / Lib / test / test_scope.py
blob0633b1433f944889d04a5c5de9f66b9a38fdfdc5
1 from __future__ import nested_scopes
3 from test.test_support import verify, TestFailed, check_syntax
5 print "1. simple nesting"
7 def make_adder(x):
8 def adder(y):
9 return x + y
10 return adder
12 inc = make_adder(1)
13 plus10 = make_adder(10)
15 verify(inc(1) == 2)
16 verify(plus10(-2) == 8)
18 print "2. extra nesting"
20 def make_adder2(x):
21 def extra(): # check freevars passing through non-use scopes
22 def adder(y):
23 return x + y
24 return adder
25 return extra()
27 inc = make_adder2(1)
28 plus10 = make_adder2(10)
30 verify(inc(1) == 2)
31 verify(plus10(-2) == 8)
33 print "3. simple nesting + rebinding"
35 def make_adder3(x):
36 def adder(y):
37 return x + y
38 x = x + 1 # check tracking of assignment to x in defining scope
39 return adder
41 inc = make_adder3(0)
42 plus10 = make_adder3(9)
44 verify(inc(1) == 2)
45 verify(plus10(-2) == 8)
47 print "4. nesting with global but no free"
49 def make_adder4(): # XXX add exta level of indirection
50 def nest():
51 def nest():
52 def adder(y):
53 return global_x + y # check that plain old globals work
54 return adder
55 return nest()
56 return nest()
58 global_x = 1
59 adder = make_adder4()
60 verify(adder(1) == 2)
62 global_x = 10
63 verify(adder(-2) == 8)
65 print "5. nesting through class"
67 def make_adder5(x):
68 class Adder:
69 def __call__(self, y):
70 return x + y
71 return Adder()
73 inc = make_adder5(1)
74 plus10 = make_adder5(10)
76 verify(inc(1) == 2)
77 verify(plus10(-2) == 8)
79 print "6. nesting plus free ref to global"
81 def make_adder6(x):
82 global global_nest_x
83 def adder(y):
84 return global_nest_x + y
85 global_nest_x = x
86 return adder
88 inc = make_adder6(1)
89 plus10 = make_adder6(10)
91 verify(inc(1) == 11) # there's only one global
92 verify(plus10(-2) == 8)
94 print "7. nearest enclosing scope"
96 def f(x):
97 def g(y):
98 x = 42 # check that this masks binding in f()
99 def h(z):
100 return x + z
101 return h
102 return g(2)
104 test_func = f(10)
105 verify(test_func(5) == 47)
107 print "8. mixed freevars and cellvars"
109 def identity(x):
110 return x
112 def f(x, y, z):
113 def g(a, b, c):
114 a = a + x # 3
115 def h():
116 # z * (4 + 9)
117 # 3 * 13
118 return identity(z * (b + y))
119 y = c + z # 9
120 return h
121 return g
123 g = f(1, 2, 3)
124 h = g(2, 4, 6)
125 verify(h() == 39)
127 print "9. free variable in method"
129 def test():
130 method_and_var = "var"
131 class Test:
132 def method_and_var(self):
133 return "method"
134 def test(self):
135 return method_and_var
136 def actual_global(self):
137 return str("global")
138 def str(self):
139 return str(self)
140 return Test()
142 t = test()
143 verify(t.test() == "var")
144 verify(t.method_and_var() == "method")
145 verify(t.actual_global() == "global")
147 method_and_var = "var"
148 class Test:
149 # this class is not nested, so the rules are different
150 def method_and_var(self):
151 return "method"
152 def test(self):
153 return method_and_var
154 def actual_global(self):
155 return str("global")
156 def str(self):
157 return str(self)
159 t = Test()
160 verify(t.test() == "var")
161 verify(t.method_and_var() == "method")
162 verify(t.actual_global() == "global")
164 print "10. recursion"
166 def f(x):
167 def fact(n):
168 if n == 0:
169 return 1
170 else:
171 return n * fact(n - 1)
172 if x >= 0:
173 return fact(x)
174 else:
175 raise ValueError, "x must be >= 0"
177 verify(f(6) == 720)
180 print "11. unoptimized namespaces"
182 check_syntax("""from __future__ import nested_scopes
183 def unoptimized_clash1(strip):
184 def f(s):
185 from string import *
186 return strip(s) # ambiguity: free or local
187 return f
188 """)
190 check_syntax("""from __future__ import nested_scopes
191 def unoptimized_clash2():
192 from string import *
193 def f(s):
194 return strip(s) # ambiguity: global or local
195 return f
196 """)
198 check_syntax("""from __future__ import nested_scopes
199 def unoptimized_clash2():
200 from string import *
201 def g():
202 def f(s):
203 return strip(s) # ambiguity: global or local
204 return f
205 """)
207 # XXX could allow this for exec with const argument, but what's the point
208 check_syntax("""from __future__ import nested_scopes
209 def error(y):
210 exec "a = 1"
211 def f(x):
212 return x + y
213 return f
214 """)
216 check_syntax("""from __future__ import nested_scopes
217 def f(x):
218 def g():
219 return x
220 del x # can't del name
221 """)
223 check_syntax("""from __future__ import nested_scopes
224 def f():
225 def g():
226 from string import *
227 return strip # global or local?
228 """)
230 # and verify a few cases that should work
232 def noproblem1():
233 from string import *
234 f = lambda x:x
236 def noproblem2():
237 from string import *
238 def f(x):
239 return x + 1
241 def noproblem3():
242 from string import *
243 def f(x):
244 global y
245 y = x
247 print "12. lambdas"
249 f1 = lambda x: lambda y: x + y
250 inc = f1(1)
251 plus10 = f1(10)
252 verify(inc(1) == 2)
253 verify(plus10(5) == 15)
255 f2 = lambda x: (lambda : lambda y: x + y)()
256 inc = f2(1)
257 plus10 = f2(10)
258 verify(inc(1) == 2)
259 verify(plus10(5) == 15)
261 f3 = lambda x: lambda y: global_x + y
262 global_x = 1
263 inc = f3(None)
264 verify(inc(2) == 3)
266 f8 = lambda x, y, z: lambda a, b, c: lambda : z * (b + y)
267 g = f8(1, 2, 3)
268 h = g(2, 4, 6)
269 verify(h() == 18)
271 print "13. UnboundLocal"
273 def errorInOuter():
274 print y
275 def inner():
276 return y
277 y = 1
279 def errorInInner():
280 def inner():
281 return y
282 inner()
283 y = 1
285 try:
286 errorInOuter()
287 except UnboundLocalError:
288 pass
289 else:
290 raise TestFailed
292 try:
293 errorInInner()
294 except UnboundLocalError:
295 pass
296 else:
297 raise TestFailed
299 print "14. complex definitions"
301 def makeReturner(*lst):
302 def returner():
303 return lst
304 return returner
306 verify(makeReturner(1,2,3)() == (1,2,3))
308 def makeReturner2(**kwargs):
309 def returner():
310 return kwargs
311 return returner
313 verify(makeReturner2(a=11)()['a'] == 11)
315 def makeAddPair((a, b)):
316 def addPair((c, d)):
317 return (a + c, b + d)
318 return addPair
320 verify(makeAddPair((1, 2))((100, 200)) == (101,202))
322 print "15. scope of global statements"
323 # Examples posted by Samuele Pedroni to python-dev on 3/1/2001
326 x = 7
327 def f():
328 x = 1
329 def g():
330 global x
331 def i():
332 def h():
333 return x
334 return h()
335 return i()
336 return g()
337 verify(f() == 7)
338 verify(x == 7)
340 # II
341 x = 7
342 def f():
343 x = 1
344 def g():
345 x = 2
346 def i():
347 def h():
348 return x
349 return h()
350 return i()
351 return g()
352 verify(f() == 2)
353 verify(x == 7)
355 # III
356 x = 7
357 def f():
358 x = 1
359 def g():
360 global x
361 x = 2
362 def i():
363 def h():
364 return x
365 return h()
366 return i()
367 return g()
368 verify(f() == 2)
369 verify(x == 2)
371 # IV
372 x = 7
373 def f():
374 x = 3
375 def g():
376 global x
377 x = 2
378 def i():
379 def h():
380 return x
381 return h()
382 return i()
383 return g()
384 verify(f() == 2)
385 verify(x == 2)