The way decorators are parsng
Hello Today I've tried to write a one-liner for a decorator, The decorator is a method in a class. I wanted to do something like this: @Class().decorator() def function(): ... That threw a syntax error to my surprise. But the semantic is correct, since I am currently writing: obj = Class() @obj.decorator() def function(): ... And I can also write dec = Class().decorator @dec() def function(): ... Is there something obvious I am missing, or is there a weird thing in the way decoratirs are parsed ? Demo:
class Some(object): ... def stuff(self, func): ... return func ... s = Some() @s.stuff ... def ok(): ... print 'ok' ... ok() ok s = Some().stuff @s ... def ok(): ... print 'ok' ... ok() ok @Some().stuff File "<stdin>", line 1 @Some().stuff ^ SyntaxError: invalid syntax
Cheers Tarek -- Tarek Ziadé | http://ziade.org
On Wed, Oct 19, 2011 at 2:32 PM, Tarek Ziadé <ziade.tarek@gmail.com> wrote: Hello
Today I've tried to write a one-liner for a decorator, The decorator is a method in a class.
I wanted to do something like this:
@Class().decorator() def function(): ...
That threw a syntax error to my surprise. <snip> Is there something obvious I am missing, or is there a weird thing in the way decoratirs are parsed ?
PEP 318 -- Decorators for Functions and Methods (http://www.python.org/dev/peps/pep-0318/ ): "Current Syntax [...] The decorator statement is limited in what it can accept -- arbitrary expressions will not work. Guido preferred this because of a gut feeling [17]." [17]: http://mail.python.org/pipermail/python-dev/2004-August/046711.html According to Python 2.7's grammar (http://docs.python.org/reference/grammar.html ): decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE dotted_name: NAME ('.' NAME)* So, you're limited to an arbitrarily-long sequence of attribute accesses, followed by an optional call. Cheers, Chris -- http://rebertia.com
On Wed, Oct 19, 2011 at 3:43 PM, Chris Rebert <pyideas@rebertia.com> wrote:
On Wed, Oct 19, 2011 at 2:32 PM, Tarek Ziadé <ziade.tarek@gmail.com> wrote: Hello
Today I've tried to write a one-liner for a decorator, The decorator is a method in a class.
I wanted to do something like this:
@Class().decorator() def function(): ...
That threw a syntax error to my surprise. <snip> Is there something obvious I am missing, or is there a weird thing in the way decoratirs are parsed ?
PEP 318 -- Decorators for Functions and Methods (http://www.python.org/dev/peps/pep-0318/ ): "Current Syntax [...] The decorator statement is limited in what it can accept -- arbitrary expressions will not work. Guido preferred this because of a gut feeling [17]." [17]: http://mail.python.org/pipermail/python-dev/2004-August/046711.html
According to Python 2.7's grammar (http://docs.python.org/reference/grammar.html ): decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE dotted_name: NAME ('.' NAME)*
So, you're limited to an arbitrarily-long sequence of attribute accesses, followed by an optional call.
Interesting. I would have expected at least the following to work: decorator: '@' NAME trailer* NEWLINE trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME Regardless, good to know, even if uncommon. -eric
Cheers, Chris -- http://rebertia.com _______________________________________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas
On Wed, Oct 19, 2011 at 11:43 PM, Chris Rebert <pyideas@rebertia.com> wrote:
<snip>
Is there something obvious I am missing, or is there a weird thing in the way decoratirs are parsed ?
PEP 318 -- Decorators for Functions and Methods (http://www.python.org/dev/peps/pep-0318/ ): "Current Syntax [...] The decorator statement is limited in what it can accept -- arbitrary expressions will not work. Guido preferred this because of a gut feeling [17]." [17]: http://mail.python.org/pipermail/python-dev/2004-August/046711.html
According to Python 2.7's grammar (http://docs.python.org/reference/grammar.html ): decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE dotted_name: NAME ('.' NAME)*
So, you're limited to an arbitrarily-long sequence of attribute accesses, followed by an optional call.
Thanks for the pointers
Cheers, Chris -- http://rebertia.com
-- Tarek Ziadé | http://ziade.org
On Thu, Oct 20, 2011 at 7:52 AM, Tarek Ziadé <ziade.tarek@gmail.com> wrote:
So, you're limited to an arbitrarily-long sequence of attribute accesses, followed by an optional call.
Thanks for the pointers
In the time since, Guido gave his approval to removing the restriction, but nobody has been interested enough to actually implement the change. He was persuaded the restriction was pointless largely due to people using tricks like the following to avoid it: def deco(x): return x @deco(anything[I].like().can.go[here].and_the.compiler.will_not(care)) def f(): pass (There were also legitimate use cases related to looking up decorators via a subscript rather than a function call). Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
On Wed, Oct 19, 2011 at 3:36 PM, Nick Coghlan <ncoghlan@gmail.com> wrote:
On Thu, Oct 20, 2011 at 7:52 AM, Tarek Ziadé <ziade.tarek@gmail.com> wrote:
So, you're limited to an arbitrarily-long sequence of attribute accesses, followed by an optional call.
Thanks for the pointers
In the time since, Guido gave his approval to removing the restriction, but nobody has been interested enough to actually implement the change. He was persuaded the restriction was pointless largely due to people using tricks like the following to avoid it:
def deco(x): return x
@deco(anything[I].like().can.go[here].and_the.compiler.will_not(care)) def f(): pass
(There were also legitimate use cases related to looking up decorators via a subscript rather than a function call).
If this gets changed we won't be able to give a different meaning to e.g. @(...) @[...] @{...} since those will all have to be accepted as valid forms of the syntax @<expr> -- --Guido van Rossum (python.org/~guido)
2011/10/20 Guido van Rossum <guido@python.org>:
If this gets changed we won't be able to give a different meaning to e.g.
@(...) @[...] @{...}
since those will all have to be accepted as valid forms of the syntax
@<expr>
True, although the restriction could just be weakened to "must start with an identifier" rather than eliminated entirely. Since tuples, lists, dictionaries and sets aren't callable, that wouldn't be a noticeable restriction in practice. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
2011/10/19 Nick Coghlan <ncoghlan@gmail.com>:
2011/10/20 Guido van Rossum <guido@python.org>:
If this gets changed we won't be able to give a different meaning to e.g.
@(...) @[...] @{...}
since those will all have to be accepted as valid forms of the syntax
@<expr>
True, although the restriction could just be weakened to "must start with an identifier" rather than eliminated entirely. Since tuples, lists, dictionaries and sets aren't callable, that wouldn't be a noticeable restriction in practice.
But surely someone would manage to come up with a use case for an expression *starting* with one of those, e.g. @[f, g, h][i] or @{a: b, c: d}[x] I don't think it's reasonable to constrain it less than it currently is but more than a general expression. Though I wouldn't allow commas -- there's no way that @f, g def pooh(): ... can make sense. Oh way, it could be a shorthand for @f @g def pooh(): ... :-) -- --Guido van Rossum (python.org/~guido)
participants (5)
-
Chris Rebert
-
Eric Snow
-
Guido van Rossum
-
Nick Coghlan
-
Tarek Ziadé