method (a, b = '', *c, **d): gets a syntax error?

A

Andreas Neudecker

Hello.

I am relatively new to Python and I have a strange problem with some
code. In a class the __call__ method gets parameters like this:


class WhatsUp:
__call__ (
self,
var1,
var2 = '',
*moreVars,
**moreNamedVars,
):
pass


I always get an error for the **moreNamedVars, line where the '^' points
at the comma at the end (or, if I remove the comma, it points at the
colon). I also tried commenting-out the other variables passed to the
method. Same result.
I assumed the order of variables and variable lists of variables had to
be like this? What is wrong?


Kind regards



Andreas
 
M

Michael Hudson

Andreas Neudecker said:
Hello.

I am relatively new to Python and I have a strange problem with some
code. In a class the __call__ method gets parameters like this:


class WhatsUp:
__call__ (
self,
var1,
var2 = '',
*moreVars,
**moreNamedVars,
):
pass


I always get an error for the **moreNamedVars, line where the '^'
points at the comma at the end (or, if I remove the comma, it points
at the colon). I also tried commenting-out the other variables passed
to the method. Same result.
I assumed the order of variables and variable lists of variables had
to be like this? What is wrong?

Missing a def?

Cheers,
mwh
 
A

Alex Martelli

Andreas said:
Hello.

I am relatively new to Python and I have a strange problem with some
code. In a class the __call__ method gets parameters like this:


