Kaydet (Commit) c6fdec6d authored tarafından Georg Brandl's avatar Georg Brandl

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.
üst 3a3d8ea4
...@@ -379,8 +379,8 @@ test_support provides the following useful objects: ...@@ -379,8 +379,8 @@ test_support provides the following useful objects:
point numbers when you expect them to only be approximately equal point numbers when you expect them to only be approximately equal
withing a fuzz factor (``test_support.FUZZ``, which defaults to 1e-6). withing a fuzz factor (``test_support.FUZZ``, which defaults to 1e-6).
* ``check_syntax(statement)`` - make sure that the statement is *not* * ``check_syntax_error(testcase, statement)`` - make sure that the
correct Python syntax. statement is *not* correct Python syntax.
Python and C statement coverage results are currently available at Python and C statement coverage results are currently available at
......
test_global
got SyntaxError as expected
got SyntaxError as expected
got SyntaxError as expected
as expected, no SyntaxError
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')]
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
"""Verify that warnings are issued for global statements following use.""" """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 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): def test1(self):
try: prog_text_1 = """\
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 wrong1(): def wrong1():
a = 1 a = 1
b = 2 b = 2
global a global a
global b 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(): def wrong2():
print x print x
global 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(): def wrong3():
print x print x
x = 2 x = 2
global x 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 global x
x = 2 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()
...@@ -8,848 +8,910 @@ ...@@ -8,848 +8,910 @@
# regression test, the filterwarnings() call has been added to # regression test, the filterwarnings() call has been added to
# regrtest.py. # 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 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:
print '1.1.1 Backslashes' x = 1 \
+ 1
# Backslash means line continuation: self.assertEquals(x, 2, 'backslash for line continuation')
x = 1 \
+ 1 # Backslash does not means continuation in comments :\
if x != 2: raise TestFailed, 'backslash for line continuation' x = 0
self.assertEquals(x, 0, 'backslash ending comment')
# Backslash does not means continuation in comments :\
x = 0 def testPlainIntegers(self):
if x != 0: raise TestFailed, 'backslash ending comment' self.assertEquals(0xff, 255)
self.assertEquals(0377, 255)
print '1.1.2 Numeric literals' self.assertEquals(2147483647, 017777777777)
from sys import maxint
print '1.1.2.1 Plain integers' if maxint == 2147483647:
if 0xff != 255: raise TestFailed, 'hex int' self.assertEquals(-2147483647-1, -020000000000)
if 0377 != 255: raise TestFailed, 'octal int' # XXX -2147483648
if 2147483647 != 017777777777: raise TestFailed, 'large positive int' self.assert_(037777777777 > 0)
try: self.assert_(0xffffffff > 0)
from sys import maxint for s in '2147483648', '040000000000', '0x100000000':
except ImportError: try:
maxint = 2147483647 x = eval(s)
if maxint == 2147483647: except OverflowError:
# The following test will start to fail in Python 2.4; self.fail("OverflowError on huge integer literal %r" % s)
# change the 020000000000 to -020000000000 elif maxint == 9223372036854775807:
if -2147483647-1 != -020000000000: raise TestFailed, 'max negative int' self.assertEquals(-9223372036854775807-1, -01000000000000000000000)
# XXX -2147483648 self.assert_(01777777777777777777777 > 0)
if 037777777777 < 0: raise TestFailed, 'large oct' self.assert_(0xffffffffffffffff > 0)
if 0xffffffff < 0: raise TestFailed, 'large hex' for s in '9223372036854775808', '02000000000000000000000', \
for s in '2147483648', '040000000000', '0x100000000': '0x10000000000000000':
try: try:
x = eval(s) x = eval(s)
except OverflowError: except OverflowError:
print "OverflowError on huge integer literal " + repr(s) self.fail("OverflowError on huge integer literal %r" % s)
elif eval('maxint == 9223372036854775807'): else:
if eval('-9223372036854775807-1 != -01000000000000000000000'): self.fail('Weird maxint value %r' % maxint)
raise TestFailed, 'max negative int'
if eval('01777777777777777777777') < 0: raise TestFailed, 'large oct' def testLongIntegers(self):
if eval('0xffffffffffffffff') < 0: raise TestFailed, 'large hex' x = 0L
for s in '9223372036854775808', '02000000000000000000000', \ x = 0l
'0x10000000000000000': x = 0xffffffffffffffffL
try: x = 0xffffffffffffffffl
x = eval(s) x = 077777777777777777L
except OverflowError: x = 077777777777777777l
print "OverflowError on huge integer literal " + repr(s) x = 123456789012345678901234567890L
else: x = 123456789012345678901234567890l
print 'Weird maxint value', maxint
def testFloats(self):
print '1.1.2.2 Long integers' x = 3.14
x = 0L x = 314.
x = 0l x = 0.314
x = 0xffffffffffffffffL # XXX x = 000.314
x = 0xffffffffffffffffl x = .314
x = 077777777777777777L x = 3e14
x = 077777777777777777l x = 3E14
x = 123456789012345678901234567890L x = 3e-14
x = 123456789012345678901234567890l x = 3e+14
x = 3.e14
print '1.1.2.3 Floating point' x = .3e14
x = 3.14 x = 3.1e4
x = 314.
x = 0.314 def testStringLiterals(self):
# XXX x = 000.314 x = ''; y = ""; self.assert_(len(x) == 0 and x == y)
x = .314 x = '\''; y = "'"; self.assert_(len(x) == 1 and x == y and ord(x) == 39)
x = 3e14 x = '"'; y = "\""; self.assert_(len(x) == 1 and x == y and ord(x) == 34)
x = 3E14 x = "doesn't \"shrink\" does it"
x = 3e-14 y = 'doesn\'t "shrink" does it'
x = 3e+14 self.assert_(len(x) == 24 and x == y)
x = 3.e14 x = "does \"shrink\" doesn't it"
x = .3e14 y = 'does "shrink" doesn\'t it'
x = 3.1e4 self.assert_(len(x) == 24 and x == y)
x = """
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 = """
The "quick" The "quick"
brown fox brown fox
jumps over jumps over
the 'lazy' dog. the 'lazy' dog.
""" """
y = '\nThe "quick"\nbrown fox\njumps over\nthe \'lazy\' dog.\n' y = '\nThe "quick"\nbrown fox\njumps over\nthe \'lazy\' dog.\n'
verify(x == y) self.assertEquals(x, y)
y = ''' y = '''
The "quick" The "quick"
brown fox brown fox
jumps over jumps over
the 'lazy' dog. the 'lazy' dog.
'''; verify(x == y) '''
y = "\n\ self.assertEquals(x, y)
y = "\n\
The \"quick\"\n\ The \"quick\"\n\
brown fox\n\ brown fox\n\
jumps over\n\ jumps over\n\
the 'lazy' dog.\n\ the 'lazy' dog.\n\
"; verify(x == y) "
y = '\n\ self.assertEquals(x, y)
y = '\n\
The \"quick\"\n\ The \"quick\"\n\
brown fox\n\ brown fox\n\
jumps over\n\ jumps over\n\
the \'lazy\' dog.\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
print 'file_input' # (NEWLINE | stmt)* ENDMARKER
# Being tested as this very moment this very module # file_input: (NEWLINE | stmt)* ENDMARKER
# Being tested as this very moment this very module
print 'expr_input' # testlist NEWLINE
# XXX Hard to test -- used only in calls to input() # expr_input: testlist NEWLINE
# XXX Hard to test -- used only in calls to input()
print 'eval_input' # testlist ENDMARKER
x = eval('1, 0 or 1') def testEvalInput(self):
# testlist ENDMARKER
print 'funcdef' x = eval('1, 0 or 1')
### 'def' NAME parameters ':' suite
### parameters: '(' [varargslist] ')' def testFuncdef(self):
### varargslist: (fpdef ['=' test] ',')* ('*' NAME [',' ('**'|'*' '*') NAME] ### 'def' NAME parameters ':' suite
### | ('**'|'*' '*') NAME) ### parameters: '(' [varargslist] ')'
### | fpdef ['=' test] (',' fpdef ['=' test])* [','] ### varargslist: (fpdef ['=' test] ',')* ('*' NAME [',' ('**'|'*' '*') NAME]
### fpdef: NAME | '(' fplist ')' ### | ('**'|'*' '*') NAME)
### fplist: fpdef (',' fpdef)* [','] ### | fpdef ['=' test] (',' fpdef ['=' test])* [',']
### arglist: (argument ',')* (argument | *' test [',' '**' test] | '**' test) ### fpdef: NAME | '(' fplist ')'
### argument: [test '='] test # Really [keyword '='] test ### fplist: fpdef (',' fpdef)* [',']
def f1(): pass ### arglist: (argument ',')* (argument | *' test [',' '**' test] | '**' test)
f1() ### argument: [test '='] test # Really [keyword '='] test
f1(*()) def f1(): pass
f1(*(), **{}) f1()
def f2(one_argument): pass f1(*())
def f3(two, arguments): pass f1(*(), **{})
def f4(two, (compound, (argument, list))): pass def f2(one_argument): pass
def f5((compound, first), two): pass def f3(two, arguments): pass
vereq(f2.func_code.co_varnames, ('one_argument',)) def f4(two, (compound, (argument, list))): pass
vereq(f3.func_code.co_varnames, ('two', 'arguments')) def f5((compound, first), two): pass
if sys.platform.startswith('java'): self.assertEquals(f2.func_code.co_varnames, ('one_argument',))
vereq(f4.func_code.co_varnames, self.assertEquals(f3.func_code.co_varnames, ('two', 'arguments'))
('two', '(compound, (argument, list))', 'compound', 'argument', if sys.platform.startswith('java'):
'list',)) self.assertEquals(f4.func_code.co_varnames,
vereq(f5.func_code.co_varnames, ('two', '(compound, (argument, list))', 'compound', 'argument',
('(compound, first)', 'two', 'compound', 'first')) 'list',))
else: self.assertEquals(f5.func_code.co_varnames,
vereq(f4.func_code.co_varnames, ('(compound, first)', 'two', 'compound', 'first'))
('two', '.1', 'compound', 'argument', 'list')) else:
vereq(f5.func_code.co_varnames, self.assertEquals(f4.func_code.co_varnames,
('.0', 'two', 'compound', 'first')) ('two', '.1', 'compound', 'argument', 'list'))
def a1(one_arg,): pass self.assertEquals(f5.func_code.co_varnames,
def a2(two, args,): pass ('.0', 'two', 'compound', 'first'))
def v0(*rest): pass def a1(one_arg,): pass
def v1(a, *rest): pass def a2(two, args,): pass
def v2(a, b, *rest): pass def v0(*rest): pass
def v3(a, (b, c), *rest): return a, b, c, rest def v1(a, *rest): pass
# ceval unpacks the formal arguments into the first argcount names; def v2(a, b, *rest): pass
# thus, the names nested inside tuples must appear after these names. def v3(a, (b, c), *rest): return a, b, c, rest
if sys.platform.startswith('java'):
verify(v3.func_code.co_varnames == ('a', '(b, c)', 'rest', 'b', 'c')) f1()
else: f2(1)
vereq(v3.func_code.co_varnames, ('a', '.1', 'rest', 'b', 'c')) f2(1,)
verify(v3(1, (2, 3), 4) == (1, 2, 3, (4,))) f3(1, 2)
def d01(a=1): pass f3(1, 2,)
d01() f4(1, (2, (3, 4)))
d01(1) v0()
d01(*(1,)) v0(1)
d01(**{'a':2}) v0(1,)
def d11(a, b=1): pass v0(1,2)
d11(1) v0(1,2,3,4,5,6,7,8,9,0)
d11(1, 2) v1(1)
d11(1, **{'b':2}) v1(1,)
def d21(a, b, c=1): pass v1(1,2)
d21(1, 2) v1(1,2,3)
d21(1, 2, 3) v1(1,2,3,4,5,6,7,8,9,0)
d21(*(1, 2, 3)) v2(1,2)
d21(1, *(2, 3)) v2(1,2,3)
d21(1, 2, *(3,)) v2(1,2,3,4)
d21(1, 2, **{'c':3}) v2(1,2,3,4,5,6,7,8,9,0)
def d02(a=1, b=2): pass v3(1,(2,3))
d02() v3(1,(2,3),4)
d02(1) v3(1,(2,3),4,5,6,7,8,9,0)
d02(1, 2)
d02(*(1, 2)) # ceval unpacks the formal arguments into the first argcount names;
d02(1, *(2,)) # thus, the names nested inside tuples must appear after these names.
d02(1, **{'b':2}) if sys.platform.startswith('java'):
d02(**{'a': 1, 'b': 2}) self.assertEquals(v3.func_code.co_varnames, ('a', '(b, c)', 'rest', 'b', 'c'))
def d12(a, b=1, c=2): pass else:
d12(1) self.assertEquals(v3.func_code.co_varnames, ('a', '.1', 'rest', 'b', 'c'))
d12(1, 2) self.assertEquals(v3(1, (2, 3), 4), (1, 2, 3, (4,)))
d12(1, 2, 3) def d01(a=1): pass
def d22(a, b, c=1, d=2): pass d01()
d22(1, 2) d01(1)
d22(1, 2, 3) d01(*(1,))
d22(1, 2, 3, 4) d01(**{'a':2})
def d01v(a=1, *rest): pass def d11(a, b=1): pass
d01v() d11(1)
d01v(1) d11(1, 2)
d01v(1, 2) d11(1, **{'b':2})
d01v(*(1, 2, 3, 4)) def d21(a, b, c=1): pass
d01v(*(1,)) d21(1, 2)
d01v(**{'a':2}) d21(1, 2, 3)
def d11v(a, b=1, *rest): pass d21(*(1, 2, 3))
d11v(1) d21(1, *(2, 3))
d11v(1, 2) d21(1, 2, *(3,))
d11v(1, 2, 3) d21(1, 2, **{'c':3})
def d21v(a, b, c=1, *rest): pass def d02(a=1, b=2): pass
d21v(1, 2) d02()
d21v(1, 2, 3) d02(1)
d21v(1, 2, 3, 4) d02(1, 2)
d21v(*(1, 2, 3, 4)) d02(*(1, 2))
d21v(1, 2, **{'c': 3}) d02(1, *(2,))
def d02v(a=1, b=2, *rest): pass d02(1, **{'b':2})
d02v() d02(**{'a': 1, 'b': 2})
d02v(1) def d12(a, b=1, c=2): pass
d02v(1, 2) d12(1)
d02v(1, 2, 3) d12(1, 2)
d02v(1, *(2, 3, 4)) d12(1, 2, 3)
d02v(**{'a': 1, 'b': 2}) def d22(a, b, c=1, d=2): pass
def d12v(a, b=1, c=2, *rest): pass d22(1, 2)
d12v(1) d22(1, 2, 3)
d12v(1, 2) d22(1, 2, 3, 4)
d12v(1, 2, 3) def d01v(a=1, *rest): pass
d12v(1, 2, 3, 4) d01v()
d12v(*(1, 2, 3, 4)) d01v(1)
d12v(1, 2, *(3, 4, 5)) d01v(1, 2)
d12v(1, *(2,), **{'c': 3}) d01v(*(1, 2, 3, 4))
def d22v(a, b, c=1, d=2, *rest): pass d01v(*(1,))
d22v(1, 2) d01v(**{'a':2})
d22v(1, 2, 3) def d11v(a, b=1, *rest): pass
d22v(1, 2, 3, 4) d11v(1)
d22v(1, 2, 3, 4, 5) d11v(1, 2)
d22v(*(1, 2, 3, 4)) d11v(1, 2, 3)
d22v(1, 2, *(3, 4, 5)) def d21v(a, b, c=1, *rest): pass
d22v(1, *(2, 3), **{'d': 4}) d21v(1, 2)
def d31v((x)): pass d21v(1, 2, 3)
d31v(1) d21v(1, 2, 3, 4)
def d32v((x,)): pass d21v(*(1, 2, 3, 4))
d32v((1,)) d21v(1, 2, **{'c': 3})
def d02v(a=1, b=2, *rest): pass
### lambdef: 'lambda' [varargslist] ':' test d02v()
print 'lambdef' d02v(1)
l1 = lambda : 0 d02v(1, 2)
verify(l1() == 0) d02v(1, 2, 3)
l2 = lambda : a[d] # XXX just testing the expression d02v(1, *(2, 3, 4))
l3 = lambda : [2 < x for x in [-1, 3, 0L]] d02v(**{'a': 1, 'b': 2})
verify(l3() == [0, 1, 0]) def d12v(a, b=1, c=2, *rest): pass
l4 = lambda x = lambda y = lambda z=1 : z : y() : x() d12v(1)
verify(l4() == 1) d12v(1, 2)
l5 = lambda x, y, z=2: x + y + z d12v(1, 2, 3)
verify(l5(1, 2) == 5) d12v(1, 2, 3, 4)
verify(l5(1, 2, 3) == 6) d12v(*(1, 2, 3, 4))
check_syntax("lambda x: x = 2") d12v(1, 2, *(3, 4, 5))
d12v(1, *(2,), **{'c': 3})
### stmt: simple_stmt | compound_stmt def d22v(a, b, c=1, d=2, *rest): pass
# Tested below d22v(1, 2)
d22v(1, 2, 3)
### simple_stmt: small_stmt (';' small_stmt)* [';'] d22v(1, 2, 3, 4)
print 'simple_stmt' d22v(1, 2, 3, 4, 5)
x = 1; pass; del x d22v(*(1, 2, 3, 4))
def foo(): d22v(1, 2, *(3, 4, 5))
# verify statments that end with semi-colons d22v(1, *(2, 3), **{'d': 4})
x = 1; pass; del x; def d31v((x)): pass
foo() d31v(1)
def d32v((x,)): pass
### small_stmt: expr_stmt | print_stmt | pass_stmt | del_stmt | flow_stmt | import_stmt | global_stmt | access_stmt | exec_stmt d32v((1,))
# Tested below
def testLambdef(self):
print 'expr_stmt' # (exprlist '=')* exprlist ### lambdef: 'lambda' [varargslist] ':' test
1 l1 = lambda : 0
1, 2, 3 self.assertEquals(l1(), 0)
x = 1 l2 = lambda : a[d] # XXX just testing the expression
x = 1, 2, 3 l3 = lambda : [2 < x for x in [-1, 3, 0L]]
x = y = z = 1, 2, 3 self.assertEquals(l3(), [0, 1, 0])
x, y, z = 1, 2, 3 l4 = lambda x = lambda y = lambda z=1 : z : y() : x()
abc = a, b, c = x, y, z = xyz = 1, 2, (3, 4) self.assertEquals(l4(), 1)
# NB these variables are deleted below l5 = lambda x, y, z=2: x + y + z
self.assertEquals(l5(1, 2), 5)
check_syntax("x + 1 = 1") self.assertEquals(l5(1, 2, 3), 6)
check_syntax("a + 1 = b + 2") check_syntax_error(self, "lambda x: x = 2")
print 'print_stmt' # 'print' (test ',')* [test] ### stmt: simple_stmt | compound_stmt
print 1, 2, 3 # Tested below
print 1, 2, 3,
print def testSimpleStmt(self):
print 0 or 1, 0 or 1, ### simple_stmt: small_stmt (';' small_stmt)* [';']
print 0 or 1 x = 1; pass; del x
def foo():
print 'extended print_stmt' # 'print' '>>' test ',' # verify statments that end with semi-colons
import sys x = 1; pass; del x;
print >> sys.stdout, 1, 2, 3 foo()
print >> sys.stdout, 1, 2, 3,
print >> sys.stdout ### small_stmt: expr_stmt | print_stmt | pass_stmt | del_stmt | flow_stmt | import_stmt | global_stmt | access_stmt | exec_stmt
print >> sys.stdout, 0 or 1, 0 or 1, # Tested below
print >> sys.stdout, 0 or 1
def testExprStmt(self):
# test printing to an instance # (exprlist '=')* exprlist
class Gulp: 1
def write(self, msg): pass 1, 2, 3
x = 1
gulp = Gulp() x = 1, 2, 3
print >> gulp, 1, 2, 3 x = y = z = 1, 2, 3
print >> gulp, 1, 2, 3, x, y, z = 1, 2, 3
print >> gulp abc = a, b, c = x, y, z = xyz = 1, 2, (3, 4)
print >> gulp, 0 or 1, 0 or 1,
print >> gulp, 0 or 1 check_syntax_error(self, "x + 1 = 1")
check_syntax_error(self, "a + 1 = b + 2")
# test print >> None
def driver(): def testPrintStmt(self):
oldstdout = sys.stdout # 'print' (test ',')* [test]
sys.stdout = Gulp() import StringIO
try:
tellme(Gulp()) # Can't test printing to real stdout without comparing output
tellme() # which is not available in unittest.
finally: save_stdout = sys.stdout
sys.stdout = oldstdout sys.stdout = StringIO.StringIO()
# we should see this once print 1, 2, 3
def tellme(file=sys.stdout): print 1, 2, 3,
print >> file, 'hello world' print
print 0 or 1, 0 or 1,
driver() print 0 or 1
# we should not see this at all # 'print' '>>' test ','
def tellme(file=None): print >> sys.stdout, 1, 2, 3
print >> file, 'goodbye universe' print >> sys.stdout, 1, 2, 3,
print >> sys.stdout
driver() print >> sys.stdout, 0 or 1, 0 or 1,
print >> sys.stdout, 0 or 1
# syntax errors
check_syntax('print ,') # test printing to an instance
check_syntax('print >> x,') class Gulp:
def write(self, msg): pass
print 'del_stmt' # 'del' exprlist
del abc gulp = Gulp()
del x, y, (z, xyz) print >> gulp, 1, 2, 3
print >> gulp, 1, 2, 3,
print 'pass_stmt' # 'pass' print >> gulp
pass print >> gulp, 0 or 1, 0 or 1,
print >> gulp, 0 or 1
print 'flow_stmt' # break_stmt | continue_stmt | return_stmt | raise_stmt
# Tested below # test print >> None
def driver():
print 'break_stmt' # 'break' oldstdout = sys.stdout
while 1: break sys.stdout = Gulp()
try:
print 'continue_stmt' # 'continue' tellme(Gulp())
i = 1 tellme()
while i: i = 0; continue finally:
sys.stdout = oldstdout
msg = ""
while not msg: # we should see this once
msg = "continue + try/except ok" def tellme(file=sys.stdout):
try: print >> file, 'hello world'
continue
msg = "continue failed to continue inside try" driver()
except:
msg = "continue inside try called except block" # we should not see this at all
print msg def tellme(file=None):
print >> file, 'goodbye universe'
msg = ""
while not msg: driver()
msg = "finally block not called"
try: self.assertEqual(sys.stdout.getvalue(), '''\
continue 1 2 3
finally: 1 2 3
msg = "continue + try/finally ok" 1 1 1
print msg 1 2 3
1 2 3
1 1 1
# This test warrants an explanation. It is a test specifically for SF bugs hello world
# #463359 and #462937. The bug is that a 'break' statement executed or ''')
# exception raised inside a try/except inside a loop, *after* a continue sys.stdout = save_stdout
# 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 # syntax errors
# a very small number (usually 0.) Because of this, the following test check_syntax_error(self, 'print ,')
# *must* written as a function, and the tracking vars *must* be function check_syntax_error(self, 'print >> x,')
# arguments with default values. Otherwise, the test will loop and loop.
def testDelStmt(self):
print "testing continue and break in try/except in loop" # 'del' exprlist
def test_break_continue_loop(extra_burning_oil = 1, count=0): abc = [1,2,3]
big_hippo = 2 x, y, z = abc
while big_hippo: xyz = x, y, z
count += 1
del abc
del x, y, (z, xyz)
def testPassStmt(self):
# 'pass'
pass
# flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt
# Tested below
def testBreakStmt(self):
# 'break'
while 1: break
def testContinueStmt(self):
# 'continue'
i = 1
while i: i = 0; continue
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)
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="<string>")
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: try:
if extra_burning_oil and big_hippo == 1: assert 0, "msg"
extra_burning_oil -= 1 except AssertionError, e:
break self.assertEquals(e.args[0], "msg")
big_hippo -= 1 else:
continue self.fail("AssertionError not raised by assert 0")
except:
raise ### compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
if count > 2 or big_hippo <> 1: # Tested below
print "continue then break in try/except in loop broken!"
test_break_continue_loop() def testIf(self):
# 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
print 'return_stmt' # 'return' [testlist] if 1: pass
def g1(): return if 1: pass
def g2(): return 1 else: pass
g1() if 0: pass
x = g2() elif 0: pass
check_syntax("class foo:return 1") if 0: pass
elif 0: pass
print 'yield_stmt' elif 0: pass
check_syntax("class foo:yield 1") elif 0: pass
else: pass
print 'raise_stmt' # 'raise' test [',' test]
try: raise RuntimeError, 'just testing' def testWhile(self):
except RuntimeError: pass # 'while' test ':' suite ['else' ':' suite]
try: raise KeyboardInterrupt while 0: pass
except KeyboardInterrupt: pass while 0: pass
else: pass
print 'import_name' # 'import' dotted_as_names
import sys def testFor(self):
import time, sys # 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite]
print 'import_from' # 'from' dotted_name 'import' ('*' | '(' import_as_names ')' | import_as_names) for i in 1, 2, 3: pass
from time import time for i, j, k in (): pass
from time import (time) else: pass
from sys import * class Squares:
from sys import path, argv def __init__(self, max):
from sys import (path, argv) self.max = max
from sys import (path, argv,) self.sofar = []
def __len__(self): return len(self.sofar)
print 'global_stmt' # 'global' NAME (',' NAME)* def __getitem__(self, i):
def f(): if not 0 <= i < self.max: raise IndexError
global a n = len(self.sofar)
global a, b while n <= i:
global one, two, three, four, five, six, seven, eight, nine, ten self.sofar.append(n*n)
n = n+1
print 'exec_stmt' # 'exec' expr ['in' expr [',' expr]] return self.sofar[i]
def f(): n = 0
z = None for x in Squares(10): n = n+x
del z if n != 285:
exec 'z=1+1\n' self.fail('for over growing sequence')
if z != 2: raise TestFailed, 'exec \'z=1+1\'\\n'
del z result = []
exec 'z=1+1' for x, in [(1,), (2,), (3,)]:
if z != 2: raise TestFailed, 'exec \'z=1+1\'' result.append(x)
z = None self.assertEqual(result, [1, 2, 3])
del z
import types def testTry(self):
if hasattr(types, "UnicodeType"): ### try_stmt: 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite]
exec r"""if 1: ### | 'try' ':' suite 'finally' ':' suite
exec u'z=1+1\n' ### except_clause: 'except' [expr [',' expr]]
if z != 2: raise TestFailed, 'exec u\'z=1+1\'\\n' try:
del z 1/0
exec u'z=1+1' except ZeroDivisionError:
if z != 2: raise TestFailed, 'exec u\'z=1+1\'' pass
""" else:
f() pass
g = {} try: 1/0
exec 'z = 1' in g except EOFError: pass
if g.has_key('__builtins__'): del g['__builtins__'] except TypeError, msg: pass
if g != {'z': 1}: raise TestFailed, 'exec \'z = 1\' in g' except RuntimeError, msg: pass
g = {} except: pass
l = {} else: pass
try: 1/0
import warnings except (EOFError, TypeError, ZeroDivisionError): pass
warnings.filterwarnings("ignore", "global statement", module="<string>") try: 1/0
exec 'global a; a = 1; b = 2' in g, l except (EOFError, TypeError, ZeroDivisionError), msg: pass
if g.has_key('__builtins__'): del g['__builtins__'] try: pass
if l.has_key('__builtins__'): del l['__builtins__'] finally: pass
if (g, l) != ({'a':1}, {'b':2}): raise TestFailed, 'exec ... in g (%s), l (%s)' %(g,l)
def testSuite(self):
# simple_stmt | NEWLINE INDENT NEWLINE* (stmt NEWLINE*)+ DEDENT
print "assert_stmt" # assert_stmt: 'assert' test [',' test] if 1: pass
assert 1 if 1:
assert 1, 1 pass
assert lambda x:x if 1:
assert 1, lambda x:x+1 #
#
### compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef #
# Tested below pass
pass
print 'if_stmt' # 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite] #
if 1: pass pass
if 1: pass #
else: pass
if 0: pass def testTest(self):
elif 0: pass ### and_test ('or' and_test)*
if 0: pass ### and_test: not_test ('and' not_test)*
elif 0: pass ### not_test: 'not' not_test | comparison
elif 0: pass if not 1: pass
elif 0: pass if 1 and 1: pass
else: pass if 1 or 1: pass
if not not not 1: pass
print 'while_stmt' # 'while' test ':' suite ['else' ':' suite] if not 1 and 1 and 1: pass
while 0: pass if 1 and 1 or 1 and 1 and 1 or not 1 and 1: pass
while 0: pass
else: pass def testComparison(self):
### comparison: expr (comp_op expr)*
print 'for_stmt' # 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite] ### comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'
for i in 1, 2, 3: pass if 1: pass
for i, j, k in (): pass x = (1 == 1)
else: pass if 1 == 1: pass
class Squares: if 1 != 1: pass
def __init__(self, max): if 1 <> 1: pass
self.max = max if 1 < 1: pass
self.sofar = [] if 1 > 1: pass
def __len__(self): return len(self.sofar) if 1 <= 1: pass
def __getitem__(self, i): if 1 >= 1: pass
if not 0 <= i < self.max: raise IndexError if 1 is 1: pass
n = len(self.sofar) if 1 is not 1: pass
while n <= i: if 1 in (): pass
self.sofar.append(n*n) if 1 not in (): pass
n = n+1 if 1 < 1 > 1 == 1 >= 1 <= 1 <> 1 != 1 in 1 not in 1 is 1 is not 1: pass
return self.sofar[i]
n = 0 def testBinaryMaskOps(self):
for x in Squares(10): n = n+x x = 1 & 1
if n != 285: raise TestFailed, 'for over growing sequence' x = 1 ^ 1
x = 1 | 1
result = []
for x, in [(1,), (2,), (3,)]: def testShiftOps(self):
result.append(x) x = 1 << 1
vereq(result, [1, 2, 3]) x = 1 >> 1
x = 1 << 1 >> 1
print 'try_stmt'
### try_stmt: 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite] def testAdditiveOps(self):
### | 'try' ':' suite 'finally' ':' suite x = 1
### except_clause: 'except' [expr [',' expr]] x = 1 + 1
try: x = 1 - 1 - 1
1/0 x = 1 - 1 + 1 - 1 + 1
except ZeroDivisionError:
pass def testMultiplicativeOps(self):
else: x = 1 * 1
pass x = 1 / 1
try: 1/0 x = 1 % 1
except EOFError: pass x = 1 / 1 * 1 % 1
except TypeError, msg: pass
except RuntimeError, msg: pass def testUnaryOps(self):
except: pass x = +1
else: pass x = -1
try: 1/0 x = ~1
except (EOFError, TypeError, ZeroDivisionError): pass x = ~1 ^ 1 & 1 | 1 & 1 ^ -1
try: 1/0 x = -1*1/1 + 1*1 - ---1*1
except (EOFError, TypeError, ZeroDivisionError), msg: pass
try: pass def testSelectors(self):
finally: pass ### trailer: '(' [testlist] ')' | '[' subscript ']' | '.' NAME
### subscript: expr | [expr] ':' [expr]
print 'suite' # simple_stmt | NEWLINE INDENT NEWLINE* (stmt NEWLINE*)+ DEDENT
if 1: pass import sys, time
if 1: c = sys.path[0]
pass x = time.time()
if 1: x = sys.modules['time'].time()
# a = '01234'
# c = a[0]
# c = a[-1]
pass s = a[0:5]
pass s = a[:5]
# s = a[0:]
pass s = a[:]
# s = a[-5:]
s = a[:-1]
print 'test' s = a[-4:-3]
### and_test ('or' and_test)* # A rough test of SF bug 1333982. http://python.org/sf/1333982
### and_test: not_test ('and' not_test)* # The testing here is fairly incomplete.
### not_test: 'not' not_test | comparison # Test cases should include: commas with 1 and 2 colons
if not 1: pass d = {}
if 1 and 1: pass d[1] = 1
if 1 or 1: pass d[1,] = 2
if not not not 1: pass d[1,2] = 3
if not 1 and 1 and 1: pass d[1,2,3] = 4
if 1 and 1 or 1 and 1 and 1 or not 1 and 1: pass L = list(d)
L.sort()
print 'comparison' self.assertEquals(str(L), '[1, (1,), (1, 2), (1, 2, 3)]')
### comparison: expr (comp_op expr)*
### comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not' def testAtoms(self):
if 1: pass ### atom: '(' [testlist] ')' | '[' [testlist] ']' | '{' [dictmaker] '}' | '`' testlist '`' | NAME | NUMBER | STRING
x = (1 == 1) ### dictmaker: test ':' test (',' test ':' test)* [',']
if 1 == 1: pass
if 1 != 1: pass x = (1)
if 1 <> 1: pass x = (1 or 2 or 3)
if 1 < 1: pass x = (1 or 2 or 3, 2, 3)
if 1 > 1: pass
if 1 <= 1: pass x = []
if 1 >= 1: pass x = [1]
if 1 is 1: pass x = [1 or 2 or 3]
if 1 is not 1: pass x = [1 or 2 or 3, 2, 3]
if 1 in (): pass x = []
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 x = {}
x = {'one': 1}
print 'binary mask ops' x = {'one': 1,}
x = 1 & 1 x = {'one' or 'two': 1 or 2}
x = 1 ^ 1 x = {'one': 1, 'two': 2}
x = 1 | 1 x = {'one': 1, 'two': 2,}
x = {'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'six': 6}
print 'shift ops'
x = 1 << 1 x = `x`
x = 1 >> 1 x = `1 or 2 or 3`
x = 1 << 1 >> 1 x = x
x = 'x'
print 'additive ops' x = 123
x = 1
x = 1 + 1 ### exprlist: expr (',' expr)* [',']
x = 1 - 1 - 1 ### testlist: test (',' test)* [',']
x = 1 - 1 + 1 - 1 + 1 # These have been exercised enough above
print 'multiplicative ops' def testClassdef(self):
x = 1 * 1 # 'class' NAME ['(' [testlist] ')'] ':' suite
x = 1 / 1 class B: pass
x = 1 % 1 class B2(): pass
x = 1 / 1 * 1 % 1 class C1(B): pass
class C2(B): pass
print 'unary ops' class D(C1, C2, B): pass
x = +1 class C:
x = -1 def meth1(self): pass
x = ~1 def meth2(self, arg): pass
x = ~1 ^ 1 & 1 | 1 & 1 ^ -1 def meth3(self, a1, a2): pass
x = -1*1/1 + 1*1 - ---1*1
def testListcomps(self):
print 'selectors' # list comprehension tests
### trailer: '(' [testlist] ')' | '[' subscript ']' | '.' NAME nums = [1, 2, 3, 4, 5]
### subscript: expr | [expr] ':' [expr] strs = ["Apple", "Banana", "Coconut"]
f1() spcs = [" Apple", " Banana ", "Coco nut "]
f2(1)
f2(1,) self.assertEqual([s.strip() for s in spcs], ['Apple', 'Banana', 'Coco nut'])
f3(1, 2) self.assertEqual([3 * x for x in nums], [3, 6, 9, 12, 15])
f3(1, 2,) self.assertEqual([x for x in nums if x > 2], [3, 4, 5])
f4(1, (2, (3, 4))) self.assertEqual([(i, s) for i in nums for s in strs],
v0() [(1, 'Apple'), (1, 'Banana'), (1, 'Coconut'),
v0(1) (2, 'Apple'), (2, 'Banana'), (2, 'Coconut'),
v0(1,) (3, 'Apple'), (3, 'Banana'), (3, 'Coconut'),
v0(1,2) (4, 'Apple'), (4, 'Banana'), (4, 'Coconut'),
v0(1,2,3,4,5,6,7,8,9,0) (5, 'Apple'), (5, 'Banana'), (5, 'Coconut')])
v1(1) self.assertEqual([(i, s) for i in nums for s in [f for f in strs if "n" in f]],
v1(1,) [(1, 'Banana'), (1, 'Coconut'), (2, 'Banana'), (2, 'Coconut'),
v1(1,2) (3, 'Banana'), (3, 'Coconut'), (4, 'Banana'), (4, 'Coconut'),
v1(1,2,3) (5, 'Banana'), (5, 'Coconut')])
v1(1,2,3,4,5,6,7,8,9,0) self.assertEqual([(lambda a:[a**i for i in range(a+1)])(j) for j in range(5)],
v2(1,2) [[1], [1, 1], [1, 2, 4], [1, 3, 9, 27], [1, 4, 16, 64, 256]])
v2(1,2,3)
v2(1,2,3,4) def test_in_func(l):
v2(1,2,3,4,5,6,7,8,9,0) return [None < x < 3 for x in l if x > 2]
v3(1,(2,3))
v3(1,(2,3),4) self.assertEqual(test_in_func(nums), [False, False, False])
v3(1,(2,3),4,5,6,7,8,9,0)
print def test_nested_front():
import sys, time self.assertEqual([[y for y in [x, x + 1]] for x in [1,3,5]],
c = sys.path[0] [[1, 2], [3, 4], [5, 6]])
x = time.time()
x = sys.modules['time'].time() test_nested_front()
a = '01234'
c = a[0] check_syntax_error(self, "[i, s for i in nums for s in strs]")
c = a[-1] check_syntax_error(self, "[x if y]")
s = a[0:5]
s = a[:5] suppliers = [
s = a[0:] (1, "Boeing"),
s = a[:] (2, "Ford"),
s = a[-5:] (3, "Macdonalds")
s = a[:-1] ]
s = a[-4:-3]
# A rough test of SF bug 1333982. http://python.org/sf/1333982 parts = [
# The testing here is fairly incomplete. (10, "Airliner"),
# Test cases should include: commas with 1 and 2 colons (20, "Engine"),
d = {} (30, "Cheeseburger")
d[1] = 1 ]
d[1,] = 2
d[1,2] = 3 suppart = [
d[1,2,3] = 4 (1, 10), (1, 20), (2, 20), (3, 30)
L = list(d) ]
L.sort()
print L x = [
(sname, pname)
for (sno, sname) in suppliers
print 'atoms' for (pno, pname) in parts
### atom: '(' [testlist] ')' | '[' [testlist] ']' | '{' [dictmaker] '}' | '`' testlist '`' | NAME | NUMBER | STRING for (sp_sno, sp_pno) in suppart
### dictmaker: test ':' test (',' test ':' test)* [','] if sno == sp_sno and pno == sp_pno
]
x = (1)
x = (1 or 2 or 3) self.assertEqual(x, [('Boeing', 'Airliner'), ('Boeing', 'Engine'), ('Ford', 'Engine'),
x = (1 or 2 or 3, 2, 3) ('Macdonalds', 'Cheeseburger')])
x = [] def testGenexps(self):
x = [1] # generator expression tests
x = [1 or 2 or 3] g = ([x for x in range(10)] for x in range(1))
x = [1 or 2 or 3, 2, 3] self.assertEqual(g.next(), [x for x in range(10)])
x = [] try:
g.next()
x = {} self.fail('should produce StopIteration exception')
x = {'one': 1} except StopIteration:
x = {'one': 1,} pass
x = {'one' or 'two': 1 or 2}
x = {'one': 1, 'two': 2} a = 1
x = {'one': 1, 'two': 2,} try:
x = {'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'six': 6} g = (a for d in a)
g.next()
x = `x` self.fail('should produce TypeError')
x = `1 or 2 or 3` except TypeError:
x = x pass
x = 'x'
x = 123 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'])
### exprlist: expr (',' expr)* [',']
### testlist: test (',' test)* [','] a = [x for x in range(10)]
# These have been exercised enough above b = (x for x in (y for y in a))
self.assertEqual(sum(b), sum([x for x in range(10)]))
print 'classdef' # 'class' NAME ['(' [testlist] ')'] ':' suite
class B: pass self.assertEqual(sum(x**2 for x in range(10)), sum([x**2 for x in range(10)]))
class B2(): pass self.assertEqual(sum(x*x for x in range(10) if x%2), sum([x*x for x in range(10) if x%2]))
class C1(B): pass self.assertEqual(sum(x for x in (y for y in range(10))), sum([x for x in range(10)]))
class C2(B): pass self.assertEqual(sum(x for x in (y for y in (z for z in range(10)))), sum([x for x in range(10)]))
class D(C1, C2, B): pass self.assertEqual(sum(x for x in [y for y in (z for z in range(10))]), sum([x for x in range(10)]))
class C: 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)]))
def meth1(self): pass self.assertEqual(sum(x for x in (y for y in (z for z in range(10) if True) if False) if True), 0)
def meth2(self, arg): pass check_syntax_error(self, "foo(x for x in range(10), 100)")
def meth3(self, a1, a2): pass check_syntax_error(self, "foo(100, x for x in range(10))")
# list comprehension tests def testComprehensionSpecials(self):
nums = [1, 2, 3, 4, 5] # test for outmost iterable precomputation
strs = ["Apple", "Banana", "Coconut"] x = 10; g = (i for i in range(x)); x = 5
spcs = [" Apple", " Banana ", "Coco nut "] self.assertEqual(len(list(g)), 10)
print [s.strip() for s in spcs] # This should hold, since we're only precomputing outmost iterable.
print [3 * x for x in nums] x = 10; t = False; g = ((i,j) for i in range(x) if t for j in range(x))
print [x for x in nums if x > 2] x = 5; t = True;
print [(i, s) for i in nums for s in strs] self.assertEqual([(i,j) for i in range(10) for j in range(5)], list(g))
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)] # Grammar allows multiple adjacent 'if's in listcomps and genexps,
# even though it's silly. Make sure it works (ifelse broke this.)
def test_in_func(l): self.assertEqual([ x for x in range(10) if x % 2 if x % 3 ], [1, 5, 7])
return [None < x < 3 for x in l if x > 2] self.assertEqual(list(x for x in range(10) if x % 2 if x % 3), [1, 5, 7])
print test_in_func(nums) # verify unpacking single element tuples in listcomp/genexp.
self.assertEqual([x for x, in [(4,), (5,), (6,)]], [4, 5, 6])
def test_nested_front(): self.assertEqual(list(x for x, in [(7,), (8,), (9,)]), [7, 8, 9])
print [[y for y in [x, x + 1]] for x in [1,3,5]]
def testIfElseExpr(self):
test_nested_front() # Test ifelse expressions in various cases
def _checkeval(msg, ret):
check_syntax("[i, s for i in nums for s in strs]") "helper to check that evaluation of expressions is done correctly"
check_syntax("[x if y]") print x
return ret
suppliers = [
(1, "Boeing"), self.assertEqual([ x() for x in lambda: True, lambda: False if x() ], [True])
(2, "Ford"), self.assertEqual([ x() for x in (lambda: True, lambda: False) if x() ], [True])
(3, "Macdonalds") 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)
parts = [ self.assertEqual((5 and 6 if 0 else 1), 1)
(10, "Airliner"), self.assertEqual(((5 and 6) if 0 else 1), 1)
(20, "Engine"), self.assertEqual((5 and (6 if 1 else 1)), 6)
(30, "Cheeseburger") 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)
suppart = [ self.assertEqual((not 5 if 1 else 1), False)
(1, 10), (1, 20), (2, 20), (3, 30) 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)
print [ self.assertEqual((6 * 2 if 1 else 4), 12)
(sname, pname) self.assertEqual((6 / 2 if 1 else 3), 3)
for (sno, sname) in suppliers self.assertEqual((6 < 4 if 0 else 2), 2)
for (pno, pname) in parts
for (sp_sno, sp_pno) in suppart
if sno == sp_sno and pno == sp_pno def test_main():
] run_unittest(TokenTests, GrammarTests)
# generator expression tests if __name__ == '__main__':
g = ([x for x in range(10)] for x in range(1)) test_main()
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)
from test.test_support import verify, TestFailed, check_syntax, vereq import unittest
from test.test_support import check_syntax_error, run_unittest
import warnings import warnings
warnings.filterwarnings("ignore", r"import \*", SyntaxWarning, "<test string>")
warnings.filterwarnings("ignore", r"import \*", SyntaxWarning, "<string>") warnings.filterwarnings("ignore", r"import \*", SyntaxWarning, "<string>")
print "1. simple nesting" class ScopeTests(unittest.TestCase):
def make_adder(x): def testSimpleNesting(self):
def adder(y):
return x + y def make_adder(x):
return adder def adder(y):
return x + y
return adder
inc = make_adder(1) inc = make_adder(1)
plus10 = make_adder(10) plus10 = make_adder(10)
vereq(inc(1), 2) self.assertEqual(inc(1), 2)
vereq(plus10(-2), 8) self.assertEqual(plus10(-2), 8)
print "2. extra nesting" def testExtraNesting(self):
def make_adder2(x): def make_adder2(x):
def extra(): # check freevars passing through non-use scopes def extra(): # check freevars passing through non-use scopes
def adder(y): def adder(y):
return x + y return x + y
return adder return adder
return extra() return extra()
inc = make_adder2(1) inc = make_adder2(1)
plus10 = make_adder2(10) plus10 = make_adder2(10)
vereq(inc(1), 2) self.assertEqual(inc(1), 2)
vereq(plus10(-2), 8) self.assertEqual(plus10(-2), 8)
print "3. simple nesting + rebinding" def testSimpleAndRebinding(self):
def make_adder3(x): def make_adder3(x):
def adder(y): def adder(y):
return x + y return x + y
x = x + 1 # check tracking of assignment to x in defining scope x = x + 1 # check tracking of assignment to x in defining scope
return adder return adder
inc = make_adder3(0) inc = make_adder3(0)
plus10 = make_adder3(9) plus10 = make_adder3(9)
vereq(inc(1), 2) self.assertEqual(inc(1), 2)
vereq(plus10(-2), 8) self.assertEqual(plus10(-2), 8)
print "4. nesting with global but no free" def testNestingGlobalNoFree(self):
def make_adder4(): # XXX add exta level of indirection def make_adder4(): # XXX add exta level of indirection
def nest(): def nest():
def nest(): def nest():
def adder(y): def adder(y):
return global_x + y # check that plain old globals work return global_x + y # check that plain old globals work
return adder return adder
return nest() return nest()
return nest() return nest()
global_x = 1 global_x = 1
adder = make_adder4() adder = make_adder4()
vereq(adder(1), 2) self.assertEqual(adder(1), 2)
global_x = 10 global_x = 10
vereq(adder(-2), 8) self.assertEqual(adder(-2), 8)
print "5. nesting through class" def testNestingThroughClass(self):
def make_adder5(x): def make_adder5(x):
class Adder: class Adder:
def __call__(self, y): def __call__(self, y):
return x + y return x + y
return Adder() return Adder()
inc = make_adder5(1) inc = make_adder5(1)
plus10 = make_adder5(10) plus10 = make_adder5(10)
vereq(inc(1), 2) self.assertEqual(inc(1), 2)
vereq(plus10(-2), 8) self.assertEqual(plus10(-2), 8)
print "6. nesting plus free ref to global" def testNestingPlusFreeRefToGlobal(self):
def make_adder6(x): def make_adder6(x):
global global_nest_x global global_nest_x
def adder(y): def adder(y):
return global_nest_x + y return global_nest_x + y
global_nest_x = x global_nest_x = x
return adder return adder
inc = make_adder6(1) inc = make_adder6(1)
plus10 = make_adder6(10) plus10 = make_adder6(10)
vereq(inc(1), 11) # there's only one global self.assertEqual(inc(1), 11) # there's only one global
vereq(plus10(-2), 8) self.assertEqual(plus10(-2), 8)
print "7. nearest enclosing scope" def testNearestEnclosingScope(self):
def f(x): def f(x):
def g(y): def g(y):
x = 42 # check that this masks binding in f() x = 42 # check that this masks binding in f()
def h(z): def h(z):
return x + z return x + z
return h return h
return g(2) return g(2)
test_func = f(10)
vereq(test_func(5), 47)
print "8. mixed freevars and cellvars"
def identity(x):
return x
def f(x, y, z):
def g(a, b, c):
a = a + x # 3
def h():
# z * (4 + 9)
# 3 * 13
return identity(z * (b + y))
y = c + z # 9
return h
return g
g = f(1, 2, 3)
h = g(2, 4, 6)
vereq(h(), 39)
print "9. free variable in method"
def test():
method_and_var = "var"
class Test:
def method_and_var(self):
return "method"
def test(self):
return method_and_var
def actual_global(self):
return str("global")
def str(self):
return str(self)
return Test()
t = test()
vereq(t.test(), "var")
vereq(t.method_and_var(), "method")
vereq(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()
vereq(t.test(), "var")
vereq(t.method_and_var(), "method")
vereq(t.actual_global(), "global")
print "10. recursion"
def f(x): test_func = f(10)
def fact(n): self.assertEqual(test_func(5), 47)
if n == 0:
return 1
else:
return n * fact(n - 1)
if x >= 0:
return fact(x)
else:
raise ValueError, "x must be >= 0"
vereq(f(6), 720) def testMixedFreevarsAndCellvars(self):
def identity(x):
return x
print "11. unoptimized namespaces" def f(x, y, z):
def g(a, b, c):
check_syntax("""\ a = a + x # 3
def h():
# z * (4 + 9)
# 3 * 13
return identity(z * (b + y))
y = c + z # 9
return h
return g
g = f(1, 2, 3)
h = g(2, 4, 6)
self.assertEqual(h(), 39)
def testFreeVarInMethod(self):
def test():
method_and_var = "var"
class Test:
def method_and_var(self):
return "method"
def test(self):
return method_and_var
def actual_global(self):
return str("global")
def str(self):
return str(self)
return Test()
t = test()
self.assertEqual(t.test(), "var")
self.assertEqual(t.method_and_var(), "method")
self.assertEqual(t.actual_global(), "global")
method_and_var = "var"
class Test:
# this class is not nested, so the rules are different
def method_and_var(self):
return "method"
def test(self):
return method_and_var
def actual_global(self):
return str("global")
def str(self):
return str(self)
t = Test()
self.assertEqual(t.test(), "var")
self.assertEqual(t.method_and_var(), "method")
self.assertEqual(t.actual_global(), "global")
def testRecursion(self):
def f(x):
def fact(n):
if n == 0:
return 1
else:
return n * fact(n - 1)
if x >= 0:
return fact(x)
else:
raise ValueError, "x must be >= 0"
self.assertEqual(f(6), 720)
def testUnoptimizedNamespaces(self):
check_syntax_error(self, """\
def unoptimized_clash1(strip): def unoptimized_clash1(strip):
def f(s): def f(s):
from string import * from string import *
...@@ -188,7 +192,7 @@ def unoptimized_clash1(strip): ...@@ -188,7 +192,7 @@ def unoptimized_clash1(strip):
return f return f
""") """)
check_syntax("""\ check_syntax_error(self, """\
def unoptimized_clash2(): def unoptimized_clash2():
from string import * from string import *
def f(s): def f(s):
...@@ -196,7 +200,7 @@ def unoptimized_clash2(): ...@@ -196,7 +200,7 @@ def unoptimized_clash2():
return f return f
""") """)
check_syntax("""\ check_syntax_error(self, """\
def unoptimized_clash2(): def unoptimized_clash2():
from string import * from string import *
def g(): def g():
...@@ -205,8 +209,8 @@ def unoptimized_clash2(): ...@@ -205,8 +209,8 @@ def unoptimized_clash2():
return f return f
""") """)
# XXX could allow this for exec with const argument, but what's the point # XXX could allow this for exec with const argument, but what's the point
check_syntax("""\ check_syntax_error(self, """\
def error(y): def error(y):
exec "a = 1" exec "a = 1"
def f(x): def f(x):
...@@ -214,23 +218,23 @@ def error(y): ...@@ -214,23 +218,23 @@ def error(y):
return f return f
""") """)
check_syntax("""\ check_syntax_error(self, """\
def f(x): def f(x):
def g(): def g():
return x return x
del x # can't del name del x # can't del name
""") """)
check_syntax("""\ check_syntax_error(self, """\
def f(): def f():
def g(): def g():
from string import * from string import *
return strip # global or local? 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(): def noproblem1():
from string import * from string import *
f = lambda x:x f = lambda x:x
...@@ -247,59 +251,60 @@ def noproblem3(): ...@@ -247,59 +251,60 @@ def noproblem3():
y = x y = x
""" """
print "12. lambdas" def testLambdas(self):
f1 = lambda x: lambda y: x + y f1 = lambda x: lambda y: x + y
inc = f1(1) inc = f1(1)
plus10 = f1(10) plus10 = f1(10)
vereq(inc(1), 2) self.assertEqual(inc(1), 2)
vereq(plus10(5), 15) self.assertEqual(plus10(5), 15)
f2 = lambda x: (lambda : lambda y: x + y)() f2 = lambda x: (lambda : lambda y: x + y)()
inc = f2(1) inc = f2(1)
plus10 = f2(10) plus10 = f2(10)
vereq(inc(1), 2) self.assertEqual(inc(1), 2)
vereq(plus10(5), 15) self.assertEqual(plus10(5), 15)
f3 = lambda x: lambda y: global_x + y f3 = lambda x: lambda y: global_x + y
global_x = 1 global_x = 1
inc = f3(None) inc = f3(None)
vereq(inc(2), 3) self.assertEqual(inc(2), 3)
f8 = lambda x, y, z: lambda a, b, c: lambda : z * (b + y) f8 = lambda x, y, z: lambda a, b, c: lambda : z * (b + y)
g = f8(1, 2, 3) g = f8(1, 2, 3)
h = g(2, 4, 6) h = g(2, 4, 6)
vereq(h(), 18) self.assertEqual(h(), 18)
print "13. UnboundLocal" def testUnboundLocal(self):
def errorInOuter(): def errorInOuter():
print y print y
def inner(): def inner():
return y return y
y = 1 y = 1
def errorInInner(): def errorInInner():
def inner(): def inner():
return y return y
inner() inner()
y = 1 y = 1
try: try:
errorInOuter() errorInOuter()
except UnboundLocalError: except UnboundLocalError:
pass pass
else: else:
raise TestFailed self.fail()
try: try:
errorInInner() errorInInner()
except NameError: except NameError:
pass pass
else: else:
raise TestFailed self.fail()
# test for bug #1501934: incorrect LOAD/STORE_GLOBAL generation # test for bug #1501934: incorrect LOAD/STORE_GLOBAL generation
exec """
global_x = 1 global_x = 1
def f(): def f():
global_x += 1 global_x += 1
...@@ -308,34 +313,36 @@ try: ...@@ -308,34 +313,36 @@ try:
except UnboundLocalError: except UnboundLocalError:
pass pass
else: 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 makeReturner(*lst):
def returner(): def returner():
return lst return lst
return returner return returner
vereq(makeReturner(1,2,3)(), (1,2,3)) self.assertEqual(makeReturner(1,2,3)(), (1,2,3))
def makeReturner2(**kwargs): def makeReturner2(**kwargs):
def returner(): def returner():
return kwargs return kwargs
return returner return returner
vereq(makeReturner2(a=11)()['a'], 11) self.assertEqual(makeReturner2(a=11)()['a'], 11)
def makeAddPair((a, b)): def makeAddPair((a, b)):
def addPair((c, d)): def addPair((c, d)):
return (a + c, b + d) return (a + c, b + d)
return addPair 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 # Examples posted by Samuele Pedroni to python-dev on 3/1/2001
exec """\
# I # I
x = 7 x = 7
def f(): def f():
...@@ -348,8 +355,8 @@ def f(): ...@@ -348,8 +355,8 @@ def f():
return h() return h()
return i() return i()
return g() return g()
vereq(f(), 7) self.assertEqual(f(), 7)
vereq(x, 7) self.assertEqual(x, 7)
# II # II
x = 7 x = 7
...@@ -363,8 +370,8 @@ def f(): ...@@ -363,8 +370,8 @@ def f():
return h() return h()
return i() return i()
return g() return g()
vereq(f(), 2) self.assertEqual(f(), 2)
vereq(x, 7) self.assertEqual(x, 7)
# III # III
x = 7 x = 7
...@@ -379,8 +386,8 @@ def f(): ...@@ -379,8 +386,8 @@ def f():
return h() return h()
return i() return i()
return g() return g()
vereq(f(), 2) self.assertEqual(f(), 2)
vereq(x, 2) self.assertEqual(x, 2)
# IV # IV
x = 7 x = 7
...@@ -395,8 +402,8 @@ def f(): ...@@ -395,8 +402,8 @@ def f():
return h() return h()
return i() return i()
return g() return g()
vereq(f(), 2) self.assertEqual(f(), 2)
vereq(x, 2) self.assertEqual(x, 2)
# XXX what about global statements in class blocks? # XXX what about global statements in class blocks?
# do they affect methods? # do they affect methods?
...@@ -411,34 +418,36 @@ class Global: ...@@ -411,34 +418,36 @@ class Global:
return x return x
g = Global() g = Global()
vereq(g.get(), 13) self.assertEqual(g.get(), 13)
g.set(15) g.set(15)
vereq(g.get(), 13) self.assertEqual(g.get(), 13)
"""
print "16. check leaks" def testLeaks(self):
class Foo: class Foo:
count = 0 count = 0
def __init__(self): def __init__(self):
Foo.count += 1 Foo.count += 1
def __del__(self): def __del__(self):
Foo.count -= 1 Foo.count -= 1
def f1(): def f1():
x = Foo() x = Foo()
def f2(): def f2():
return x return x
f2() f2()
for i in range(100): for i in range(100):
f1() f1()
vereq(Foo.count, 0) self.assertEqual(Foo.count, 0)
print "17. class and global" def testClassAndGlobal(self):
exec """\
def test(x): def test(x):
class Foo: class Foo:
global x global x
...@@ -447,9 +456,9 @@ def test(x): ...@@ -447,9 +456,9 @@ def test(x):
return Foo() return Foo()
x = 0 x = 0
vereq(test(6)(2), 8) self.assertEqual(test(6)(2), 8)
x = -1 x = -1
vereq(test(3)(2), 5) self.assertEqual(test(3)(2), 5)
looked_up_by_load_name = False looked_up_by_load_name = False
class X: class X:
...@@ -458,104 +467,106 @@ class X: ...@@ -458,104 +467,106 @@ class X:
locals()['looked_up_by_load_name'] = True locals()['looked_up_by_load_name'] = True
passed = looked_up_by_load_name 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 f(x):
def g(y): def g(y):
def h(z): def h(z):
return y + z return y + z
w = x + y w = x + y
y += 3 y += 3
return locals() return locals()
return g return g
d = f(2)(4) d = f(2)(4)
verify(d.has_key('h')) self.assert_(d.has_key('h'))
del d['h'] del d['h']
vereq(d, {'x': 2, 'y': 7, 'w': 6}) 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): def f(x):
class C: class C:
def m(self): def m(self):
return x return x
a = x a = x
return C return C
inst = f(3)() inst = f(3)()
vereq(inst.a, inst.m()) self.assertEqual(inst.a, inst.m())
print "20. interaction with trace function" def testInteractionWithTraceFunc(self):
import sys import sys
def tracer(a,b,c): def tracer(a,b,c):
return tracer return tracer
def adaptgetter(name, klass, getter): def adaptgetter(name, klass, getter):
kind, des = getter kind, des = getter
if kind == 1: # AV happens when stepping from this line to next if kind == 1: # AV happens when stepping from this line to next
if des == "": if des == "":
des = "_%s__%s" % (klass.__name__, name) des = "_%s__%s" % (klass.__name__, name)
return lambda obj: getattr(obj, des) return lambda obj: getattr(obj, des)
class TestClass: class TestClass:
pass pass
sys.settrace(tracer) sys.settrace(tracer)
adaptgetter("foo", TestClass, (1, "")) adaptgetter("foo", TestClass, (1, ""))
sys.settrace(None) sys.settrace(None)
try: sys.settrace() self.assertRaises(TypeError, sys.settrace)
except TypeError: pass
else: raise TestFailed, 'sys.settrace() did not raise TypeError'
print "20. eval and exec with free variables" def testEvalExecFreeVars(self):
def f(x): def f(x):
return lambda: x + 1 return lambda: x + 1
g = f(3) g = f(3)
try: self.assertRaises(TypeError, eval, g.func_code)
eval(g.func_code)
except TypeError:
pass
else:
print "eval() should have failed, because code contained free vars"
try: try:
exec g.func_code exec g.func_code in {}
except TypeError: except TypeError:
pass pass
else: else:
print "exec should have failed, because code contained free vars" self.fail("exec should have failed, because code contained free vars")
print "21. list comprehension with local variables" def testListCompLocalVars(self):
try: try:
print bad print bad
except NameError: except NameError:
pass pass
else: else:
print "bad should not be defined" print "bad should not be defined"
def x(): def x():
[bad for s in 'a b' for bad in s.split()] [bad for s in 'a b' for bad in s.split()]
x() x()
try: try:
print bad print bad
except NameError: except NameError:
pass pass
print "22. eval with free variables" def testEvalFreeVars(self):
def f(x): def f(x):
def g(): def g():
x x
eval("x + 1") eval("x + 1")
return g return g
f(4)()
def test_main():
run_unittest(ScopeTests)
f(4)() if __name__ == '__main__':
test_main()
...@@ -245,13 +245,13 @@ def sortdict(dict): ...@@ -245,13 +245,13 @@ def sortdict(dict):
withcommas = ", ".join(reprpairs) withcommas = ", ".join(reprpairs)
return "{%s}" % withcommas return "{%s}" % withcommas
def check_syntax(statement): def check_syntax_error(testcase, statement):
try: try:
compile(statement, '<string>', 'exec') compile(statement, '<test string>', 'exec')
except SyntaxError: except SyntaxError:
pass pass
else: else:
print 'Missing SyntaxError: "%s"' % statement testcase.fail('Missing SyntaxError: "%s"' % statement)
def open_urlresource(url): def open_urlresource(url):
import urllib, urlparse import urllib, urlparse
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment