Why does the trailing comma have a SyntaxError value in the argument list that uses the * args syntax?

Why can't you use trailing comma with *args in Python? In other words, it works

 >>> f(1, 2, b=4,) 

But it is not

 >>> f(*(1, 2), b=4,) File "<stdin>", line 1 f(*(1, 2), b=4,) ^ SyntaxError: invalid syntax 

This applies to both Python 2 and Python 3.

+69
python syntax python-internals
Jun 05
source share
2 answers

Look at the language specification :

 call ::= primary "(" [argument_list [","] | expression genexpr_for] ")" argument_list ::= positional_arguments ["," keyword_arguments] ["," "*" expression] ["," keyword_arguments] ["," "**" expression] | keyword_arguments ["," "*" expression] ["," "**" expression] | "*" expression ["," "*" expression] ["," "**" expression] | "**" expression positional_arguments ::= expression ("," expression)* keyword_arguments ::= keyword_item ("," keyword_item)* keyword_item ::= identifier "=" expression 

Let sift to the parts we care about:

 call ::= primary "(" [argument_list [","]] ")" argument_list ::= positional_arguments ["," keyword_arguments] ["," "*" expression] ["," keyword_arguments] ["," "**" expression] positional_arguments ::= expression ("," expression)* keyword_arguments ::= keyword_item ("," keyword_item)* keyword_item ::= identifier "=" expression 

So, it seems that after any arguments to the function call, we are allowed to optional,. So this seems like a bug in cpython implementation.

Something like: f(1, *(2,3,4), ) should work according to this grammar, but not in CPython.




In an earlier answer, Eric is related to the CPython grammar specification , which includes the CPython implementation of the above grammar. Here it is below:

 arglist: (argument ',')* ( argument [','] | '*' test (',' argument)* [',' '**' test] | '**' test ) 

Please note that this grammar does not match with the language specification as such. I would consider this an implementation error.




Please note that there are additional issues with the implementation of CPython. This should also be supported: f(*(1,2,3), *(4,5,6))

Oddly enough, the specification does not allow f(*(1,2,3), *(4,5,6), *(7,8,9))

Since I look at this more, it seems to me that this part of the specification needs some fixing. This is allowed: f(x=1, *(2,3)) , but it is not: f(x=1, 2, 3) .




And perhaps a useful starting question, in CPython, you can have a trailing comma if you don't use the *args or **kwargs function. I agree that this is lame.

+100
Jun 05 '13 at 21:50
source share

After some discussion of this error in issue 9232 , Guido van Rossum commented :

I added +1. I do not think this requires THE PEP. The back comma in the definitions is already supported in some places, so I do not buy the argument that it catches errors. During the moratorium, we were perhaps too strict.

Subsequently, a patch was made by Mark Dickinson . So now this is fixed in Python 3.6.0 alpha 1.

+5
Sep 28 '15 at 11:22
source share



All Articles