mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 03:44:55 +00:00 
			
		
		
		
	imports e.g. test_support must do so using an absolute package name such as "import test.test_support" or "from test import test_support". This also updates the README in Lib/test, and gets rid of the duplicate data dirctory in Lib/test/data (replaced by Lib/email/test/data). Now Tim and Jack can have at it. :)
		
			
				
	
	
		
			524 lines
		
	
	
	
		
			9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			524 lines
		
	
	
	
		
			9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
from test.test_support import verify, TestFailed, check_syntax
 | 
						|
 | 
						|
import warnings
 | 
						|
warnings.filterwarnings("ignore", r"import \*", SyntaxWarning, "<string>")
 | 
						|
 | 
						|
print "1. simple nesting"
 | 
						|
 | 
						|
def make_adder(x):
 | 
						|
    def adder(y):
 | 
						|
        return x + y
 | 
						|
    return adder
 | 
						|
 | 
						|
inc = make_adder(1)
 | 
						|
plus10 = make_adder(10)
 | 
						|
 | 
						|
verify(inc(1) == 2)
 | 
						|
verify(plus10(-2) == 8)
 | 
						|
 | 
						|
print "2. extra nesting"
 | 
						|
 | 
						|
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)
 | 
						|
 | 
						|
verify(inc(1) == 2)
 | 
						|
verify(plus10(-2) == 8)
 | 
						|
 | 
						|
print "3. simple nesting + rebinding"
 | 
						|
 | 
						|
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)
 | 
						|
 | 
						|
verify(inc(1) == 2)
 | 
						|
verify(plus10(-2) == 8)
 | 
						|
 | 
						|
print "4. nesting with global but no free"
 | 
						|
 | 
						|
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()
 | 
						|
verify(adder(1) == 2)
 | 
						|
 | 
						|
global_x = 10
 | 
						|
verify(adder(-2) == 8)
 | 
						|
 | 
						|
print "5. nesting through class"
 | 
						|
 | 
						|
def make_adder5(x):
 | 
						|
    class Adder:
 | 
						|
        def __call__(self, y):
 | 
						|
            return x + y
 | 
						|
    return Adder()
 | 
						|
 | 
						|
inc = make_adder5(1)
 | 
						|
plus10 = make_adder5(10)
 | 
						|
 | 
						|
verify(inc(1) == 2)
 | 
						|
verify(plus10(-2) == 8)
 | 
						|
 | 
						|
print "6. nesting plus free ref to global"
 | 
						|
 | 
						|
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)
 | 
						|
 | 
						|
verify(inc(1) == 11) # there's only one global
 | 
						|
verify(plus10(-2) == 8)
 | 
						|
 | 
						|
print "7. nearest enclosing scope"
 | 
						|
 | 
						|
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)
 | 
						|
verify(test_func(5) == 47)
 | 
						|
 | 
						|
print "8. mixed freevars and cellvars"
 | 
						|
 | 
						|
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)
 | 
						|
verify(h() == 39)
 | 
						|
 | 
						|
print "9. free variable in method"
 | 
						|
 | 
						|
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()
 | 
						|
verify(t.test() == "var")
 | 
						|
verify(t.method_and_var() == "method")
 | 
						|
