follow-up of issue3473: update the compiler package to recognize the new syntax.
This commit is contained in:
parent
bd6a05fe81
commit
67f24f1ed6
|
@ -1222,12 +1222,27 @@ class Transformer:
|
||||||
return CallFunc(primaryNode, [], lineno=extractLineNo(nodelist))
|
return CallFunc(primaryNode, [], lineno=extractLineNo(nodelist))
|
||||||
args = []
|
args = []
|
||||||
kw = 0
|
kw = 0
|
||||||
|
star_node = dstar_node = None
|
||||||
len_nodelist = len(nodelist)
|
len_nodelist = len(nodelist)
|
||||||
for i in range(1, len_nodelist, 2):
|
i = 1
|
||||||
|
while i < len_nodelist:
|
||||||
node = nodelist[i]
|
node = nodelist[i]
|
||||||
if node[0] == token.STAR or node[0] == token.DOUBLESTAR:
|
|
||||||
break
|
if node[0]==token.STAR:
|
||||||
kw, result = self.com_argument(node, kw)
|
if star_node is not None:
|
||||||
|
raise SyntaxError, 'already have the varargs indentifier'
|
||||||
|
star_node = self.com_node(nodelist[i+1])
|
||||||
|
i = i + 3
|
||||||
|
continue
|
||||||
|
elif node[0]==token.DOUBLESTAR:
|
||||||
|
if dstar_node is not None:
|
||||||
|
raise SyntaxError, 'already have the kwargs indentifier'
|
||||||
|
dstar_node = self.com_node(nodelist[i+1])
|
||||||
|
i = i + 3
|
||||||
|
continue
|
||||||
|
|
||||||
|
# positional or named parameters
|
||||||
|
kw, result = self.com_argument(node, kw, star_node)
|
||||||
|
|
||||||
if len_nodelist != 2 and isinstance(result, GenExpr) \
|
if len_nodelist != 2 and isinstance(result, GenExpr) \
|
||||||
and len(node) == 3 and node[2][0] == symbol.gen_for:
|
and len(node) == 3 and node[2][0] == symbol.gen_for:
|
||||||
|
@ -1236,37 +1251,20 @@ class Transformer:
|
||||||
raise SyntaxError, 'generator expression needs parenthesis'
|
raise SyntaxError, 'generator expression needs parenthesis'
|
||||||
|
|
||||||
args.append(result)
|
args.append(result)
|
||||||
else:
|
i = i + 2
|
||||||
# No broken by star arg, so skip the last one we processed.
|
|
||||||
i = i + 1
|
|
||||||
if i < len_nodelist and nodelist[i][0] == token.COMMA:
|
|
||||||
# need to accept an application that looks like "f(a, b,)"
|
|
||||||
i = i + 1
|
|
||||||
star_node = dstar_node = None
|
|
||||||
while i < len_nodelist:
|
|
||||||
tok = nodelist[i]
|
|
||||||
ch = nodelist[i+1]
|
|
||||||
i = i + 3
|
|
||||||
if tok[0]==token.STAR:
|
|
||||||
if star_node is not None:
|
|
||||||
raise SyntaxError, 'already have the varargs indentifier'
|
|
||||||
star_node = self.com_node(ch)
|
|
||||||
elif tok[0]==token.DOUBLESTAR:
|
|
||||||
if dstar_node is not None:
|
|
||||||
raise SyntaxError, 'already have the kwargs indentifier'
|
|
||||||
dstar_node = self.com_node(ch)
|
|
||||||
else:
|
|
||||||
raise SyntaxError, 'unknown node type: %s' % tok
|
|
||||||
return CallFunc(primaryNode, args, star_node, dstar_node,
|
return CallFunc(primaryNode, args, star_node, dstar_node,
|
||||||
lineno=extractLineNo(nodelist))
|
lineno=extractLineNo(nodelist))
|
||||||
|
|
||||||
def com_argument(self, nodelist, kw):
|
def com_argument(self, nodelist, kw, star_node):
|
||||||
if len(nodelist) == 3 and nodelist[2][0] == symbol.gen_for:
|
if len(nodelist) == 3 and nodelist[2][0] == symbol.gen_for:
|
||||||
test = self.com_node(nodelist[1])
|
test = self.com_node(nodelist[1])
|
||||||
return 0, self.com_generator_expression(test, nodelist[2])
|
return 0, self.com_generator_expression(test, nodelist[2])
|
||||||
if len(nodelist) == 2:
|
if len(nodelist) == 2:
|
||||||
if kw:
|
if kw:
|
||||||
raise SyntaxError, "non-keyword arg after keyword arg"
|
raise SyntaxError, "non-keyword arg after keyword arg"
|
||||||
|
if star_node:
|
||||||
|
raise SyntaxError, "only named arguments may follow *expression"
|
||||||
return 0, self.com_node(nodelist[1])
|
return 0, self.com_node(nodelist[1])
|
||||||
result = self.com_node(nodelist[3])
|
result = self.com_node(nodelist[3])
|
||||||
n = nodelist[1]
|
n = nodelist[1]
|
||||||
|
|
|
@ -64,6 +64,15 @@ class CompilerTest(unittest.TestCase):
|
||||||
def testYieldExpr(self):
|
def testYieldExpr(self):
|
||||||
compiler.compile("def g(): yield\n\n", "<string>", "exec")
|
compiler.compile("def g(): yield\n\n", "<string>", "exec")
|
||||||
|
|
||||||
|
def testKeywordAfterStarargs(self):
|
||||||
|
def f(*args, **kwargs):
|
||||||
|
self.assertEqual((args, kwargs), ((2,3), {'x': 1, 'y': 4}))
|
||||||
|
c = compiler.compile('f(x=1, *(2, 3), y=4)', '<string>', 'exec')
|
||||||
|
exec c in {'f': f}
|
||||||
|
|
||||||
|
self.assertRaises(SyntaxError, compiler.parse, "foo(a=1, b)")
|
||||||
|
self.assertRaises(SyntaxError, compiler.parse, "foo(1, *args, 3)")
|
||||||
|
|
||||||
def testTryExceptFinally(self):
|
def testTryExceptFinally(self):
|
||||||
# Test that except and finally clauses in one try stmt are recognized
|
# Test that except and finally clauses in one try stmt are recognized
|
||||||
c = compiler.compile("try:\n 1/0\nexcept:\n e = 1\nfinally:\n f = 1",
|
c = compiler.compile("try:\n 1/0\nexcept:\n e = 1\nfinally:\n f = 1",
|
||||||
|
|
Loading…
Reference in New Issue