mirror of
				https://github.com/python/cpython.git
				synced 2025-11-01 06:01:29 +00:00 
			
		
		
		
	Convert test_global, test_scope and test_grammar to unittest.
I tried to enclose all tests which must be run at the toplevel (instead of inside a method) in exec statements.
This commit is contained in:
		
							parent
							
								
									3a3d8ea497
								
							
						
					
					
						commit
						c6fdec6d7e
					
				
					 8 changed files with 1203 additions and 1228 deletions
				
			
		|  | @ -379,8 +379,8 @@ test_support provides the following useful objects: | |||
|       point numbers when you expect them to only be approximately equal | ||||
|       withing a fuzz factor (``test_support.FUZZ``, which defaults to 1e-6). | ||||
| 
 | ||||
|     * ``check_syntax(statement)`` - make sure that the statement is *not* | ||||
|       correct Python syntax. | ||||
|     * ``check_syntax_error(testcase, statement)`` - make sure that the | ||||
|       statement is *not* correct Python syntax. | ||||
| 
 | ||||
| 
 | ||||
| Python and C statement coverage results are currently available at | ||||
|  |  | |||
|  | @ -1,5 +0,0 @@ | |||
| test_global | ||||
| got SyntaxError as expected | ||||
| got SyntaxError as expected | ||||
| got SyntaxError as expected | ||||
| as expected, no SyntaxError | ||||
|  | @ -1,69 +0,0 @@ | |||
| test_grammar | ||||
| 1. Parser | ||||
| 1.1 Tokens | ||||
| 1.1.1 Backslashes | ||||
| 1.1.2 Numeric literals | ||||
| 1.1.2.1 Plain integers | ||||
| 1.1.2.2 Long integers | ||||
| 1.1.2.3 Floating point | ||||
| 1.1.3 String literals | ||||
| 1.2 Grammar | ||||
| single_input | ||||
| file_input | ||||
| expr_input | ||||
| eval_input | ||||
| funcdef | ||||
| lambdef | ||||
| simple_stmt | ||||
| expr_stmt | ||||
| print_stmt | ||||
| 1 2 3 | ||||
| 1 2 3 | ||||
| 1 1 1 | ||||
| extended print_stmt | ||||
| 1 2 3 | ||||
| 1 2 3 | ||||
| 1 1 1 | ||||
| hello world | ||||
| del_stmt | ||||
| pass_stmt | ||||
| flow_stmt | ||||
| break_stmt | ||||
| continue_stmt | ||||
| continue + try/except ok | ||||
| continue + try/finally ok | ||||
| testing continue and break in try/except in loop | ||||
| return_stmt | ||||
| yield_stmt | ||||
| raise_stmt | ||||
| import_name | ||||
| import_from | ||||
| global_stmt | ||||
| exec_stmt | ||||
| assert_stmt | ||||
| if_stmt | ||||
| while_stmt | ||||
| for_stmt | ||||
| try_stmt | ||||
| suite | ||||
| test | ||||
| comparison | ||||
| binary mask ops | ||||
| shift ops | ||||
| additive ops | ||||
| multiplicative ops | ||||
| unary ops | ||||
| selectors | ||||
| 
 | ||||
