The way decorators are parsng
![](https://secure.gravatar.com/avatar/5e5142d6a1a578f02e2d94c4d6d31088.jpg?s=120&d=mm&r=g)
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:
Cheers Tarek -- Tarek Ziadé | http://ziade.org
![](https://secure.gravatar.com/avatar/d922aaa11ce4526c34b33b3fd02af9dd.jpg?s=120&d=mm&r=g)
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
![](https://secure.gravatar.com/avatar/dd4761743695d5efd3692f2a3b35d37d.jpg?s=120&d=mm&r=g)
On Wed, Oct 19, 2011 at 3:43 PM, Chris Rebert <pyideas@rebertia.com> wrote:
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
![](https://secure.gravatar.com/avatar/5e5142d6a1a578f02e2d94c4d6d31088.jpg?s=120&d=mm&r=g)
On Wed, Oct 19, 2011 at 11:43 PM, Chris Rebert <pyideas@rebertia.com> wrote:
Thanks for the pointers
-- Tarek Ziadé | http://ziade.org
![](https://secure.gravatar.com/avatar/f3ba3ecffd20251d73749afbfa636786.jpg?s=120&d=mm&r=g)
On Thu, Oct 20, 2011 at 7:52 AM, Tarek Ziadé <ziade.tarek@gmail.com> wrote:
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
![](https://secure.gravatar.com/avatar/047f2332cde3730f1ed661eebb0c5686.jpg?s=120&d=mm&r=g)
On Wed, Oct 19, 2011 at 3:36 PM, Nick Coghlan <ncoghlan@gmail.com> wrote:
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)
![](https://secure.gravatar.com/avatar/f3ba3ecffd20251d73749afbfa636786.jpg?s=120&d=mm&r=g)
2011/10/20 Guido van Rossum <guido@python.org>:
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
![](https://secure.gravatar.com/avatar/047f2332cde3730f1ed661eebb0c5686.jpg?s=120&d=mm&r=g)
2011/10/19 Nick Coghlan <ncoghlan@gmail.com>:
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)
![](https://secure.gravatar.com/avatar/d922aaa11ce4526c34b33b3fd02af9dd.jpg?s=120&d=mm&r=g)
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
![](https://secure.gravatar.com/avatar/dd4761743695d5efd3692f2a3b35d37d.jpg?s=120&d=mm&r=g)
On Wed, Oct 19, 2011 at 3:43 PM, Chris Rebert <pyideas@rebertia.com> wrote:
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
![](https://secure.gravatar.com/avatar/5e5142d6a1a578f02e2d94c4d6d31088.jpg?s=120&d=mm&r=g)
On Wed, Oct 19, 2011 at 11:43 PM, Chris Rebert <pyideas@rebertia.com> wrote:
Thanks for the pointers
-- Tarek Ziadé | http://ziade.org
![](https://secure.gravatar.com/avatar/f3ba3ecffd20251d73749afbfa636786.jpg?s=120&d=mm&r=g)
On Thu, Oct 20, 2011 at 7:52 AM, Tarek Ziadé <ziade.tarek@gmail.com> wrote:
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
![](https://secure.gravatar.com/avatar/047f2332cde3730f1ed661eebb0c5686.jpg?s=120&d=mm&r=g)
On Wed, Oct 19, 2011 at 3:36 PM, Nick Coghlan <ncoghlan@gmail.com> wrote:
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)
![](https://secure.gravatar.com/avatar/f3ba3ecffd20251d73749afbfa636786.jpg?s=120&d=mm&r=g)
2011/10/20 Guido van Rossum <guido@python.org>:
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
![](https://secure.gravatar.com/avatar/047f2332cde3730f1ed661eebb0c5686.jpg?s=120&d=mm&r=g)
2011/10/19 Nick Coghlan <ncoghlan@gmail.com>:
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é