From d12d73263f5d1664a65a42f71f19158b7e07ef2c Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Mon, 12 Jul 2010 18:04:10 +0200 Subject: [PATCH] Reverse order of execution of post-request handlers. This fixes #82 --- CHANGES | 3 +++ docs/upgrading.rst | 11 +++++++++++ flask/app.py | 8 ++++++-- tests/flask_tests.py | 24 ++++++++++++++++++++++++ 4 files changed, 44 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 840d1a3d..c09b9e04 100644 --- a/CHANGES +++ b/CHANGES @@ -8,6 +8,9 @@ Version 0.6 Release date to be announced, codename to be decided. +- after request functions are now called in reverse order of + registration. + Version 0.5.1 ------------- diff --git a/docs/upgrading.rst b/docs/upgrading.rst index 7ee35176..f3a7a27d 100644 --- a/docs/upgrading.rst +++ b/docs/upgrading.rst @@ -19,6 +19,17 @@ installation, make sure to pass it the ``-U`` parameter:: $ easy_install -U Flask +Version 0.6 +----------- + +Flask 0.6 comes with a backwards incompatible change which affects the +order of after-request handlers. Previously they were called in the order +of the registration, now they are called in reverse order. This change +was made so that Flask behaves more like people expected it to work and +how other systems handle request pre- and postprocessing. If you +dependend on the order of execution of post-request functions, be sure to +change the order. + Version 0.5 ----------- diff --git a/flask/app.py b/flask/app.py index d16613b7..49852e5e 100644 --- a/flask/app.py +++ b/flask/app.py @@ -707,6 +707,10 @@ class Flask(_PackageBoundObject): before it's sent to the WSGI server. By default this will call all the :meth:`after_request` decorated functions. + .. versionchanged:: 0.5 + As of Flask 0.5 the functions registered for after request + execution are called in reverse order of registration. + :param response: a :attr:`response_class` object. :return: a new response object or the same, has to be an instance of :attr:`response_class`. @@ -717,9 +721,9 @@ class Flask(_PackageBoundObject): self.save_session(ctx.session, response) funcs = () if mod and mod in self.after_request_funcs: - funcs = chain(funcs, self.after_request_funcs[mod]) + funcs = reversed(self.after_request_funcs[mod]) if None in self.after_request_funcs: - funcs = chain(funcs, self.after_request_funcs[None]) + funcs = chain(funcs, reversed(self.after_request_funcs[None])) for handler in funcs: response = handler(response) return response diff --git a/tests/flask_tests.py b/tests/flask_tests.py index 5b4f34ef..380ecdad 100644 --- a/tests/flask_tests.py +++ b/tests/flask_tests.py @@ -318,6 +318,30 @@ class BasicFunctionalityTestCase(unittest.TestCase): assert 'Internal Server Error' in rv.data assert len(called) == 1 + def test_before_after_request_order(self): + called = [] + app = flask.Flask(__name__) + @app.before_request + def before1(): + called.append(1) + @app.before_request + def before2(): + called.append(2) + @app.after_request + def after1(response): + called.append(4) + return response + @app.after_request + def after1(response): + called.append(3) + return response + @app.route('/') + def index(): + return '42' + rv = app.test_client().get('/') + assert rv.data == '42' + assert called == [1, 2, 3, 4] + def test_error_handling(self): app = flask.Flask(__name__) @app.errorhandler(404)