| [1, (1,), (1, 2), (1, 2, 3)] | ||||
| atoms | ||||
| classdef | ||||
| ['Apple', 'Banana', 'Coco  nut'] | ||||
| [3, 6, 9, 12, 15] | ||||
| [3, 4, 5] | ||||
| [(1, 'Apple'), (1, 'Banana'), (1, 'Coconut'), (2, 'Apple'), (2, 'Banana'), (2, 'Coconut'), (3, 'Apple'), (3, 'Banana'), (3, 'Coconut'), (4, 'Apple'), (4, 'Banana'), (4, 'Coconut'), (5, 'Apple'), (5, 'Banana'), (5, 'Coconut')] | ||||
| [(1, 'Banana'), (1, 'Coconut'), (2, 'Banana'), (2, 'Coconut'), (3, 'Banana'), (3, 'Coconut'), (4, 'Banana'), (4, 'Coconut'), (5, 'Banana'), (5, 'Coconut')] | ||||
| [[1], [1, 1], [1, 2, 4], [1, 3, 9, 27], [1, 4, 16, 64, 256]] | ||||
| [False, False, False] | ||||
| [[1, 2], [3, 4], [5, 6]] | ||||
| [('Boeing', 'Airliner'), ('Boeing', 'Engine'), ('Ford', 'Engine'), ('Macdonalds', 'Cheeseburger')] | ||||
|  | @ -1,24 +0,0 @@ | |||
| test_scope | ||||
| 1. simple nesting | ||||
| 2. extra nesting | ||||
| 3. simple nesting + rebinding | ||||
| 4. nesting with global but no free | ||||
| 5. nesting through class | ||||
| 6. nesting plus free ref to global | ||||
| 7. nearest enclosing scope | ||||
| 8. mixed freevars and cellvars | ||||
| 9. free variable in method | ||||
| 10. recursion | ||||
| 11. unoptimized namespaces | ||||
| 12. lambdas | ||||
| 13. UnboundLocal | ||||
| 14. complex definitions | ||||
| 15. scope of global statements | ||||
| 16. check leaks | ||||
| 17. class and global | ||||
| 18. verify that locals() works | ||||
| 19. var is bound and free in class | ||||
| 20. interaction with trace function | ||||
| 20. eval and exec with free variables | ||||
| 21. list comprehension with local variables | ||||
| 22. eval with free variables | ||||
|  | @ -1,51 +1,51 @@ | |||
| """Verify that warnings are issued for global statements following use.""" | ||||
| 
 | ||||
| from test.test_support import check_syntax | ||||
| from test.test_support import run_unittest, check_syntax_error | ||||
| import unittest | ||||
| 
 | ||||
| import warnings | ||||
| warnings.filterwarnings("error", module="<test string>") | ||||
| 
 | ||||
| warnings.filterwarnings("error", module="<test code>") | ||||
| class GlobalTests(unittest.TestCase): | ||||
| 
 | ||||
| def compile_and_check(text, should_fail=1): | ||||
|     try: | ||||
|         compile(text, "<test code>", "exec") | ||||
|     except SyntaxError, msg: | ||||
|         if should_fail: | ||||
|             print "got SyntaxError as expected" | ||||
|         else: | ||||
|             print "raised unexpected SyntaxError:", text | ||||
|     else: | ||||
|         if should_fail: | ||||
|             print "should have raised SyntaxError:", text | ||||
|         else: | ||||
|             print "as expected, no SyntaxError" | ||||
| 
 | ||||
| prog_text_1 = """ | ||||
|     def test1(self): | ||||
|         prog_text_1 = """\ | ||||
| def wrong1(): | ||||
|     a = 1 | ||||
|     b = 2 | ||||
|     global a | ||||
|     global b | ||||
| """ | ||||
| compile_and_check(prog_text_1) | ||||
|         check_syntax_error(self, prog_text_1) | ||||
| 
 | ||||
| prog_text_2 = """ | ||||
|     def test2(self): | ||||
|         prog_text_2 = """\ | ||||
| def wrong2(): | ||||
|     print x | ||||
|     global x | ||||
| """ | ||||
| compile_and_check(prog_text_2) | ||||
|         check_syntax_error(self, prog_text_2) | ||||
| 
 | ||||
| prog_text_3 = """ | ||||
|     def test3(self): | ||||
|         prog_text_3 = """\ | ||||
| def wrong3(): | ||||
|     print x | ||||
|     x = 2 | ||||
|     global x | ||||
| """ | ||||
| compile_and_check(prog_text_3) | ||||
|         check_syntax_error(self, prog_text_3) | ||||
| 
 | ||||
| prog_text_4 = """ | ||||
|     def test4(self): | ||||
|         prog_text_4 = """\ | ||||
| global x | ||||
| x = 2 | ||||
| """ | ||||
| compile_and_check(prog_text_4, 0) | ||||
|         # this should work | ||||
|         compile(prog_text_4, "<test string>", "exec") | ||||
| 
 | ||||
| 
 | ||||
| def test_main(): | ||||
|     run_unittest(GlobalTests) | ||||
| 
 | ||||
| if __name__ == "__main__": | ||||
|     test_main() | ||||
|  |  | |||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -1,186 +1,190 @@ | |||
| from test.test_support import verify, TestFailed, check_syntax, vereq | ||||
| 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>") | ||||
| 
 | ||||
| print "1. simple nesting" | ||||
| class ScopeTests(unittest.TestCase): | ||||
| 
 | ||||
