From c6fdec6d7eef0582baefd77b4a51da9b69326a37 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sat, 28 Oct 2006 13:10:17 +0000 Subject: [PATCH] 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. --- Lib/test/README | 4 +- Lib/test/output/test_global | 5 - Lib/test/output/test_grammar | 69 -- Lib/test/output/test_scope | 24 - Lib/test/test_global.py | 48 +- Lib/test/test_grammar.py | 1614 ++++++++++++++++++---------------- Lib/test/test_scope.py | 661 +++++++------- Lib/test/test_support.py | 6 +- 8 files changed, 1203 insertions(+), 1228 deletions(-) delete mode 100644 Lib/test/output/test_global delete mode 100644 Lib/test/output/test_grammar delete mode 100644 Lib/test/output/test_scope diff --git a/Lib/test/README b/Lib/test/README index 496c40040b6..27f696cdbf9 100644 --- a/Lib/test/README +++ b/Lib/test/README @@ -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 diff --git a/Lib/test/output/test_global b/Lib/test/output/test_global deleted file mode 100644 index a427a29cb09..00000000000 --- a/Lib/test/output/test_global +++ /dev/null @@ -1,5 +0,0 @@ -test_global -got SyntaxError as expected -got SyntaxError as expected -got SyntaxError as expected -as expected, no SyntaxError diff --git a/Lib/test/output/test_grammar b/Lib/test/output/test_grammar deleted file mode 100644 index 4fa9cb03c98..00000000000 --- a/Lib/test/output/test_grammar +++ /dev/null @@ -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')] diff --git a/Lib/test/output/test_scope b/Lib/test/output/test_scope deleted file mode 100644 index a439e441e60..00000000000 --- a/Lib/test/output/test_scope +++ /dev/null @@ -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 diff --git a/Lib/test/test_global.py b/Lib/test/test_global.py index 4cc953cd3f4..22e4b254c22 100644 --- a/Lib/test/test_global.py +++ b/Lib/test/test_global.py @@ -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="") -warnings.filterwarnings("error", module="") +class GlobalTests(unittest.TestCase): -def compile_and_check(text, should_fail=1): - try: - compile(text, "", "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, "", "exec") + + +def test_main(): + run_unittest(GlobalTests) + +if __name__ == "__main__": + test_main() diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py index c39e41699e9..584bbafeb06 100644 --- a/Lib/test/test_grammar.py +++ b/Lib/test/test_grammar.py @@ -8,848 +8,910 @@ # regression test, the filterwarnings() call has been added to # regrtest.py. -from test.test_support import TestFailed, verify, vereq, check_syntax +from test.test_support import run_unittest, check_syntax_error +import unittest import sys +# testing import * +from sys import * -print '1. Parser' +class TokenTests(unittest.TestCase): -print '1.1 Tokens' + def testBackslash(self): + # Backslash means line continuation: + x = 1 \ + + 1 + self.assertEquals(x, 2, 'backslash for line continuation') -print '1.1.1 Backslashes' + # Backslash does not means continuation in comments :\ + x = 0 + self.assertEquals(x, 0, 'backslash ending comment') -# Backslash means line continuation: -x = 1 \ -+ 1 -if x != 2: raise TestFailed, 'backslash for line continuation' + def testPlainIntegers(self): + self.assertEquals(0xff, 255) + self.assertEquals(0377, 255) + self.assertEquals(2147483647, 017777777777) + from sys import maxint + if maxint == 2147483647: + self.assertEquals(-2147483647-1, -020000000000) + # XXX -2147483648 + self.assert_(037777777777 > 0) + self.assert_(0xffffffff > 0) + for s in '2147483648', '040000000000', '0x100000000': + try: + x = eval(s) + except OverflowError: + self.fail("OverflowError on huge integer literal %r" % s) + elif maxint == 9223372036854775807: + self.assertEquals(-9223372036854775807-1, -01000000000000000000000) + self.assert_(01777777777777777777777 > 0) + self.assert_(0xffffffffffffffff > 0) + for s in '9223372036854775808', '02000000000000000000000', \ + '0x10000000000000000': + try: + x = eval(s) + except OverflowError: + self.fail("OverflowError on huge integer literal %r" % s) + else: + self.fail('Weird maxint value %r' % maxint) -# Backslash does not means continuation in comments :\ -x = 0 -if x != 0: raise TestFailed, 'backslash ending comment' + def testLongIntegers(self): + x = 0L + x = 0l + x = 0xffffffffffffffffL + x = 0xffffffffffffffffl + x = 077777777777777777L + x = 077777777777777777l + x = 123456789012345678901234567890L + x = 123456789012345678901234567890l -print '1.1.2 Numeric literals' + def testFloats(self): + x = 3.14 + x = 314. + x = 0.314 + # XXX x = 000.314 + x = .314 + x = 3e14 + x = 3E14 + x = 3e-14 + x = 3e+14 + x = 3.e14 + x = .3e14 + x = 3.1e4 -print '1.1.2.1 Plain integers' -if 0xff != 255: raise TestFailed, 'hex int' -if 0377 != 255: raise TestFailed, 'octal int' -if 2147483647 != 017777777777: raise TestFailed, 'large positive int' -try: - from sys import maxint -except ImportError: - maxint = 2147483647 -if maxint == 2147483647: - # The following test will start to fail in Python 2.4; - # change the 020000000000 to -020000000000 - if -2147483647-1 != -020000000000: raise TestFailed, 'max negative int' - # XXX -2147483648 - if 037777777777 < 0: raise TestFailed, 'large oct' - if 0xffffffff < 0: raise TestFailed, 'large hex' - for s in '2147483648', '040000000000', '0x100000000': - try: - x = eval(s) - except OverflowError: - print "OverflowError on huge integer literal " + repr(s) -elif eval('maxint == 9223372036854775807'): - if eval('-9223372036854775807-1 != -01000000000000000000000'): - raise TestFailed, 'max negative int' - if eval('01777777777777777777777') < 0: raise TestFailed, 'large oct' - if eval('0xffffffffffffffff') < 0: raise TestFailed, 'large hex' - for s in '9223372036854775808', '02000000000000000000000', \ - '0x10000000000000000': - try: - x = eval(s) - except OverflowError: - print "OverflowError on huge integer literal " + repr(s) -else: - print 'Weird maxint value', maxint - -print '1.1.2.2 Long integers' -x = 0L -x = 0l -x = 0xffffffffffffffffL -x = 0xffffffffffffffffl -x = 077777777777777777L -x = 077777777777777777l -x = 123456789012345678901234567890L -x = 123456789012345678901234567890l - -print '1.1.2.3 Floating point' -x = 3.14 -x = 314. -x = 0.314 -# XXX x = 000.314 -x = .314 -x = 3e14 -x = 3E14 -x = 3e-14 -x = 3e+14 -x = 3.e14 -x = .3e14 -x = 3.1e4 - -print '1.1.3 String literals' - -x = ''; y = ""; verify(len(x) == 0 and x == y) -x = '\''; y = "'"; verify(len(x) == 1 and x == y and ord(x) == 39) -x = '"'; y = "\""; verify(len(x) == 1 and x == y and ord(x) == 34) -x = "doesn't \"shrink\" does it" -y = 'doesn\'t "shrink" does it' -verify(len(x) == 24 and x == y) -x = "does \"shrink\" doesn't it" -y = 'does "shrink" doesn\'t it' -verify(len(x) == 24 and x == y) -x = """ + def testStringLiterals(self): + x = ''; y = ""; self.assert_(len(x) == 0 and x == y) + x = '\''; y = "'"; self.assert_(len(x) == 1 and x == y and ord(x) == 39) + x = '"'; y = "\""; self.assert_(len(x) == 1 and x == y and ord(x) == 34) + x = "doesn't \"shrink\" does it" + y = 'doesn\'t "shrink" does it' + self.assert_(len(x) == 24 and x == y) + x = "does \"shrink\" doesn't it" + y = 'does "shrink" doesn\'t it' + self.assert_(len(x) == 24 and x == y) + x = """ The "quick" brown fox jumps over the 'lazy' dog. """ -y = '\nThe "quick"\nbrown fox\njumps over\nthe \'lazy\' dog.\n' -verify(x == y) -y = ''' + y = '\nThe "quick"\nbrown fox\njumps over\nthe \'lazy\' dog.\n' + self.assertEquals(x, y) + y = ''' The "quick" brown fox jumps over the 'lazy' dog. -'''; verify(x == y) -y = "\n\ +''' + self.assertEquals(x, y) + y = "\n\ The \"quick\"\n\ brown fox\n\ jumps over\n\ the 'lazy' dog.\n\ -"; verify(x == y) -y = '\n\ +" + self.assertEquals(x, y) + y = '\n\ The \"quick\"\n\ brown fox\n\ jumps over\n\ the \'lazy\' dog.\n\ -'; verify(x == y) +' + self.assertEquals(x, y) -print '1.2 Grammar' +class GrammarTests(unittest.TestCase): -print 'single_input' # NEWLINE | simple_stmt | compound_stmt NEWLINE -# XXX can't test in a script -- this rule is only used when interactive + # single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE + # XXX can't test in a script -- this rule is only used when interactive + + # file_input: (NEWLINE | stmt)* ENDMARKER + # Being tested as this very moment this very module + + # expr_input: testlist NEWLINE + # XXX Hard to test -- used only in calls to input() -print 'file_input' # (NEWLINE | stmt)* ENDMARKER -# Being tested as this very moment this very module + def testEvalInput(self): + # testlist ENDMARKER + x = eval('1, 0 or 1') -print 'expr_input' # testlist NEWLINE -# XXX Hard to test -- used only in calls to input() + def testFuncdef(self): + ### 'def' NAME parameters ':' suite + ### parameters: '(' [varargslist] ')' + ### varargslist: (fpdef ['=' test] ',')* ('*' NAME [',' ('**'|'*' '*') NAME] + ### | ('**'|'*' '*') NAME) + ### | fpdef ['=' test] (',' fpdef ['=' test])* [','] + ### fpdef: NAME | '(' fplist ')' + ### fplist: fpdef (',' fpdef)* [','] + ### arglist: (argument ',')* (argument | *' test [',' '**' test] | '**' test) + ### argument: [test '='] test # Really [keyword '='] test + def f1(): pass + f1() + f1(*()) + f1(*(), **{}) + def f2(one_argument): pass + def f3(two, arguments): pass + def f4(two, (compound, (argument, list))): pass + def f5((compound, first), two): pass + self.assertEquals(f2.func_code.co_varnames, ('one_argument',)) + self.assertEquals(f3.func_code.co_varnames, ('two', 'arguments')) + if sys.platform.startswith('java'): + self.assertEquals(f4.func_code.co_varnames, + ('two', '(compound, (argument, list))', 'compound', 'argument', + 'list',)) + self.assertEquals(f5.func_code.co_varnames, + ('(compound, first)', 'two', 'compound', 'first')) + else: + self.assertEquals(f4.func_code.co_varnames, + ('two', '.1', 'compound', 'argument', 'list')) + self.assertEquals(f5.func_code.co_varnames, + ('.0', 'two', 'compound', 'first')) + def a1(one_arg,): pass + def a2(two, args,): pass + def v0(*rest): pass + def v1(a, *rest): pass + def v2(a, b, *rest): pass + def v3(a, (b, c), *rest): return a, b, c, rest -print 'eval_input' # testlist ENDMARKER -x = eval('1, 0 or 1') + f1() + f2(1) + f2(1,) + f3(1, 2) + f3(1, 2,) + f4(1, (2, (3, 4))) + v0() + v0(1) + v0(1,) + v0(1,2) + v0(1,2,3,4,5,6,7,8,9,0) + v1(1) + v1(1,) + v1(1,2) + v1(1,2,3) + v1(1,2,3,4,5,6,7,8,9,0) + v2(1,2) + v2(1,2,3) + v2(1,2,3,4) + v2(1,2,3,4,5,6,7,8,9,0) + v3(1,(2,3)) + v3(1,(2,3),4) + v3(1,(2,3),4,5,6,7,8,9,0) -print 'funcdef' -### 'def' NAME parameters ':' suite -### parameters: '(' [varargslist] ')' -### varargslist: (fpdef ['=' test] ',')* ('*' NAME [',' ('**'|'*' '*') NAME] -### | ('**'|'*' '*') NAME) -### | fpdef ['=' test] (',' fpdef ['=' test])* [','] -### fpdef: NAME | '(' fplist ')' -### fplist: fpdef (',' fpdef)* [','] -### arglist: (argument ',')* (argument | *' test [',' '**' test] | '**' test) -### argument: [test '='] test # Really [keyword '='] test -def f1(): pass -f1() -f1(*()) -f1(*(), **{}) -def f2(one_argument): pass -def f3(two, arguments): pass -def f4(two, (compound, (argument, list))): pass -def f5((compound, first), two): pass -vereq(f2.func_code.co_varnames, ('one_argument',)) -vereq(f3.func_code.co_varnames, ('two', 'arguments')) -if sys.platform.startswith('java'): - vereq(f4.func_code.co_varnames, - ('two', '(compound, (argument, list))', 'compound', 'argument', - 'list',)) - vereq(f5.func_code.co_varnames, - ('(compound, first)', 'two', 'compound', 'first')) -else: - vereq(f4.func_code.co_varnames, - ('two', '.1', 'compound', 'argument', 'list')) - vereq(f5.func_code.co_varnames, - ('.0', 'two', 'compound', 'first')) -def a1(one_arg,): pass -def a2(two, args,): pass -def v0(*rest): pass -def v1(a, *rest): pass -def v2(a, b, *rest): pass -def v3(a, (b, c), *rest): return a, b, c, rest -# ceval unpacks the formal arguments into the first argcount names; -# thus, the names nested inside tuples must appear after these names. -if sys.platform.startswith('java'): - verify(v3.func_code.co_varnames == ('a', '(b, c)', 'rest', 'b', 'c')) -else: - vereq(v3.func_code.co_varnames, ('a', '.1', 'rest', 'b', 'c')) -verify(v3(1, (2, 3), 4) == (1, 2, 3, (4,))) -def d01(a=1): pass -d01() -d01(1) -d01(*(1,)) -d01(**{'a':2}) -def d11(a, b=1): pass -d11(1) -d11(1, 2) -d11(1, **{'b':2}) -def d21(a, b, c=1): pass -d21(1, 2) -d21(1, 2, 3) -d21(*(1, 2, 3)) -d21(1, *(2, 3)) -d21(1, 2, *(3,)) -d21(1, 2, **{'c':3}) -def d02(a=1, b=2): pass -d02() -d02(1) -d02(1, 2) -d02(*(1, 2)) -d02(1, *(2,)) -d02(1, **{'b':2}) -d02(**{'a': 1, 'b': 2}) -def d12(a, b=1, c=2): pass -d12(1) -d12(1, 2) -d12(1, 2, 3) -def d22(a, b, c=1, d=2): pass -d22(1, 2) -d22(1, 2, 3) -d22(1, 2, 3, 4) -def d01v(a=1, *rest): pass -d01v() -d01v(1) -d01v(1, 2) -d01v(*(1, 2, 3, 4)) -d01v(*(1,)) -d01v(**{'a':2}) -def d11v(a, b=1, *rest): pass -d11v(1) -d11v(1, 2) -d11v(1, 2, 3) -def d21v(a, b, c=1, *rest): pass -d21v(1, 2) -d21v(1, 2, 3) -d21v(1, 2, 3, 4) -d21v(*(1, 2, 3, 4)) -d21v(1, 2, **{'c': 3}) -def d02v(a=1, b=2, *rest): pass -d02v() -d02v(1) -d02v(1, 2) -d02v(1, 2, 3) -d02v(1, *(2, 3, 4)) -d02v(**{'a': 1, 'b': 2}) -def d12v(a, b=1, c=2, *rest): pass -d12v(1) -d12v(1, 2) -d12v(1, 2, 3) -d12v(1, 2, 3, 4) -d12v(*(1, 2, 3, 4)) -d12v(1, 2, *(3, 4, 5)) -d12v(1, *(2,), **{'c': 3}) -def d22v(a, b, c=1, d=2, *rest): pass -d22v(1, 2) -d22v(1, 2, 3) -d22v(1, 2, 3, 4) -d22v(1, 2, 3, 4, 5) -d22v(*(1, 2, 3, 4)) -d22v(1, 2, *(3, 4, 5)) -d22v(1, *(2, 3), **{'d': 4}) -def d31v((x)): pass -d31v(1) -def d32v((x,)): pass -d32v((1,)) + # ceval unpacks the formal arguments into the first argcount names; + # thus, the names nested inside tuples must appear after these names. + if sys.platform.startswith('java'): + self.assertEquals(v3.func_code.co_varnames, ('a', '(b, c)', 'rest', 'b', 'c')) + else: + self.assertEquals(v3.func_code.co_varnames, ('a', '.1', 'rest', 'b', 'c')) + self.assertEquals(v3(1, (2, 3), 4), (1, 2, 3, (4,))) + def d01(a=1): pass + d01() + d01(1) + d01(*(1,)) + d01(**{'a':2}) + def d11(a, b=1): pass + d11(1) + d11(1, 2) + d11(1, **{'b':2}) + def d21(a, b, c=1): pass + d21(1, 2) + d21(1, 2, 3) + d21(*(1, 2, 3)) + d21(1, *(2, 3)) + d21(1, 2, *(3,)) + d21(1, 2, **{'c':3}) + def d02(a=1, b=2): pass + d02() + d02(1) + d02(1, 2) + d02(*(1, 2)) + d02(1, *(2,)) + d02(1, **{'b':2}) + d02(**{'a': 1, 'b': 2}) + def d12(a, b=1, c=2): pass + d12(1) + d12(1, 2) + d12(1, 2, 3) + def d22(a, b, c=1, d=2): pass + d22(1, 2) + d22(1, 2, 3) + d22(1, 2, 3, 4) + def d01v(a=1, *rest): pass + d01v() + d01v(1) + d01v(1, 2) + d01v(*(1, 2, 3, 4)) + d01v(*(1,)) + d01v(**{'a':2}) + def d11v(a, b=1, *rest): pass + d11v(1) + d11v(1, 2) + d11v(1, 2, 3) + def d21v(a, b, c=1, *rest): pass + d21v(1, 2) + d21v(1, 2, 3) + d21v(1, 2, 3, 4) + d21v(*(1, 2, 3, 4)) + d21v(1, 2, **{'c': 3}) + def d02v(a=1, b=2, *rest): pass + d02v() + d02v(1) + d02v(1, 2) + d02v(1, 2, 3) + d02v(1, *(2, 3, 4)) + d02v(**{'a': 1, 'b': 2}) + def d12v(a, b=1, c=2, *rest): pass + d12v(1) + d12v(1, 2) + d12v(1, 2, 3) + d12v(1, 2, 3, 4) + d12v(*(1, 2, 3, 4)) + d12v(1, 2, *(3, 4, 5)) + d12v(1, *(2,), **{'c': 3}) + def d22v(a, b, c=1, d=2, *rest): pass + d22v(1, 2) + d22v(1, 2, 3) + d22v(1, 2, 3, 4) + d22v(1, 2, 3, 4, 5) + d22v(*(1, 2, 3, 4)) + d22v(1, 2, *(3, 4, 5)) + d22v(1, *(2, 3), **{'d': 4}) + def d31v((x)): pass + d31v(1) + def d32v((x,)): pass + d32v((1,)) -### lambdef: 'lambda' [varargslist] ':' test -print 'lambdef' -l1 = lambda : 0 -verify(l1() == 0) -l2 = lambda : a[d] # XXX just testing the expression -l3 = lambda : [2 < x for x in [-1, 3, 0L]] -verify(l3() == [0, 1, 0]) -l4 = lambda x = lambda y = lambda z=1 : z : y() : x() -verify(l4() == 1) -l5 = lambda x, y, z=2: x + y + z -verify(l5(1, 2) == 5) -verify(l5(1, 2, 3) == 6) -check_syntax("lambda x: x = 2") + def testLambdef(self): + ### lambdef: 'lambda' [varargslist] ':' test + l1 = lambda : 0 + self.assertEquals(l1(), 0) + l2 = lambda : a[d] # XXX just testing the expression + l3 = lambda : [2 < x for x in [-1, 3, 0L]] + self.assertEquals(l3(), [0, 1, 0]) + l4 = lambda x = lambda y = lambda z=1 : z : y() : x() + self.assertEquals(l4(), 1) + l5 = lambda x, y, z=2: x + y + z + self.assertEquals(l5(1, 2), 5) + self.assertEquals(l5(1, 2, 3), 6) + check_syntax_error(self, "lambda x: x = 2") -### stmt: simple_stmt | compound_stmt -# Tested below + ### stmt: simple_stmt | compound_stmt + # Tested below -### simple_stmt: small_stmt (';' small_stmt)* [';'] -print 'simple_stmt' -x = 1; pass; del x -def foo(): - # verify statments that end with semi-colons - x = 1; pass; del x; -foo() + def testSimpleStmt(self): + ### simple_stmt: small_stmt (';' small_stmt)* [';'] + x = 1; pass; del x + def foo(): + # verify statments that end with semi-colons + x = 1; pass; del x; + foo() -### small_stmt: expr_stmt | print_stmt | pass_stmt | del_stmt | flow_stmt | import_stmt | global_stmt | access_stmt | exec_stmt -# Tested below + ### small_stmt: expr_stmt | print_stmt | pass_stmt | del_stmt | flow_stmt | import_stmt | global_stmt | access_stmt | exec_stmt + # Tested below -print 'expr_stmt' # (exprlist '=')* exprlist -1 -1, 2, 3 -x = 1 -x = 1, 2, 3 -x = y = z = 1, 2, 3 -x, y, z = 1, 2, 3 -abc = a, b, c = x, y, z = xyz = 1, 2, (3, 4) -# NB these variables are deleted below + def testExprStmt(self): + # (exprlist '=')* exprlist + 1 + 1, 2, 3 + x = 1 + x = 1, 2, 3 + x = y = z = 1, 2, 3 + x, y, z = 1, 2, 3 + abc = a, b, c = x, y, z = xyz = 1, 2, (3, 4) -check_syntax("x + 1 = 1") -check_syntax("a + 1 = b + 2") + check_syntax_error(self, "x + 1 = 1") + check_syntax_error(self, "a + 1 = b + 2") -print 'print_stmt' # 'print' (test ',')* [test] -print 1, 2, 3 -print 1, 2, 3, -print -print 0 or 1, 0 or 1, -print 0 or 1 + def testPrintStmt(self): + # 'print' (test ',')* [test] + import StringIO -print 'extended print_stmt' # 'print' '>>' test ',' -import sys -print >> sys.stdout, 1, 2, 3 -print >> sys.stdout, 1, 2, 3, -print >> sys.stdout -print >> sys.stdout, 0 or 1, 0 or 1, -print >> sys.stdout, 0 or 1 + # Can't test printing to real stdout without comparing output + # which is not available in unittest. + save_stdout = sys.stdout + sys.stdout = StringIO.StringIO() + + print 1, 2, 3 + print 1, 2, 3, + print + print 0 or 1, 0 or 1, + print 0 or 1 -# test printing to an instance -class Gulp: - def write(self, msg): pass + # 'print' '>>' test ',' + print >> sys.stdout, 1, 2, 3 + print >> sys.stdout, 1, 2, 3, + print >> sys.stdout + print >> sys.stdout, 0 or 1, 0 or 1, + print >> sys.stdout, 0 or 1 -gulp = Gulp() -print >> gulp, 1, 2, 3 -print >> gulp, 1, 2, 3, -print >> gulp -print >> gulp, 0 or 1, 0 or 1, -print >> gulp, 0 or 1 + # test printing to an instance + class Gulp: + def write(self, msg): pass -# test print >> None -def driver(): - oldstdout = sys.stdout - sys.stdout = Gulp() - try: - tellme(Gulp()) - tellme() - finally: - sys.stdout = oldstdout + gulp = Gulp() + print >> gulp, 1, 2, 3 + print >> gulp, 1, 2, 3, + print >> gulp + print >> gulp, 0 or 1, 0 or 1, + print >> gulp, 0 or 1 -# we should see this once -def tellme(file=sys.stdout): - print >> file, 'hello world' + # test print >> None + def driver(): + oldstdout = sys.stdout + sys.stdout = Gulp() + try: + tellme(Gulp()) + tellme() + finally: + sys.stdout = oldstdout -driver() + # we should see this once + def tellme(file=sys.stdout): + print >> file, 'hello world' -# we should not see this at all -def tellme(file=None): - print >> file, 'goodbye universe' + driver() -driver() + # we should not see this at all + def tellme(file=None): + print >> file, 'goodbye universe' -# syntax errors -check_syntax('print ,') -check_syntax('print >> x,') + driver() -print 'del_stmt' # 'del' exprlist -del abc -del x, y, (z, xyz) + self.assertEqual(sys.stdout.getvalue(), '''\ +1 2 3 +1 2 3 +1 1 1 +1 2 3 +1 2 3 +1 1 1 +hello world +''') + sys.stdout = save_stdout -print 'pass_stmt' # 'pass' -pass + # syntax errors + check_syntax_error(self, 'print ,') + check_syntax_error(self, 'print >> x,') -print 'flow_stmt' # break_stmt | continue_stmt | return_stmt | raise_stmt -# Tested below + def testDelStmt(self): + # 'del' exprlist + abc = [1,2,3] + x, y, z = abc + xyz = x, y, z -print 'break_stmt' # 'break' -while 1: break + del abc + del x, y, (z, xyz) -print 'continue_stmt' # 'continue' -i = 1 -while i: i = 0; continue + def testPassStmt(self): + # 'pass' + pass -msg = "" -while not msg: - msg = "continue + try/except ok" - try: - continue - msg = "continue failed to continue inside try" - except: - msg = "continue inside try called except block" -print msg + # flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt + # Tested below -msg = "" -while not msg: - msg = "finally block not called" - try: - continue - finally: - msg = "continue + try/finally ok" -print msg + def testBreakStmt(self): + # 'break' + while 1: break + def testContinueStmt(self): + # 'continue' + i = 1 + while i: i = 0; continue -# This test warrants an explanation. It is a test specifically for SF bugs -# #463359 and #462937. The bug is that a 'break' statement executed or -# exception raised inside a try/except inside a loop, *after* a continue -# statement has been executed in that loop, will cause the wrong number of -# arguments to be popped off the stack and the instruction pointer reset to -# a very small number (usually 0.) Because of this, the following test -# *must* written as a function, and the tracking vars *must* be function -# arguments with default values. Otherwise, the test will loop and loop. + msg = "" + while not msg: + msg = "ok" + try: + continue + msg = "continue failed to continue inside try" + except: + msg = "continue inside try called except block" + if msg != "ok": + self.fail(msg) -print "testing continue and break in try/except in loop" -def test_break_continue_loop(extra_burning_oil = 1, count=0): - big_hippo = 2 - while big_hippo: - count += 1 + msg = "" + while not msg: + msg = "finally block not called" + try: + continue + finally: + msg = "ok" + if msg != "ok": + self.fail(msg) + + def test_break_continue_loop(self): + # This test warrants an explanation. It is a test specifically for SF bugs + # #463359 and #462937. The bug is that a 'break' statement executed or + # exception raised inside a try/except inside a loop, *after* a continue + # statement has been executed in that loop, will cause the wrong number of + # arguments to be popped off the stack and the instruction pointer reset to + # a very small number (usually 0.) Because of this, the following test + # *must* written as a function, and the tracking vars *must* be function + # arguments with default values. Otherwise, the test will loop and loop. + + def test_inner(extra_burning_oil = 1, count=0): + big_hippo = 2 + while big_hippo: + count += 1 + try: + if extra_burning_oil and big_hippo == 1: + extra_burning_oil -= 1 + break + big_hippo -= 1 + continue + except: + raise + if count > 2 or big_hippo <> 1: + self.fail("continue then break in try/except in loop broken!") + test_inner() + + def testReturn(self): + # 'return' [testlist] + def g1(): return + def g2(): return 1 + g1() + x = g2() + check_syntax_error(self, "class foo:return 1") + + def testYield(self): + check_syntax_error(self, "class foo:yield 1") + + def testRaise(self): + # 'raise' test [',' test] + try: raise RuntimeError, 'just testing' + except RuntimeError: pass + try: raise KeyboardInterrupt + except KeyboardInterrupt: pass + + def testImport(self): + # 'import' dotted_as_names + import sys + import time, sys + # 'from' dotted_name 'import' ('*' | '(' import_as_names ')' | import_as_names) + from time import time + from time import (time) + # not testable inside a function, but already done at top of the module + # from sys import * + from sys import path, argv + from sys import (path, argv) + from sys import (path, argv,) + + def testGlobal(self): + # 'global' NAME (',' NAME)* + global a + global a, b + global one, two, three, four, five, six, seven, eight, nine, ten + + def testExec(self): + # 'exec' expr ['in' expr [',' expr]] + z = None + del z + exec 'z=1+1\n' + if z != 2: self.fail('exec \'z=1+1\'\\n') + del z + exec 'z=1+1' + if z != 2: self.fail('exec \'z=1+1\'') + z = None + del z + import types + if hasattr(types, "UnicodeType"): + exec r"""if 1: + exec u'z=1+1\n' + if z != 2: self.fail('exec u\'z=1+1\'\\n') + del z + exec u'z=1+1' + if z != 2: self.fail('exec u\'z=1+1\'')""" + g = {} + exec 'z = 1' in g + if g.has_key('__builtins__'): del g['__builtins__'] + if g != {'z': 1}: self.fail('exec \'z = 1\' in g') + g = {} + l = {} + + import warnings + warnings.filterwarnings("ignore", "global statement", module="") + exec 'global a; a = 1; b = 2' in g, l + if g.has_key('__builtins__'): del g['__builtins__'] + if l.has_key('__builtins__'): del l['__builtins__'] + if (g, l) != ({'a':1}, {'b':2}): + self.fail('exec ... in g (%s), l (%s)' %(g,l)) + + def testAssert(self): + # assert_stmt: 'assert' test [',' test] + assert 1 + assert 1, 1 + assert lambda x:x + assert 1, lambda x:x+1 try: - if extra_burning_oil and big_hippo == 1: - extra_burning_oil -= 1 - break - big_hippo -= 1 - continue - except: - raise - if count > 2 or big_hippo <> 1: - print "continue then break in try/except in loop broken!" -test_break_continue_loop() + assert 0, "msg" + except AssertionError, e: + self.assertEquals(e.args[0], "msg") + else: + self.fail("AssertionError not raised by assert 0") -print 'return_stmt' # 'return' [testlist] -def g1(): return -def g2(): return 1 -g1() -x = g2() -check_syntax("class foo:return 1") + ### compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef + # Tested below -print 'yield_stmt' -check_syntax("class foo:yield 1") + def testIf(self): + # 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite] + if 1: pass + if 1: pass + else: pass + if 0: pass + elif 0: pass + if 0: pass + elif 0: pass + elif 0: pass + elif 0: pass + else: pass + + def testWhile(self): + # 'while' test ':' suite ['else' ':' suite] + while 0: pass + while 0: pass + else: pass -print 'raise_stmt' # 'raise' test [',' test] -try: raise RuntimeError, 'just testing' -except RuntimeError: pass -try: raise KeyboardInterrupt -except KeyboardInterrupt: pass + def testFor(self): + # 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite] + for i in 1, 2, 3: pass + for i, j, k in (): pass + else: pass + class Squares: + def __init__(self, max): + self.max = max + self.sofar = [] + def __len__(self): return len(self.sofar) + def __getitem__(self, i): + if not 0 <= i < self.max: raise IndexError + n = len(self.sofar) + while n <= i: + self.sofar.append(n*n) + n = n+1 + return self.sofar[i] + n = 0 + for x in Squares(10): n = n+x + if n != 285: + self.fail('for over growing sequence') -print 'import_name' # 'import' dotted_as_names -import sys -import time, sys -print 'import_from' # 'from' dotted_name 'import' ('*' | '(' import_as_names ')' | import_as_names) -from time import time -from time import (time) -from sys import * -from sys import path, argv -from sys import (path, argv) -from sys import (path, argv,) + result = [] + for x, in [(1,), (2,), (3,)]: + result.append(x) + self.assertEqual(result, [1, 2, 3]) -print 'global_stmt' # 'global' NAME (',' NAME)* -def f(): - global a - global a, b - global one, two, three, four, five, six, seven, eight, nine, ten + def testTry(self): + ### try_stmt: 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite] + ### | 'try' ':' suite 'finally' ':' suite + ### except_clause: 'except' [expr [',' expr]] + try: + 1/0 + except ZeroDivisionError: + pass + else: + pass + try: 1/0 + except EOFError: pass + except TypeError, msg: pass + except RuntimeError, msg: pass + except: pass + else: pass + try: 1/0 + except (EOFError, TypeError, ZeroDivisionError): pass + try: 1/0 + except (EOFError, TypeError, ZeroDivisionError), msg: pass + try: pass + finally: pass -print 'exec_stmt' # 'exec' expr ['in' expr [',' expr]] -def f(): - z = None - del z - exec 'z=1+1\n' - if z != 2: raise TestFailed, 'exec \'z=1+1\'\\n' - del z - exec 'z=1+1' - if z != 2: raise TestFailed, 'exec \'z=1+1\'' - z = None - del z - import types - if hasattr(types, "UnicodeType"): - exec r"""if 1: - exec u'z=1+1\n' - if z != 2: raise TestFailed, 'exec u\'z=1+1\'\\n' - del z - exec u'z=1+1' - if z != 2: raise TestFailed, 'exec u\'z=1+1\'' -""" -f() -g = {} -exec 'z = 1' in g -if g.has_key('__builtins__'): del g['__builtins__'] -if g != {'z': 1}: raise TestFailed, 'exec \'z = 1\' in g' -g = {} -l = {} + def testSuite(self): + # simple_stmt | NEWLINE INDENT NEWLINE* (stmt NEWLINE*)+ DEDENT + if 1: pass + if 1: + pass + if 1: + # + # + # + pass + pass + # + pass + # -import warnings -warnings.filterwarnings("ignore", "global statement", module="") -exec 'global a; a = 1; b = 2' in g, l -if g.has_key('__builtins__'): del g['__builtins__'] -if l.has_key('__builtins__'): del l['__builtins__'] -if (g, l) != ({'a':1}, {'b':2}): raise TestFailed, 'exec ... in g (%s), l (%s)' %(g,l) + def testTest(self): + ### and_test ('or' and_test)* + ### and_test: not_test ('and' not_test)* + ### not_test: 'not' not_test | comparison + if not 1: pass + if 1 and 1: pass + if 1 or 1: pass + if not not not 1: pass + if not 1 and 1 and 1: pass + if 1 and 1 or 1 and 1 and 1 or not 1 and 1: pass + + def testComparison(self): + ### comparison: expr (comp_op expr)* + ### comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not' + if 1: pass + x = (1 == 1) + if 1 == 1: pass + if 1 != 1: pass + if 1 <> 1: pass + if 1 < 1: pass + if 1 > 1: pass + if 1 <= 1: pass + if 1 >= 1: pass + if 1 is 1: pass + if 1 is not 1: pass + if 1 in (): pass + if 1 not in (): pass + if 1 < 1 > 1 == 1 >= 1 <= 1 <> 1 != 1 in 1 not in 1 is 1 is not 1: pass + + def testBinaryMaskOps(self): + x = 1 & 1 + x = 1 ^ 1 + x = 1 | 1 + + def testShiftOps(self): + x = 1 << 1 + x = 1 >> 1 + x = 1 << 1 >> 1 + + def testAdditiveOps(self): + x = 1 + x = 1 + 1 + x = 1 - 1 - 1 + x = 1 - 1 + 1 - 1 + 1 + + def testMultiplicativeOps(self): + x = 1 * 1 + x = 1 / 1 + x = 1 % 1 + x = 1 / 1 * 1 % 1 + + def testUnaryOps(self): + x = +1 + x = -1 + x = ~1 + x = ~1 ^ 1 & 1 | 1 & 1 ^ -1 + x = -1*1/1 + 1*1 - ---1*1 + + def testSelectors(self): + ### trailer: '(' [testlist] ')' | '[' subscript ']' | '.' NAME + ### subscript: expr | [expr] ':' [expr] + + import sys, time + c = sys.path[0] + x = time.time() + x = sys.modules['time'].time() + a = '01234' + c = a[0] + c = a[-1] + s = a[0:5] + s = a[:5] + s = a[0:] + s = a[:] + s = a[-5:] + s = a[:-1] + s = a[-4:-3] + # A rough test of SF bug 1333982. http://python.org/sf/1333982 + # The testing here is fairly incomplete. + # Test cases should include: commas with 1 and 2 colons + d = {} + d[1] = 1 + d[1,] = 2 + d[1,2] = 3 + d[1,2,3] = 4 + L = list(d) + L.sort() + self.assertEquals(str(L), '[1, (1,), (1, 2), (1, 2, 3)]') + + def testAtoms(self): + ### atom: '(' [testlist] ')' | '[' [testlist] ']' | '{' [dictmaker] '}' | '`' testlist '`' | NAME | NUMBER | STRING + ### dictmaker: test ':' test (',' test ':' test)* [','] + + x = (1) + x = (1 or 2 or 3) + x = (1 or 2 or 3, 2, 3) + + x = [] + x = [1] + x = [1 or 2 or 3] + x = [1 or 2 or 3, 2, 3] + x = [] + + x = {} + x = {'one': 1} + x = {'one': 1,} + x = {'one' or 'two': 1 or 2} + x = {'one': 1, 'two': 2} + x = {'one': 1, 'two': 2,} + x = {'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'six': 6} + + x = `x` + x = `1 or 2 or 3` + x = x + x = 'x' + x = 123 + + ### exprlist: expr (',' expr)* [','] + ### testlist: test (',' test)* [','] + # These have been exercised enough above + + def testClassdef(self): + # 'class' NAME ['(' [testlist] ')'] ':' suite + class B: pass + class B2(): pass + class C1(B): pass + class C2(B): pass + class D(C1, C2, B): pass + class C: + def meth1(self): pass + def meth2(self, arg): pass + def meth3(self, a1, a2): pass + + def testListcomps(self): + # list comprehension tests + nums = [1, 2, 3, 4, 5] + strs = ["Apple", "Banana", "Coconut"] + spcs = [" Apple", " Banana ", "Coco nut "] + + self.assertEqual([s.strip() for s in spcs], ['Apple', 'Banana', 'Coco nut']) + self.assertEqual([3 * x for x in nums], [3, 6, 9, 12, 15]) + self.assertEqual([x for x in nums if x > 2], [3, 4, 5]) + self.assertEqual([(i, s) for i in nums for s in strs], + [(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')]) + self.assertEqual([(i, s) for i in nums for s in [f for f in strs if "n" in f]], + [(1, 'Banana'), (1, 'Coconut'), (2, 'Banana'), (2, 'Coconut'), + (3, 'Banana'), (3, 'Coconut'), (4, 'Banana'), (4, 'Coconut'), + (5, 'Banana'), (5, 'Coconut')]) + self.assertEqual([(lambda a:[a**i for i in range(a+1)])(j) for j in range(5)], + [[1], [1, 1], [1, 2, 4], [1, 3, 9, 27], [1, 4, 16, 64, 256]]) + + def test_in_func(l): + return [None < x < 3 for x in l if x > 2] + + self.assertEqual(test_in_func(nums), [False, False, False]) + + def test_nested_front(): + self.assertEqual([[y for y in [x, x + 1]] for x in [1,3,5]], + [[1, 2], [3, 4], [5, 6]]) + + test_nested_front() + + check_syntax_error(self, "[i, s for i in nums for s in strs]") + check_syntax_error(self, "[x if y]") + + suppliers = [ + (1, "Boeing"), + (2, "Ford"), + (3, "Macdonalds") + ] + + parts = [ + (10, "Airliner"), + (20, "Engine"), + (30, "Cheeseburger") + ] + + suppart = [ + (1, 10), (1, 20), (2, 20), (3, 30) + ] + + x = [ + (sname, pname) + for (sno, sname) in suppliers + for (pno, pname) in parts + for (sp_sno, sp_pno) in suppart + if sno == sp_sno and pno == sp_pno + ] + + self.assertEqual(x, [('Boeing', 'Airliner'), ('Boeing', 'Engine'), ('Ford', 'Engine'), + ('Macdonalds', 'Cheeseburger')]) + + def testGenexps(self): + # generator expression tests + g = ([x for x in range(10)] for x in range(1)) + self.assertEqual(g.next(), [x for x in range(10)]) + try: + g.next() + self.fail('should produce StopIteration exception') + except StopIteration: + pass + + a = 1 + try: + g = (a for d in a) + g.next() + self.fail('should produce TypeError') + except TypeError: + pass + + self.assertEqual(list((x, y) for x in 'abcd' for y in 'abcd'), [(x, y) for x in 'abcd' for y in 'abcd']) + self.assertEqual(list((x, y) for x in 'ab' for y in 'xy'), [(x, y) for x in 'ab' for y in 'xy']) + + a = [x for x in range(10)] + b = (x for x in (y for y in a)) + self.assertEqual(sum(b), sum([x for x in range(10)])) + + self.assertEqual(sum(x**2 for x in range(10)), sum([x**2 for x in range(10)])) + self.assertEqual(sum(x*x for x in range(10) if x%2), sum([x*x for x in range(10) if x%2])) + self.assertEqual(sum(x for x in (y for y in range(10))), sum([x for x in range(10)])) + self.assertEqual(sum(x for x in (y for y in (z for z in range(10)))), sum([x for x in range(10)])) + self.assertEqual(sum(x for x in [y for y in (z for z in range(10))]), sum([x for x in range(10)])) + self.assertEqual(sum(x for x in (y for y in (z for z in range(10) if True)) if True), sum([x for x in range(10)])) + self.assertEqual(sum(x for x in (y for y in (z for z in range(10) if True) if False) if True), 0) + check_syntax_error(self, "foo(x for x in range(10), 100)") + check_syntax_error(self, "foo(100, x for x in range(10))") + + def testComprehensionSpecials(self): + # test for outmost iterable precomputation + x = 10; g = (i for i in range(x)); x = 5 + self.assertEqual(len(list(g)), 10) + + # This should hold, since we're only precomputing outmost iterable. + x = 10; t = False; g = ((i,j) for i in range(x) if t for j in range(x)) + x = 5; t = True; + self.assertEqual([(i,j) for i in range(10) for j in range(5)], list(g)) + + # Grammar allows multiple adjacent 'if's in listcomps and genexps, + # even though it's silly. Make sure it works (ifelse broke this.) + self.assertEqual([ x for x in range(10) if x % 2 if x % 3 ], [1, 5, 7]) + self.assertEqual(list(x for x in range(10) if x % 2 if x % 3), [1, 5, 7]) + + # verify unpacking single element tuples in listcomp/genexp. + self.assertEqual([x for x, in [(4,), (5,), (6,)]], [4, 5, 6]) + self.assertEqual(list(x for x, in [(7,), (8,), (9,)]), [7, 8, 9]) + + def testIfElseExpr(self): + # Test ifelse expressions in various cases + def _checkeval(msg, ret): + "helper to check that evaluation of expressions is done correctly" + print x + return ret + + self.assertEqual([ x() for x in lambda: True, lambda: False if x() ], [True]) + self.assertEqual([ x() for x in (lambda: True, lambda: False) if x() ], [True]) + self.assertEqual([ x(False) for x in (lambda x: False if x else True, lambda x: True if x else False) if x(False) ], [True]) + self.assertEqual((5 if 1 else _checkeval("check 1", 0)), 5) + self.assertEqual((_checkeval("check 2", 0) if 0 else 5), 5) + self.assertEqual((5 and 6 if 0 else 1), 1) + self.assertEqual(((5 and 6) if 0 else 1), 1) + self.assertEqual((5 and (6 if 1 else 1)), 6) + self.assertEqual((0 or _checkeval("check 3", 2) if 0 else 3), 3) + self.assertEqual((1 or _checkeval("check 4", 2) if 1 else _checkeval("check 5", 3)), 1) + self.assertEqual((0 or 5 if 1 else _checkeval("check 6", 3)), 5) + self.assertEqual((not 5 if 1 else 1), False) + self.assertEqual((not 5 if 0 else 1), 1) + self.assertEqual((6 + 1 if 1 else 2), 7) + self.assertEqual((6 - 1 if 1 else 2), 5) + self.assertEqual((6 * 2 if 1 else 4), 12) + self.assertEqual((6 / 2 if 1 else 3), 3) + self.assertEqual((6 < 4 if 0 else 2), 2) -print "assert_stmt" # assert_stmt: 'assert' test [',' test] -assert 1 -assert 1, 1 -assert lambda x:x -assert 1, lambda x:x+1 +def test_main(): + run_unittest(TokenTests, GrammarTests) -### compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef -# Tested below - -print 'if_stmt' # 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite] -if 1: pass -if 1: pass -else: pass -if 0: pass -elif 0: pass -if 0: pass -elif 0: pass -elif 0: pass -elif 0: pass -else: pass - -print 'while_stmt' # 'while' test ':' suite ['else' ':' suite] -while 0: pass -while 0: pass -else: pass - -print 'for_stmt' # 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite] -for i in 1, 2, 3: pass -for i, j, k in (): pass -else: pass -class Squares: - def __init__(self, max): - self.max = max - self.sofar = [] - def __len__(self): return len(self.sofar) - def __getitem__(self, i): - if not 0 <= i < self.max: raise IndexError - n = len(self.sofar) - while n <= i: - self.sofar.append(n*n) - n = n+1 - return self.sofar[i] -n = 0 -for x in Squares(10): n = n+x -if n != 285: raise TestFailed, 'for over growing sequence' - -result = [] -for x, in [(1,), (2,), (3,)]: - result.append(x) -vereq(result, [1, 2, 3]) - -print 'try_stmt' -### try_stmt: 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite] -### | 'try' ':' suite 'finally' ':' suite -### except_clause: 'except' [expr [',' expr]] -try: - 1/0 -except ZeroDivisionError: - pass -else: - pass -try: 1/0 -except EOFError: pass -except TypeError, msg: pass -except RuntimeError, msg: pass -except: pass -else: pass -try: 1/0 -except (EOFError, TypeError, ZeroDivisionError): pass -try: 1/0 -except (EOFError, TypeError, ZeroDivisionError), msg: pass -try: pass -finally: pass - -print 'suite' # simple_stmt | NEWLINE INDENT NEWLINE* (stmt NEWLINE*)+ DEDENT -if 1: pass -if 1: - pass -if 1: - # - # - # - pass - pass - # - pass - # - -print 'test' -### and_test ('or' and_test)* -### and_test: not_test ('and' not_test)* -### not_test: 'not' not_test | comparison -if not 1: pass -if 1 and 1: pass -if 1 or 1: pass -if not not not 1: pass -if not 1 and 1 and 1: pass -if 1 and 1 or 1 and 1 and 1 or not 1 and 1: pass - -print 'comparison' -### comparison: expr (comp_op expr)* -### comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not' -if 1: pass -x = (1 == 1) -if 1 == 1: pass -if 1 != 1: pass -if 1 <> 1: pass -if 1 < 1: pass -if 1 > 1: pass -if 1 <= 1: pass -if 1 >= 1: pass -if 1 is 1: pass -if 1 is not 1: pass -if 1 in (): pass -if 1 not in (): pass -if 1 < 1 > 1 == 1 >= 1 <= 1 <> 1 != 1 in 1 not in 1 is 1 is not 1: pass - -print 'binary mask ops' -x = 1 & 1 -x = 1 ^ 1 -x = 1 | 1 - -print 'shift ops' -x = 1 << 1 -x = 1 >> 1 -x = 1 << 1 >> 1 - -print 'additive ops' -x = 1 -x = 1 + 1 -x = 1 - 1 - 1 -x = 1 - 1 + 1 - 1 + 1 - -print 'multiplicative ops' -x = 1 * 1 -x = 1 / 1 -x = 1 % 1 -x = 1 / 1 * 1 % 1 - -print 'unary ops' -x = +1 -x = -1 -x = ~1 -x = ~1 ^ 1 & 1 | 1 & 1 ^ -1 -x = -1*1/1 + 1*1 - ---1*1 - -print 'selectors' -### trailer: '(' [testlist] ')' | '[' subscript ']' | '.' NAME -### subscript: expr | [expr] ':' [expr] -f1() -f2(1) -f2(1,) -f3(1, 2) -f3(1, 2,) -f4(1, (2, (3, 4))) -v0() -v0(1) -v0(1,) -v0(1,2) -v0(1,2,3,4,5,6,7,8,9,0) -v1(1) -v1(1,) -v1(1,2) -v1(1,2,3) -v1(1,2,3,4,5,6,7,8,9,0) -v2(1,2) -v2(1,2,3) -v2(1,2,3,4) -v2(1,2,3,4,5,6,7,8,9,0) -v3(1,(2,3)) -v3(1,(2,3),4) -v3(1,(2,3),4,5,6,7,8,9,0) -print -import sys, time -c = sys.path[0] -x = time.time() -x = sys.modules['time'].time() -a = '01234' -c = a[0] -c = a[-1] -s = a[0:5] -s = a[:5] -s = a[0:] -s = a[:] -s = a[-5:] -s = a[:-1] -s = a[-4:-3] -# A rough test of SF bug 1333982. http://python.org/sf/1333982 -# The testing here is fairly incomplete. -# Test cases should include: commas with 1 and 2 colons -d = {} -d[1] = 1 -d[1,] = 2 -d[1,2] = 3 -d[1,2,3] = 4 -L = list(d) -L.sort() -print L - - -print 'atoms' -### atom: '(' [testlist] ')' | '[' [testlist] ']' | '{' [dictmaker] '}' | '`' testlist '`' | NAME | NUMBER | STRING -### dictmaker: test ':' test (',' test ':' test)* [','] - -x = (1) -x = (1 or 2 or 3) -x = (1 or 2 or 3, 2, 3) - -x = [] -x = [1] -x = [1 or 2 or 3] -x = [1 or 2 or 3, 2, 3] -x = [] - -x = {} -x = {'one': 1} -x = {'one': 1,} -x = {'one' or 'two': 1 or 2} -x = {'one': 1, 'two': 2} -x = {'one': 1, 'two': 2,} -x = {'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'six': 6} - -x = `x` -x = `1 or 2 or 3` -x = x -x = 'x' -x = 123 - -### exprlist: expr (',' expr)* [','] -### testlist: test (',' test)* [','] -# These have been exercised enough above - -print 'classdef' # 'class' NAME ['(' [testlist] ')'] ':' suite -class B: pass -class B2(): pass -class C1(B): pass -class C2(B): pass -class D(C1, C2, B): pass -class C: - def meth1(self): pass - def meth2(self, arg): pass - def meth3(self, a1, a2): pass - -# list comprehension tests -nums = [1, 2, 3, 4, 5] -strs = ["Apple", "Banana", "Coconut"] -spcs = [" Apple", " Banana ", "Coco nut "] - -print [s.strip() for s in spcs] -print [3 * x for x in nums] -print [x for x in nums if x > 2] -print [(i, s) for i in nums for s in strs] -print [(i, s) for i in nums for s in [f for f in strs if "n" in f]] -print [(lambda a:[a**i for i in range(a+1)])(j) for j in range(5)] - -def test_in_func(l): - return [None < x < 3 for x in l if x > 2] - -print test_in_func(nums) - -def test_nested_front(): - print [[y for y in [x, x + 1]] for x in [1,3,5]] - -test_nested_front() - -check_syntax("[i, s for i in nums for s in strs]") -check_syntax("[x if y]") - -suppliers = [ - (1, "Boeing"), - (2, "Ford"), - (3, "Macdonalds") -] - -parts = [ - (10, "Airliner"), - (20, "Engine"), - (30, "Cheeseburger") -] - -suppart = [ - (1, 10), (1, 20), (2, 20), (3, 30) -] - -print [ - (sname, pname) - for (sno, sname) in suppliers - for (pno, pname) in parts - for (sp_sno, sp_pno) in suppart - if sno == sp_sno and pno == sp_pno -] - -# generator expression tests -g = ([x for x in range(10)] for x in range(1)) -verify(g.next() == [x for x in range(10)]) -try: - g.next() - raise TestFailed, 'should produce StopIteration exception' -except StopIteration: - pass - -a = 1 -try: - g = (a for d in a) - g.next() - raise TestFailed, 'should produce TypeError' -except TypeError: - pass - -verify(list((x, y) for x in 'abcd' for y in 'abcd') == [(x, y) for x in 'abcd' for y in 'abcd']) -verify(list((x, y) for x in 'ab' for y in 'xy') == [(x, y) for x in 'ab' for y in 'xy']) - -a = [x for x in range(10)] -b = (x for x in (y for y in a)) -verify(sum(b) == sum([x for x in range(10)])) - -verify(sum(x**2 for x in range(10)) == sum([x**2 for x in range(10)])) -verify(sum(x*x for x in range(10) if x%2) == sum([x*x for x in range(10) if x%2])) -verify(sum(x for x in (y for y in range(10))) == sum([x for x in range(10)])) -verify(sum(x for x in (y for y in (z for z in range(10)))) == sum([x for x in range(10)])) -verify(sum(x for x in [y for y in (z for z in range(10))]) == sum([x for x in range(10)])) -verify(sum(x for x in (y for y in (z for z in range(10) if True)) if True) == sum([x for x in range(10)])) -verify(sum(x for x in (y for y in (z for z in range(10) if True) if False) if True) == 0) -check_syntax("foo(x for x in range(10), 100)") -check_syntax("foo(100, x for x in range(10))") - -# test for outmost iterable precomputation -x = 10; g = (i for i in range(x)); x = 5 -verify(len(list(g)) == 10) - -# This should hold, since we're only precomputing outmost iterable. -x = 10; t = False; g = ((i,j) for i in range(x) if t for j in range(x)) -x = 5; t = True; -verify([(i,j) for i in range(10) for j in range(5)] == list(g)) - -# Grammar allows multiple adjacent 'if's in listcomps and genexps, -# even though it's silly. Make sure it works (ifelse broke this.) -verify([ x for x in range(10) if x % 2 if x % 3 ], [1, 5, 7]) -verify((x for x in range(10) if x % 2 if x % 3), [1, 5, 7]) - -# Verify unpacking single element tuples in listcomp/genexp. -vereq([x for x, in [(4,), (5,), (6,)]], [4, 5, 6]) -vereq(list(x for x, in [(7,), (8,), (9,)]), [7, 8, 9]) - -# Test ifelse expressions in various cases -def _checkeval(msg, ret): - "helper to check that evaluation of expressions is done correctly" - print x - return ret - -verify([ x() for x in lambda: True, lambda: False if x() ] == [True]) -verify([ x() for x in (lambda: True, lambda: False) if x() ] == [True]) -verify([ x(False) for x in (lambda x: False if x else True, lambda x: True if x else False) if x(False) ] == [True]) -verify((5 if 1 else _checkeval("check 1", 0)) == 5) -verify((_checkeval("check 2", 0) if 0 else 5) == 5) -verify((5 and 6 if 0 else 1) == 1) -verify(((5 and 6) if 0 else 1) == 1) -verify((5 and (6 if 1 else 1)) == 6) -verify((0 or _checkeval("check 3", 2) if 0 else 3) == 3) -verify((1 or _checkeval("check 4", 2) if 1 else _checkeval("check 5", 3)) == 1) -verify((0 or 5 if 1 else _checkeval("check 6", 3)) == 5) -verify((not 5 if 1 else 1) == False) -verify((not 5 if 0 else 1) == 1) -verify((6 + 1 if 1 else 2) == 7) -verify((6 - 1 if 1 else 2) == 5) -verify((6 * 2 if 1 else 4) == 12) -verify((6 / 2 if 1 else 3) == 3) -verify((6 < 4 if 0 else 2) == 2) +if __name__ == '__main__': + test_main() diff --git a/Lib/test/test_scope.py b/Lib/test/test_scope.py index 239745c613f..c703a06c0be 100644 --- a/Lib/test/test_scope.py +++ b/Lib/test/test_scope.py @@ -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, "") warnings.filterwarnings("ignore", r"import \*", SyntaxWarning, "") -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 unoptimized_clash1(strip): return f """) -check_syntax("""\ + check_syntax_error(self, """\ def unoptimized_clash2(): from string import * def f(s): @@ -196,7 +200,7 @@ def unoptimized_clash2(): return f """) -check_syntax("""\ + check_syntax_error(self, """\ def unoptimized_clash2(): from string import * def g(): @@ -205,8 +209,8 @@ def unoptimized_clash2(): 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 error(y): 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 noproblem3(): 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 @@ try: 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 f(): 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 f(): 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 f(): 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 f(): 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 @@ class Global: 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 test(x): 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() diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py index a9d5dabcc76..ae39aa13c6e 100644 --- a/Lib/test/test_support.py +++ b/Lib/test/test_support.py @@ -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, '', 'exec') + compile(statement, '', 'exec') except SyntaxError: pass else: - print 'Missing SyntaxError: "%s"' % statement + testcase.fail('Missing SyntaxError: "%s"' % statement) def open_urlresource(url): import urllib, urlparse