[Python-ideas] Decorator syntax restriction

Brett Cannon brett at python.org
Sun Sep 6 22:18:51 CEST 2009


On Sun, Sep 6, 2009 at 09:41, Rob Cliffe<rob.cliffe at btinternet.com> wrote:
> Can I make another plea for the syntax following '@' to be an unrestricted
> expression?  Guido has said he has a 'gut feeling' against this but has not
> as far as I know rationalised it.
>

When it comes to Guido's gut, a rationalization isn't needed. Perk of
being BDFL. Plus his gut is right so often it tends to not be
questioned.

> 1) It is inconsistent with Python in general (unPythonic) to impose
> arbitrary restrictions in one particular place, and hard to explain to
> someone learning the language.
>

It's not difficult to explain; decorators can only be a dotted name w/
an optional method call and its corresponding arguments. It keeps the
syntax simple and clean, IMO. Decorators add a mental overhead of
having to think about what they will do to a function when reading the
code. If I then also have to figure out what an arbitrary expression
evaluates to in order to figure that out that is more mental effort
than needed. Yes, you can do whatever with the decorator you are
passing in, but hopefully you are not so evil/stupid as to make a
decorator that copmlicated. Give people the power of full expressions
and that will happen more often.

> 2) The restriction is in any case more apparent than real,
> as
>     @ <any-expression> # disallowed, SyntaxError
> can be implemented, albeit in a more verbose aka less Pythonic was, as:
>
>     AnyExpr = <any-expression>
>     @AnyExpr
>
> or as
>
>     def Identity(x): return x
>      ...
>     @Identity( <any-expression> ) # smuggle in as func arg
>

And we almost ditched lambdas in Python 3 because you can implement
them in the same way. The only reason they got to stick around was
they were already in use and people threw a fit over them.

> 3) I propose the following as plausible use cases (I know other people will
> have their own):
>
> 3.1)
>     @DecoratorList[index]
>
> 3.2)
>     @DecoratorDictionary[key]
>
> 3.3)
>     @Decorator1 if <condition> else Decorator2
> #   Special case of the last one:
>     def Identity(x): return x
>     @Decorator if __debug__ else Identity
>

Plausible does not equal useful. You need to show that this actually
comes up in normal coding for a decent amount of Python code to
warrant tweaking the language over.

> Xavier Morel has pointed out that 3.1) can be implemented now as
>     @DecoratorList.__getitem__[index]
> but this doesn't seem a good reason for forbidding the simpler syntax; after
> all Python allows the simpler syntax in other contexts.  Similarly 3.2) can
> be written as
>     @DecoratorDictionary.get(key)
>
> (As an aside, perhaps a decorator that evaluates to None could be treated at
> run-time the same as no decorator, i.e. equivalent to the Identity function
> in the above examples.  Currently it naturally raises TypeError: 'NoneType'
> object is not callable.  Just a thought.)

That's not going to happen. =) Complicates the bytecode unnecessarily.
Once again, this needs to actually come up in regular usage to warrant
even considering the change.

>
> Finally, sorry if I have not sent this e-mail to the right place (I wanted
> to attach it to the 'allow lambdas as decorators' thread but don't yet know
> how to do this).  Also sorry that this partly duplicates a message I sent to
> python-dev.  I am still finding my way round the Python mailing lists.

No, this is the place to send thought out proposals for changing
Python before they get promoted to hitting python-dev.

-Brett



More information about the Python-ideas mailing list