| def make_adder(x): | ||||
|     def adder(y): | ||||
|         return x + y | ||||
|     return adder | ||||
| 
 | ||||
| inc = make_adder(1) | ||||
| plus10 = make_adder(10) | ||||
| 
 | ||||
| vereq(inc(1), 2) | ||||
| vereq(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) | ||||
| 
 | ||||
| vereq(inc(1), 2) | ||||
| vereq(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) | ||||
| 
 | ||||
| vereq(inc(1), 2) | ||||
| vereq(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 testSimpleNesting(self): | ||||
|          | ||||
|         def make_adder(x): | ||||
|             def adder(y): | ||||
|                 return global_x + y # check that plain old globals work | ||||
|                 return x + y | ||||
|             return adder | ||||
|         return nest() | ||||
|     return nest() | ||||
| 
 | ||||
| global_x = 1 | ||||
| adder = make_adder4() | ||||
| vereq(adder(1), 2) | ||||
|         inc = make_adder(1) | ||||
|         plus10 = make_adder(10) | ||||
| 
 | ||||
| global_x = 10 | ||||
| vereq(adder(-2), 8) | ||||
|         self.assertEqual(inc(1), 2) | ||||
|         self.assertEqual(plus10(-2), 8) | ||||
| 
 | ||||
| print "5. nesting through class" | ||||
|     def testExtraNesting(self): | ||||
| 
 | ||||
| def make_adder5(x): | ||||
|     class Adder: | ||||
|         def __call__(self, y): | ||||
|             return x + y | ||||
|     return Adder() | ||||
|         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_adder5(1) | ||||
| plus10 = make_adder5(10) | ||||
|         inc = make_adder2(1) | ||||
|         plus10 = make_adder2(10) | ||||
| 
 | ||||
| vereq(inc(1), 2) | ||||
| vereq(plus10(-2), 8) | ||||
|         self.assertEqual(inc(1), 2) | ||||
|         self.assertEqual(plus10(-2), 8) | ||||
| 
 | ||||
| print "6. nesting plus free ref to global" | ||||
|     def testSimpleAndRebinding(self): | ||||
| 
 | ||||
| def make_adder6(x): | ||||
|     global global_nest_x | ||||
|     def adder(y): | ||||
|         return global_nest_x + y | ||||
|     global_nest_x = x | ||||
|     return adder | ||||
|         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_adder6(1) | ||||
| plus10 = make_adder6(10) | ||||
|         inc = make_adder3(0) | ||||
|         plus10 = make_adder3(9) | ||||
| 
 | ||||
| vereq(inc(1), 11) # there's only one global | ||||
| vereq(plus10(-2), 8) | ||||
|         self.assertEqual(inc(1), 2) | ||||
|         self.assertEqual(plus10(-2), 8) | ||||
| 
 | ||||
| print "7. nearest enclosing scope" | ||||
|     def testNestingGlobalNoFree(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) | ||||
|         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() | ||||
| 
 | ||||
| test_func = f(10) | ||||
| vereq(test_func(5), 47) | ||||
|         global_x = 1 | ||||
|         adder = make_adder4() | ||||
|         self.assertEqual(adder(1), 2) | ||||
| 
 | ||||
| print "8. mixed freevars and cellvars" | ||||
|         global_x = 10 | ||||
|         self.assertEqual(adder(-2), 8) | ||||
| 
 | ||||
| def identity(x): | ||||
|     return x | ||||
|     def testNestingThroughClass(self): | ||||
| 
 | ||||
| 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 | ||||
|         def make_adder5(x): | ||||
|             class Adder: | ||||
|                 def __call__(self, y): | ||||
|                     return x + y | ||||
|             return Adder() | ||||
| 
 | ||||
| g = f(1, 2, 3) | ||||
| h = g(2, 4, 6) | ||||
| vereq(h(), 39) | ||||
|         inc = make_adder5(1) | ||||
|         plus10 = make_adder5(10) | ||||
| 
 | ||||
| print "9. free variable in method" | ||||
|         self.assertEqual(inc(1), 2) | ||||
|         self.assertEqual(plus10(-2), 8) | ||||
| 
 | ||||
| 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() | ||||
|     def testNestingPlusFreeRefToGlobal(self): | ||||
| 
 | ||||
| t = test() | ||||
| vereq(t.test(), "var") | ||||
| vereq(t.method_and_var(), "method") | ||||
| vereq(t.actual_global(), "global") | ||||
|         def make_adder6(x): | ||||
|             global global_nest_x | ||||
|             def adder(y): | ||||
|                 return global_nest_x + y | ||||
|             global_nest_x = x | ||||
|             return adder | ||||
| 
 | ||||
| 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) | ||||
|         inc = make_adder6(1) | ||||
|         plus10 = make_adder6(10) | ||||
| 
 | ||||
