[Python-checkins] r65872 - in python/trunk: Doc/reference/expressions.rst Grammar/Grammar Lib/test/test_grammar.py Python/ast.c Python/graminit.c

benjamin.peterson python-checkins at python.org
Tue Aug 19 21:52:47 CEST 2008


Author: benjamin.peterson
Date: Tue Aug 19 21:52:46 2008
New Revision: 65872

Log:
allow keyword args to be passed in after *args #3473

Modified:
   python/trunk/Doc/reference/expressions.rst
   python/trunk/Grammar/Grammar
   python/trunk/Lib/test/test_grammar.py
   python/trunk/Python/ast.c
   python/trunk/Python/graminit.c

Modified: python/trunk/Doc/reference/expressions.rst
==============================================================================
--- python/trunk/Doc/reference/expressions.rst	(original)
+++ python/trunk/Doc/reference/expressions.rst	Tue Aug 19 21:52:46 2008
@@ -625,11 +625,11 @@
    call: `primary` "(" [`argument_list` [","]
        : | `expression` `genexpr_for`] ")"
    argument_list: `positional_arguments` ["," `keyword_arguments`]
-                : ["," "*" `expression`]
-                : ["," "**" `expression`]
+                :   ["," "*" `expression`] ["," `keyword_arguments`]
+                :   ["," "**" `expression`]
                 : | `keyword_arguments` ["," "*" `expression`]
-                : ["," "**" `expression`]
-                : | "*" `expression` ["," "**" `expression`]
+                :   ["," "**" `expression`]
+                : | "*" `expression` ["," "*" `expression`] ["," "**" `expression`]
                 : | "**" `expression`
    positional_arguments: `expression` ("," `expression`)*
    keyword_arguments: `keyword_item` ("," `keyword_item`)*
@@ -686,12 +686,13 @@
 
 If the syntax ``*expression`` appears in the function call, ``expression`` must
 evaluate to a sequence.  Elements from this sequence are treated as if they were
-additional positional arguments; if there are positional arguments *x1*,...,*xN*
-, and ``expression`` evaluates to a sequence *y1*,...,*yM*, this is equivalent
-to a call with M+N positional arguments *x1*,...,*xN*,*y1*,...,*yM*.
+additional positional arguments; if there are positional arguments *x1*,...,
+*xN*, and ``expression`` evaluates to a sequence *y1*, ..., *yM*, this is
+equivalent to a call with M+N positional arguments *x1*, ..., *xN*, *y1*, ...,
+*yM*.
 
-A consequence of this is that although the ``*expression`` syntax appears
-*after* any keyword arguments, it is processed *before* the keyword arguments
+A consequence of this is that although the ``*expression`` syntax may appear
+*after* some keyword arguments, it is processed *before* the keyword arguments
 (and the ``**expression`` argument, if any -- see below).  So::
 
    >>> def f(a, b):

Modified: python/trunk/Grammar/Grammar
==============================================================================
--- python/trunk/Grammar/Grammar	(original)
+++ python/trunk/Grammar/Grammar	Tue Aug 19 21:52:46 2008
@@ -130,7 +130,9 @@
 
 classdef: 'class' NAME ['(' [testlist] ')'] ':' suite
 
-arglist: (argument ',')* (argument [',']| '*' test [',' '**' test] | '**' test)
+arglist: (argument ',')* (argument [',']
+                         |'*' test (',' argument)* [',' '**' test] 
+                         |'**' test)
 argument: test [gen_for] | test '=' test  # Really [keyword '='] test
 
 list_iter: list_for | list_if

Modified: python/trunk/Lib/test/test_grammar.py
==============================================================================
--- python/trunk/Lib/test/test_grammar.py	(original)
+++ python/trunk/Lib/test/test_grammar.py	Tue Aug 19 21:52:46 2008
@@ -282,6 +282,14 @@
         def d32v((x,)): pass
         d32v((1,))
 
+        # keyword arguments after *arglist
+        def f(*args, **kwargs):
+            return args, kwargs
+        self.assertEquals(f(1, x=2, *[3, 4], y=5), ((1, 3, 4),
+                                                    {'x':2, 'y':5}))
+        self.assertRaises(SyntaxError, eval, "f(1, *(2,3), 4)")
+        self.assertRaises(SyntaxError, eval, "f(1, x=2, *(3,4), x=5)")
+
         # Check ast errors in *args and *kwargs
         check_syntax_error(self, "f(*g(1=2))")
         check_syntax_error(self, "f(**g(1=2))")

Modified: python/trunk/Python/ast.c
==============================================================================
--- python/trunk/Python/ast.c	(original)
+++ python/trunk/Python/ast.c	Tue Aug 19 21:52:46 2008
@@ -1898,6 +1898,11 @@
                               "non-keyword arg after keyword arg");
                     return NULL;
                 }
+                if (vararg) {
+                    ast_error(CHILD(ch, 0),
+                              "only named arguments may follow *expression");
+                    return NULL;
+                }
                 e = ast_for_expr(c, CHILD(ch, 0));
                 if (!e)
                     return NULL;

Modified: python/trunk/Python/graminit.c
==============================================================================
--- python/trunk/Python/graminit.c	(original)
+++ python/trunk/Python/graminit.c	Tue Aug 19 21:52:46 2008
@@ -1609,7 +1609,8 @@
 static arc arcs_74_6[1] = {
 	{0, 6},
 };
-static arc arcs_74_7[1] = {
+static arc arcs_74_7[2] = {
+	{162, 5},
 	{31, 3},
 };
 static state states_74[8] = {
@@ -1620,7 +1621,7 @@
 	{4, arcs_74_4},
 	{2, arcs_74_5},
 	{1, arcs_74_6},
-	{1, arcs_74_7},
+	{2, arcs_74_7},
 };
 static arc arcs_75_0[1] = {
 	{28, 1},


More information about the Python-checkins mailing list