def test2(self): prog_text_2 = """\ def wrong2(): print(x) global x """ check_syntax_error(self, prog_text_2, lineno=3, offset=4)
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, 0]] 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") l6 = lambda x, y, *, k=20: x + y + k self.assertEqual(l6(1, 2), 1 + 2 + 20) self.assertEqual(l6(1, 2, k=10), 1 + 2 + 10) # check that trailing commas are permitted l10 = lambda a, : 0 l11 = lambda *args, : 0 l12 = lambda **kwds, : 0 l13 = lambda a, *args, : 0 l14 = lambda a, **kwds, : 0 l15 = lambda *args, b, : 0 l16 = lambda *, b, : 0 l17 = lambda *args, **kwds, : 0 l18 = lambda a, *args, b, : 0 l19 = lambda a, *, b, : 0 l20 = lambda a, *args, **kwds, : 0 l21 = lambda *args, b, **kwds, : 0 l22 = lambda *, b, **kwds, : 0 l23 = lambda a, *args, b, **kwds, : 0 l24 = lambda a, *, b, **kwds, : 0
def test3(self): prog_text_3 = """\ def wrong3(): print(x) x = 2 global x """ check_syntax_error(self, prog_text_3, lineno=4, offset=4)
def test1(self): prog_text_1 = """\ def wrong1(): a = 1 b = 2 global a global b """ check_syntax_error(self, prog_text_1, lineno=4, offset=4)
def test_return(self): # 'return' [testlist] def g1(): return def g2(): return 1 g1() x = g2() check_syntax_error(self, "class foo:return 1")
def test_expr_stmt(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 test_listcomps(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 [0 < 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 test_genexps(self): # generator expression tests g = ([x for x in range(10)] for x in range(1)) self.assertEqual(next(g), [x for x in range(10)]) try: next(g) self.fail('should produce StopIteration exception') except StopIteration: pass a = 1 try: g = (a for d in a) next(g) 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 test_funcdef(self): ### [decorators] 'def' NAME parameters ['->' test] ':' suite ### decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE ### decorators: decorator+ ### parameters: '(' [typedargslist] ')' ### typedargslist: ((tfpdef ['=' test] ',')* ### ('*' [tfpdef] (',' tfpdef ['=' test])* [',' '**' tfpdef] | '**' tfpdef) ### | tfpdef ['=' test] (',' tfpdef ['=' test])* [',']) ### tfpdef: NAME [':' test] ### varargslist: ((vfpdef ['=' test] ',')* ### ('*' [vfpdef] (',' vfpdef ['=' test])* [',' '**' vfpdef] | '**' vfpdef) ### | vfpdef ['=' test] (',' vfpdef ['=' test])* [',']) ### vfpdef: NAME def f1(): pass f1() f1(*()) f1(*(), **{}) def f2(one_argument): pass def f3(two, arguments): pass self.assertEqual(f2.__code__.co_varnames, ('one_argument', )) self.assertEqual(f3.__code__.co_varnames, ('two', 'arguments')) 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 f1() f2(1) f2(1, ) f3(1, 2) f3( 1, 2, ) 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) def d01(a=1): pass d01() d01(1) d01(*(1, )) d01(*[] or [2]) d01(*() or (), *{} and (), **() or {}) 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}) # keyword argument type tests try: str('x', **{b'foo': 1}) except TypeError: pass else: self.fail('Bytes should not work as keyword argument names') # 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) self.assertRaises(SyntaxError, eval, "def f(*): pass") self.assertRaises(SyntaxError, eval, "def f(*,): pass") self.assertRaises(SyntaxError, eval, "def f(*, **kwds): pass") # 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.assertEqual(f(1, *(2, 3), 4), ((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' })) # argument annotation tests def f(x) -> list: pass self.assertEqual(f.__annotations__, {'return': list}) def f(x: int): pass self.assertEqual(f.__annotations__, {'x': int}) def f(*x: str): pass self.assertEqual(f.__annotations__, {'x': str}) def f(**x: float): pass self.assertEqual(f.__annotations__, {'x': float}) def f(x, y: 1 + 2): pass self.assertEqual(f.__annotations__, {'y': 3}) def f(a, b: 1, c: 2, d): pass self.assertEqual(f.__annotations__, {'b': 1, 'c': 2}) def f(a, b: 1, c: 2, d, e: 3 = 4, f=5, *g: 6): pass self.assertEqual(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.assertEqual(f.__annotations__, { 'b': 1, 'c': 2, 'e': 3, 'g': 6, 'h': 7, 'j': 9, 'k': 11, 'return': 12 }) # Check for issue #20625 -- annotations mangling class Spam: def f(self, *, __kw: 1): pass class Ham(Spam): pass self.assertEqual(Spam.f.__annotations__, {'_Spam__kw': 1}) self.assertEqual(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.assertEqual(f.__annotations__, {'return': list}) # test closures with a variety of opargs closure = 1 def f(): return closure def f(x=1): return closure def f(*, k=1): return closure def f() -> int: return closure # 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 def f(*args, ): pass def f(**kwds, ): pass def f( a, *args, ): pass def f( a, **kwds, ): pass def f( *args, b, ): pass def f( *, b, ): pass def f( *args, **kwds, ): pass def f( a, *args, b, ): pass def f( a, *, b, ): pass def f( a, *args, **kwds, ): pass def f( *args, b, **kwds, ): pass def f( *, b, **kwds, ): pass def f( a, *args, b, **kwds, ): pass def f( a, *, b, **kwds, ): pass
def test_var_annot_syntax_errors(self): # parser pass check_syntax_error(self, "def f: int") check_syntax_error(self, "x: int: str") check_syntax_error(self, "def f():\n" " nonlocal x: int\n") # AST pass check_syntax_error(self, "[x, 0]: int\n") check_syntax_error(self, "f(): int\n") check_syntax_error(self, "(x,): int") check_syntax_error(self, "def f():\n" " (x, y): int = (1, 2)\n") # symtable pass check_syntax_error(self, "def f():\n" " x: int\n" " global x\n") check_syntax_error(self, "def f():\n" " global x\n" " x: int\n")
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 test_check_syntax_error(self): support.check_syntax_error(self, "def class", lineno=1, offset=9) with self.assertRaises(AssertionError): support.check_syntax_error(self, "x=1")