| t = Test() | ||||
| vereq(t.test(), "var") | ||||
| vereq(t.method_and_var(), "method") | ||||
| vereq(t.actual_global(), "global") | ||||
|         self.assertEqual(inc(1), 11) # there's only one global | ||||
|         self.assertEqual(plus10(-2), 8) | ||||
| 
 | ||||
| print "10. recursion" | ||||
|     def testNearestEnclosingScope(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" | ||||
|         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) | ||||
| 
 | ||||
| vereq(f(6), 720) | ||||
|         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) | ||||
| 
 | ||||
| 
 | ||||
| print "11. unoptimized namespaces" | ||||
|     def testUnoptimizedNamespaces(self): | ||||
| 
 | ||||
| check_syntax("""\ | ||||
|         check_syntax_error(self, """\ | ||||
| def unoptimized_clash1(strip): | ||||
|     def f(s): | ||||
|         from string import * | ||||
|  | @ -188,7 +192,7 @@ def f(s): | |||
|     return f | ||||
| """) | ||||
| 
 | ||||
| check_syntax("""\ | ||||
|         check_syntax_error(self, """\ | ||||
| def unoptimized_clash2(): | ||||
|     from string import * | ||||
|     def f(s): | ||||
|  | @ -196,7 +200,7 @@ def f(s): | |||
|     return f | ||||
| """) | ||||
| 
 | ||||
| check_syntax("""\ | ||||
|         check_syntax_error(self, """\ | ||||
| def unoptimized_clash2(): | ||||
|     from string import * | ||||
|     def g(): | ||||
|  | @ -205,8 +209,8 @@ def f(s): | |||
|         return f | ||||
| """) | ||||
| 
 | ||||
| # XXX could allow this for exec with const argument, but what's the point | ||||
| check_syntax("""\ | ||||
|         # 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): | ||||
|  | @ -214,23 +218,23 @@ def f(x): | |||
|     return f | ||||
| """) | ||||
| 
 | ||||
| check_syntax("""\ | ||||
|         check_syntax_error(self, """\ | ||||
| def f(x): | ||||
|     def g(): | ||||
|         return x | ||||
|     del x # can't del name | ||||
| """) | ||||
| 
 | ||||
| check_syntax("""\ | ||||
|         check_syntax_error(self, """\ | ||||
| def f(): | ||||
|     def g(): | ||||
|          from string import * | ||||
|          return strip # global or local? | ||||
|         from string import * | ||||
|         return strip # global or local? | ||||
| """) | ||||
| 
 | ||||
| # and verify a few cases that should work | ||||
|         # and verify a few cases that should work | ||||
| 
 | ||||
| exec """ | ||||
|         exec """ | ||||
| def noproblem1(): | ||||
|     from string import * | ||||
|     f = lambda x:x | ||||
|  | @ -247,59 +251,60 @@ def f(x): | |||
|         y = x | ||||
| """ | ||||
| 
 | ||||
| print "12. lambdas" | ||||
|     def testLambdas(self): | ||||
| 
 | ||||
| f1 = lambda x: lambda y: x + y | ||||
| inc = f1(1) | ||||
| plus10 = f1(10) | ||||
| vereq(inc(1), 2) | ||||
| vereq(plus10(5), 15) | ||||
|         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) | ||||
| vereq(inc(1), 2) | ||||
| vereq(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) | ||||
| vereq(inc(2), 3) | ||||
|         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) | ||||
| vereq(h(), 18) | ||||
|         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) | ||||
| 
 | ||||
| print "13. UnboundLocal" | ||||
|     def testUnboundLocal(self): | ||||
| 
 | ||||
| def errorInOuter(): | ||||
|     print y | ||||
|     def inner(): | ||||
|         return y | ||||
|     y = 1 | ||||
|         def errorInOuter(): | ||||
|             print y | ||||
|             def inner(): | ||||
|                 return y | ||||
|             y = 1 | ||||
| 
 | ||||
