Exceptions raised during renaming in rotating file handlers are now passed to handleE...
[python.git] / Lib / test / test_scope.py
blobf37254c9df9533a29a35ae8310b2ebaf794a8011
1 from test.test_support import verify, TestFailed, check_syntax, vereq
3 import warnings
4 warnings.filterwarnings("ignore", r"import \*", SyntaxWarning, "<string>")
6 print "1. simple nesting"
8 def make_adder(x):
9 def adder(y):
10 return x + y
11 return adder
13 inc = make_adder(1)
14 plus10 = make_adder(10)
16 vereq(inc(1), 2)
17 vereq(plus10(-2), 8)
19 print "2. extra nesting"
21 def make_adder2(x):
22 def extra(): # check freevars passing through non-use scopes
23 def adder(y):
24 return x + y
25 return adder
26 return extra()
28 inc = make_adder2(1)
29 plus10 = make_adder2(10)
31 vereq(inc(1), 2)
32 vereq(plus10(-2), 8)
34 print "3. simple nesting + rebinding"
36 def make_adder3(x):
37 def adder(y):
38 return x + y
39 x = x + 1 # check tracking of assignment to x in defining scope
40 return adder
42 inc = make_adder3(0)
43 plus10 = make_adder3(9)
45 vereq(inc(1), 2)
46 vereq(plus10(-2), 8)
48 print "4. nesting with global but no free"
50 def make_adder4(): # XXX add exta level of indirection
51 def nest():
52 def nest():
53 def adder(y):
54 return global_x + y # check that plain old globals work
55 return adder
56 return nest()
57 return nest()
59 global_x = 1
60 adder = make_adder4()
61 vereq(adder(1), 2)
63 global_x = 10
64 vereq(adder(-2), 8)
66 print "5. nesting through class"
68 def make_adder5(x):
69 class Adder:
70 def __call__(self, y):
71 return x + y
72 return Adder()
74 inc = make_adder5(1)
75 plus10 = make_adder5(10)
77 vereq(inc(1), 2)
78 vereq(plus10(-2), 8)
80 print "6. nesting plus free ref to global"
82 def make_adder6(x):
83 global global_nest_x
84 def adder(y):
85 return global_nest_x + y
86 global_nest_x = x
87 return adder
89 inc = make_adder6(1)
90 plus10 = make_adder6(10)
92 vereq(inc(1), 11) # there's only one global
93 vereq(plus10(-2), 8)
95 print "7. nearest enclosing scope"
97 def f(x):
98 def g(y):
99 x = 42 # check that this masks binding in f()
100 def h(z):
101 return x + z
102 return h
103 return g(2)
105 test_func = f(10)
106 vereq(test_func(5), 47)
108 print "8. mixed freevars and cellvars"
110 def identity(x):
111 return x
113 def f(x, y, z):
114 def g(a, b, c):
115 a = a + x # 3
116 def h():
117 # z * (4 + 9)
118 # 3 * 13
119 return identity(z * (b + y))
120 y = c + z # 9
121 return h
122 return g
124 g = f(1, 2, 3)
125 h = g(2, 4, 6)
126 vereq(h(), 39)
128 print "9. free variable in method"
130 def test():
131 method_and_var = "var"
132 class Test:
133 def method_and_var(self):
134 return "method"
135 def test(self):
136 return method_and_var
137 def actual_global(self):
138 return str("global")
139 def str(self):
140 return str(self)
141 return Test()
143 t = test()
144 vereq(t.test(), "var")
145 vereq(t.method_and_var(), "method")
146 vereq(t.actual_global(), "global")
148 method_and_var = "var"
149 class Test:
150 # this class is not nested, so the rules are different
151 def method_and_var(self):
152 return "method"
153 def test(self):
154 return method_and_var
155 def actual_global(self):
156 return str("global")
157 def str(self):
158 return str(self)
160 t = Test()
161 vereq(t.test(), "var")
162 vereq(t.method_and_var(), "method")
163 vereq(t.actual_global(), "global")
165 print "10. recursion"
167 def f(x):
168 def fact(n):
169 if n == 0:
170 return 1
171 else:
172 return n * fact(n - 1)
173 if x >= 0:
174 return fact(x)
175 else:
176 raise ValueError, "x must be >= 0"
178 vereq(f(6), 720)
181 print "11. unoptimized namespaces"
183 check_syntax("""\
184 def unoptimized_clash1(strip):
185 def f(s):
186 from string import *
187 return strip(s) # ambiguity: free or local
188 return f
189 """)
191 check_syntax("""\
192 def unoptimized_clash2():
193 from string import *
194 def f(s):
195 return strip(s) # ambiguity: global or local
196 return f
197 """)
199 check_syntax("""\
200 def unoptimized_clash2():
201 from string import *
202 def g():
203 def f(s):
204 return strip(s) # ambiguity: global or local
205 return f
206 """)
208 # XXX could allow this for exec with const argument, but what's the point
209 check_syntax("""\
210 def error(y):
211 exec "a = 1"
212 def f(x):
213 return x + y
214 return f
215 """)
217 check_syntax("""\
218 def f(x):
219 def g():
220 return x
221 del x # can't del name
222 """)
224 check_syntax("""\
225 def f():
226 def g():
227 from string import *
228 return strip # global or local?
229 """)
231 # and verify a few cases that should work
233 exec """
234 def noproblem1():
235 from string import *
236 f = lambda x:x
238 def noproblem2():
239 from string import *
240 def f(x):
241 return x + 1
243 def noproblem3():
244 from string import *
245 def f(x):
246 global y
247 y = x
250 print "12. lambdas"
252 f1 = lambda x: lambda y: x + y
253 inc = f1(1)
254 plus10 = f1(10)
255 vereq(inc(1), 2)
256 vereq(plus10(5), 15)
258 f2 = lambda x: (lambda : lambda y: x + y)()
259 inc = f2(1)
260 plus10 = f2(10)
261 vereq(inc(1), 2)
262 vereq(plus10(5), 15)
264 f3 = lambda x: lambda y: global_x + y
265 global_x = 1
266 inc = f3(None)
267 vereq(inc(2), 3)
269 f8 = lambda x, y, z: lambda a, b, c: lambda : z * (b + y)
270 g = f8(1, 2, 3)
271 h = g(2, 4, 6)
272 vereq(h(), 18)
274 print "13. UnboundLocal"
276 def errorInOuter():
277 print y
278 def inner():
279 return y
280 y = 1
282 def errorInInner():
283 def inner():
284 return y
285 inner()
286 y = 1
288 try:
289 errorInOuter()
290 except UnboundLocalError:
291 pass
292 else:
293 raise TestFailed
295 try:
296 errorInInner()
297 except NameError:
298 pass
299 else:
300 raise TestFailed
302 print "14. complex definitions"
304 def makeReturner(*lst):
305 def returner():
306 return lst
307 return returner
309 vereq(makeReturner(1,2,3)(), (1,2,3))
311 def makeReturner2(**kwargs):
312 def returner():
313 return kwargs
314 return returner
316 vereq(makeReturner2(a=11)()['a'], 11)
318 def makeAddPair((a, b)):
319 def addPair((c, d)):
320 return (a + c, b + d)
321 return addPair
323 vereq(makeAddPair((1, 2))((100, 200)), (101,202))
325 print "15. scope of global statements"
326 # Examples posted by Samuele Pedroni to python-dev on 3/1/2001
329 x = 7
330 def f():
331 x = 1
332 def g():
333 global x
334 def i():
335 def h():
336 return x
337 return h()
338 return i()
339 return g()
340 vereq(f(), 7)
341 vereq(x, 7)
343 # II
344 x = 7
345 def f():
346 x = 1
347 def g():
348 x = 2
349 def i():
350 def h():
351 return x
352 return h()
353 return i()
354 return g()
355 vereq(f(), 2)
356 vereq(x, 7)
358 # III
359 x = 7
360 def f():
361 x = 1
362 def g():
363 global x
364 x = 2
365 def i():
366 def h():
367 return x
368 return h()
369 return i()
370 return g()
371 vereq(f(), 2)
372 vereq(x, 2)
374 # IV
375 x = 7
376 def f():
377 x = 3
378 def g():
379 global x
380 x = 2
381 def i():
382 def h():
383 return x
384 return h()
385 return i()
386 return g()
387 vereq(f(), 2)
388 vereq(x, 2)
390 # XXX what about global statements in class blocks?
391 # do they affect methods?
393 x = 12
394 class Global:
395 global x
396 x = 13
397 def set(self, val):
398 x = val
399 def get(self):
400 return x
402 g = Global()
403 vereq(g.get(), 13)
404 g.set(15)
405 vereq(g.get(), 13)
407 print "16. check leaks"
409 class Foo:
410 count = 0
412 def __init__(self):
413 Foo.count += 1
415 def __del__(self):
416 Foo.count -= 1
418 def f1():
419 x = Foo()
420 def f2():
421 return x
422 f2()
424 for i in range(100):
425 f1()
427 vereq(Foo.count, 0)
429 print "17. class and global"
431 def test(x):
432 class Foo:
433 global x
434 def __call__(self, y):
435 return x + y
436 return Foo()
438 x = 0
439 vereq(test(6)(2), 8)
440 x = -1
441 vereq(test(3)(2), 5)
443 looked_up_by_load_name = False
444 class X:
445 # Implicit globals inside classes are be looked up by LOAD_NAME, not
446 # LOAD_GLOBAL.
447 locals()['looked_up_by_load_name'] = True
448 passed = looked_up_by_load_name
450 verify(X.passed)
452 print "18. verify that locals() works"
454 def f(x):
455 def g(y):
456 def h(z):
457 return y + z
458 w = x + y
459 y += 3
460 return locals()
461 return g
463 d = f(2)(4)
464 verify(d.has_key('h'))
465 del d['h']
466 vereq(d, {'x': 2, 'y': 7, 'w': 6})
468 print "19. var is bound and free in class"
470 def f(x):
471 class C:
472 def m(self):
473 return x
474 a = x
475 return C
477 inst = f(3)()
478 vereq(inst.a, inst.m())
480 print "20. interaction with trace function"
482 import sys
483 def tracer(a,b,c):
484 return tracer
486 def adaptgetter(name, klass, getter):
487 kind, des = getter
488 if kind == 1: # AV happens when stepping from this line to next
489 if des == "":
490 des = "_%s__%s" % (klass.__name__, name)
491 return lambda obj: getattr(obj, des)
493 class TestClass:
494 pass
496 sys.settrace(tracer)
497 adaptgetter("foo", TestClass, (1, ""))
498 sys.settrace(None)
500 try: sys.settrace()
501 except TypeError: pass
502 else: raise TestFailed, 'sys.settrace() did not raise TypeError'
504 print "20. eval and exec with free variables"
506 def f(x):
507 return lambda: x + 1
509 g = f(3)
510 try:
511 eval(g.func_code)
512 except TypeError:
513 pass
514 else:
515 print "eval() should have failed, because code contained free vars"
517 try:
518 exec g.func_code
519 except TypeError:
520 pass
521 else:
522 print "exec should have failed, because code contained free vars"
524 print "21. list comprehension with local variables"
526 try:
527 print bad
528 except NameError:
529 pass
530 else:
531 print "bad should not be defined"
533 def x():
534 [bad for s in 'a b' for bad in s.split()]
537 try:
538 print bad
539 except NameError:
540 pass
542 print "22. eval with free variables"
544 def f(x):
545 def g():
547 eval("x + 1")
548 return g
550 f(4)()