aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib/test/test_grammar.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test/test_grammar.py')
-rw-r--r--Lib/test/test_grammar.py338
1 files changed, 132 insertions, 206 deletions
diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py
index 86cc0843eef..268a633b2c7 100644
--- a/Lib/test/test_grammar.py
+++ b/Lib/test/test_grammar.py
@@ -1,8 +1,7 @@
# Python test set -- part 1, grammar.
# This just tests whether the parser accepts them all.
-from test.test_support import run_unittest, check_syntax_error, \
- check_py3k_warnings
+from test.support import run_unittest, check_syntax_error
import unittest
import sys
# testing import *
@@ -22,44 +21,50 @@ class TokenTests(unittest.TestCase):
self.assertEqual(x, 0, 'backslash ending comment')
def testPlainIntegers(self):
+ self.assertEqual(type(000), type(0))
self.assertEqual(0xff, 255)
- self.assertEqual(0377, 255)
- self.assertEqual(2147483647, 017777777777)
+ self.assertEqual(0o377, 255)
+ self.assertEqual(2147483647, 0o17777777777)
+ self.assertEqual(0b1001, 9)
# "0x" is not a valid literal
self.assertRaises(SyntaxError, eval, "0x")
- from sys import maxint
- if maxint == 2147483647:
- self.assertEqual(-2147483647-1, -020000000000)
+ from sys import maxsize
+ if maxsize == 2147483647:
+ self.assertEqual(-2147483647-1, -0o20000000000)
# XXX -2147483648
- self.assertTrue(037777777777 > 0)
+ self.assertTrue(0o37777777777 > 0)
self.assertTrue(0xffffffff > 0)
- for s in '2147483648', '040000000000', '0x100000000':
+ self.assertTrue(0b1111111111111111111111111111111 > 0)
+ for s in ('2147483648', '0o40000000000', '0x100000000',
+ '0b10000000000000000000000000000000'):
try:
x = eval(s)
except OverflowError:
self.fail("OverflowError on huge integer literal %r" % s)
- elif maxint == 9223372036854775807:
- self.assertEqual(-9223372036854775807-1, -01000000000000000000000)
- self.assertTrue(01777777777777777777777 > 0)
+ elif maxsize == 9223372036854775807:
+ self.assertEqual(-9223372036854775807-1, -0o1000000000000000000000)
+ self.assertTrue(0o1777777777777777777777 > 0)
self.assertTrue(0xffffffffffffffff > 0)
- for s in '9223372036854775808', '02000000000000000000000', \
- '0x10000000000000000':
+ self.assertTrue(0b11111111111111111111111111111111111111111111111111111111111111 > 0)
+ for s in '9223372036854775808', '0o2000000000000000000000', \
+ '0x10000000000000000', \
+ '0b100000000000000000000000000000000000000000000000000000000000000':
try:
x = eval(s)
except OverflowError:
self.fail("OverflowError on huge integer literal %r" % s)
else:
- self.fail('Weird maxint value %r' % maxint)
+ self.fail('Weird maxsize value %r' % maxsize)
def testLongIntegers(self):
- x = 0L
- x = 0l
- x = 0xffffffffffffffffL
- x = 0xffffffffffffffffl
- x = 077777777777777777L
- x = 077777777777777777l
- x = 123456789012345678901234567890L
- x = 123456789012345678901234567890l
+ x = 0
+ x = 0xffffffffffffffff
+ x = 0Xffffffffffffffff
+ x = 0o77777777777777777
+ x = 0O77777777777777777
+ x = 123456789012345678901234567890
+ x = 0b100000000000000000000000000000000000000000000000000000000000000000000
+ x = 0B111111111111111111111111111111111111111111111111111111111111111111111
def testFloats(self):
x = 3.14
@@ -115,6 +120,10 @@ the \'lazy\' dog.\n\
'
self.assertEqual(x, y)
+ def testEllipsis(self):
+ x = ...
+ self.assertTrue(x is Ellipsis)
+ self.assertRaises(SyntaxError, eval, ".. .")
class GrammarTests(unittest.TestCase):
@@ -132,51 +141,37 @@ class GrammarTests(unittest.TestCase):
x = eval('1, 0 or 1')
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
+ ### [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
- # 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'))
+ 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
- # 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,)
@@ -191,17 +186,7 @@ class GrammarTests(unittest.TestCase):
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)
@@ -274,11 +259,24 @@ class GrammarTests(unittest.TestCase):
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 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)
# keyword arguments after *arglist
def f(*args, **kwargs):
@@ -288,6 +286,40 @@ class GrammarTests(unittest.TestCase):
self.assertRaises(SyntaxError, eval, "f(1, *(2,3), 4)")
self.assertRaises(SyntaxError, eval, "f(1, x=2, *(3,4), x=5)")
+ # 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 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 MAKE_CLOSURE with a variety of oparg's
+ 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))")
@@ -297,7 +329,7 @@ class GrammarTests(unittest.TestCase):
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]]
+ 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)
@@ -306,6 +338,10 @@ class GrammarTests(unittest.TestCase):
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)
+
### stmt: simple_stmt | compound_stmt
# Tested below
@@ -318,7 +354,7 @@ class GrammarTests(unittest.TestCase):
x = 1; pass; del x;
foo()
- ### small_stmt: expr_stmt | print_stmt | pass_stmt | del_stmt | flow_stmt | import_stmt | global_stmt | access_stmt | exec_stmt
+ ### small_stmt: expr_stmt | pass_stmt | del_stmt | flow_stmt | import_stmt | global_stmt | access_stmt
# Tested below
def testExprStmt(self):
@@ -334,76 +370,6 @@ class GrammarTests(unittest.TestCase):
check_syntax_error(self, "x + 1 = 1")
check_syntax_error(self, "a + 1 = b + 2")
- 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 testDelStmt(self):
# 'del' exprlist
abc = [1,2,3]
@@ -489,7 +455,7 @@ hello world
def testRaise(self):
# 'raise' test [',' test]
- try: raise RuntimeError, 'just testing'
+ try: raise RuntimeError('just testing')
except RuntimeError: pass
try: raise KeyboardInterrupt
except KeyboardInterrupt: pass
@@ -513,37 +479,13 @@ hello world
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 '__builtins__' in g: del g['__builtins__']
- if g != {'z': 1}: self.fail('exec \'z = 1\' in g')
- g = {}
- l = {}
-
- exec 'global a; a = 1; b = 2' in g, l
- if '__builtins__' in g: del g['__builtins__']
- if '__builtins__' in l: del l['__builtins__']
- if (g, l) != ({'a':1}, {'b':2}):
- self.fail('exec ... in g (%s), l (%s)' %(g,l))
+ def testNonlocal(self):
+ # 'nonlocal' NAME (',' NAME)*
+ x = 0
+ y = 0
+ def f():
+ nonlocal x
+ nonlocal x, y
def testAssert(self):
# assertTruestmt: 'assert' test [',' test]
@@ -568,7 +510,7 @@ hello world
def testAssert2(self):
try:
assert 0, "msg"
- except AssertionError, e:
+ except AssertionError as e:
self.assertEqual(e.args[0], "msg")
else:
self.fail("AssertionError not raised by assert 0")
@@ -642,7 +584,7 @@ hello world
def testTry(self):
### try_stmt: 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite]
### | 'try' ':' suite 'finally' ':' suite
- ### except_clause: 'except' [expr [('as' | ',') expr]]
+ ### except_clause: 'except' [expr ['as' expr]]
try:
1/0
except ZeroDivisionError:
@@ -652,13 +594,13 @@ hello world
try: 1/0
except EOFError: pass
except TypeError as msg: pass
- except RuntimeError, msg: pass
+ except RuntimeError as msg: pass
except: pass
else: pass
try: 1/0
except (EOFError, TypeError, ZeroDivisionError): pass
try: 1/0
- except (EOFError, TypeError, ZeroDivisionError), msg: pass
+ except (EOFError, TypeError, ZeroDivisionError) as msg: pass
try: pass
finally: pass
@@ -690,7 +632,7 @@ hello world
def testComparison(self):
### comparison: expr (comp_op expr)*
- ### comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'
+ ### comp_op: '<'|'>'|'=='|'>='|'<='|'!='|'in'|'not' 'in'|'is'|'is' 'not'
if 1: pass
x = (1 == 1)
if 1 == 1: pass
@@ -704,9 +646,6 @@ hello world
if 1 in (): pass
if 1 not in (): pass
if 1 < 1 > 1 == 1 >= 1 <= 1 != 1 in 1 not in 1 is 1 is not 1: pass
- # Silence Py3k warning
- if eval('1 <> 1'): pass
- if eval('1 < 1 > 1 == 1 >= 1 <= 1 <> 1 != 1 in 1 not in 1 is 1 is not 1'): pass
def testBinaryMaskOps(self):
x = 1 & 1
@@ -764,12 +703,12 @@ hello world
d[1,2] = 3
d[1,2,3] = 4
L = list(d)
- L.sort()
+ L.sort(key=lambda x: x if isinstance(x, tuple) else ())
self.assertEqual(str(L), '[1, (1,), (1, 2), (1, 2, 3)]')
def testAtoms(self):
- ### atom: '(' [testlist] ')' | '[' [testlist] ']' | '{' [dictmaker] '}' | '`' testlist '`' | NAME | NUMBER | STRING
- ### dictorsetmaker: (test ':' test (',' test ':' test)* [',']) | (test (',' test)* [','])
+ ### atom: '(' [testlist] ')' | '[' [testlist] ']' | '{' [dictsetmaker] '}' | NAME | NUMBER | STRING
+ ### dictsetmaker: (test ':' test (',' test ':' test)* [',']) | (test (',' test)* [','])
x = (1)
x = (1 or 2 or 3)
@@ -794,11 +733,6 @@ hello world
x = {'one', 'two', 'three'}
x = {2, 3, 4,}
- # Silence Py3k warning
- x = eval('`x`')
- x = eval('`1 or 2 or 3`')
- self.assertEqual(eval('`1,2`'), '(1, 2)')
-
x = x
x = 'x'
x = 123
@@ -818,16 +752,13 @@ hello world
def meth1(self): pass
def meth2(self, arg): pass
def meth3(self, a1, a2): pass
+
# decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
# decorators: decorator+
# decorated: decorators (classdef | funcdef)
- def class_decorator(x):
- x.decorated = True
- return x
+ def class_decorator(x): return x
@class_decorator
- class G:
- pass
- self.assertEqual(G.decorated, True)
+ class G: pass
def testDictcomps(self):
# dictorsetmaker: ( (test ':' test (comp_for |
@@ -859,7 +790,7 @@ hello world
[[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]
+ return [0 < x < 3 for x in l if x > 2]
self.assertEqual(test_in_func(nums), [False, False, False])
@@ -902,9 +833,9 @@ hello world
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)])
+ self.assertEqual(next(g), [x for x in range(10)])
try:
- g.next()
+ next(g)
self.fail('should produce StopIteration exception')
except StopIteration:
pass
@@ -912,7 +843,7 @@ hello world
a = 1
try:
g = (a for d in a)
- g.next()
+ next(g)
self.fail('should produce TypeError')
except TypeError:
pass
@@ -977,10 +908,11 @@ hello world
# Test ifelse expressions in various cases
def _checkeval(msg, ret):
"helper to check that evaluation of expressions is done correctly"
- print x
+ print(x)
return ret
- self.assertEqual([ x() for x in lambda: True, lambda: False if x() ], [True])
+ # the next line is not allowed anymore
+ #self.assertEqual([ x() for x in lambda: True, lambda: False if x() ], [True])
self.assertEqual([ x() for x in (lambda: True, lambda: False) if x() ], [True])
self.assertEqual([ x(False) for x in (lambda x: False if x else True, lambda x: True if x else False) if x(False) ], [True])
self.assertEqual((5 if 1 else _checkeval("check 1", 0)), 5)
@@ -1009,13 +941,7 @@ hello world
def test_main():
- with check_py3k_warnings(
- ("backquote not supported", SyntaxWarning),
- ("tuple parameter unpacking has been removed", SyntaxWarning),
- ("parenthesized argument names are invalid", SyntaxWarning),
- ("classic int division", DeprecationWarning),
- (".+ not supported in 3.x", DeprecationWarning)):
- run_unittest(TokenTests, GrammarTests)
+ run_unittest(TokenTests, GrammarTests)
if __name__ == '__main__':
test_main()