| def errorInInner(): | ||||
|     def inner(): | ||||
|         return y | ||||
|     inner() | ||||
|     y = 1 | ||||
|         def errorInInner(): | ||||
|             def inner(): | ||||
|                 return y | ||||
|             inner() | ||||
|             y = 1 | ||||
| 
 | ||||
| try: | ||||
|     errorInOuter() | ||||
| except UnboundLocalError: | ||||
|     pass | ||||
| else: | ||||
|     raise TestFailed | ||||
|         try: | ||||
|             errorInOuter() | ||||
|         except UnboundLocalError: | ||||
|             pass | ||||
|         else: | ||||
|             self.fail() | ||||
| 
 | ||||
| try: | ||||
|     errorInInner() | ||||
| except NameError: | ||||
|     pass | ||||
| else: | ||||
|     raise TestFailed | ||||
|         try: | ||||
|             errorInInner() | ||||
|         except NameError: | ||||
|             pass | ||||
|         else: | ||||
|             self.fail() | ||||
| 
 | ||||
| # test for bug #1501934: incorrect LOAD/STORE_GLOBAL generation | ||||
|         # test for bug #1501934: incorrect LOAD/STORE_GLOBAL generation | ||||
|         exec """ | ||||
| global_x = 1 | ||||
| def f(): | ||||
|     global_x += 1 | ||||
|  | @ -308,34 +313,36 @@ def f(): | |||
| except UnboundLocalError: | ||||
|     pass | ||||
| else: | ||||
|     raise TestFailed, 'scope of global_x not correctly determined' | ||||
|     fail('scope of global_x not correctly determined') | ||||
| """ in {'fail': self.fail} | ||||
| 
 | ||||
| print "14. complex definitions" | ||||
|     def testComplexDefinitions(self): | ||||
| 
 | ||||
| def makeReturner(*lst): | ||||
|     def returner(): | ||||
|         return lst | ||||
|     return returner | ||||
|         def makeReturner(*lst): | ||||
|             def returner(): | ||||
|                 return lst | ||||
|             return returner | ||||
| 
 | ||||
| vereq(makeReturner(1,2,3)(), (1,2,3)) | ||||
|         self.assertEqual(makeReturner(1,2,3)(), (1,2,3)) | ||||
| 
 | ||||
| def makeReturner2(**kwargs): | ||||
|     def returner(): | ||||
|         return kwargs | ||||
|     return returner | ||||
|         def makeReturner2(**kwargs): | ||||
|             def returner(): | ||||
|                 return kwargs | ||||
|             return returner | ||||
| 
 | ||||
| vereq(makeReturner2(a=11)()['a'], 11) | ||||
|         self.assertEqual(makeReturner2(a=11)()['a'], 11) | ||||
| 
 | ||||
| def makeAddPair((a, b)): | ||||
|     def addPair((c, d)): | ||||
|         return (a + c, b + d) | ||||
|     return addPair | ||||
|         def makeAddPair((a, b)): | ||||
|             def addPair((c, d)): | ||||
|                 return (a + c, b + d) | ||||
|             return addPair | ||||
| 
 | ||||
| vereq(makeAddPair((1, 2))((100, 200)), (101,202)) | ||||
|         self.assertEqual(makeAddPair((1, 2))((100, 200)), (101,202)) | ||||
| 
 | ||||
| print "15. scope of global statements" | ||||
|     def testScopeOfGlobalStmt(self): | ||||
| # Examples posted by Samuele Pedroni to python-dev on 3/1/2001 | ||||
| 
 | ||||
