Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 4588c78

Browse files
committed
PEP 227 implementation
New tests cases for nested scopes.
1 parent 5e2d076 commit 4588c78

2 files changed

Lines changed: 262 additions & 0 deletions

File tree

Lib/test/output/test_scope

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
test_scope
2+
1. simple nesting
3+
2. extra nesting
4+
3. simple nesting + rebinding
5+
4. nesting with global but no free
6+
5. nesting through class
7+
6. nesting plus free ref to global
8+
7. nearest enclosing scope
9+
8. mixed freevars and cellvars
10+
9. free variable in method
11+
10. recursion
12+
11. unoptimized namespaces
13+
12. lambdas

Lib/test/test_scope.py

Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
1+
from test.test_support import verify, TestFailed
2+
3+
print "1. simple nesting"
4+
5+
def make_adder(x):
6+
def adder(y):
7+
return x + y
8+
return adder
9+
10+
inc = make_adder(1)
11+
plus10 = make_adder(10)
12+
13+
verify(inc(1) == 2)
14+
verify(plus10(-2) == 8)
15+
16+
print "2. extra nesting"
17+
18+
def make_adder2(x):
19+
def extra(): # check freevars passing through non-use scopes
20+
def adder(y):
21+
return x + y
22+
return adder
23+
return extra()
24+
25+
inc = make_adder2(1)
26+
plus10 = make_adder2(10)
27+
28+
verify(inc(1) == 2)
29+
verify(plus10(-2) == 8)
30+
31+
print "3. simple nesting + rebinding"
32+
33+
def make_adder3(x):
34+
def adder(y):
35+
return x + y
36+
x = x + 1 # check tracking of assignment to x in defining scope
37+
return adder
38+
39+
inc = make_adder3(0)
40+
plus10 = make_adder3(9)
41+
42+
verify(inc(1) == 2)
43+
verify(plus10(-2) == 8)
44+
45+
print "4. nesting with global but no free"
46+
47+
def make_adder4(): # XXX add exta level of indirection
48+
def nest():
49+
def nest():
50+
def adder(y):
51+
return global_x + y # check that plain old globals work
52+
return adder
53+
return nest()
54+
return nest()
55+
56+
global_x = 1
57+
adder = make_adder4()
58+
verify(adder(1) == 2)
59+
60+
global_x = 10
61+
verify(adder(-2) == 8)
62+
63+
print "5. nesting through class"
64+
65+
def make_adder5(x):
66+
class Adder:
67+
def __call__(self, y):
68+
return x + y
69+
return Adder()
70+
71+
inc = make_adder5(1)
72+
plus10 = make_adder5(10)
73+
74+
verify(inc(1) == 2)
75+
verify(plus10(-2) == 8)
76+
77+
print "6. nesting plus free ref to global"
78+
79+
def make_adder6(x):
80+
global global_nest_x
81+
def adder(y):
82+
return global_nest_x + y
83+
global_nest_x = x
84+
return adder
85+
86+
inc = make_adder6(1)
87+
plus10 = make_adder6(10)
88+
89+
verify(inc(1) == 2)
90+
verify(plus10(-2) == 8)
91+
92+
print "7. nearest enclosing scope"
93+
94+
def f(x):
95+
def g(y):
96+
x = 42 # check that this masks binding in f()
97+
def h(z):
98+
return x + z
99+
return h
100+
return g(2)
101+
102+
test_func = f(10)
103+
verify(test_func(5) == 47)
104+
105+
print "8. mixed freevars and cellvars"
106+
107+
def identity(x):
108+
return x
109+
110+
def f(x, y, z):
111+
def g(a, b, c):
112+
a = a + x # 3
113+
def h():
114+
# z * (4 + 9)
115+
# 3 * 13
116+
return identity(z * (b + y))
117+
y = c + z # 9
118+
return h
119+
return g
120+
121+
g = f(1, 2, 3)
122+
h = g(2, 4, 6)
123+
verify(h() == 39)
124+
125+
print "9. free variable in method"
126+
127+
def test():
128+
method_and_var = "var"
129+
class Test:
130+
def method_and_var(self):
131+
return "method"
132+
def test(self):
133+
return method_and_var
134+
def actual_global(self):
135+
return str("global")
136+
def str(self):
137+
return str(self)
138+
return Test()
139+
140+
t = test()
141+
verify(t.test() == "var")
142+
verify(t.method_and_var() == "method")
143+
verify(t.actual_global() == "global")
144+
145+
method_and_var = "var"
146+
class Test:
147+
# this class is not nested, so the rules are different
148+
def method_and_var(self):
149+
return "method"
150+
def test(self):
151+
return method_and_var
152+
def actual_global(self):
153+
return str("global")
154+
def str(self):
155+
return str(self)
156+
157+
t = test()
158+
verify(t.test() == "var")
159+
verify(t.method_and_var() == "method")
160+
verify(t.actual_global() == "global")
161+
162+
print "10. recursion"
163+
164+
def f(x):
165+
def fact(n):
166+
if n == 0:
167+
return 1
168+
else:
169+
return n * fact(n - 1)
170+
if x >= 0:
171+
return fact(x)
172+
else:
173+
raise ValueError, "x must be >= 0"
174+
175+
verify(f(6) == 720)
176+
177+
178+
print "11. unoptimized namespaces"
179+
180+
def check_syntax(s):
181+
try:
182+
compile(s, '?', 'exec')
183+
except SyntaxError:
184+
pass
185+
else:
186+
raise TestFailed
187+
188+
# XXX for now, it is easiest to call this a syntax error:
189+
# explicit is better than implicit...
190+
test1 = \
191+
"""def unoptimized_clash1(strip):
192+
def f(s):
193+
from string import *
194+
return strip(s) # ambiguity: free or local
195+
return f
196+
"""
197+
check_syntax(test1)
198+
199+
# a little harder to reject this one, but possible...
200+
test2 = \
201+
"""def unoptimized_clash2():
202+
from string import *
203+
def f(s):
204+
return strip(s) # ambiguity: global or local
205+
return f
206+
"""
207+
# check_syntax(test2)
208+
209+
# XXX could allow this for exec with const argument, but what's the point
210+
test3 = \
211+
"""def error(y):
212+
exec "a = 1"
213+
def f(x):
214+
return x + y
215+
return f
216+
"""
217+
check_syntax(test3)
218+
219+
test4 = \
220+
"""def f(x):
221+
def g():
222+
return x
223+
del x
224+
"""
225+
check_syntax(test4)
226+
227+
print "12. lambdas"
228+
229+
f1 = lambda x: lambda y: x + y
230+
inc = f1(1)
231+
plus10 = f1(10)
232+
verify(inc(1) == 2)
233+
verify(plus10(5) == 15)
234+
235+
f2 = lambda x: (lambda : lambda y: x + y)()
236+
inc = f2(1)
237+
plus10 = f2(10)
238+
verify(inc(1) == 2)
239+
verify(plus10(5) == 15)
240+
241+
f3 = lambda x: lambda y: global_x + y
242+
global_x = 1
243+
inc = f3(None)
244+
verify(inc(2) == 3)
245+
246+
f8 = lambda x, y, z: lambda a, b, c: lambda : z * (b + y)
247+
g = f8(1, 2, 3)
248+
h = g(2, 4, 6)
249+
verify(h() == 18)

0 commit comments

Comments
 (0)