How to assure applying order of function decorators in Python?
Question: Some decorators should only be used in the outermost layer.

A decorator that augments the original function and add a configure parameter
is one example.

    
    
    from functools import wraps
    
    def special_case(f):
        @wraps(f)
        def _(a, b, config_x=False):
            if config_x:
               print "Special case here"
               return
            return f(a, b)
    

How can I avoid decorators like this getting decorated by another decorator?

**EDIT**

It is really disgusting to let everyone trying to apply a new decorator worry
about the application order.

So, is it possible to avoid this kind of situation? Is it possible to add a
config option without introducing a new parameter?


Answer: There isn't any way to stop it from being decorated. You just have to document
that it needs to apply last and tell people not to use it inside another
decorator.

Edit responding to your edit: In Python 3 you can give your function a
[keyword-only argument](http://www.python.org/dev/peps/pep-3102/). This
drastically reduces the impact that the change will have on existing uses of
the function. Unfortunately this only works in Python 3.

Ultimately, applying a decorator to a function just means passing the
decorated function as an argument to another function. There's no way for a
function (or any object) to even know _that_ it's being passed as an argument,
let alone what it's being passed to. The reason you can't know about later
decorators is the same reason that in an ordinary function call like
`f(g(x))`, the function `g` can't know that it will later be called by `f`.

This is one reason writing decorators is tricky. Code that relies on heavy use
of decorators that pass explicit arguments to their wrapped functions (as
yours passes `a` and `b`) is inherently going to be fragile. Fortunately, a
lot of the time you can write a decorator that uses `*args` and `**kwargs` so
it can pass all the arguments it doesn't use along to the decorated function.

If someone takes the code you provide, and writes another decorator that
explicitly accepts only `a` and `b` as arguments, and then calls the decorated
function as `f(a, b, True)`, it's their own fault if it fails. They should
have known that other decorators they used might have changed the function
signature.

