symbian-qemu-0.9.1-12/python-2.6.1/Lib/test/test_scope.py
changeset 1 2fb8b9db1c86
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/symbian-qemu-0.9.1-12/python-2.6.1/Lib/test/test_scope.py	Fri Jul 31 15:01:17 2009 +0100
@@ -0,0 +1,641 @@
+import unittest
+from test.test_support import check_syntax_error, run_unittest
+
+import warnings
+warnings.filterwarnings("ignore", r"import \*", SyntaxWarning, "<test string>")
+warnings.filterwarnings("ignore", r"import \*", SyntaxWarning, "<string>")
+
+class ScopeTests(unittest.TestCase):
+
+    def testSimpleNesting(self):
+
+        def make_adder(x):
+            def adder(y):
+                return x + y
+            return adder
+
+        inc = make_adder(1)
+        plus10 = make_adder(10)
+
+        self.assertEqual(inc(1), 2)
+        self.assertEqual(plus10(-2), 8)
+
+    def testExtraNesting(self):
+
+        def make_adder2(x):
+            def extra(): # check freevars passing through non-use scopes
+                def adder(y):
+                    return x + y
+                return adder
+            return extra()
+
+        inc = make_adder2(1)
+        plus10 = make_adder2(10)
+
+        self.assertEqual(inc(1), 2)
+        self.assertEqual(plus10(-2), 8)
+
+    def testSimpleAndRebinding(self):
+
+        def make_adder3(x):
+            def adder(y):
+                return x + y
+            x = x + 1 # check tracking of assignment to x in defining scope
+            return adder
+
+        inc = make_adder3(0)
+        plus10 = make_adder3(9)
+
+        self.assertEqual(inc(1), 2)
+        self.assertEqual(plus10(-2), 8)
+
+    def testNestingGlobalNoFree(self):
+
+        def make_adder4(): # XXX add exta level of indirection
+            def nest():
+                def nest():
+                    def adder(y):
+                        return global_x + y # check that plain old globals work
+                    return adder
+                return nest()
+            return nest()
+
+        global_x = 1
+        adder = make_adder4()
+        self.assertEqual(adder(1), 2)
+
+        global_x = 10
+        self.assertEqual(adder(-2), 8)
+
+    def testNestingThroughClass(self):
+
+        def make_adder5(x):
+            class Adder:
+                def __call__(self, y):
+                    return x + y
+            return Adder()
+
+        inc = make_adder5(1)
+        plus10 = make_adder5(10)
+
+        self.assertEqual(inc(1), 2)
+        self.assertEqual(plus10(-2), 8)
+
+    def testNestingPlusFreeRefToGlobal(self):
+
+        def make_adder6(x):
+            global global_nest_x
+            def adder(y):
+                return global_nest_x + y
+            global_nest_x = x
+            return adder
+
+        inc = make_adder6(1)
+        plus10 = make_adder6(10)
+
+        self.assertEqual(inc(1), 11) # there's only one global
+        self.assertEqual(plus10(-2), 8)
+
+    def testNearestEnclosingScope(self):
+
+        def f(x):
+            def g(y):
+                x = 42 # check that this masks binding in f()
+                def h(z):
+                    return x + z
+                return h
+            return g(2)
+
+        test_func = f(10)
+        self.assertEqual(test_func(5), 47)
+
+    def testMixedFreevarsAndCellvars(self):
+
+        def identity(x):
+            return x
+
+        def f(x, y, z):
+            def g(a, b, c):
+                a = a + x # 3
+                def h():
+                    # z * (4 + 9)
+                    # 3 * 13
+                    return identity(z * (b + y))
+                y = c + z # 9
+                return h
+            return g
+
+        g = f(1, 2, 3)
+        h = g(2, 4, 6)
+        self.assertEqual(h(), 39)
+
+    def testFreeVarInMethod(self):
+
+        def test():
+            method_and_var = "var"
+            class Test:
+                def method_and_var(self):
+                    return "method"
+                def test(self):
+                    return method_and_var
+                def actual_global(self):
+                    return str("global")
+                def str(self):
+                    return str(self)
+            return Test()
+
+        t = test()
+        self.assertEqual(t.test(), "var")
+        self.assertEqual(t.method_and_var(), "method")
+        self.assertEqual(t.actual_global(), "global")
+
+        method_and_var = "var"
+        class Test:
+            # this class is not nested, so the rules are different
+            def method_and_var(self):
+                return "method"
+            def test(self):
+                return method_and_var
+            def actual_global(self):
+                return str("global")
+            def str(self):
+                return str(self)
+
+        t = Test()
+        self.assertEqual(t.test(), "var")
+        self.assertEqual(t.method_and_var(), "method")
+        self.assertEqual(t.actual_global(), "global")
+
+    def testRecursion(self):
+
+        def f(x):
+            def fact(n):
+                if n == 0:
+                    return 1
+                else:
+                    return n * fact(n - 1)
+            if x >= 0:
+                return fact(x)
+            else:
+                raise ValueError, "x must be >= 0"
+
+        self.assertEqual(f(6), 720)
+
+
+    def testUnoptimizedNamespaces(self):
+
+        check_syntax_error(self, """\
+def unoptimized_clash1(strip):
+    def f(s):
+        from string import *
+        return strip(s) # ambiguity: free or local
+    return f
+""")
+
+        check_syntax_error(self, """\
+def unoptimized_clash2():
+    from string import *
+    def f(s):
+        return strip(s) # ambiguity: global or local
+    return f
+""")
+
+        check_syntax_error(self, """\
+def unoptimized_clash2():
+    from string import *
+    def g():
+        def f(s):
+            return strip(s) # ambiguity: global or local
+        return f
+""")
+
+        # XXX could allow this for exec with const argument, but what's the point
+        check_syntax_error(self, """\
+def error(y):
+    exec "a = 1"
+    def f(x):
+        return x + y
+    return f
+""")
+
+        check_syntax_error(self, """\
+def f(x):
+    def g():
+        return x
+    del x # can't del name
+""")
+
+        check_syntax_error(self, """\
+def f():
+    def g():
+        from string import *
+        return strip # global or local?
+""")
+
+        # and verify a few cases that should work
+
+        exec """
+def noproblem1():
+    from string import *
+    f = lambda x:x
+
+def noproblem2():
+    from string import *
+    def f(x):
+        return x + 1
+
+def noproblem3():
+    from string import *
+    def f(x):
+        global y
+        y = x
+"""
+
+    def testLambdas(self):
+
+        f1 = lambda x: lambda y: x + y
+        inc = f1(1)
+        plus10 = f1(10)
+        self.assertEqual(inc(1), 2)
+        self.assertEqual(plus10(5), 15)
+
+        f2 = lambda x: (lambda : lambda y: x + y)()
+        inc = f2(1)
+        plus10 = f2(10)
+        self.assertEqual(inc(1), 2)
+        self.assertEqual(plus10(5), 15)
+
+        f3 = lambda x: lambda y: global_x + y
+        global_x = 1
+        inc = f3(None)
+        self.assertEqual(inc(2), 3)
+
+        f8 = lambda x, y, z: lambda a, b, c: lambda : z * (b + y)
+        g = f8(1, 2, 3)
+        h = g(2, 4, 6)
+        self.assertEqual(h(), 18)
+
+    def testUnboundLocal(self):
+
+        def errorInOuter():
+            print y
+            def inner():
+                return y
+            y = 1
+
+        def errorInInner():
+            def inner():
+                return y
+            inner()
+            y = 1
+
+        try:
+            errorInOuter()
+        except UnboundLocalError:
+            pass
+        else:
+            self.fail()
+
+        try:
+            errorInInner()
+        except NameError:
+            pass
+        else:
+            self.fail()
+
+        # test for bug #1501934: incorrect LOAD/STORE_GLOBAL generation
+        exec """
+global_x = 1
+def f():
+    global_x += 1
+try:
+    f()
+except UnboundLocalError:
+    pass
+else:
+    fail('scope of global_x not correctly determined')
+""" in {'fail': self.fail}
+
+    def testComplexDefinitions(self):
+
+        def makeReturner(*lst):
+            def returner():
+                return lst
+            return returner
+
+        self.assertEqual(makeReturner(1,2,3)(), (1,2,3))
+
+        def makeReturner2(**kwargs):
+            def returner():
+                return kwargs
+            return returner
+
+        self.assertEqual(makeReturner2(a=11)()['a'], 11)
+
+        def makeAddPair((a, b)):
+            def addPair((c, d)):
+                return (a + c, b + d)
+            return addPair
+
+        self.assertEqual(makeAddPair((1, 2))((100, 200)), (101,202))
+
+    def testScopeOfGlobalStmt(self):
+# Examples posted by Samuele Pedroni to python-dev on 3/1/2001
+
+        exec """\
+# I
+x = 7
+def f():
+    x = 1
+    def g():
+        global x
+        def i():
+            def h():
+                return x
+            return h()
+        return i()
+    return g()
+self.assertEqual(f(), 7)
+self.assertEqual(x, 7)
+
+# II
+x = 7
+def f():
+    x = 1
+    def g():
+        x = 2
+        def i():
+            def h():
+                return x
+            return h()
+        return i()
+    return g()
+self.assertEqual(f(), 2)
+self.assertEqual(x, 7)
+
+# III
+x = 7
+def f():
+    x = 1
+    def g():
+        global x
+        x = 2
+        def i():
+            def h():
+                return x
+            return h()
+        return i()
+    return g()
+self.assertEqual(f(), 2)
+self.assertEqual(x, 2)
+
+# IV
+x = 7
+def f():
+    x = 3
+    def g():
+        global x
+        x = 2
+        def i():
+            def h():
+                return x
+            return h()
+        return i()
+    return g()
+self.assertEqual(f(), 2)
+self.assertEqual(x, 2)
+
+# XXX what about global statements in class blocks?
+# do they affect methods?
+
+x = 12
+class Global:
+    global x
+    x = 13
+    def set(self, val):
+        x = val
+    def get(self):
+        return x
+
+g = Global()
+self.assertEqual(g.get(), 13)
+g.set(15)
+self.assertEqual(g.get(), 13)
+"""
+
+    def testLeaks(self):
+
+        class Foo:
+            count = 0
+
+            def __init__(self):
+                Foo.count += 1
+
+            def __del__(self):
+                Foo.count -= 1
+
+        def f1():
+            x = Foo()
+            def f2():
+                return x
+            f2()
+
+        for i in range(100):
+            f1()
+
+        self.assertEqual(Foo.count, 0)
+
+    def testClassAndGlobal(self):
+
+        exec """\
+def test(x):
+    class Foo:
+        global x
+        def __call__(self, y):
+            return x + y
+    return Foo()
+
+x = 0
+self.assertEqual(test(6)(2), 8)
+x = -1
+self.assertEqual(test(3)(2), 5)
+
+looked_up_by_load_name = False
+class X:
+    # Implicit globals inside classes are be looked up by LOAD_NAME, not
+    # LOAD_GLOBAL.
+    locals()['looked_up_by_load_name'] = True
+    passed = looked_up_by_load_name
+
+self.assert_(X.passed)
+"""
+
+    def testLocalsFunction(self):
+
+        def f(x):
+            def g(y):
+                def h(z):
+                    return y + z
+                w = x + y
+                y += 3
+                return locals()
+            return g
+
+        d = f(2)(4)
+        self.assert_(d.has_key('h'))
+        del d['h']
+        self.assertEqual(d, {'x': 2, 'y': 7, 'w': 6})
+
+    def testLocalsClass(self):
+        # This test verifies that calling locals() does not pollute
+        # the local namespace of the class with free variables.  Old
+        # versions of Python had a bug, where a free variable being
+        # passed through a class namespace would be inserted into
+        # locals() by locals() or exec or a trace function.
+        #
+        # The real bug lies in frame code that copies variables
+        # between fast locals and the locals dict, e.g. when executing
+        # a trace function.
+
+        def f(x):
+            class C:
+                x = 12
+                def m(self):
+                    return x
+                locals()
+            return C
+
+        self.assertEqual(f(1).x, 12)
+
+        def f(x):
+            class C:
+                y = x
+                def m(self):
+                    return x
+                z = list(locals())
+            return C
+
+        varnames = f(1).z
+        self.assert_("x" not in varnames)
+        self.assert_("y" in varnames)
+
+    def testLocalsClass_WithTrace(self):
+        # Issue23728: after the trace function returns, the locals()
+        # dictionary is used to update all variables, this used to
+        # include free variables. But in class statements, free
+        # variables are not inserted...
+        import sys
+        sys.settrace(lambda a,b,c:None)
+        try:
+            x = 12
+
+            class C:
+                def f(self):
+                    return x
+
+            self.assertEquals(x, 12) # Used to raise UnboundLocalError
+        finally:
+            sys.settrace(None)
+
+    def testBoundAndFree(self):
+        # var is bound and free in class
+
+        def f(x):
+            class C:
+                def m(self):
+                    return x
+                a = x
+            return C
+
+        inst = f(3)()
+        self.assertEqual(inst.a, inst.m())
+
+    def testInteractionWithTraceFunc(self):
+
+        import sys
+        def tracer(a,b,c):
+            return tracer
+
+        def adaptgetter(name, klass, getter):
+            kind, des = getter
+            if kind == 1:       # AV happens when stepping from this line to next
+                if des == "":
+                    des = "_%s__%s" % (klass.__name__, name)
+                return lambda obj: getattr(obj, des)
+
+        class TestClass:
+            pass
+
+        sys.settrace(tracer)
+        adaptgetter("foo", TestClass, (1, ""))
+        sys.settrace(None)
+
+        self.assertRaises(TypeError, sys.settrace)
+
+    def testEvalExecFreeVars(self):
+
+        def f(x):
+            return lambda: x + 1
+
+        g = f(3)
+        self.assertRaises(TypeError, eval, g.func_code)
+
+        try:
+            exec g.func_code in {}
+        except TypeError:
+            pass
+        else:
+            self.fail("exec should have failed, because code contained free vars")
+
+    def testListCompLocalVars(self):
+
+        try:
+            print bad
+        except NameError:
+            pass
+        else:
+            print "bad should not be defined"
+
+        def x():
+            [bad for s in 'a b' for bad in s.split()]
+
+        x()
+        try:
+            print bad
+        except NameError:
+            pass
+
+    def testEvalFreeVars(self):
+
+        def f(x):
+            def g():
+                x
+                eval("x + 1")
+            return g
+
+        f(4)()
+
+    def testFreeingCell(self):
+        # Test what happens when a finalizer accesses
+        # the cell where the object was stored.
+        class Special:
+            def __del__(self):
+                nestedcell_get()
+
+        def f():
+            global nestedcell_get
+            def nestedcell_get():
+                return c
+
+            c = (Special(),)
+            c = 2
+
+        f() # used to crash the interpreter...
+
+
+
+def test_main():
+    run_unittest(ScopeTests)
+
+if __name__ == '__main__':
+    test_main()