class WhatsUp:
__call__ (

You're missing the keyword 'def' here, right before the method name.


Alex
 
T

Terry Reedy

Andreas Neudecker said:
class WhatsUp:
__call__ (
self,
var1,
var2 = '',
*moreVars,
**moreNamedVars,
):
pass


I always get an error for the **moreNamedVars, line where the '^' points
at the comma at the end (or, if I remove the comma, it points at the
colon). ...What is wrong?

Generaly, when reporting 'I got an error', you should copy the actual
error message. In this case, I presume you got 'SyntaxError: invalid
syntax' for each of your two syntax errors.

1. When you make a function call and use **whatever, it must be the
last item in the argument list, just as in a function definition. A
following comma is not allowed for either defs or calls. So when you
add 'def' to correct your actual error, you also need to omit the
comma.

2. The colon suffix is required for defs but forbidden for calls.
With the comma present, the parser never got far enough to this.
Unlike most batch compilers, the CPython parser quits at the first
error it sees. So when you correct one error and resubmit, you may
expose another further in your code.

Welcom to Python. Enjoy.

Terry J. Reedy
 
A

Andreas Neudecker

Hi.

Terry said:
Generaly, when reporting 'I got an error', you should copy the actual
error message.

Will do from now. Thanks.
In this case, I presume you got 'SyntaxError: invalid
syntax' for each of your two syntax errors.

Exactly. Got one. As Michael Peuser states, the comma behind the last
parameter is fine. I am doing this all the time when the list is long
and I write it one parameter per line, because it makes swapping order
or adding another parameter less error-prone (how often have you
forgotten to add the comma to the previous parameter when adding a new
'last one').
1. When you make a function call and use **whatever, it must be the
last item in the argument list, just as in a function definition.

I knew that. That was what puzzled me. And the pointer of the error
message pointed to the comma. So I simply overlooked that I had
forgotten the 'def' - what a dumb bug!
Welcom to Python. Enjoy.

I do. Used to do some C long, long ago. Python is so much more
comfortable ...

Regards


Andreas
 
A

Andreas Neudecker

Sorry, have to correct myself on the comma topic:


class WhatsUp:
# No comma at the end of the list. This works fine.
def method1 (
self,
var1,
var2 = '',
*more,
**moreNamed
):
print "This works fine."

# This also works fine, even with the comma at the end.
def method2 (
self,
var1,
var2 = '',
var3 = '', # <- THIS COMMA IS FINE.
):
print "This works fine."

# This will raise a Syntax error because of the comma.
def method3 (
self,
var1,
var2 = '',
*more,
**moreNamed, # <- THIS COMMA IS NOT ALLOWED.
):
print "The comma at the end of the parameter list will \
raise a syntax error."


So to me it looks like it makes a difference whether the list contains a
variable parameter list or not. I use the version as in method2 often
for reasons stated in my previous posting.

Still it puzzles me that in one case it is okay in the other one not.
Seems unlogical to me. Can anyone enlighten me to why this is so?

Thanks to all of you who bothered to point me to my stupid error of
forgetting the 'def' and discussing with me the comma problem.


Kind regards


Andreas
 
T

Terry Reedy

Michael Peuser said:
[...}
1. When you make a function call and use **whatever, it must be the
last item in the argument list, just as in a function definition. A
following comma is not allowed for either defs or calls.

This in fact is not true. Funnily you can add *one* comma at the end of any
list-like construct.

For 2.2.1 and whatever version Andreas is running, **whatever is an
exception and CANNOT be followed by a comma in either def or call,
just as I said. I tested before writing. (Did you? Can you test
below on 2.3?)
.... for i,v in d.items(): print i, v
....two 2
one 1 File "<stdin>", line 1
f(**b,)
^
SyntaxError: invalid syntax
File "<stdin>", line 1
def f2(**d,): pass
^
SyntaxError: invalid syntax

# On the original fixed-pitch font screen, both arrows point at
offending comma.

Can someone verify this for 2.3? If so, there is a bug in either doc
or interpreter.

Terry J. Reedy
 
G

Gerrit Holl

Terry said:
File "<stdin>", line 1
def f2(**d,): pass
^
SyntaxError: invalid syntax

# On the original fixed-pitch font screen, both arrows point at
offending comma.

Can someone verify this for 2.3? If so, there is a bug in either doc
or interpreter.

Python 2.3 does the same.

Python 2.3 (#1, Aug 5 2003, 14:13:25)
[GCC 3.2.2 20030222 (Red Hat Linux 3.2.2-5)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
0 >>> zip(**(),)
File "<stdin>", line 1
zip(**(),)
^
SyntaxError: invalid syntax
1 >>> def foo(**a,): pass
File "<stdin>", line 1
def foo(**a,): pass
^
SyntaxError: invalid syntax

yours,
Gerrit.
 
M

Michael Hudson

[comma inconsistencies]
Still it puzzles me that in one case it is okay in the other one
not. Seems unlogical to me. Can anyone enlighten me to why this is so?

Because that's what the grammar says. The chances of this being
deliberate are, I would hazard, pretty tiny.
Thanks to all of you who bothered to point me to my stupid error of
forgetting the 'def' and discussing with me the comma problem.

If it's any consolation, it took quite a bit of staring at it before I
noticed the flaw...

Cheers,
mwh
 
P

Piet van Oostrum

AN> Still it puzzles me that in one case it is okay in the other one not. Seems
AN> unlogical to me. Can anyone enlighten me to why this is so?

It is quite logical. The idea behind the optional comma after the last
parameter is such that it would be easy to change your function to include
additional parameters. When you put each parameter on a separate line (as
you did in your examples) , you just have to add a single line with the new
parameter and it doesn't matter whether the new parameter comes in as the
last one or at any other place. If you leave out the final comma, and the
new parameter is the last one, you would have to add the comma to the
previous line, which can easily be forgotten.

However, when you have **kwargs it must be last, so there is no need to
put an additional comma. In fact it would be confusing as it would suggest
that you can add additional parameters after it.
 
T

Terry Reedy

(Gerrit Holl) Python 2.3 does the same.

Python 2.3 (#1, Aug 5 2003, 14:13:25)
[GCC 3.2.2 20030222 (Red Hat Linux 3.2.2-5)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
0 >>> zip(**(),)
File "<stdin>", line 1
zip(**(),)
^
SyntaxError: invalid syntax
1 >>> def foo(**a,): pass
File "<stdin>", line 1
def foo(**a,): pass
^
SyntaxError: invalid syntax

Thank you for the verification. I have submitted doc bug report SF
798652
(Michael Hudson): Because that's what the grammar says

After the grammer in 5.3.4 follows :"A trailing comma may be present
after an argument list but does not affect the semantics. " I
suggested instead "If an argument list does *not* end with *expr or
**expr, a trailing comma may be added without affecting the
semantics."

I also suggested a change in 7.5 Function definitions to the
production for parameter_list.
(Piet von Oostrum) [Explanation of why '**dic,)' should be error]

I agree, which is why I filed as doc bug. Note
File "<stdin>", line 1
def fl(*lis,): pass
^ # points at ')'
SyntaxError: invalid syntax

The error is detected as ')' instead of ',' because **dic could have
followed, but didn't.

Terry J. Reedy
 
M

Michael Hudson

Terry Reedy said:
After the grammer in 5.3.4 follows :"A trailing comma may be present
after an argument list but does not affect the semantics. " I
suggested instead "If an argument list does *not* end with *expr or
**expr, a trailing comma may be added without affecting the
semantics."

Perhaps I should have said Grammar, as in the Grammar/Grammar file in
the source distribution.

FWIW, *I'd* rather see *that* tweaked so the documentation became
correct. But really, there are more important fish to fry (and
metaphors to mix :).

Cheers,
mwh
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top