|         exec """\ | ||||
| # I | ||||
| x = 7 | ||||
| def f(): | ||||
|  | @ -348,8 +355,8 @@ def h(): | |||
|             return h() | ||||
|         return i() | ||||
|     return g() | ||||
| vereq(f(), 7) | ||||
| vereq(x, 7) | ||||
| self.assertEqual(f(), 7) | ||||
| self.assertEqual(x, 7) | ||||
| 
 | ||||
| # II | ||||
| x = 7 | ||||
|  | @ -363,8 +370,8 @@ def h(): | |||
|             return h() | ||||
|         return i() | ||||
|     return g() | ||||
| vereq(f(), 2) | ||||
| vereq(x, 7) | ||||
| self.assertEqual(f(), 2) | ||||
| self.assertEqual(x, 7) | ||||
| 
 | ||||
| # III | ||||
| x = 7 | ||||
|  | @ -379,8 +386,8 @@ def h(): | |||
|             return h() | ||||
|         return i() | ||||
|     return g() | ||||
| vereq(f(), 2) | ||||
| vereq(x, 2) | ||||
| self.assertEqual(f(), 2) | ||||
| self.assertEqual(x, 2) | ||||
| 
 | ||||
| # IV | ||||
| x = 7 | ||||
|  | @ -395,8 +402,8 @@ def h(): | |||
|             return h() | ||||
|         return i() | ||||
|     return g() | ||||
| vereq(f(), 2) | ||||
| vereq(x, 2) | ||||
| self.assertEqual(f(), 2) | ||||
| self.assertEqual(x, 2) | ||||
| 
 | ||||
| # XXX what about global statements in class blocks? | ||||
| # do they affect methods? | ||||
|  | @ -411,34 +418,36 @@ def get(self): | |||
|         return x | ||||
| 
 | ||||
| g = Global() | ||||
| vereq(g.get(), 13) | ||||
| self.assertEqual(g.get(), 13) | ||||
| g.set(15) | ||||
| vereq(g.get(), 13) | ||||
| self.assertEqual(g.get(), 13) | ||||
| """ | ||||
| 
 | ||||
| print "16. check leaks" | ||||
|     def testLeaks(self): | ||||
| 
 | ||||
| class Foo: | ||||
|     count = 0 | ||||
|         class Foo: | ||||
|             count = 0 | ||||
| 
 | ||||
|     def __init__(self): | ||||
|         Foo.count += 1 | ||||
|             def __init__(self): | ||||
|                 Foo.count += 1 | ||||
| 
 | ||||
|     def __del__(self): | ||||
|         Foo.count -= 1 | ||||
|             def __del__(self): | ||||
|                 Foo.count -= 1 | ||||
| 
 | ||||
| def f1(): | ||||
|     x = Foo() | ||||
|     def f2(): | ||||
|         return x | ||||
|     f2() | ||||
|         def f1(): | ||||
|             x = Foo() | ||||
|             def f2(): | ||||
|                 return x | ||||
|             f2() | ||||
| 
 | ||||
| for i in range(100): | ||||
|     f1() | ||||
|         for i in range(100): | ||||
|             f1() | ||||
| 
 | ||||
| vereq(Foo.count, 0) | ||||
|         self.assertEqual(Foo.count, 0) | ||||
| 
 | ||||
| print "17. class and global" | ||||
|     def testClassAndGlobal(self): | ||||
| 
 | ||||
|         exec """\ | ||||
| def test(x): | ||||
|     class Foo: | ||||
|         global x | ||||
|  | @ -447,9 +456,9 @@ def __call__(self, y): | |||
|     return Foo() | ||||
| 
 | ||||
| x = 0 | ||||
| vereq(test(6)(2), 8) | ||||
| self.assertEqual(test(6)(2), 8) | ||||
| x = -1 | ||||
| vereq(test(3)(2), 5) | ||||
| self.assertEqual(test(3)(2), 5) | ||||
| 
 | ||||
| looked_up_by_load_name = False | ||||
| class X: | ||||
|  | @ -458,104 +467,106 @@ class X: | |||
|     locals()['looked_up_by_load_name'] = True | ||||
|     passed = looked_up_by_load_name | ||||
| 
 | ||||
| verify(X.passed) | ||||
| self.assert_(X.passed) | ||||
| """ | ||||
| 
 | ||||
| print "18. verify that locals() works" | ||||
|     def testLocalsFunction(self): | ||||
| 
 | ||||
| def f(x): | ||||
|     def g(y): | ||||
|         def h(z): | ||||
|             return y + z | ||||
|         w = x + y | ||||
|         y += 3 | ||||
|         return locals() | ||||
|     return g | ||||
|         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'] | ||||
| vereq(d, {'x': 2, 'y': 7, 'w': 6}) | ||||
|         d = f(2)(4) | ||||
|         self.assert_(d.has_key('h')) | ||||
|         del d['h'] | ||||
|         self.assertEqual(d, {'x': 2, 'y': 7, 'w': 6}) | ||||
| 
 | ||||
