symbian-qemu-0.9.1-12/python-2.6.1/Lib/test/test_scope.py
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 import unittest
       
     2 from test.test_support import check_syntax_error, run_unittest
       
     3 
       
     4 import warnings
       
     5 warnings.filterwarnings("ignore", r"import \*", SyntaxWarning, "<test string>")
       
     6 warnings.filterwarnings("ignore", r"import \*", SyntaxWarning, "<string>")
       
     7 
       
     8 class ScopeTests(unittest.TestCase):
       
     9 
       
    10     def testSimpleNesting(self):
       
    11 
       
    12         def make_adder(x):
       
    13             def adder(y):
       
    14                 return x + y
       
    15             return adder
       
    16 
       
    17         inc = make_adder(1)
       
    18         plus10 = make_adder(10)
       
    19 
       
    20         self.assertEqual(inc(1), 2)
       
    21         self.assertEqual(plus10(-2), 8)
       
    22 
       
    23     def testExtraNesting(self):
       
    24 
       
    25         def make_adder2(x):
       
    26             def extra(): # check freevars passing through non-use scopes
       
    27                 def adder(y):
       
    28                     return x + y
       
    29                 return adder
       
    30             return extra()
       
    31 
       
    32         inc = make_adder2(1)
       
    33         plus10 = make_adder2(10)
       
    34 
       
    35         self.assertEqual(inc(1), 2)
       
    36         self.assertEqual(plus10(-2), 8)
       
    37 
       
    38     def testSimpleAndRebinding(self):
       
    39 
       
    40         def make_adder3(x):
       
    41             def adder(y):
       
    42                 return x + y
       
    43             x = x + 1 # check tracking of assignment to x in defining scope
       
    44             return adder
       
    45 
       
    46         inc = make_adder3(0)
       
    47         plus10 = make_adder3(9)
       
    48 
       
    49         self.assertEqual(inc(1), 2)
       
    50         self.assertEqual(plus10(-2), 8)
       
    51 
       
    52     def testNestingGlobalNoFree(self):
       
    53 
       
    54         def make_adder4(): # XXX add exta level of indirection
       
    55             def nest():
       
    56                 def nest():
       
    57                     def adder(y):
       
    58                         return global_x + y # check that plain old globals work
       
    59                     return adder
       
    60                 return nest()
       
    61             return nest()
       
    62 
       
    63         global_x = 1
       
    64         adder = make_adder4()
       
    65         self.assertEqual(adder(1), 2)
       
    66 
       
    67         global_x = 10
       
    68         self.assertEqual(adder(-2), 8)
       
    69 
       
    70     def testNestingThroughClass(self):
       
    71 
       
    72         def make_adder5(x):
       
    73             class Adder:
       
    74                 def __call__(self, y):
       
    75                     return x + y
       
    76             return Adder()
       
    77 
       
    78         inc = make_adder5(1)
       
    79         plus10 = make_adder5(10)
       
    80 
       
    81         self.assertEqual(inc(1), 2)
       
    82         self.assertEqual(plus10(-2), 8)
       
    83 
       
    84     def testNestingPlusFreeRefToGlobal(self):
       
    85 
       
    86         def make_adder6(x):
       
    87             global global_nest_x
       
    88             def adder(y):
       
    89                 return global_nest_x + y
       
    90             global_nest_x = x
       
    91             return adder
       
    92 
       
    93         inc = make_adder6(1)
       
    94         plus10 = make_adder6(10)
       
    95 
       
    96         self.assertEqual(inc(1), 11) # there's only one global
       
    97         self.assertEqual(plus10(-2), 8)
       
    98 
       
    99     def testNearestEnclosingScope(self):
       
   100 
       
   101         def f(x):
       
   102             def g(y):
       
   103                 x = 42 # check that this masks binding in f()
       
   104                 def h(z):
       
   105                     return x + z
       
   106                 return h
       
   107             return g(2)
       
   108 
       
   109         test_func = f(10)
       
   110         self.assertEqual(test_func(5), 47)
       
   111 
       
   112     def testMixedFreevarsAndCellvars(self):
       
   113 
       
   114         def identity(x):
       
   115             return x
       
   116 
       
   117         def f(x, y, z):
       
   118             def g(a, b, c):
       
   119                 a = a + x # 3
       
   120                 def h():
       
   121                     # z * (4 + 9)
       
   122                     # 3 * 13
       
   123                     return identity(z * (b + y))
       
   124                 y = c + z # 9
       
   125                 return h
       
   126             return g
       
   127 
       
   128         g = f(1, 2, 3)
       
   129         h = g(2, 4, 6)
       
   130         self.assertEqual(h(), 39)
       
   131 
       
   132     def testFreeVarInMethod(self):
       
   133 
       
   134         def test():
       
   135             method_and_var = "var"
       
   136             class Test:
       
   137                 def method_and_var(self):
       
   138                     return "method"
       
   139                 def test(self):
       
   140                     return method_and_var
       
   141                 def actual_global(self):
       
   142                     return str("global")
       
   143                 def str(self):
       
   144                     return str(self)
       
   145             return Test()
       
   146 
       
   147         t = test()
       
   148         self.assertEqual(t.test(), "var")
       
   149         self.assertEqual(t.method_and_var(), "method")
       
   150         self.assertEqual(t.actual_global(), "global")
       
   151 
       
   152         method_and_var = "var"
       
   153         class Test:
       
   154             # this class is not nested, so the rules are different
       
   155             def method_and_var(self):
       
   156                 return "method"
       
   157             def test(self):
       
   158                 return method_and_var
       
   159             def actual_global(self):
       
   160                 return str("global")
       
   161             def str(self):
       
   162                 return str(self)
       
   163 
       
   164         t = Test()
       
   165         self.assertEqual(t.test(), "var")
       
   166         self.assertEqual(t.method_and_var(), "method")
       
   167         self.assertEqual(t.actual_global(), "global")
       
   168 
       
   169     def testRecursion(self):
       
   170 
       
   171         def f(x):
       
   172             def fact(n):
       
   173                 if n == 0:
       
   174                     return 1
       
   175                 else:
       
   176                     return n * fact(n - 1)
       
   177             if x >= 0:
       
   178                 return fact(x)
       
   179             else:
       
   180                 raise ValueError, "x must be >= 0"
       
   181 
       
   182         self.assertEqual(f(6), 720)
       
   183 
       
   184 
       
   185     def testUnoptimizedNamespaces(self):
       
   186 
       
   187         check_syntax_error(self, """\
       
   188 def unoptimized_clash1(strip):
       
   189     def f(s):
       
   190         from string import *
       
   191         return strip(s) # ambiguity: free or local
       
   192     return f
       
   193 """)
       
   194 
       
   195         check_syntax_error(self, """\
       
   196 def unoptimized_clash2():
       
   197     from string import *
       
   198     def f(s):
       
   199         return strip(s) # ambiguity: global or local
       
   200     return f
       
   201 """)
       
   202 
       
   203         check_syntax_error(self, """\
       
   204 def unoptimized_clash2():
       
   205     from string import *
       
   206     def g():
       
   207         def f(s):
       
   208             return strip(s) # ambiguity: global or local
       
   209         return f
       
   210 """)
       
   211 
       
   212         # XXX could allow this for exec with const argument, but what's the point
       
   213         check_syntax_error(self, """\
       
   214 def error(y):
       
   215     exec "a = 1"
       
   216     def f(x):
       
   217         return x + y
       
   218     return f
       
   219 """)
       
   220 
       
   221         check_syntax_error(self, """\
       
   222 def f(x):
       
   223     def g():
       
   224         return x
       
   225     del x # can't del name
       
   226 """)
       
   227 
       
   228         check_syntax_error(self, """\
       
   229 def f():
       
   230     def g():
       
   231         from string import *
       
   232         return strip # global or local?
       
   233 """)
       
   234 
       
   235         # and verify a few cases that should work
       
   236 
       
   237         exec """
       
   238 def noproblem1():
       
   239     from string import *
       
   240     f = lambda x:x
       
   241 
       
   242 def noproblem2():
       
   243     from string import *
       
   244     def f(x):
       
   245         return x + 1
       
   246 
       
   247 def noproblem3():
       
   248     from string import *
       
   249     def f(x):
       
   250         global y
       
   251         y = x
       
   252 """
       
   253 
       
   254     def testLambdas(self):
       
   255 
       
   256         f1 = lambda x: lambda y: x + y
       
   257         inc = f1(1)
       
   258         plus10 = f1(10)
       
   259         self.assertEqual(inc(1), 2)
       
   260         self.assertEqual(plus10(5), 15)
       
   261 
       
   262         f2 = lambda x: (lambda : lambda y: x + y)()
       
   263         inc = f2(1)
       
   264         plus10 = f2(10)
       
   265         self.assertEqual(inc(1), 2)
       
   266         self.assertEqual(plus10(5), 15)
       
   267 
       
   268         f3 = lambda x: lambda y: global_x + y
       
   269         global_x = 1
       
   270         inc = f3(None)
       
   271         self.assertEqual(inc(2), 3)
       
   272 
       
   273         f8 = lambda x, y, z: lambda a, b, c: lambda : z * (b + y)
       
   274         g = f8(1, 2, 3)
       
   275         h = g(2, 4, 6)
       
   276         self.assertEqual(h(), 18)
       
   277 
       
   278     def testUnboundLocal(self):
       
   279 
       
   280         def errorInOuter():
       
   281             print y
       
   282             def inner():
       
   283                 return y
       
   284             y = 1
       
   285 
       
   286         def errorInInner():
       
   287             def inner():
       
   288                 return y
       
   289             inner()
       
   290             y = 1
       
   291 
       
   292         try:
       
   293             errorInOuter()
       
   294         except UnboundLocalError:
       
   295             pass
       
   296         else:
       
   297             self.fail()
       
   298 
       
   299         try:
       
   300             errorInInner()
       
   301         except NameError:
       
   302             pass
       
   303         else:
       
   304             self.fail()
       
   305 
       
   306         # test for bug #1501934: incorrect LOAD/STORE_GLOBAL generation
       
   307         exec """
       
   308 global_x = 1
       
   309 def f():
       
   310     global_x += 1
       
   311 try:
       
   312     f()
       
   313 except UnboundLocalError:
       
   314     pass
       
   315 else:
       
   316     fail('scope of global_x not correctly determined')
       
   317 """ in {'fail': self.fail}
       
   318 
       
   319     def testComplexDefinitions(self):
       
   320 
       
   321         def makeReturner(*lst):
       
   322             def returner():
       
   323                 return lst
       
   324             return returner
       
   325 
       
   326         self.assertEqual(makeReturner(1,2,3)(), (1,2,3))
       
   327 
       
   328         def makeReturner2(**kwargs):
       
   329             def returner():
       
   330                 return kwargs
       
   331             return returner
       
   332 
       
   333         self.assertEqual(makeReturner2(a=11)()['a'], 11)
       
   334 
       
   335         def makeAddPair((a, b)):
       
   336             def addPair((c, d)):
       
   337                 return (a + c, b + d)
       
   338             return addPair
       
   339 
       
   340         self.assertEqual(makeAddPair((1, 2))((100, 200)), (101,202))
       
   341 
       
   342     def testScopeOfGlobalStmt(self):
       
   343 # Examples posted by Samuele Pedroni to python-dev on 3/1/2001
       
   344 
       
   345         exec """\
       
   346 # I
       
   347 x = 7
       
   348 def f():
       
   349     x = 1
       
   350     def g():
       
   351         global x
       
   352         def i():
       
   353             def h():
       
   354                 return x
       
   355             return h()
       
   356         return i()
       
   357     return g()
       
   358 self.assertEqual(f(), 7)
       
   359 self.assertEqual(x, 7)
       
   360 
       
   361 # II
       
   362 x = 7
       
   363 def f():
       
   364     x = 1
       
   365     def g():
       
   366         x = 2
       
   367         def i():
       
   368             def h():
       
   369                 return x
       
   370             return h()
       
   371         return i()
       
   372     return g()
       
   373 self.assertEqual(f(), 2)
       
   374 self.assertEqual(x, 7)
       
   375 
       
   376 # III
       
   377 x = 7
       
   378 def f():
       
   379     x = 1
       
   380     def g():
       
   381         global x
       
   382         x = 2
       
   383         def i():
       
   384             def h():
       
   385                 return x
       
   386             return h()
       
   387         return i()
       
   388     return g()
       
   389 self.assertEqual(f(), 2)
       
   390 self.assertEqual(x, 2)
       
   391 
       
   392 # IV
       
   393 x = 7
       
   394 def f():
       
   395     x = 3
       
   396     def g():
       
   397         global x
       
   398         x = 2
       
   399         def i():
       
   400             def h():
       
   401                 return x
       
   402             return h()
       
   403         return i()
       
   404     return g()
       
   405 self.assertEqual(f(), 2)
       
   406 self.assertEqual(x, 2)
       
   407 
       
   408 # XXX what about global statements in class blocks?
       
   409 # do they affect methods?
       
   410 
       
   411 x = 12
       
   412 class Global:
       
   413     global x
       
   414     x = 13
       
   415     def set(self, val):
       
   416         x = val
       
   417     def get(self):
       
   418         return x
       
   419 
       
   420 g = Global()
       
   421 self.assertEqual(g.get(), 13)
       
   422 g.set(15)
       
   423 self.assertEqual(g.get(), 13)
       
   424 """
       
   425 
       
   426     def testLeaks(self):
       
   427 
       
   428         class Foo:
       
   429             count = 0
       
   430 
       
   431             def __init__(self):
       
   432                 Foo.count += 1
       
   433 
       
   434             def __del__(self):
       
   435                 Foo.count -= 1
       
   436 
       
   437         def f1():
       
   438             x = Foo()
       
   439             def f2():
       
   440                 return x
       
   441             f2()
       
   442 
       
   443         for i in range(100):
       
   444             f1()
       
   445 
       
   446         self.assertEqual(Foo.count, 0)
       
   447 
       
   448     def testClassAndGlobal(self):
       
   449 
       
   450         exec """\
       
   451 def test(x):
       
   452     class Foo:
       
   453         global x
       
   454         def __call__(self, y):
       
   455             return x + y
       
   456     return Foo()
       
   457 
       
   458 x = 0
       
   459 self.assertEqual(test(6)(2), 8)
       
   460 x = -1
       
   461 self.assertEqual(test(3)(2), 5)
       
   462 
       
   463 looked_up_by_load_name = False
       
   464 class X:
       
   465     # Implicit globals inside classes are be looked up by LOAD_NAME, not
       
   466     # LOAD_GLOBAL.
       
   467     locals()['looked_up_by_load_name'] = True
       
   468     passed = looked_up_by_load_name
       
   469 
       
   470 self.assert_(X.passed)
       
   471 """
       
   472 
       
   473     def testLocalsFunction(self):
       
   474 
       
   475         def f(x):
       
   476             def g(y):
       
   477                 def h(z):
       
   478                     return y + z
       
   479                 w = x + y
       
   480                 y += 3
       
   481                 return locals()
       
   482             return g
       
   483 
       
   484         d = f(2)(4)
       
   485         self.assert_(d.has_key('h'))
       
   486         del d['h']
       
   487         self.assertEqual(d, {'x': 2, 'y': 7, 'w': 6})
       
   488 
       
   489     def testLocalsClass(self):
       
   490         # This test verifies that calling locals() does not pollute
       
   491         # the local namespace of the class with free variables.  Old
       
   492         # versions of Python had a bug, where a free variable being
       
   493         # passed through a class namespace would be inserted into
       
   494         # locals() by locals() or exec or a trace function.
       
   495         #
       
   496         # The real bug lies in frame code that copies variables
       
   497         # between fast locals and the locals dict, e.g. when executing
       
   498         # a trace function.
       
   499 
       
   500         def f(x):
       
   501             class C:
       
   502                 x = 12
       
   503                 def m(self):
       
   504                     return x
       
   505                 locals()
       
   506             return C
       
   507 
       
   508         self.assertEqual(f(1).x, 12)
       
   509 
       
   510         def f(x):
       
   511             class C:
       
   512                 y = x
       
   513                 def m(self):
       
   514                     return x
       
   515                 z = list(locals())
       
   516             return C
       
   517 
       
   518         varnames = f(1).z
       
   519         self.assert_("x" not in varnames)
       
   520         self.assert_("y" in varnames)
       
   521 
       
   522     def testLocalsClass_WithTrace(self):
       
   523         # Issue23728: after the trace function returns, the locals()
       
   524         # dictionary is used to update all variables, this used to
       
   525         # include free variables. But in class statements, free
       
   526         # variables are not inserted...
       
   527         import sys
       
   528         sys.settrace(lambda a,b,c:None)
       
   529         try:
       
   530             x = 12
       
   531 
       
   532             class C:
       
   533                 def f(self):
       
   534                     return x
       
   535 
       
   536             self.assertEquals(x, 12) # Used to raise UnboundLocalError
       
   537         finally:
       
   538             sys.settrace(None)
       
   539 
       
   540     def testBoundAndFree(self):
       
   541         # var is bound and free in class
       
   542 
       
   543         def f(x):
       
   544             class C:
       
   545                 def m(self):
       
   546                     return x
       
   547                 a = x
       
   548             return C
       
   549 
       
   550         inst = f(3)()
       
   551         self.assertEqual(inst.a, inst.m())
       
   552 
       
   553     def testInteractionWithTraceFunc(self):
       
   554 
       
   555         import sys
       
   556         def tracer(a,b,c):
       
   557             return tracer
       
   558 
       
   559         def adaptgetter(name, klass, getter):
       
   560             kind, des = getter
       
   561             if kind == 1:       # AV happens when stepping from this line to next
       
   562                 if des == "":
       
   563                     des = "_%s__%s" % (klass.__name__, name)
       
   564                 return lambda obj: getattr(obj, des)
       
   565 
       
   566         class TestClass:
       
   567             pass
       
   568 
       
   569         sys.settrace(tracer)
       
   570         adaptgetter("foo", TestClass, (1, ""))
       
   571         sys.settrace(None)
       
   572 
       
   573         self.assertRaises(TypeError, sys.settrace)
       
   574 
       
   575     def testEvalExecFreeVars(self):
       
   576 
       
   577         def f(x):
       
   578             return lambda: x + 1
       
   579 
       
   580         g = f(3)
       
   581         self.assertRaises(TypeError, eval, g.func_code)
       
   582 
       
   583         try:
       
   584             exec g.func_code in {}
       
   585         except TypeError:
       
   586             pass
       
   587         else:
       
   588             self.fail("exec should have failed, because code contained free vars")
       
   589 
       
   590     def testListCompLocalVars(self):
       
   591 
       
   592         try:
       
   593             print bad
       
   594         except NameError:
       
   595             pass
       
   596         else:
       
   597             print "bad should not be defined"
       
   598 
       
   599         def x():
       
   600             [bad for s in 'a b' for bad in s.split()]
       
   601 
       
   602         x()
       
   603         try:
       
   604             print bad
       
   605         except NameError:
       
   606             pass
       
   607 
       
   608     def testEvalFreeVars(self):
       
   609 
       
   610         def f(x):
       
   611             def g():
       
   612                 x
       
   613                 eval("x + 1")
       
   614             return g
       
   615 
       
   616         f(4)()
       
   617 
       
   618     def testFreeingCell(self):
       
   619         # Test what happens when a finalizer accesses
       
   620         # the cell where the object was stored.
       
   621         class Special:
       
   622             def __del__(self):
       
   623                 nestedcell_get()
       
   624 
       
   625         def f():
       
   626             global nestedcell_get
       
   627             def nestedcell_get():
       
   628                 return c
       
   629 
       
   630             c = (Special(),)
       
   631             c = 2
       
   632 
       
   633         f() # used to crash the interpreter...
       
   634 
       
   635 
       
   636 
       
   637 def test_main():
       
   638     run_unittest(ScopeTests)
       
   639 
       
   640 if __name__ == '__main__':
       
   641     test_main()