[Python-Dev] PEP 318: Decorators last before colon
Phillip J. Eby
pje at telecommunity.com
Wed Mar 31 12:32:35 EST 2004
At 04:38 PM 3/30/04 -0800, Guido van Rossum wrote:
> > > > Hm. So if we reversed the order so that the outermost
> > > > decorators (such as classmethod) come first in the list, would
> > > > that sway you to relent in favor of decorators-after-arguments?
> > >
> > >Not really, because they're still hidden behind the argument list.
> >
> > Because:
> >
> > 1) it won't be on the same line if there are lots of arguments
> > 2) nobody will read past the argument list
> > 3) other
> > 4) all of the above
> > 5) none of the above
> >
> > (Not trying to change your opinion; I just think the answer to this should
> > go in the PEP.)
>
>1&2, mostly.
There appears to be a strong correlation between people who have specific
use cases for decorators, and the people who want the last-before-colon
syntax. Whereas, people who have few use cases (or don't like decorators
at all) appear to favor syntaxes that move decorators earlier. Whether
that means the "earlier" syntaxes are better or worse, I don't know. <0.5
wink>
I'll assume your intent is to prevent decorators from biting the unwary --
specifically people who *don't* use decorators a lot and therefore are not
looking for them. I will therefore focus now on the issues with the
"previous line" syntax that may bite people, with an eye to how they might
be fixed.
> > By the way, you didn't mention whether it's okay to put the decorators on
> > the same logical line, e.g.:
> >
> > [classmethod] def foo(bar,baz):
> > # body goes here
> >
> > If the rationale here is that we're copying C#, I'd think that it
> > should be permissible, even though it looks a bit ugly and tempts me
> > to indent the body to align with the function name.
>
>This is much harder to do with the current parser. (My plan would be
>to tie the list expression and the function definition together in the
>code generating phase, just like doc strings.)
Yeah, this is also going to now have to be a special case for documentation
processing tools. Whereas making it part of the definition syntax, it's
more directly available in the parse tree. It also seems to be working
against the AST branch a bit, in that I would expect the decorator
expressions to be part of the function definition node, rather than in an
unrelated statement. And, it's also going to be interesting to document in
the language reference, since the grammar there is going to continue to
diverge from the "real" grammar used by the implementation.
Another issue... is this valid?
[classmethod]
def foo(bar,baz):
pass
How about this?
[classmethod]
# Okay, now we're going to define something...
def foo(bar,baz):
pass
If they *are* valid, then you can have nasty effects at a distance. If
they *aren't* valid, accidentally adding or removing whitespace or comments
can silently change the meaning of the program, and *not* in a DWIMish way.
I personally would rather have the decorators required to be on the same
logical line, and then use:
[classmethod] \
def foo(bar,baz):
pass
for visual separation. The backslash visually alerts that this is *not* a
mere bare list.
I'm not a parser guru by any stretch of the imagination, but wouldn't it be
possible to simply create a statement-level construct that was something like:
liststmt: '[' [listmaker] ']' ( funcdef | restofliststmt )
and put it where it matches sooner than the expression-based versions of
the statement? It seems like the main complexity would be the possibility
of having to duplicate a number of levels of containing rules for
'restofliststmt'. But maybe I'm completely off base here and there's no
sensible way to define a correct 'restofliststmt'.
More information about the Python-Dev
mailing list