verify(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()
 | 
						|
verify(t.test() == "var")
 | 
						|
verify(t.method_and_var() == "method")
 | 
						|
verify(t.actual_global() == "global")
 | 
						|
 | 
						|
print "10. recursion"
 | 
						|
 | 
						|
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"
 | 
						|
 | 
						|
verify(f(6) == 720)
 | 
						|
 | 
						|
 | 
						|
print "11. unoptimized namespaces"
 | 
						|
 | 
						|
check_syntax("""\
 | 
						|
def unoptimized_clash1(strip):
 | 
						|
    def f(s):
 | 
						|
        from string import *
 | 
						|
        return strip(s) # ambiguity: free or local
 | 
						|
    return f
 | 
						|
""")
 | 
						|
 | 
						|
check_syntax("""\
 | 
						|
def unoptimized_clash2():
 | 
						|
    from string import *
 | 
						|
    def f(s):
 | 
						|
        return strip(s) # ambiguity: global or local
 | 
						|
    return f
 | 
						|
""")
 | 
						|
 | 
						|
check_syntax("""\
 | 
						|
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("""\
 | 
						|
def error(y):
 | 
						|
    exec "a = 1"
 | 
						|
    def f(x):
 | 
						|
        return x + y
 | 
						|
    return f
 | 
						|
""")
 | 
						|
 | 
						|
check_syntax("""\
 | 
						|
def f(x):
 | 
						|
    def g():
 | 
						|
        return x
 | 
						|
    del x # can't del name
 | 
						|
""")
 | 
						|
 | 
						|
check_syntax("""\
 | 
						|
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
 | 
						|
"""
 | 
						|
 | 
						|
print "12. lambdas"
 | 
						|
 | 
						|
f1 = lambda x: lambda y: x + y
 | 
						|
inc = f1(1)
 | 
						|
plus10 = f1(10)
 | 
						|
verify(inc(1) == 2)
 | 
						|
verify(plus10(5) == 15)
 | 
						|
 | 
						|
f2 = lambda x: (lambda : lambda y: x + y)()
 | 
						|
inc = f2(1)
 | 
						|
plus10 = f2(10)
 | 
						|
verify(inc(1) == 2)
 | 
						|
verify(plus10(5) == 15)
 | 
						|
 | 
						|
f3 = lambda x: lambda y: global_x + y
 | 
						|
global_x = 1
 | 
						|
inc = f3(None)
 | 
						|
verify(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)
 | 
						|
verify(h() == 18)
 | 
						|
 | 
						|
print "13. UnboundLocal"
 | 
						|
 | 
						|
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:
 | 
						|
    raise TestFailed
 | 
						|
 | 
						|
try:
 | 
						|
    errorInInner()
 | 
						|
except NameError:
 | 
						|
    pass
 | 
						|
else:
 | 
						|
    raise TestFailed
 | 
						|
 | 
						|
print "14. complex definitions"
 | 
						|
 | 
						|
def makeReturner(*lst):
 | 
						|
    def returner():
 | 
						|
        return lst
 | 
						|
    return returner
 | 
						|
 | 
						|
verify(makeReturner(1,2,3)() == (1,2,3))
 | 
						|
 | 
						|
def makeReturner2(**kwargs):
 | 
						|
    def returner():
 | 
						|
        return kwargs
 | 
						|
    return returner
 | 
						|
 | 
						|
verify(makeReturner2(a=11)()['a'] == 11)
 | 
						|
 | 
						|
def makeAddPair((a, b)):
 | 
						|
    def addPair((c, d)):
 | 
						|
        return (a + c, b + d)
 | 
						|
    return addPair
 | 
						|
 | 
						|
verify(makeAddPair((1, 2))((100, 200)) == (101,202))
 | 
						|
 | 
						|
print "15. scope of global statements"
 | 
						|
# Examples posted by Samuele Pedroni to python-dev on 3/1/2001
 | 
						|
 | 
						|
# I
 | 
						|
x = 7
 | 
						|
def f():
 | 
						|
    x = 1
 | 
						|
    def g():
 | 
						|
        global x
 | 
						|
        def i():
 | 
						|
            def h():
 | 
						|
                return x
 | 
						|
            return h()
 | 
						|
        return i()
 | 
						|
    return g()
 | 
						|
verify(f() == 7)
 | 
						|
verify(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()
 | 
						|
verify(f() == 2)
 | 
						|
verify(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()
 | 
						|
verify(f() == 2)
 | 
						|
verify(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()
 | 
						|
verify(f() == 2)
 | 
						|
verify(x == 2)
 | 
						|
 | 
						|
print "16. check leaks"
 | 
						|
 | 
						|
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()
 | 
						|
 | 
						|
verify(Foo.count == 0)
 | 
						|
 | 
						|
print "17. class and global"
 | 
						|
 | 
						|
def test(x):
 | 
						|
    class Foo:
 | 
						|
        global x
 | 
						|
        def __call__(self, y):
 | 
						|
            return x + y
 | 
						|
    return Foo()
 | 
						|
 | 
						|
x = 0
 | 
						|
verify(test(6)(2) == 8)
 | 
						|
x = -1
 | 
						|
verify(test(3)(2) == 5)
 | 
						|
 | 
						|
print "18. verify that locals() works"
 | 
						|
 | 
						|
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)
 | 
						|
verify(d.has_key('h'))
 | 
						|
del d['h']
 | 
						|
verify(d == {'x': 2, 'y': 7, 'w': 6})
 | 
						|
 | 
						|
print "19. var is bound and free in class"
 | 
						|
 | 
						|
def f(x):
 | 
						|
    class C:
 | 
						|
        def m(self):
 | 
						|
            return x
 | 
						|
        a = x
 | 
						|
    return C
 | 
						|
 | 
						|
inst = f(3)()
 | 
						|
verify(inst.a == inst.m())
 | 
						|
 | 
						|
print "20. interaction with trace function"
 | 
						|
 | 
						|
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)
 | 
						|
 | 
						|
try: sys.settrace()
 | 
						|
except TypeError: pass
 | 
						|
else: raise TestFailed, 'sys.settrace() did not raise TypeError'
 | 
						|
 | 
						|
print "20. eval and exec with free variables"
 | 
						|
 | 
						|
def f(x):
 | 
						|
    return lambda: x + 1
 | 
						|
 | 
						|
g = f(3)
 | 
						|
try:
 | 
						|
    eval(g.func_code)
 | 
						|
except TypeError:
 | 
						|
    pass
 | 
						|
else:
 | 
						|
    print "eval() should have failed, because code contained free vars"
 | 
						|
 | 
						|
try:
 | 
						|
    exec g.func_code
 | 
						|
except TypeError:
 | 
						|
    pass
 | 
						|
else:
 | 
						|
    print "exec should have failed, because code contained free vars"
 | 
						|
 | 
						|
print "21. list comprehension with local variables"
 | 
						|
 | 
						|
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
 | 
						|
 | 
						|
print "22. eval with free variables"
 | 
						|
 | 
						|
def f(x):
 | 
						|
    def g():
 | 
						|
        x
 | 
						|
        eval("x + 1")
 | 
						|
    return g
 | 
						|
 | 
						|
f(4)()
 |