4 ms·
If I have the following code: @auth_required def some_view(): pass And later I decide to change that decorator to be parameterized: @auth
by MostAwesomeDude 15y ago
If I have the following code:
@auth_required
def some_view():
pass
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.
- the_mitsuhiko 15y ago> 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 :)
- d0m 15y agoYou may also use a simple wrapper to create decorators which would automatically define @decorator and @decorator().
- the_mitsuhiko 15y agoI could also aim with a bazooka at my foot. Been there done that, lesson learned :-)
- andrewflnr 15y agoApparently 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.