| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  | import unittest | 
					
						
							|  |  |  | from test.test_support import check_syntax_error, run_unittest | 
					
						
							| 
									
										
										
										
											2001-01-25 20:11:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-08-07 16:38:19 +00:00
										 |  |  | import warnings | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  | warnings.filterwarnings("ignore", r"import \*", SyntaxWarning, "<test string>") | 
					
						
							| 
									
										
										
										
											2001-12-15 18:04:10 +00:00
										 |  |  | warnings.filterwarnings("ignore", r"import \*", SyntaxWarning, "<string>") | 
					
						
							| 
									
										
										
										
											2001-08-07 16:38:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  | class ScopeTests(unittest.TestCase): | 
					
						
							| 
									
										
										
										
											2001-01-25 20:11:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |     def testSimpleNesting(self): | 
					
						
							| 
									
										
										
										
											2006-11-03 02:32:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         def make_adder(x): | 
					
						
							|  |  |  |             def adder(y): | 
					
						
							|  |  |  |                 return x + y | 
					
						
							|  |  |  |             return adder | 
					
						
							| 
									
										
										
										
											2001-01-25 20:11:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         inc = make_adder(1) | 
					
						
							|  |  |  |         plus10 = make_adder(10) | 
					
						
							| 
									
										
										
										
											2001-01-25 20:11:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         self.assertEqual(inc(1), 2) | 
					
						
							|  |  |  |         self.assertEqual(plus10(-2), 8) | 
					
						
							| 
									
										
										
										
											2001-01-25 20:11:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |     def testExtraNesting(self): | 
					
						
							| 
									
										
										
										
											2001-01-25 20:11:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         def make_adder2(x): | 
					
						
							|  |  |  |             def extra(): # check freevars passing through non-use scopes | 
					
						
							|  |  |  |                 def adder(y): | 
					
						
							|  |  |  |                     return x + y | 
					
						
							|  |  |  |                 return adder | 
					
						
							|  |  |  |             return extra() | 
					
						
							| 
									
										
										
										
											2001-01-25 20:11:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         inc = make_adder2(1) | 
					
						
							|  |  |  |         plus10 = make_adder2(10) | 
					
						
							| 
									
										
										
										
											2001-01-25 20:11:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         self.assertEqual(inc(1), 2) | 
					
						
							|  |  |  |         self.assertEqual(plus10(-2), 8) | 
					
						
							| 
									
										
										
										
											2001-01-25 20:11:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |     def testSimpleAndRebinding(self): | 
					
						
							| 
									
										
										
										
											2001-01-25 20:11:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         def make_adder3(x): | 
					
						
							|  |  |  |             def adder(y): | 
					
						
							|  |  |  |                 return x + y | 
					
						
							|  |  |  |             x = x + 1 # check tracking of assignment to x in defining scope | 
					
						
							|  |  |  |             return adder | 
					
						
							| 
									
										
										
										
											2001-01-25 20:11:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         inc = make_adder3(0) | 
					
						
							|  |  |  |         plus10 = make_adder3(9) | 
					
						
							| 
									
										
										
										
											2001-01-25 20:11:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         self.assertEqual(inc(1), 2) | 
					
						
							|  |  |  |         self.assertEqual(plus10(-2), 8) | 
					
						
							| 
									
										
										
										
											2001-01-25 20:11:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |     def testNestingGlobalNoFree(self): | 
					
						
							| 
									
										
										
										
											2001-01-25 20:11:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         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() | 
					
						
							| 
									
										
										
										
											2001-01-25 20:11:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         global_x = 1 | 
					
						
							|  |  |  |         adder = make_adder4() | 
					
						
							|  |  |  |         self.assertEqual(adder(1), 2) | 
					
						
							| 
									
										
										
										
											2001-01-25 20:11:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         global_x = 10 | 
					
						
							|  |  |  |         self.assertEqual(adder(-2), 8) | 
					
						
							| 
									
										
										
										
											2001-01-25 20:11:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |     def testNestingThroughClass(self): | 
					
						
							| 
									
										
										
										
											2001-01-25 20:11:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         def make_adder5(x): | 
					
						
							|  |  |  |             class Adder: | 
					
						
							|  |  |  |                 def __call__(self, y): | 
					
						
							|  |  |  |                     return x + y | 
					
						
							|  |  |  |             return Adder() | 
					
						
							| 
									
										
										
										
											2001-01-25 20:11:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         inc = make_adder5(1) | 
					
						
							|  |  |  |         plus10 = make_adder5(10) | 
					
						
							| 
									
										
										
										
											2001-01-25 20:11:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         self.assertEqual(inc(1), 2) | 
					
						
							|  |  |  |         self.assertEqual(plus10(-2), 8) | 
					
						
							| 
									
										
										
										
											2001-01-25 20:11:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |     def testNestingPlusFreeRefToGlobal(self): | 
					
						
							| 
									
										
										
										
											2001-01-25 20:11:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         def make_adder6(x): | 
					
						
							|  |  |  |             global global_nest_x | 
					
						
							|  |  |  |             def adder(y): | 
					
						
							|  |  |  |                 return global_nest_x + y | 
					
						
							|  |  |  |             global_nest_x = x | 
					
						
							|  |  |  |             return adder | 
					
						
							| 
									
										
										
										
											2001-01-25 20:11:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         inc = make_adder6(1) | 
					
						
							|  |  |  |         plus10 = make_adder6(10) | 
					
						
							| 
									
										
										
										
											2001-01-25 20:11:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         self.assertEqual(inc(1), 11) # there's only one global | 
					
						
							|  |  |  |         self.assertEqual(plus10(-2), 8) | 
					
						
							| 
									
										
										
										
											2001-01-25 20:11:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |     def testNearestEnclosingScope(self): | 
					
						
							| 
									
										
										
										
											2001-01-25 20:11:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         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) | 
					
						
							| 
									
										
										
										
											2001-01-25 20:11:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         test_func = f(10) | 
					
						
							|  |  |  |         self.assertEqual(test_func(5), 47) | 
					
						
							| 
									
										
										
										
											2001-01-25 20:11:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |     def testMixedFreevarsAndCellvars(self): | 
					
						
							| 
									
										
										
										
											2001-01-25 20:11:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         def identity(x): | 
					
						
							|  |  |  |             return x | 
					
						
							| 
									
										
										
										
											2001-01-25 20:11:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         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, """\
 | 
					
						
							| 
									
										
										
										
											2001-02-27 20:23:58 +00:00
										 |  |  | def unoptimized_clash1(strip): | 
					
						
							| 
									
										
										
										
											2001-01-25 20:11:23 +00:00
										 |  |  |     def f(s): | 
					
						
							|  |  |  |         from string import * | 
					
						
							|  |  |  |         return strip(s) # ambiguity: free or local | 
					
						
							|  |  |  |     return f | 
					
						
							| 
									
										
										
										
											2001-02-09 22:56:46 +00:00
										 |  |  | """)
 | 
					
						
							| 
									
										
										
										
											2001-01-25 20:11:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         check_syntax_error(self, """\
 | 
					
						
							| 
									
										
										
										
											2001-02-27 20:23:58 +00:00
										 |  |  | def unoptimized_clash2(): | 
					
						
							| 
									
										
										
										
											2001-01-25 20:11:23 +00:00
										 |  |  |     from string import * | 
					
						
							|  |  |  |     def f(s): | 
					
						
							|  |  |  |         return strip(s) # ambiguity: global or local | 
					
						
							|  |  |  |     return f | 
					
						
							| 
									
										
										
										
											2001-02-09 22:56:46 +00:00
										 |  |  | """)
 | 
					
						
							| 
									
										
										
										
											2001-01-25 20:11:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         check_syntax_error(self, """\
 | 
					
						
							| 
									
										
										
										
											2001-02-27 20:23:58 +00:00
										 |  |  | def unoptimized_clash2(): | 
					
						
							| 
									
										
										
										
											2001-02-09 22:56:46 +00:00
										 |  |  |     from string import * | 
					
						
							|  |  |  |     def g(): | 
					
						
							|  |  |  |         def f(s): | 
					
						
							|  |  |  |             return strip(s) # ambiguity: global or local | 
					
						
							|  |  |  |         return f | 
					
						
							|  |  |  | """)
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         # XXX could allow this for exec with const argument, but what's the point | 
					
						
							|  |  |  |         check_syntax_error(self, """\
 | 
					
						
							| 
									
										
										
										
											2001-02-27 20:23:58 +00:00
										 |  |  | def error(y): | 
					
						
							| 
									
										
										
										
											2001-01-25 20:11:23 +00:00
										 |  |  |     exec "a = 1" | 
					
						
							|  |  |  |     def f(x): | 
					
						
							|  |  |  |         return x + y | 
					
						
							|  |  |  |     return f | 
					
						
							| 
									
										
										
										
											2001-02-09 22:56:46 +00:00
										 |  |  | """)
 | 
					
						
							| 
									
										
										
										
											2001-01-25 20:11:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         check_syntax_error(self, """\
 | 
					
						
							| 
									
										
										
										
											2001-02-27 20:23:58 +00:00
										 |  |  | def f(x): | 
					
						
							| 
									
										
										
										
											2001-01-25 20:11:23 +00:00
										 |  |  |     def g(): | 
					
						
							|  |  |  |         return x | 
					
						
							| 
									
										
										
										
											2001-02-09 22:56:46 +00:00
										 |  |  |     del x # can't del name | 
					
						
							|  |  |  | """)
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         check_syntax_error(self, """\
 | 
					
						
							| 
									
										
										
										
											2001-02-27 20:23:58 +00:00
										 |  |  | def f(): | 
					
						
							| 
									
										
										
										
											2001-02-09 22:56:46 +00:00
										 |  |  |     def g(): | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         from string import * | 
					
						
							|  |  |  |         return strip # global or local? | 
					
						
							| 
									
										
										
										
											2001-02-15 23:56:39 +00:00
										 |  |  | """)
 | 
					
						
							| 
									
										
										
										
											2001-02-09 22:56:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         # and verify a few cases that should work | 
					
						
							| 
									
										
										
										
											2001-02-09 22:56:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         exec """
 | 
					
						
							| 
									
										
										
										
											2001-02-09 22:56:46 +00:00
										 |  |  | 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 | 
					
						
							| 
									
										
										
										
											2001-08-07 16:38:19 +00:00
										 |  |  | """
 | 
					
						
							| 
									
										
										
										
											2001-01-25 20:11:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |     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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-02 22:56:16 +00:00
										 |  |  |         self.assertRaises(UnboundLocalError, errorInOuter) | 
					
						
							|  |  |  |         self.assertRaises(NameError, errorInInner) | 
					
						
							| 
									
										
										
										
											2001-02-09 22:56:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         # test for bug #1501934: incorrect LOAD/STORE_GLOBAL generation | 
					
						
							|  |  |  |         exec """
 | 
					
						
							| 
									
										
										
										
											2006-07-09 16:16:34 +00:00
										 |  |  | global_x = 1 | 
					
						
							|  |  |  | def f(): | 
					
						
							|  |  |  |     global_x += 1 | 
					
						
							|  |  |  | try: | 
					
						
							|  |  |  |     f() | 
					
						
							|  |  |  | except UnboundLocalError: | 
					
						
							|  |  |  |     pass | 
					
						
							|  |  |  | else: | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |     fail('scope of global_x not correctly determined') | 
					
						
							|  |  |  | """ in {'fail': self.fail}
 | 
					
						
							| 
									
										
										
										
											2006-07-09 16:16:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |     def testComplexDefinitions(self): | 
					
						
							| 
									
										
										
										
											2001-02-09 22:56:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         def makeReturner(*lst): | 
					
						
							|  |  |  |             def returner(): | 
					
						
							|  |  |  |                 return lst | 
					
						
							|  |  |  |             return returner | 
					
						
							| 
									
										
										
										
											2001-02-15 23:56:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         self.assertEqual(makeReturner(1,2,3)(), (1,2,3)) | 
					
						
							| 
									
										
										
										
											2001-02-15 23:56:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         def makeReturner2(**kwargs): | 
					
						
							|  |  |  |             def returner(): | 
					
						
							|  |  |  |                 return kwargs | 
					
						
							|  |  |  |             return returner | 
					
						
							| 
									
										
										
										
											2001-02-09 22:56:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         self.assertEqual(makeReturner2(a=11)()['a'], 11) | 
					
						
							| 
									
										
										
										
											2001-02-09 22:56:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-08 19:04:16 +00:00
										 |  |  |         def makeAddPair((a, b)): | 
					
						
							|  |  |  |             def addPair((c, d)): | 
					
						
							|  |  |  |                 return (a + c, b + d) | 
					
						
							|  |  |  |             return addPair | 
					
						
							| 
									
										
										
										
											2001-02-09 22:56:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         self.assertEqual(makeAddPair((1, 2))((100, 200)), (101,202)) | 
					
						
							| 
									
										
										
										
											2001-03-01 20:35:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |     def testScopeOfGlobalStmt(self): | 
					
						
							| 
									
										
										
										
											2001-03-01 20:35:45 +00:00
										 |  |  | # Examples posted by Samuele Pedroni to python-dev on 3/1/2001 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         exec """\
 | 
					
						
							| 
									
										
										
										
											2001-03-01 20:35:45 +00:00
										 |  |  | # I | 
					
						
							|  |  |  | x = 7 | 
					
						
							|  |  |  | def f(): | 
					
						
							|  |  |  |     x = 1 | 
					
						
							|  |  |  |     def g(): | 
					
						
							|  |  |  |         global x | 
					
						
							|  |  |  |         def i(): | 
					
						
							|  |  |  |             def h(): | 
					
						
							|  |  |  |                 return x | 
					
						
							|  |  |  |             return h() | 
					
						
							|  |  |  |         return i() | 
					
						
							|  |  |  |     return g() | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  | self.assertEqual(f(), 7) | 
					
						
							|  |  |  | self.assertEqual(x, 7) | 
					
						
							| 
									
										
										
										
											2001-03-01 20:35:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # II | 
					
						
							|  |  |  | x = 7 | 
					
						
							|  |  |  | def f(): | 
					
						
							|  |  |  |     x = 1 | 
					
						
							|  |  |  |     def g(): | 
					
						
							|  |  |  |         x = 2 | 
					
						
							|  |  |  |         def i(): | 
					
						
							|  |  |  |             def h(): | 
					
						
							|  |  |  |                 return x | 
					
						
							|  |  |  |             return h() | 
					
						
							|  |  |  |         return i() | 
					
						
							|  |  |  |     return g() | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  | self.assertEqual(f(), 2) | 
					
						
							|  |  |  | self.assertEqual(x, 7) | 
					
						
							| 
									
										
										
										
											2001-03-01 20:35:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # 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() | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  | self.assertEqual(f(), 2) | 
					
						
							|  |  |  | self.assertEqual(x, 2) | 
					
						
							| 
									
										
										
										
											2001-03-01 20:35:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # 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() | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  | self.assertEqual(f(), 2) | 
					
						
							|  |  |  | self.assertEqual(x, 2) | 
					
						
							| 
									
										
										
										
											2005-10-20 19:59:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # 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() | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  | self.assertEqual(g.get(), 13) | 
					
						
							| 
									
										
										
										
											2005-10-20 19:59:25 +00:00
										 |  |  | g.set(15) | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  | self.assertEqual(g.get(), 13) | 
					
						
							|  |  |  | """
 | 
					
						
							| 
									
										
										
										
											2001-03-13 02:01:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |     def testLeaks(self): | 
					
						
							| 
									
										
										
										
											2001-03-13 02:01:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         class Foo: | 
					
						
							|  |  |  |             count = 0 | 
					
						
							| 
									
										
										
										
											2001-03-16 08:29:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |             def __init__(self): | 
					
						
							|  |  |  |                 Foo.count += 1 | 
					
						
							| 
									
										
										
										
											2001-03-13 02:01:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |             def __del__(self): | 
					
						
							|  |  |  |                 Foo.count -= 1 | 
					
						
							| 
									
										
										
										
											2001-03-13 02:01:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         def f1(): | 
					
						
							|  |  |  |             x = Foo() | 
					
						
							|  |  |  |             def f2(): | 
					
						
							|  |  |  |                 return x | 
					
						
							|  |  |  |             f2() | 
					
						
							| 
									
										
										
										
											2001-03-16 08:29:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         for i in range(100): | 
					
						
							|  |  |  |             f1() | 
					
						
							| 
									
										
										
										
											2001-03-13 02:01:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         self.assertEqual(Foo.count, 0) | 
					
						
							| 
									
										
										
										
											2001-03-21 16:44:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |     def testClassAndGlobal(self): | 
					
						
							| 
									
										
										
										
											2001-03-21 16:44:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         exec """\
 | 
					
						
							| 
									
										
										
										
											2001-03-21 16:44:39 +00:00
										 |  |  | def test(x): | 
					
						
							|  |  |  |     class Foo: | 
					
						
							|  |  |  |         global x | 
					
						
							|  |  |  |         def __call__(self, y): | 
					
						
							|  |  |  |             return x + y | 
					
						
							|  |  |  |     return Foo() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | x = 0 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  | self.assertEqual(test(6)(2), 8) | 
					
						
							| 
									
										
										
										
											2001-03-21 16:44:39 +00:00
										 |  |  | x = -1 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  | self.assertEqual(test(3)(2), 5) | 
					
						
							| 
									
										
										
										
											2001-03-21 16:44:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-23 04:24:49 +00:00
										 |  |  | 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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 22:57:08 +00:00
										 |  |  | self.assertTrue(X.passed) | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  | """
 | 
					
						
							| 
									
										
										
										
											2005-10-23 04:24:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |     def testLocalsFunction(self): | 
					
						
							| 
									
										
										
										
											2001-03-21 16:44:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         def f(x): | 
					
						
							|  |  |  |             def g(y): | 
					
						
							|  |  |  |                 def h(z): | 
					
						
							|  |  |  |                     return y + z | 
					
						
							|  |  |  |                 w = x + y | 
					
						
							|  |  |  |                 y += 3 | 
					
						
							|  |  |  |                 return locals() | 
					
						
							|  |  |  |             return g | 
					
						
							| 
									
										
										
										
											2001-03-21 16:44:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         d = f(2)(4) | 
					
						
							| 
									
										
										
										
											2010-01-08 19:04:16 +00:00
										 |  |  |         self.assertTrue(d.has_key('h')) | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         del d['h'] | 
					
						
							|  |  |  |         self.assertEqual(d, {'x': 2, 'y': 7, 'w': 6}) | 
					
						
							| 
									
										
										
										
											2001-04-13 16:51:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-02-26 18:41:18 +00:00
										 |  |  |     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 | 
					
						
							| 
									
										
										
										
											2010-01-23 23:04:36 +00:00
										 |  |  |         self.assertNotIn("x", varnames) | 
					
						
							|  |  |  |         self.assertIn("y", varnames) | 
					
						
							| 
									
										
										
										
											2007-02-26 18:41:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-21 22:00:38 +00:00
										 |  |  |     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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-21 22:05:34 +00:00
										 |  |  |             self.assertEquals(x, 12) # Used to raise UnboundLocalError | 
					
						
							| 
									
										
										
										
											2008-07-21 22:00:38 +00:00
										 |  |  |         finally: | 
					
						
							|  |  |  |             sys.settrace(None) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |     def testBoundAndFree(self): | 
					
						
							|  |  |  |         # var is bound and free in class | 
					
						
							| 
									
										
										
										
											2001-04-27 02:29:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         def f(x): | 
					
						
							|  |  |  |             class C: | 
					
						
							|  |  |  |                 def m(self): | 
					
						
							|  |  |  |                     return x | 
					
						
							|  |  |  |                 a = x | 
					
						
							|  |  |  |             return C | 
					
						
							| 
									
										
										
										
											2001-04-27 02:29:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         inst = f(3)() | 
					
						
							|  |  |  |         self.assertEqual(inst.a, inst.m()) | 
					
						
							| 
									
										
										
										
											2001-05-08 04:08:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |     def testInteractionWithTraceFunc(self): | 
					
						
							| 
									
										
										
										
											2001-05-08 04:08:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         import sys | 
					
						
							|  |  |  |         def tracer(a,b,c): | 
					
						
							|  |  |  |             return tracer | 
					
						
							| 
									
										
										
										
											2001-05-08 04:08:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         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) | 
					
						
							| 
									
										
										
										
											2001-05-08 04:08:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         class TestClass: | 
					
						
							|  |  |  |             pass | 
					
						
							| 
									
										
										
										
											2001-05-08 04:08:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         sys.settrace(tracer) | 
					
						
							|  |  |  |         adaptgetter("foo", TestClass, (1, "")) | 
					
						
							|  |  |  |         sys.settrace(None) | 
					
						
							| 
									
										
										
										
											2001-07-30 21:55:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         self.assertRaises(TypeError, sys.settrace) | 
					
						
							| 
									
										
										
										
											2002-03-03 15:12:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |     def testEvalExecFreeVars(self): | 
					
						
							| 
									
										
										
										
											2001-07-30 21:55:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         def f(x): | 
					
						
							|  |  |  |             return lambda: x + 1 | 
					
						
							| 
									
										
										
										
											2001-07-30 21:55:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         g = f(3) | 
					
						
							|  |  |  |         self.assertRaises(TypeError, eval, g.func_code) | 
					
						
							| 
									
										
										
										
											2001-08-07 16:38:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         try: | 
					
						
							|  |  |  |             exec g.func_code in {} | 
					
						
							|  |  |  |         except TypeError: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.fail("exec should have failed, because code contained free vars") | 
					
						
							| 
									
										
										
										
											2001-12-13 19:45:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |     def testListCompLocalVars(self): | 
					
						
							| 
									
										
										
										
											2001-10-18 16:23:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         try: | 
					
						
							|  |  |  |             print bad | 
					
						
							|  |  |  |         except NameError: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             print "bad should not be defined" | 
					
						
							| 
									
										
										
										
											2001-10-18 16:23:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         def x(): | 
					
						
							|  |  |  |             [bad for s in 'a b' for bad in s.split()] | 
					
						
							| 
									
										
										
										
											2001-10-18 16:23:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         x() | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             print bad | 
					
						
							|  |  |  |         except NameError: | 
					
						
							|  |  |  |             pass | 
					
						
							| 
									
										
										
										
											2002-04-20 04:51:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |     def testEvalFreeVars(self): | 
					
						
							| 
									
										
										
										
											2002-04-20 04:51:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  |         def f(x): | 
					
						
							|  |  |  |             def g(): | 
					
						
							|  |  |  |                 x | 
					
						
							|  |  |  |                 eval("x + 1") | 
					
						
							|  |  |  |             return g | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         f(4)() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-16 20:55:24 +00:00
										 |  |  |     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... | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-31 13:48:15 +00:00
										 |  |  |     def testGlobalInParallelNestedFunctions(self): | 
					
						
							|  |  |  |         # A symbol table bug leaked the global statement from one | 
					
						
							|  |  |  |         # function to other nested functions in the same block. | 
					
						
							|  |  |  |         # This test verifies that a global statement in the first | 
					
						
							|  |  |  |         # function does not affect the second function. | 
					
						
							|  |  |  |         CODE = """def f():
 | 
					
						
							|  |  |  |     y = 1 | 
					
						
							|  |  |  |     def g(): | 
					
						
							|  |  |  |         global y | 
					
						
							|  |  |  |         return y | 
					
						
							|  |  |  |     def h(): | 
					
						
							|  |  |  |         return y + 1 | 
					
						
							|  |  |  |     return g, h | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | y = 9 | 
					
						
							|  |  |  | g, h = f() | 
					
						
							|  |  |  | result9 = g() | 
					
						
							|  |  |  | result2 = h() | 
					
						
							|  |  |  | """
 | 
					
						
							|  |  |  |         local_ns = {} | 
					
						
							|  |  |  |         global_ns = {} | 
					
						
							|  |  |  |         exec CODE in local_ns, global_ns | 
					
						
							|  |  |  |         self.assertEqual(2, global_ns["result2"]) | 
					
						
							|  |  |  |         self.assertEqual(9, global_ns["result9"]) | 
					
						
							| 
									
										
										
										
											2008-02-16 20:55:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def test_main(): | 
					
						
							|  |  |  |     run_unittest(ScopeTests) | 
					
						
							| 
									
										
										
										
											2002-04-20 04:51:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-28 13:10:17 +00:00
										 |  |  | if __name__ == '__main__': | 
					
						
							|  |  |  |     test_main() |