[Python-Dev] PEP 318: Decorators last before colon (original) (raw)

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