title: Flask: why app.route() decorator, should always be the outermost?
body: <p>Say, I have a hand-crafted <code>@login-required</code> decorator:</p>
  
  <pre><code>from functools import wraps
  
  def login_required(decorated_function):
      """Decorator to check if user is logged in."""
  
          @wraps(decorated_function)
          def wrapper(*args, **kwargs):
          if False: # just to check it's working
              return decorated_function(*args, **kwargs)
          else:
              flash('You need to login, to access this page')
              return redirect(url_for('login'))
      return wrapper 
  </code></pre>
  
  <p>and a function, decorated with <code>@app.route()</code> and <code>@login_required</code> (<em>endpoint for <code>login</code> omitted for brevity</em>):</p>
  
  <pre><code>@app.route('/')
  @login_required
  def index():
      return "Hello!"
  </code></pre>
  
  <p>Now, if I try to access <code>/</code>, as expected, it won't let me and will redirect to the login page.
  <br />
  Though, if I swipe the the order of the decorators i.e.:</p>
  
  <pre><code>@login_required
  @app.route('/')
  def index():
      return "Hello!"
  </code></pre>
  
  <p>then I am able to access <code>/</code>, even though I shouldn't be.</p>
  
  <p>I am aware that <a href="http://flask.pocoo.org/docs/0.12/patterns/viewdecorators/#login-required-decorator" rel="nofollow noreferrer">Flask documentation on the subject</a> states:</p>
  
  <blockquote>
    <p>When applying further decorators, always remember that the route() decorator is the outermost.</p>
  </blockquote>
  
  <p>I have also seen <a href="https://stackoverflow.com/questions/28575234/login-required-trouble-in-flask-app">other</a> <a href="https://stackoverflow.com/questions/25288773/login-required-decorator-doesnt-work-flask-login-permits-anonymous-users">questions</a> on the same issue. </p>
  
  <hr>
  
  <p>What I'm curious about is not what is the proper way to do it (<em><code>@app.route()</code> decorator must be outermost - got it</em>), but rather why it is working this way (i.e. what is the mechanics behind it).</p>
  
  <p>I took a look at <code>@app.route()</code> <a href="https://github.com/pallets/flask/blob/master/flask/app.py" rel="nofollow noreferrer">source code</a>:</p>
  
  <pre><code>   def route(self, rule, **options):
      def decorator(f):
          endpoint = options.pop('endpoint', None)
          self.add_url_rule(rule, endpoint, f, **options)
          return f
      return decorator
  </code></pre>
  
  <p><a href="https://stackoverflow.com/a/1594484/8554766">This answer</a>, helped me to understand mechanism of decorators, more or less. Though, I have never seen function just returned (without calling it) before, so I did a little experiment myself (which turned out to be workable, of course):</p>
  
  <pre><code>def my_decorator():
      def decorator (function):
          return function
      return decorator
  
  @my_decorator()
  def test():
      print('Hi')
  
  test()
  </code></pre>
  
  <p>So, I would like to understand:</p>
  
  <ul>
  <li>Why order of decorators matter in the exact case above and for <code>@app.route()</code> and other decorators in general (which is the same answer, I guess)? What confuses me, is that <code>@app.route()</code> just adds url rule to the app (i.e. <code>self.add_url_rule(rule, endpoint, f, **options)</code> and returns the function, that's it, so why would order matter?</li>
  <li>Does <code>@app.route()</code> overrides all the decorators above it (how if so)?</li>
  </ul>
  
  <p>I am also <a href="https://stackoverflow.com/a/28204335/8554766">aware</a>, that decorators application order is from bottom to top, though it doesn't make things any clearer, for me. What am I missing?</p>