PyXR

c:\python24\lib \ test \ test_scope.py



0001 from test.test_support import verify, TestFailed, check_syntax
0002 
0003 import warnings
0004 warnings.filterwarnings("ignore", r"import \*", SyntaxWarning, "<string>")
0005 
0006 print "1. simple nesting"
0007 
0008 def make_adder(x):
0009     def adder(y):
0010         return x + y
0011     return adder
0012 
0013 inc = make_adder(1)
0014 plus10 = make_adder(10)
0015 
0016 verify(inc(1) == 2)
0017 verify(plus10(-2) == 8)
0018 
0019 print "2. extra nesting"
0020 
0021 def make_adder2(x):
0022     def extra(): # check freevars passing through non-use scopes
0023         def adder(y):
0024             return x + y
0025         return adder
0026     return extra()
0027 
0028 inc = make_adder2(1)
0029 plus10 = make_adder2(10)
0030 
0031 verify(inc(1) == 2)
0032 verify(plus10(-2) == 8)
0033 
0034 print "3. simple nesting + rebinding"
0035 
0036 def make_adder3(x):
0037     def adder(y):
0038         return x + y
0039     x = x + 1 # check tracking of assignment to x in defining scope
0040     return adder
0041 
0042 inc = make_adder3(0)
0043 plus10 = make_adder3(9)
0044 
0045 verify(inc(1) == 2)
0046 verify(plus10(-2) == 8)
0047 
0048 print "4. nesting with global but no free"
0049 
0050 def make_adder4(): # XXX add exta level of indirection
0051     def nest():
0052         def nest():
0053             def adder(y):
0054                 return global_x + y # check that plain old globals work
0055             return adder
0056         return nest()
0057     return nest()
0058 
0059 global_x = 1
0060 adder = make_adder4()
0061 verify(adder(1) == 2)
0062 
0063 global_x = 10
0064 verify(adder(-2) == 8)
0065 
0066 print "5. nesting through class"
0067 
0068 def make_adder5(x):
0069     class Adder:
0070         def __call__(self, y):
0071             return x + y
0072     return Adder()
0073 
0074 inc = make_adder5(1)
0075 plus10 = make_adder5(10)
0076 
0077 verify(inc(1) == 2)
0078 verify(plus10(-2) == 8)
0079 
0080 print "6. nesting plus free ref to global"
0081 
0082 def make_adder6(x):
0083     global global_nest_x
0084     def adder(y):
0085         return global_nest_x + y
0086     global_nest_x = x
0087     return adder
0088 
0089 inc = make_adder6(1)
0090 plus10 = make_adder6(10)
0091 
0092 verify(inc(1) == 11) # there's only one global
0093 verify(plus10(-2) == 8)
0094 
0095 print "7. nearest enclosing scope"
0096 
0097 def f(x):
0098     def g(y):
0099         x = 42 # check that this masks binding in f()
0100         def h(z):
0101             return x + z
0102         return h
0103     return g(2)
0104 
0105 test_func = f(10)
0106 verify(test_func(5) == 47)
0107 
0108 print "8. mixed freevars and cellvars"
0109 
0110 def identity(x):
0111     return x
0112 
0113 def f(x, y, z):
0114     def g(a, b, c):
0115         a = a + x # 3
0116         def h():
0117             # z * (4 + 9)
0118             # 3 * 13
0119             return identity(z * (b + y))
0120         y = c + z # 9
0121         return h
0122     return g
0123 
0124 g = f(1, 2, 3)
0125 h = g(2, 4, 6)
0126 verify(h() == 39)
0127 
0128 print "9. free variable in method"
0129 
0130 def test():
0131     method_and_var = "var"
0132     class Test:
0133         def method_and_var(self):
0134             return "method"
0135         def test(self):
0136             return method_and_var
0137         def actual_global(self):
0138             return str("global")
0139         def str(self):
0140             return str(self)
0141     return Test()
0142 
0143 t = test()
0144 verify(t.test() == "var")
0145 verify(t.method_and_var() == "method")
0146 verify(t.actual_global() == "global")
0147 
0148 method_and_var = "var"
0149 class Test:
0150     # this class is not nested, so the rules are different
0151     def method_and_var(self):
0152         return "method"
0153     def test(self):
0154         return method_and_var
0155     def actual_global(self):
0156         return str("global")
0157     def str(self):
0158         return str(self)
0159 
0160 t = Test()
0161 verify(t.test() == "var")
0162 verify(t.method_and_var() == "method")
0163 verify(t.actual_global() == "global")
0164 
0165 print "10. recursion"
0166 
0167 def f(x):
0168     def fact(n):
0169         if n == 0:
0170             return 1
0171         else:
0172             return n * fact(n - 1)
0173     if x >= 0:
0174         return fact(x)
0175     else:
0176         raise ValueError, "x must be >= 0"
0177 
0178 verify(f(6) == 720)
0179 
0180 
0181 print "11. unoptimized namespaces"
0182 
0183 check_syntax("""\
0184 def unoptimized_clash1(strip):
0185     def f(s):
0186         from string import *
0187         return strip(s) # ambiguity: free or local
0188     return f
0189 """)
0190 
0191 check_syntax("""\
0192 def unoptimized_clash2():
0193     from string import *
0194     def f(s):
0195         return strip(s) # ambiguity: global or local
0196     return f
0197 """)
0198 
0199 check_syntax("""\
0200 def unoptimized_clash2():
0201     from string import *
0202     def g():
0203         def f(s):
0204             return strip(s) # ambiguity: global or local
0205         return f
0206 """)
0207 
0208 # XXX could allow this for exec with const argument, but what's the point
0209 check_syntax("""\
0210 def error(y):
0211     exec "a = 1"
0212     def f(x):
0213         return x + y
0214     return f
0215 """)
0216 
0217 check_syntax("""\
0218 def f(x):
0219     def g():
0220         return x
0221     del x # can't del name
0222 """)
0223 
0224 check_syntax("""\
0225 def f():
0226     def g():
0227          from string import *
0228          return strip # global or local?
0229 """)
0230 
0231 # and verify a few cases that should work
0232 
0233 exec """
0234 def noproblem1():
0235     from string import *
0236     f = lambda x:x
0237 
0238 def noproblem2():
0239     from string import *
0240     def f(x):
0241         return x + 1
0242 
0243 def noproblem3():
0244     from string import *
0245     def f(x):
0246         global y
0247         y = x
0248 """
0249 
0250 print "12. lambdas"
0251 
0252 f1 = lambda x: lambda y: x + y
0253 inc = f1(1)
0254 plus10 = f1(10)
0255 verify(inc(1) == 2)
0256 verify(plus10(5) == 15)
0257 
0258 f2 = lambda x: (lambda : lambda y: x + y)()
0259 inc = f2(1)
0260 plus10 = f2(10)
0261 verify(inc(1) == 2)
0262 verify(plus10(5) == 15)
0263 
0264 f3 = lambda x: lambda y: global_x + y
0265 global_x = 1
0266 inc = f3(None)
0267 verify(inc(2) == 3)
0268 
0269 f8 = lambda x, y, z: lambda a, b, c: lambda : z * (b + y)
0270 g = f8(1, 2, 3)
0271 h = g(2, 4, 6)
0272 verify(h() == 18)
0273 
0274 print "13. UnboundLocal"
0275 
0276 def errorInOuter():
0277     print y
0278     def inner():
0279         return y
0280     y = 1
0281 
0282 def errorInInner():
0283     def inner():
0284         return y
0285     inner()
0286     y = 1
0287 
0288 try:
0289     errorInOuter()
0290 except UnboundLocalError:
0291     pass
0292 else:
0293     raise TestFailed
0294 
0295 try:
0296     errorInInner()
0297 except NameError:
0298     pass
0299 else:
0300     raise TestFailed
0301 
0302 print "14. complex definitions"
0303 
0304 def makeReturner(*lst):
0305     def returner():
0306         return lst
0307     return returner
0308 
0309 verify(makeReturner(1,2,3)() == (1,2,3))
0310 
0311 def makeReturner2(**kwargs):
0312     def returner():
0313         return kwargs
0314     return returner
0315 
0316 verify(makeReturner2(a=11)()['a'] == 11)
0317 
0318 def makeAddPair((a, b)):
0319     def addPair((c, d)):
0320         return (a + c, b + d)
0321     return addPair
0322 
0323 verify(makeAddPair((1, 2))((100, 200)) == (101,202))
0324 
0325 print "15. scope of global statements"
0326 # Examples posted by Samuele Pedroni to python-dev on 3/1/2001
0327 
0328 # I
0329 x = 7
0330 def f():
0331     x = 1
0332     def g():
0333         global x
0334         def i():
0335             def h():
0336                 return x
0337             return h()
0338         return i()
0339     return g()
0340 verify(f() == 7)
0341 verify(x == 7)
0342 
0343 # II
0344 x = 7
0345 def f():
0346     x = 1
0347     def g():
0348         x = 2
0349         def i():
0350             def h():
0351                 return x
0352             return h()
0353         return i()
0354     return g()
0355 verify(f() == 2)
0356 verify(x == 7)
0357 
0358 # III
0359 x = 7
0360 def f():
0361     x = 1
0362     def g():
0363         global x
0364         x = 2
0365         def i():
0366             def h():
0367                 return x
0368             return h()
0369         return i()
0370     return g()
0371 verify(f() == 2)
0372 verify(x == 2)
0373 
0374 # IV
0375 x = 7
0376 def f():
0377     x = 3
0378     def g():
0379         global x
0380         x = 2
0381         def i():
0382             def h():
0383                 return x
0384             return h()
0385         return i()
0386     return g()
0387 verify(f() == 2)
0388 verify(x == 2)
0389 
0390 print "16. check leaks"
0391 
0392 class Foo:
0393     count = 0
0394 
0395     def __init__(self):
0396         Foo.count += 1
0397 
0398     def __del__(self):
0399         Foo.count -= 1
0400 
0401 def f1():
0402     x = Foo()
0403     def f2():
0404         return x
0405     f2()
0406 
0407 for i in range(100):
0408     f1()
0409 
0410 verify(Foo.count == 0)
0411 
0412 print "17. class and global"
0413 
0414 def test(x):
0415     class Foo:
0416         global x
0417         def __call__(self, y):
0418             return x + y
0419     return Foo()
0420 
0421 x = 0
0422 verify(test(6)(2) == 8)
0423 x = -1
0424 verify(test(3)(2) == 5)
0425 
0426 print "18. verify that locals() works"
0427 
0428 def f(x):
0429     def g(y):
0430         def h(z):
0431             return y + z
0432         w = x + y
0433         y += 3
0434         return locals()
0435     return g
0436 
0437 d = f(2)(4)
0438 verify(d.has_key('h'))
0439 del d['h']
0440 verify(d == {'x': 2, 'y': 7, 'w': 6})
0441 
0442 print "19. var is bound and free in class"
0443 
0444 def f(x):
0445     class C:
0446         def m(self):
0447             return x
0448         a = x
0449     return C
0450 
0451 inst = f(3)()
0452 verify(inst.a == inst.m())
0453 
0454 print "20. interaction with trace function"
0455 
0456 import sys
0457 def tracer(a,b,c):
0458     return tracer
0459 
0460 def adaptgetter(name, klass, getter):
0461     kind, des = getter
0462     if kind == 1:       # AV happens when stepping from this line to next
0463         if des == "":
0464             des = "_%s__%s" % (klass.__name__, name)
0465         return lambda obj: getattr(obj, des)
0466 
0467 class TestClass:
0468     pass
0469 
0470 sys.settrace(tracer)
0471 adaptgetter("foo", TestClass, (1, ""))
0472 sys.settrace(None)
0473 
0474 try: sys.settrace()
0475 except TypeError: pass
0476 else: raise TestFailed, 'sys.settrace() did not raise TypeError'
0477 
0478 print "20. eval and exec with free variables"
0479 
0480 def f(x):
0481     return lambda: x + 1
0482 
0483 g = f(3)
0484 try:
0485     eval(g.func_code)
0486 except TypeError:
0487     pass
0488 else:
0489     print "eval() should have failed, because code contained free vars"
0490 
0491 try:
0492     exec g.func_code
0493 except TypeError:
0494     pass
0495 else:
0496     print "exec should have failed, because code contained free vars"
0497 
0498 print "21. list comprehension with local variables"
0499 
0500 try:
0501     print bad
0502 except NameError:
0503     pass
0504 else:
0505     print "bad should not be defined"
0506 
0507 def x():
0508     [bad for s in 'a b' for bad in s.split()]
0509 
0510 x()
0511 try:
0512     print bad
0513 except NameError:
0514     pass
0515 
0516 print "22. eval with free variables"
0517 
0518 def f(x):
0519     def g():
0520         x
0521         eval("x + 1")
0522     return g
0523 
0524 f(4)()
0525 

Generated by PyXR 0.9.4
SourceForge.net Logo