def test2(self): prog_text_2 = """\ def wrong2(): print x global x """ check_syntax_error(self, prog_text_2)
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 testReturn(self): # 'return' [testlist] def g1(): return def g2(): return 1 g1() x = g2() check_syntax_error(self, "class foo:return 1")
def test2(self): prog_text_2 = """\ def wrong2(): shout x global x """ check_syntax_error(self, prog_text_2)
def test3(self): prog_text_3 = """\ def wrong3(): print x x = 2 global x """ check_syntax_error(self, prog_text_3)
def test2(self): prog_text_2 = """\ def wrong2(): print x global x """ if not test_support.due_to_ironpython_bug("http://tkbgitvstfat01:8080/WorkItemTracking/WorkItem.aspx?artifactMoniker=317569"): check_syntax_error(self, prog_text_2)
def test3(self): prog_text_3 = """\ def wrong3(): shout x x = 2 global x """ check_syntax_error(self, prog_text_3)
def test1(self): prog_text_1 = """\ def wrong1(): a = 1 b = 2 global a global b """ check_syntax_error(self, prog_text_1)
def test2(self): prog_text_2 = """\ def wrong2(): print x global x """ if not test_support.due_to_ironpython_bug( "http://tkbgitvstfat01:8080/WorkItemTracking/WorkItem.aspx?artifactMoniker=317569" ): check_syntax_error(self, prog_text_2)
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_error(self, "x + 1 = 1") check_syntax_error(self, "a + 1 = b + 2")
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 testLambdef(self): ### lambdef: 'lambda' [varargslist] ':' test l1 = lambda : 0 self.assertEqual(l1(), 0) l2 = lambda : a[d] # XXX just testing the expression l3 = lambda : [2 < x for x in [-1, 3, 0L]] self.assertEqual(l3(), [0, 1, 0]) l4 = lambda x = lambda y = lambda z=1 : z : y() : x() self.assertEqual(l4(), 1) l5 = lambda x, y, z=2: x + y + z self.assertEqual(l5(1, 2), 5) self.assertEqual(l5(1, 2, 3), 6) check_syntax_error(self, "lambda x: x = 2") check_syntax_error(self, "lambda (None,): None")
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") check_syntax_error(self, "lambda (None,): None")
def testUnoptimizedNamespaces(self): check_syntax_error(self, """\ def unoptimized_clash1(strip): def f(s): from string import * return strip(s) # ambiguity: free or local return f """) check_syntax_error(self, """\ def unoptimized_clash2(): from string import * def f(s): return strip(s) # ambiguity: global or local return f """) check_syntax_error(self, """\ def unoptimized_clash2(): from string import * def g(): def f(s): return strip(s) # ambiguity: global or local return f """) # 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): return x + y return f """) check_syntax_error(self, """\ def f(): def g(): from string import * return strip # global or local? """) # and verify a few cases that should work exec """
def test_lambdef(self): ### lambdef: 'lambda' [varargslist] ':' test l1 = lambda: 0 self.assertEqual(l1(), 0) l2 = lambda: a[d] # XXX just testing the expression l3 = lambda: [2 < x for x in [-1, 3, 0L]] self.assertEqual(l3(), [0, 1, 0]) l4 = lambda x=lambda y=lambda z=1: z: y(): x() self.assertEqual(l4(), 1) l5 = lambda x, y, z=2: x + y + z self.assertEqual(l5(1, 2), 5) self.assertEqual(l5(1, 2, 3), 6) check_syntax_error(self, "lambda x: x = 2") with check_py3k_warnings( ('tuple parameter unpacking has been removed', SyntaxWarning)): check_syntax_error(self, "lambda (None,): None") # check that trailing commas are permitted l10 = lambda a, : 0
def test_lambdef(self): ### lambdef: 'lambda' [varargslist] ':' test l1 = lambda : 0 self.assertEqual(l1(), 0) l2 = lambda : a[d] # XXX just testing the expression l3 = lambda : [2 < x for x in [-1, 3, 0L]] self.assertEqual(l3(), [0, 1, 0]) l4 = lambda x = lambda y = lambda z=1 : z : y() : x() self.assertEqual(l4(), 1) l5 = lambda x, y, z=2: x + y + z self.assertEqual(l5(1, 2), 5) self.assertEqual(l5(1, 2, 3), 6) check_syntax_error(self, "lambda x: x = 2") with check_py3k_warnings(('tuple parameter unpacking has been removed', SyntaxWarning)): check_syntax_error(self, "lambda (None,): None") # check that trailing commas are permitted l10 = lambda a,: 0
def test_yield_in_comprehensions(self): # Check yield in comprehensions def g(): [x for x in [(yield 1)]] def check(code, warntext): with check_py3k_warnings((warntext, DeprecationWarning)): compile(code, '<test string>', 'exec') if sys.py3kwarning: import warnings with warnings.catch_warnings(): warnings.filterwarnings('error', category=DeprecationWarning) with self.assertRaises(SyntaxError) as cm: compile(code, '<test string>', 'exec') self.assertIn(warntext, str(cm.exception)) check("def g(): [(yield x) for x in ()]", "'yield' inside list comprehension") check("def g(): [x for x in () if not (yield x)]", "'yield' inside list comprehension") check("def g(): [y for x in () for y in [(yield x)]]", "'yield' inside list comprehension") check("def g(): {(yield x) for x in ()}", "'yield' inside set comprehension") check("def g(): {(yield x): x for x in ()}", "'yield' inside dict comprehension") check("def g(): {x: (yield x) for x in ()}", "'yield' inside dict comprehension") check("def g(): ((yield x) for x in ())", "'yield' inside generator expression") with check_py3k_warnings( ("'yield' inside list comprehension", DeprecationWarning)): check_syntax_error(self, "class C: [(yield x) for x in ()]") check("class C: ((yield x) for x in ())", "'yield' inside generator expression") with check_py3k_warnings( ("'yield' inside list comprehension", DeprecationWarning)): check_syntax_error(self, "[(yield x) for x in ()]") check("((yield x) for x in ())", "'yield' inside generator expression")
def test_yield_in_comprehensions(self): # Check yield in comprehensions def g(): [x for x in [(yield 1)]] def check(code, warntext): with check_py3k_warnings((warntext, DeprecationWarning)): compile(code, '<test string>', 'exec') if sys.py3kwarning: import warnings with warnings.catch_warnings(): warnings.filterwarnings('error', category=DeprecationWarning) with self.assertRaises(SyntaxError) as cm: compile(code, '<test string>', 'exec') self.assertIn(warntext, str(cm.exception)) check("def g(): [(yield x) for x in ()]", "'yield' inside list comprehension") check("def g(): [x for x in () if not (yield x)]", "'yield' inside list comprehension") check("def g(): [y for x in () for y in [(yield x)]]", "'yield' inside list comprehension") check("def g(): {(yield x) for x in ()}", "'yield' inside set comprehension") check("def g(): {(yield x): x for x in ()}", "'yield' inside dict comprehension") check("def g(): {x: (yield x) for x in ()}", "'yield' inside dict comprehension") check("def g(): ((yield x) for x in ())", "'yield' inside generator expression") with check_py3k_warnings(("'yield' inside list comprehension", DeprecationWarning)): check_syntax_error(self, "class C: [(yield x) for x in ()]") check("class C: ((yield x) for x in ())", "'yield' inside generator expression") with check_py3k_warnings(("'yield' inside list comprehension", DeprecationWarning)): check_syntax_error(self, "[(yield x) for x in ()]") check("((yield x) for x in ())", "'yield' inside generator expression")
def testPrintStmt(self): # 'print' (test ',')* [test] import StringIO # 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 # '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 # test printing to an instance class Gulp: def write(self, msg): pass 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 print >> None def driver(): oldstdout = sys.stdout sys.stdout = Gulp() try: tellme(Gulp()) tellme() finally: sys.stdout = oldstdout # we should see this once def tellme(file=sys.stdout): print >> file, 'hello world' driver() # we should not see this at all def tellme(file=None): print >> file, 'goodbye universe' driver() 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 # syntax errors check_syntax_error(self, 'print ,') check_syntax_error(self, 'print >> x,')
def test_yield(self): # Allowed as standalone statement def g(): yield 1 # Allowed as RHS of assignment def g(): x = yield 1 # Ordinary yield accepts implicit tuples def g(): yield 1, 1 def g(): x = yield 1, 1 # Requires parentheses as subexpression def g(): 1, (yield 1) check_syntax_error(self, "def g(): 1, yield 1") # Requires parentheses as call argument def g(): f((yield 1)) def g(): f((yield 1), 1) check_syntax_error(self, "def g(): f(yield 1)") check_syntax_error(self, "def g(): f(yield 1, 1)") # Not allowed at top level check_syntax_error(self, "yield") # Not allowed at class scope check_syntax_error(self, "class foo:yield 1") # Check annotation refleak on SyntaxError check_syntax_error(self, "def g(a:(yield)): pass")
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 # Silence Py3k warning exec('def f4(two, (compound, (argument, list))): pass') exec('def f5((compound, first), two): pass') self.assertEqual(f2.func_code.co_varnames, ('one_argument',)) self.assertEqual(f3.func_code.co_varnames, ('two', 'arguments')) if sys.platform.startswith('java'): self.assertEqual(f4.func_code.co_varnames, ('two', '(compound, (argument, list))', 'compound', 'argument', 'list',)) self.assertEqual(f5.func_code.co_varnames, ('(compound, first)', 'two', 'compound', 'first')) else: self.assertEqual(f4.func_code.co_varnames, ('two', '.1', 'compound', 'argument', 'list')) self.assertEqual(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 # Silence Py3k warning exec('def v3(a, (b, c), *rest): return a, b, c, rest') 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) # 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.assertEqual(v3.func_code.co_varnames, ('a', '(b, c)', 'rest', 'b', 'c')) else: self.assertEqual(v3.func_code.co_varnames, ('a', '.1', 'rest', 'b', 'c')) self.assertEqual(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}) # Silence Py3k warning exec('def d31v((x)): pass') exec('def d32v((x,)): pass') d31v(1) d32v((1,)) # keyword arguments after *arglist def f(*args, **kwargs): return args, kwargs self.assertEqual(f(1, x=2, *[3, 4], y=5), ((1, 3, 4), {'x':2, 'y':5})) self.assertRaises(SyntaxError, eval, "f(1, *(2,3), 4)") self.assertRaises(SyntaxError, eval, "f(1, x=2, *(3,4), x=5)") # Check ast errors in *args and *kwargs check_syntax_error(self, "f(*g(1=2))") check_syntax_error(self, "f(**g(1=2))")
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: pass # 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 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) # 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}) # NOTE # def d31v((x)): pass # d31v(1) # def d32v((x,)): pass # d32v((1,)) # keyword arguments after *arglist def f(*args, **kwargs): return args, kwargs self.assertEquals(f(1, x=2, *[3, 4], y=5), ((1, 3, 4), {"x": 2, "y": 5})) self.assertRaises(SyntaxError, eval, "f(1, *(2,3), 4)") self.assertRaises(SyntaxError, eval, "f(1, x=2, *(3,4), x=5)") # Check ast errors in *args and *kwargs check_syntax_error(self, "f(*g(1=2))") check_syntax_error(self, "f(**g(1=2))")
def testUnoptimizedNamespaces(self): check_syntax_error(self, """\ def unoptimized_clash1(strip): def f(s): from string import * return strip(s) # ambiguity: free or local return f """) check_syntax_error(self, """\ def unoptimized_clash2(): from string import * def f(s): return strip(s) # ambiguity: global or local return f """) check_syntax_error(self, """\ def unoptimized_clash2(): from string import * def g(): def f(s): return strip(s) # ambiguity: global or local return f """) # 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): return x + y return f """) check_syntax_error(self, """\ def f(x): def g(): return x del x # can't del name """) check_syntax_error(self, """\ def f(): def g(): from string import * return strip # global or local? """) # and verify a few cases that should work exec """
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 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) # 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,)) # keyword arguments after *arglist def f(*args, **kwargs): return args, kwargs self.assertEquals(f(1, x=2, *[3, 4], y=5), ((1, 3, 4), {'x':2, 'y':5})) self.assertRaises(SyntaxError, eval, "f(1, *(2,3), 4)") self.assertRaises(SyntaxError, eval, "f(1, x=2, *(3,4), x=5)") # Check ast errors in *args and *kwargs check_syntax_error(self, "f(*g(1=2))") check_syntax_error(self, "f(**g(1=2))")
def test_yield(self): # Allowed as standalone statement def g(): yield 1 def g(): yield from () # Allowed as RHS of assignment def g(): x = yield 1 def g(): x = yield from () # Ordinary yield accepts implicit tuples def g(): yield 1, 1 def g(): x = yield 1, 1 # 'yield from' does not check_syntax_error(self, "def g(): yield from (), 1") check_syntax_error(self, "def g(): x = yield from (), 1") # Requires parentheses as subexpression def g(): 1, (yield 1) def g(): 1, (yield from ()) check_syntax_error(self, "def g(): 1, yield 1") check_syntax_error(self, "def g(): 1, yield from ()") # Requires parentheses as call argument def g(): f((yield 1)) def g(): f((yield 1), 1) def g(): f((yield from ())) def g(): f((yield from ()), 1) check_syntax_error(self, "def g(): f(yield 1)") check_syntax_error(self, "def g(): f(yield 1, 1)") check_syntax_error(self, "def g(): f(yield from ())") check_syntax_error(self, "def g(): f(yield from (), 1)") # Not allowed at top level check_syntax_error(self, "yield") check_syntax_error(self, "yield from") # Not allowed at class scope check_syntax_error(self, "class foo:yield 1") check_syntax_error(self, "class foo:yield from ()") # Check annotation refleak on SyntaxError check_syntax_error(self, "def g(a:(yield)): 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')])
d32v((1, )) # keyword arguments after *arglist def f(*args, **kwargs): return args, kwargs self.assertEquals(f(1, x=2, *[3, 4], y=5), ((1, 3, 4), { 'x': 2, 'y': 5 })) self.assertRaises(SyntaxError, eval, "f(1, *(2,3), 4)") self.assertRaises(SyntaxError, eval, "f(1, x=2, *(3,4), x=5)") # Check ast errors in *args and *kwargs check_syntax_error(self, "f(*g(1=2))") check_syntax_error(self, "f(**g(1=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")
def testYield(self): check_syntax_error(self, "class foo:yield 1")
def test_funcdef(self): ### 'def' NAME parameters ['->' test] ':' suite ### parameters: '(' [typedargslist] ')' ### typedargslist: ((tfpdef ['=' test] ',')* ### ('*' [tname] (',' tname ['=' test])* [',' '**' tname] | '**' tname) ### | tfpdef ['=' test] (',' tfpdef ['=' test])* [',']) ### tname: NAME [':' test] ### tfpdef: tname | '(' tfplist ')' ### tfplist: tfpdef (',' tfpdef)* [','] ### varargslist: ((vfpdef ['=' test] ',')* ### ('*' [vname] (',' vname ['=' test])* [',' '**' vname] | '**' vname) ### | vfpdef ['=' test] (',' vfpdef ['=' test])* [',']) ### vname: NAME ### vfpdef: vname | '(' vfplist ')' ### vfplist: vfpdef (',' vfpdef)* [','] def f1(): pass f1() f1(*()) f1(*(), **{}) def f2(one_argument): pass def f3(two, arguments): pass with check_py3k_warnings(('tuple parameter unpacking has been removed', SyntaxWarning)): exec('def f4(two, (compound, (argument, list))): pass') exec('def f5((compound, first), two): pass') self.assertEqual(f2.func_code.co_varnames, ('one_argument',)) self.assertEqual(f3.func_code.co_varnames, ('two', 'arguments')) if sys.platform.startswith('java'): self.assertEqual(f4.func_code.co_varnames, ('two', '(compound, (argument, list))', 'compound', 'argument', 'list',)) self.assertEqual(f5.func_code.co_varnames, ('(compound, first)', 'two', 'compound', 'first')) else: self.assertEqual(f4.func_code.co_varnames, ('two', '.1', 'compound', 'argument', 'list')) self.assertEqual(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 with check_py3k_warnings(('tuple parameter unpacking has been removed', SyntaxWarning)): exec('def v3(a, (b, c), *rest): return a, b, c, rest') 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) # 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.assertEqual(v3.func_code.co_varnames, ('a', '(b, c)', 'rest', 'b', 'c')) else: self.assertEqual(v3.func_code.co_varnames, ('a', '.1', 'rest', 'b', 'c')) self.assertEqual(v3(1, (2, 3), 4), (1, 2, 3, (4,))) def d01(a=1): pass d01() d01(1) d01(*(1,)) d01(*[] or [2]) d01(**{'a':2}) d01(**{'a':2} or {}) 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}) with check_py3k_warnings(('parenthesized argument names are invalid', SyntaxWarning)): exec('def d31v((x)): pass') with check_py3k_warnings(('tuple parameter unpacking has been removed', SyntaxWarning)): exec('def d32v((x,)): pass') d31v(1) d32v((1,)) #keyword only argument tests def pos0key1(*, key): return key pos0key1(key=100) def pos2key2(p1, p2, *, k1, k2=100): return p1,p2,k1,k2 pos2key2(1, 2, k1=100) pos2key2(1, 2, k1=100, k2=200) pos2key2(1, 2, k2=100, k1=200) def pos2key2dict(p1, p2, *, k1=100, k2, **kwarg): return p1,p2,k1,k2,kwarg pos2key2dict(1,2,k2=100,tokwarg1=100,tokwarg2=200) pos2key2dict(1,2,tokwarg1=100,tokwarg2=200, k2=100) # keyword arguments after *arglist def f(*args, **kwargs): return args, kwargs self.assertEqual(f(1, x=2, *[3, 4], y=5), ((1, 3, 4), {'x':2, 'y':5})) self.assertRaises(SyntaxError, eval, "f(1, *(2,3), 4)") self.assertRaises(SyntaxError, eval, "f(1, x=2, *(3,4), x=5)") self.assertEqual(f(**{'eggs':'scrambled', 'spam':'fried'}), ((), {'eggs':'scrambled', 'spam':'fried'})) self.assertEqual(f(spam='fried', **{'eggs':'scrambled'}), ((), {'eggs':'scrambled', 'spam':'fried'})) # Check ast errors in *args and *kwargs check_syntax_error(self, "f(*g(1=2))") check_syntax_error(self, "f(**g(1=2))") # Check trailing commas are permitted in funcdef argument list def f(a,): pass # argument annotation tests def f(x) -> list: pass self.assertEquals(f.__annotations__, {'return': list}) def f(x:int): pass self.assertEquals(f.__annotations__, {'x': int}) def f(*x:str): pass self.assertEquals(f.__annotations__, {'x': str}) def f(**x:float): pass self.assertEquals(f.__annotations__, {'x': float}) def f(x, y:1+2): pass self.assertEquals(f.__annotations__, {'y': 3}) def f(a, (b:1, c:2, d)): pass self.assertEquals(f.__annotations__, {'b': 1, 'c': 2}) def f(a, (b:1, c:2, d), e:3=4, f=5, *g:6): pass self.assertEquals(f.__annotations__, {'b': 1, 'c': 2, 'e': 3, 'g': 6}) def f(a, (b:1, c:2, d), e:3=4, f=5, *g:6, h:7, i=8, j:9=10, **k:11) -> 12: pass self.assertEquals(f.__annotations__, {'b': 1, 'c': 2, 'e': 3, 'g': 6, 'h': 7, 'j': 9, 'k': 11, 'return': 12}) d = {} exec(""" def foo(): def bar(): def baz(a:int) -> bar: return bar return baz return bar """, d) foo = d['foo'] bar = foo() baz = bar() self.assertEquals(baz.__annotations__, {'a': int, 'return': bar}) # asnyc and keyword args and annotations d = {} exec("async def f(a:int, *, b) -> str: pass", d) self.assertEquals(d['f'].__annotations__, {'a': int, 'return': str}) # Check for issue #20625 -- annotations mangling class Spam: def f(self, *, __kw:1): pass class Ham(Spam): pass self.assertEquals(Spam.f.__annotations__, {'_Spam__kw': 1}) self.assertEquals(Ham.f.__annotations__, {'_Spam__kw': 1}) # Check for SF Bug #1697248 - mixing decorators and a return annotation def null(x): return x @null def f(x) -> list: pass self.assertEquals(f.__annotations__, {'return': list})