| print "19. var is bound and free in class" | ||||
|     def testBoundAndFree(self): | ||||
|         # var is bound and free in class | ||||
| 
 | ||||
| def f(x): | ||||
|     class C: | ||||
|         def m(self): | ||||
|             return x | ||||
|         a = x | ||||
|     return C | ||||
|         def f(x): | ||||
|             class C: | ||||
|                 def m(self): | ||||
|                     return x | ||||
|                 a = x | ||||
|             return C | ||||
| 
 | ||||
| inst = f(3)() | ||||
| vereq(inst.a, inst.m()) | ||||
|         inst = f(3)() | ||||
|         self.assertEqual(inst.a, inst.m()) | ||||
| 
 | ||||
| print "20. interaction with trace function" | ||||
|     def testInteractionWithTraceFunc(self): | ||||
| 
 | ||||
| import sys | ||||
| def tracer(a,b,c): | ||||
|     return tracer | ||||
|         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) | ||||
|         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 | ||||
|         class TestClass: | ||||
|             pass | ||||
| 
 | ||||
| sys.settrace(tracer) | ||||
| adaptgetter("foo", TestClass, (1, "")) | ||||
| sys.settrace(None) | ||||
|         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' | ||||
|         self.assertRaises(TypeError, sys.settrace) | ||||
| 
 | ||||
| print "20. eval and exec with free variables" | ||||
|     def testEvalExecFreeVars(self): | ||||
| 
 | ||||
| def f(x): | ||||
|     return lambda: x + 1 | ||||
|         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" | ||||
|         g = f(3) | ||||
|         self.assertRaises(TypeError, eval, g.func_code) | ||||
| 
 | ||||
| try: | ||||
|     exec g.func_code | ||||
| except TypeError: | ||||
|     pass | ||||
| else: | ||||
|     print "exec should have failed, because code contained free vars" | ||||
|         try: | ||||
|             exec g.func_code in {} | ||||
|         except TypeError: | ||||
|             pass | ||||
|         else: | ||||
|             self.fail("exec should have failed, because code contained free vars") | ||||
| 
 | ||||
| print "21. list comprehension with local variables" | ||||
|     def testListCompLocalVars(self): | ||||
| 
 | ||||
| try: | ||||
|     print bad | ||||
| except NameError: | ||||
|     pass | ||||
| else: | ||||
|     print "bad should not be defined" | ||||
|         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()] | ||||
|         def x(): | ||||
|             [bad for s in 'a b' for bad in s.split()] | ||||
| 
 | ||||
| x() | ||||
| try: | ||||
|     print bad | ||||
| except NameError: | ||||
|     pass | ||||
|         x() | ||||
|         try: | ||||
|             print bad | ||||
|         except NameError: | ||||
|             pass | ||||
| 
 | ||||
| print "22. eval with free variables" | ||||
|     def testEvalFreeVars(self): | ||||
| 
 | ||||
| def f(x): | ||||
|     def g(): | ||||
|         x | ||||
|         eval("x + 1") | ||||
|     return g | ||||
|         def f(x): | ||||
|             def g(): | ||||
|                 x | ||||
|                 eval("x + 1") | ||||
|             return g | ||||
| 
 | ||||
| f(4)() | ||||
|         f(4)() | ||||
| 
 | ||||
| 
 | ||||
| def test_main(): | ||||
|     run_unittest(ScopeTests) | ||||
| 
 | ||||
| if __name__ == '__main__': | ||||
|     test_main() | ||||
|  |  | |||
|  | @ -245,13 +245,13 @@ def sortdict(dict): | |||
|     withcommas = ", ".join(reprpairs) | ||||
|     return "{%s}" % withcommas | ||||
| 
 | ||||
| def check_syntax(statement): | ||||
| def check_syntax_error(testcase, statement): | ||||
|     try: | ||||
|         compile(statement, '<string>', 'exec') | ||||
|         compile(statement, '<test string>', 'exec') | ||||
|     except SyntaxError: | ||||
|         pass | ||||
|     else: | ||||
|         print 'Missing SyntaxError: "%s"' % statement | ||||
|         testcase.fail('Missing SyntaxError: "%s"' % statement) | ||||
| 
 | ||||
| def open_urlresource(url): | ||||
|     import urllib, urlparse | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Georg Brandl
						Georg Brandl