diff options
author | Amaury Forgeot d'Arc <amauryfa@gmail.com> | 2008-08-20 00:08:47 (GMT) |
---|---|---|
committer | Amaury Forgeot d'Arc <amauryfa@gmail.com> | 2008-08-20 00:08:47 (GMT) |
commit | 67f24f1ed65d02511dbf2a9e219a78552566f71b (patch) | |
tree | b0bf92323c0883d551474237c077c4c2711a221a | |
parent | bd6a05fe81fe1573f0517ce8982d62341f3b0f85 (diff) | |
download | cpython-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.py | 50 | ||||
-rw-r--r-- | Lib/test/test_compiler.py | 9 |
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", |