And later I decide to change that decorator to be parameterized:
@auth_required("basic")
def some_view():
pass
I have now created a massive amount of pain for myself if I decide to define auth_required() such that it defaults its argument to "basic", unless I force people to call it as @auth_required(), because of the differing callable signatures.
Some people feel @auth_required() is ugly. That's all.
Apparently there's something pretty big here I'm not getting. If you add a parameter to auth_required, of course you're causing a huge amount of pain because you're totally changing what auth_required means. It's going from being directly applied to some_view to generating a function that is applied to some_view. If every decorator was automatically called, every decorator would have to return a function. Among other consequences, you wouldn't be able to use property as a decorator.
Even if it's inconvenient, python's behavior here is still not surprising. It's perfectly consistent, and more general than automatically adding parentheses.
> Some people feel @auth_required() is ugly. That's all.
The biggest issue here is backwards compatibility. Nowadays I just make a separate decorator that accepts arguments and keep the old one around unchanged. I learned my lesson :)
Some people feel @auth_required() is ugly. That's all.