summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmaury Forgeot d'Arc <amauryfa@gmail.com>2008-08-20 00:08:47 (GMT)
committerAmaury Forgeot d'Arc <amauryfa@gmail.com>2008-08-20 00:08:47 (GMT)
commit67f24f1ed65d02511dbf2a9e219a78552566f71b (patch)
treeb0bf92323c0883d551474237c077c4c2711a221a
parentbd6a05fe81fe1573f0517ce8982d62341f3b0f85 (diff)
downloadcpython-67f24f1ed65d02511dbf2a9e219a78552566f71b.zip
cpython-67f24f1ed65d02511dbf2a9e219a78552566f71b.tar.gz
cpython-67f24f1ed65d02511dbf2a9e219a78552566f71b.tar.bz2
follow-up of issue3473: update the compiler package to recognize the new syntax.
-rw-r--r--Lib/compiler/transformer.py50
-rw-r--r--Lib/test/test_compiler.py9
2 files changed, 33 insertions, 26 deletions
diff --git a/Lib/compiler/transformer.py b/Lib/compiler/transformer.py
index 8c367e2..eccade3 100644
--- a/Lib/compiler/transformer.py
+++ b/Lib/compiler/transformer.py
@@ -1222,12 +1222,27 @@ class Transformer:
return CallFunc(primaryNode, [], lineno=extractLineNo(nodelist))
args = []
kw = 0
+ star_node = dstar_node = None
len_nodelist = len(nodelist)
- for i in range(1, len_nodelist, 2):
+ i = 1
+ while i < len_nodelist:
node = nodelist[i]
- if node[0] == token.STAR or node[0] == token.DOUBLESTAR:
- break
- kw, result = self.com_argument(node, kw)
+
+ if node[0]==token.STAR:
+ 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) \
and len(node) == 3 and node[2][0] == symbol.gen_for:
@@ -1236,37 +1251,20 @@ class Transformer:
raise SyntaxError, 'generator expression needs parenthesis'
args.append(result)
- else:
- # 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
+ i = i + 2
+
return CallFunc(primaryNode, args, star_node, dstar_node,
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:
test = self.com_node(nodelist[1])
return 0, self.com_generator_expression(test, nodelist[2])
if len(nodelist) == 2:
if kw:
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])
result = self.com_node(nodelist[3])
n = nodelist[1]
diff --git a/Lib/test/test_compiler.py b/Lib/test/test_compiler.py
index 390c469..c7ec50f 100644
--- a/Lib/test/test_compiler.py
+++ b/Lib/test/test_compiler.py
@@ -64,6 +64,15 @@ class CompilerTest(unittest.TestCase):
def testYieldExpr(self):
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):
# 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",