From b9355a7d5f79cfa06324a72cbaef4b9ec7a299d3 Mon Sep 17 00:00:00 2001 From: Steve Leonard Date: Thu, 4 Apr 2013 06:56:24 -0300 Subject: [PATCH 01/23] Mention register_error_handler in errorhandler doc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The documentation for @errorhandler gives "app.error_handler_spec[None][404] = page_not_found" as an example for adding an error handler without the decorator.  However, register_error_handler appears to be the correct way to do this (added 0.7), and it eliminates the problems with modifying error_handler_spec directly. --- flask/app.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/flask/app.py b/flask/app.py index 373479f5..036903a3 100644 --- a/flask/app.py +++ b/flask/app.py @@ -1065,6 +1065,11 @@ class Flask(_PackageBoundObject): The first `None` refers to the active blueprint. If the error handler should be application wide `None` shall be used. + .. versionadded:: 0.7 + Use :meth:`register_error_handler` instead of modifying + :attr:`error_handler_spec` directly, for application wide error + handlers. + .. versionadded:: 0.7 One can now additionally also register custom exception types that do not necessarily have to be a subclass of the From 63a126c66a047507f634348688dfcf760b14d5ae Mon Sep 17 00:00:00 2001 From: Jamie Grove Date: Sat, 10 Aug 2013 11:35:47 -0400 Subject: [PATCH 02/23] Update blueprints.rst - Error Handlers Added information about custom error handlers in Blueprints with example based simple_page. --- docs/blueprints.rst | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/docs/blueprints.rst b/docs/blueprints.rst index 4e3888c2..8f83e120 100644 --- a/docs/blueprints.rst +++ b/docs/blueprints.rst @@ -202,3 +202,18 @@ you can use relative redirects by prefixing the endpoint with a dot only:: This will link to ``admin.index`` for instance in case the current request was dispatched to any other admin blueprint endpoint. + +Error Handlers +-------------- + +Blueprints support the errorhandler decorator just like the :class:`Flask` +application object, so it is easy to make Blueprint-specific custom error +pages. + +Here is an example for a "404 Page Not Found" exception:: + + @simple_page.errorhandler(404) + def page_not_found(e): + return render_template('pages/404.html') + +More information on error handling see :ref:`errorpages`. From f5d38dc4fcdf1d8edb3e42c67b6e0e1127cd00c7 Mon Sep 17 00:00:00 2001 From: enkore Date: Sat, 17 Aug 2013 21:32:52 +0200 Subject: [PATCH 03/23] Update sessions.py get_cookie_path: fix docstring --- flask/sessions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flask/sessions.py b/flask/sessions.py index d6b7e5ae..cdebe4b0 100644 --- a/flask/sessions.py +++ b/flask/sessions.py @@ -223,7 +223,7 @@ class SessionInterface(object): def get_cookie_path(self, app): """Returns the path for which the cookie should be valid. The - default implementation uses the value from the SESSION_COOKIE_PATH`` + default implementation uses the value from the ``SESSION_COOKIE_PATH`` config var if it's set, and falls back to ``APPLICATION_ROOT`` or uses ``/`` if it's `None`. """ From b03181363bd78ab0934af3badd9b4845e454fbb3 Mon Sep 17 00:00:00 2001 From: Wouter Van Hemel Date: Wed, 4 Sep 2013 12:15:32 +0300 Subject: [PATCH 04/23] Add a non-decorator version of the error handler register function The main application object has a register_error_handler function which mirrors the decorator's functionality. According to the principle of least surprise, make sure blueprints also have this convenience function. --- flask/blueprints.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/flask/blueprints.py b/flask/blueprints.py index d45fd062..2b64c1f9 100644 --- a/flask/blueprints.py +++ b/flask/blueprints.py @@ -399,3 +399,14 @@ class Blueprint(_PackageBoundObject): self.name, code_or_exception, f)) return f return decorator + + def register_error_handler(self, code_or_exception, f): + """Non-decorator version of the :meth:`errorhandler` error attach + function, akin to the :meth:`~flask.Flask.register_error_handler` + application-wide function of the :class:`~flask.Flask` object but + for error handlers limited to this blueprint. + + .. versionadded:: 0.11 + """ + self.record_once(lambda s: s.app._register_error_handler( + self.name, code_or_exception, f)) From 079ae20f24e23ba4ab32faeca88705b247fd3eb2 Mon Sep 17 00:00:00 2001 From: Wouter Van Hemel Date: Fri, 6 Sep 2013 10:43:02 +0300 Subject: [PATCH 05/23] Add tests for user-defined exceptions in blueprints --- flask/testsuite/blueprints.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/flask/testsuite/blueprints.py b/flask/testsuite/blueprints.py index 72cf5182..57abdb6e 100644 --- a/flask/testsuite/blueprints.py +++ b/flask/testsuite/blueprints.py @@ -296,6 +296,39 @@ class BlueprintTestCase(FlaskTestCase): self.assert_equal(c.get('/backend-no').data, b'backend says no') self.assert_equal(c.get('/what-is-a-sideend').data, b'application itself says no') + def test_blueprint_specific_user_error_handling(self): + class MyDecoratorException(Exception): + pass + class MyFunctionException(Exception): + pass + + blue = flask.Blueprint('blue', __name__) + + @blue.errorhandler(MyDecoratorException) + def my_decorator_exception_handler(e): + self.assert_true(isinstance(e, MyDecoratorException)) + return 'boom' + + def my_function_exception_handler(e): + self.assert_true(isinstance(e, MyFunctionException)) + return 'bam' + blue.register_error_handler(MyFunctionException, my_function_exception_handler) + + @blue.route('/decorator') + def blue_deco_test(): + raise MyDecoratorException() + @blue.route('/function') + def blue_func_test(): + raise MyFunctionException() + + app = flask.Flask(__name__) + app.register_blueprint(blue) + + c = app.test_client() + + self.assert_equal(c.get('/decorator').data, b'boom') + self.assert_equal(c.get('/function').data, b'bam') + def test_blueprint_url_definitions(self): bp = flask.Blueprint('test', __name__) From cff35237efea11c4bbc8c2fc75e24cbea30b26ce Mon Sep 17 00:00:00 2001 From: Michael Bikovitsky Date: Sat, 7 Sep 2013 18:21:15 +0300 Subject: [PATCH 06/23] Fix test_no_error_swallowing Path in assertion is now cross-platform. --- flask/testsuite/ext.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/flask/testsuite/ext.py b/flask/testsuite/ext.py index 5cc3df43..7bdf6886 100644 --- a/flask/testsuite/ext.py +++ b/flask/testsuite/ext.py @@ -125,7 +125,9 @@ class ExtImportHookTestCase(FlaskTestCase): next = tb.tb_next.tb_next if not PY2: next = next.tb_next - self.assert_in('flask_broken/__init__.py', next.tb_frame.f_code.co_filename) + + import os.path + self.assert_in(os.path.join('flask_broken', '__init__.py'), next.tb_frame.f_code.co_filename) def suite(): From b7337080e48990393cf960890504710bc7cbc136 Mon Sep 17 00:00:00 2001 From: Michael Bikovitsky Date: Sat, 7 Sep 2013 18:29:49 +0300 Subject: [PATCH 07/23] Fix test_send_file_object static/index.html now opens in binary mode, and therefore newline conversion does not take place. --- flask/testsuite/helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flask/testsuite/helpers.py b/flask/testsuite/helpers.py index 7de70c0a..4bb43ac2 100644 --- a/flask/testsuite/helpers.py +++ b/flask/testsuite/helpers.py @@ -260,7 +260,7 @@ class SendfileTestCase(FlaskTestCase): app = flask.Flask(__name__) with catch_warnings() as captured: with app.test_request_context(): - f = open(os.path.join(app.root_path, 'static/index.html')) + f = open(os.path.join(app.root_path, 'static/index.html'), mode='rb') rv = flask.send_file(f) rv.direct_passthrough = False with app.open_resource('static/index.html') as f: From bb882454a0c7b161a2ac29126a74b25dc8e12940 Mon Sep 17 00:00:00 2001 From: Oliver Beattie Date: Mon, 9 Sep 2013 15:13:42 +0100 Subject: [PATCH 08/23] Make the decorators attribute on View a tuple by default To discourage accidental runtime modification applying to all views. --- flask/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flask/views.py b/flask/views.py index b3b61b52..f4422ff4 100644 --- a/flask/views.py +++ b/flask/views.py @@ -60,7 +60,7 @@ class View(object): #: view function is created the result is automatically decorated. #: #: .. versionadded:: 0.8 - decorators = [] + decorators = () def dispatch_request(self): """Subclasses have to override this method to implement the From 8089eb576915e71e3238147631bb4a261b3366f6 Mon Sep 17 00:00:00 2001 From: Christopher Su Date: Thu, 19 Sep 2013 23:31:09 -0700 Subject: [PATCH 09/23] added missing import in sqlalchemy doc --- docs/patterns/sqlalchemy.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/patterns/sqlalchemy.rst b/docs/patterns/sqlalchemy.rst index 07a762d8..fef9b2e9 100644 --- a/docs/patterns/sqlalchemy.rst +++ b/docs/patterns/sqlalchemy.rst @@ -177,7 +177,7 @@ SQL Abstraction Layer If you just want to use the database system (and SQL) abstraction layer you basically only need the engine:: - from sqlalchemy import create_engine, MetaData + from sqlalchemy import create_engine, MetaData, Table engine = create_engine('sqlite:////tmp/test.db', convert_unicode=True) metadata = MetaData(bind=engine) From 3e485009a8ca606c742c88c92cfd178547b708cd Mon Sep 17 00:00:00 2001 From: defuz Date: Mon, 30 Sep 2013 18:40:35 +0300 Subject: [PATCH 10/23] add TEMPLATES_AUTO_RELOAD option to config --- CHANGES | 4 ++++ docs/config.rst | 9 +++++++++ flask/app.py | 7 +++++++ flask/testsuite/templating.py | 8 ++++++++ 4 files changed, 28 insertions(+) diff --git a/CHANGES b/CHANGES index 8699718c..acba98db 100644 --- a/CHANGES +++ b/CHANGES @@ -15,6 +15,10 @@ Version 1.0 Non permanent sessions are not affected by this and will always expire if the browser window closes. +- Added ``TEMPLATES_AUTO_RELOAD`` config key. If disabled the + templates will be reloaded only if the application is running in + debug mode. For higher performance it’s possible to disable that. + Version 0.10.2 -------------- diff --git a/docs/config.rst b/docs/config.rst index 1bc46afa..55e34786 100644 --- a/docs/config.rst +++ b/docs/config.rst @@ -174,6 +174,12 @@ The following configuration values are used internally by Flask: if they are not requested by an XMLHttpRequest object (controlled by the ``X-Requested-With`` header) +``TEMPLATES_AUTO_RELOAD`` Flask checks if template was modified each + time it is requested and reloads it if + necessary. But disk I/O is costly and it may + be viable to disable this feature by setting + this key to ``False``. This option does not + affect debug mode. ================================= ========================================= .. admonition:: More on ``SERVER_NAME`` @@ -222,6 +228,9 @@ The following configuration values are used internally by Flask: .. versionadded:: 1.0 ``SESSION_REFRESH_EACH_REQUEST`` +.. versionadded:: 1.0 + ``TEMPLATES_AUTO_RELOAD`` + Configuring from Files ---------------------- diff --git a/flask/app.py b/flask/app.py index 1ea82fe7..066de664 100644 --- a/flask/app.py +++ b/flask/app.py @@ -294,6 +294,7 @@ class Flask(_PackageBoundObject): 'JSON_AS_ASCII': True, 'JSON_SORT_KEYS': True, 'JSONIFY_PRETTYPRINT_REGULAR': True, + 'TEMPLATES_AUTO_RELOAD': True, }) #: The rule object to use for URL rules created. This is used by @@ -644,10 +645,16 @@ class Flask(_PackageBoundObject): this function to customize the behavior. .. versionadded:: 0.5 + .. versionchanged:: 1.0 + ``Environment.auto_reload`` set in accordance with + ``TEMPLATES_AUTO_RELOAD`` configuration option. """ options = dict(self.jinja_options) if 'autoescape' not in options: options['autoescape'] = self.select_jinja_autoescape + if 'auto_reload' not in options: + options['auto_reload'] = self.debug \ + or self.config['TEMPLATES_AUTO_RELOAD'] rv = Environment(self, **options) rv.globals.update( url_for=url_for, diff --git a/flask/testsuite/templating.py b/flask/testsuite/templating.py index b2870dea..135612c1 100644 --- a/flask/testsuite/templating.py +++ b/flask/testsuite/templating.py @@ -295,6 +295,14 @@ class TemplatingTestCase(FlaskTestCase): rv = app.test_client().get('/') self.assert_equal(rv.data, b'

Jameson

') + def test_templates_auto_reload(self): + app = flask.Flask(__name__) + self.assert_true(app.config['TEMPLATES_AUTO_RELOAD']) + self.assert_true(app.jinja_env.auto_reload) + app = flask.Flask(__name__) + app.config['TEMPLATES_AUTO_RELOAD'] = False + self.assert_false(app.jinja_env.auto_reload) + def suite(): suite = unittest.TestSuite() From e31a2a80ec4254e8ac8127558bc29cfd23d05511 Mon Sep 17 00:00:00 2001 From: John Hobbs Date: Fri, 11 Oct 2013 17:03:54 -0500 Subject: [PATCH 11/23] Update url_for documentation Previous documentation referenced a non-existent property on the Flask object called "build_error_handler". This should actually reference Flask.url_build_error_handlers. --- flask/helpers.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/flask/helpers.py b/flask/helpers.py index e59f7d3c..2d8f6d11 100644 --- a/flask/helpers.py +++ b/flask/helpers.py @@ -199,16 +199,16 @@ def url_for(endpoint, **values): For more information, head over to the :ref:`Quickstart `. To integrate applications, :class:`Flask` has a hook to intercept URL build - errors through :attr:`Flask.build_error_handler`. The `url_for` function - results in a :exc:`~werkzeug.routing.BuildError` when the current app does - not have a URL for the given endpoint and values. When it does, the - :data:`~flask.current_app` calls its :attr:`~Flask.build_error_handler` if + errors through :attr:`Flask.url_build_error_handlers`. The `url_for` + function results in a :exc:`~werkzeug.routing.BuildError` when the current + app does not have a URL for the given endpoint and values. When it does, the + :data:`~flask.current_app` calls its :attr:`~Flask.url_build_error_handlers` if it is not `None`, which can return a string to use as the result of `url_for` (instead of `url_for`'s default to raise the :exc:`~werkzeug.routing.BuildError` exception) or re-raise the exception. An example:: - def external_url_handler(error, endpoint, **values): + def external_url_handler(error, endpoint, values): "Looks up an external URL when `url_for` cannot build a URL." # This is an example of hooking the build_error_handler. # Here, lookup_url is some utility function you've built @@ -225,10 +225,10 @@ def url_for(endpoint, **values): # url_for will use this result, instead of raising BuildError. return url - app.build_error_handler = external_url_handler + app.url_build_error_handlers.append(external_url_handler) Here, `error` is the instance of :exc:`~werkzeug.routing.BuildError`, and - `endpoint` and `**values` are the arguments passed into `url_for`. Note + `endpoint` and `values` are the arguments passed into `url_for`. Note that this is for building URLs outside the current application, and not for handling 404 NotFound errors. From 1df0f2dc1cc227ba005d402dacfd6ee44b97e637 Mon Sep 17 00:00:00 2001 From: Matt Skone Date: Tue, 15 Oct 2013 09:17:19 -0700 Subject: [PATCH 12/23] Escaped 'text' keyword in column name. --- examples/flaskr/schema.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/flaskr/schema.sql b/examples/flaskr/schema.sql index dbb06319..25b2cadd 100644 --- a/examples/flaskr/schema.sql +++ b/examples/flaskr/schema.sql @@ -2,5 +2,5 @@ drop table if exists entries; create table entries ( id integer primary key autoincrement, title text not null, - text text not null + 'text' text not null ); From 9cecf0d81c58e5d0727d83e4ee11352997546354 Mon Sep 17 00:00:00 2001 From: Christopher Su Date: Tue, 22 Oct 2013 11:37:35 -0700 Subject: [PATCH 13/23] moved Table import to next code block --- docs/patterns/sqlalchemy.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/patterns/sqlalchemy.rst b/docs/patterns/sqlalchemy.rst index fef9b2e9..3c4d9ce9 100644 --- a/docs/patterns/sqlalchemy.rst +++ b/docs/patterns/sqlalchemy.rst @@ -177,7 +177,7 @@ SQL Abstraction Layer If you just want to use the database system (and SQL) abstraction layer you basically only need the engine:: - from sqlalchemy import create_engine, MetaData, Table + from sqlalchemy import create_engine, MetaData engine = create_engine('sqlite:////tmp/test.db', convert_unicode=True) metadata = MetaData(bind=engine) @@ -185,6 +185,8 @@ you basically only need the engine:: Then you can either declare the tables in your code like in the examples above, or automatically load them:: + from sqlalchemy import Table + users = Table('users', metadata, autoload=True) To insert data you can use the `insert` method. We have to get a From a8e88bebd1dff6b982d721c781d87888ef756e4a Mon Sep 17 00:00:00 2001 From: Matt Iversen Date: Tue, 11 Feb 2014 07:24:31 +1100 Subject: [PATCH 14/23] Update windows installation and other notes Making allowance for new convenience of `get-pip.py` that automatically installs setuptools and pip together. Stop recommending distribute, which has now been merged into setuptools. --- docs/installation.rst | 68 ++++++++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 30 deletions(-) diff --git a/docs/installation.rst b/docs/installation.rst index 965e3733..78f192fd 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -3,7 +3,7 @@ Installation ============ -Flask depends on two external libraries, `Werkzeug +Flask depends on some external libraries, like `Werkzeug `_ and `Jinja2 `_. Werkzeug is a toolkit for WSGI, the standard Python interface between web applications and a variety of servers for both development and deployment. @@ -13,7 +13,7 @@ So how do you get all that on your computer quickly? There are many ways you could do that, but the most kick-ass method is virtualenv, so let's have a look at that first. -You will need Python 2.6 or higher to get started, so be sure to have an +You will need Python 2.6 or newer to get started, so be sure to have an up-to-date Python 2.x installation. For using Flask with Python 3 have a look at :ref:`python3-support`. @@ -67,7 +67,7 @@ folder within:: $ cd myproject $ virtualenv venv New python executable in venv/bin/python - Installing distribute............done. + Installing setuptools, pip............done. Now, whenever you want to work on a project, you only have to activate the corresponding environment. On OS X and Linux, do the following:: @@ -113,9 +113,9 @@ Get the git checkout in a new virtualenv and run in development mode:: $ git clone http://github.com/mitsuhiko/flask.git Initialized empty Git repository in ~/dev/flask/.git/ $ cd flask - $ virtualenv venv --distribute + $ virtualenv venv New python executable in venv/bin/python - Installing distribute............done. + Installing setuptools, pip............done. $ . venv/bin/activate $ python setup.py develop ... @@ -129,45 +129,53 @@ To just get the development version without git, do this instead:: $ mkdir flask $ cd flask - $ virtualenv venv --distribute + $ virtualenv venv $ . venv/bin/activate New python executable in venv/bin/python - Installing distribute............done. + Installing setuptools, pip............done. $ pip install Flask==dev ... Finished processing dependencies for Flask==dev .. _windows-easy-install: -`pip` and `distribute` on Windows ------------------------------------ +`pip` and `setuptools` on Windows +--------------------------------- + +Sometimes getting the standard "Python packaging tools" like *pip*, *setuptools* +and *virtualenv* can be a little trickier, but nothing very hard. The two crucial +packages you will need are setuptools and pip - these will let you install +anything else (like virtualenv). Fortunately there are two "bootstrap scripts" +you can run to install either. + +If you don't currently have either, then `get-pip.py` will install both for you +(you won't need to run ez_setup.py). + +`get-pip.py`_ -On Windows, installation of `easy_install` is a little bit trickier, but still -quite easy. The easiest way to do it is to download the -`distribute_setup.py`_ file and run it. The easiest way to run the file is to -open your downloads folder and double-click on the file. +To install the latest setuptools, you can use its bootstrap file: -Next, add the `easy_install` command and other Python scripts to the -command search path, by adding your Python installation's Scripts folder -to the `PATH` environment variable. To do that, right-click on the -"Computer" icon on the Desktop or in the Start menu, and choose "Properties". -Then click on "Advanced System settings" (in Windows XP, click on the -"Advanced" tab instead). Then click on the "Environment variables" button. -Finally, double-click on the "Path" variable in the "System variables" section, -and add the path of your Python interpreter's Scripts folder. Be sure to -delimit it from existing values with a semicolon. Assuming you are using -Python 2.7 on the default path, add the following value:: +`ez_setup.py`_ +Either should be double-clickable once you download them. If you already have pip, +you can upgrade them by running:: - ;C:\Python27\Scripts + > pip install --upgrade pip setuptools -And you are done! To check that it worked, open the Command Prompt and execute -``easy_install``. If you have User Account Control enabled on Windows Vista or -Windows 7, it should prompt you for administrator privileges. +Most often, once you pull up a command prompt you want to be able to type ``pip`` +and ``python`` which will run those things, but this might not automatically happen +on Windows, because it doesn't know where those executables are (give either a try!). -Now that you have ``easy_install``, you can use it to install ``pip``:: +To fix this, you should be able to navigate to your Python install directory +(e.g ``C:\Python27``), then go to ``Tools``, then ``Scripts``; then find the +``win_add2path.py`` file and run that. Open a **new** Command Prompt and +check that you can now just type ``python`` to bring up the interpreter. - > easy_install pip +Finally, to install `virtualenv`_, you can simply run:: + > pip install virtualenv + +Then you can be off on your way following the installation instructions above. -.. _distribute_setup.py: http://python-distribute.org/distribute_setup.py +.. _get-pip.py: https://raw.github.com/pypa/pip/master/contrib/get-pip.py +.. _ez_setup.py: https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py From cb25c42316690860fd928d9ec6fc997eea3f062b Mon Sep 17 00:00:00 2001 From: max demian Date: Sat, 15 Mar 2014 14:35:21 +0100 Subject: [PATCH 15/23] Update json.py --- flask/json.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flask/json.py b/flask/json.py index e83f8b36..bdebf707 100644 --- a/flask/json.py +++ b/flask/json.py @@ -25,7 +25,7 @@ except ImportError: from itsdangerous import json as _json -# figure out if simplejson escapes slashes. This behavior was changed +# Figure out if simplejson escapes slashes. This behavior was changed # from one version to another without reason. _slash_escape = '\\/' not in _json.dumps('/') From f3f7b640b979a3d9f298c25ee42c72e7bb44b479 Mon Sep 17 00:00:00 2001 From: max demian Date: Sat, 15 Mar 2014 14:38:19 +0100 Subject: [PATCH 16/23] Update sessions.py missing backticks in docstring --- flask/sessions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flask/sessions.py b/flask/sessions.py index 598ba4e9..82ba3506 100644 --- a/flask/sessions.py +++ b/flask/sessions.py @@ -223,7 +223,7 @@ class SessionInterface(object): def get_cookie_path(self, app): """Returns the path for which the cookie should be valid. The - default implementation uses the value from the SESSION_COOKIE_PATH`` + default implementation uses the value from the ``SESSION_COOKIE_PATH`` config var if it's set, and falls back to ``APPLICATION_ROOT`` or uses ``/`` if it's `None`. """ From 2eef63a3208ebc5ee69a7feebb57090de3982110 Mon Sep 17 00:00:00 2001 From: max demian Date: Sat, 15 Mar 2014 14:42:21 +0100 Subject: [PATCH 17/23] Update signals.py --- flask/signals.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flask/signals.py b/flask/signals.py index ac71b8ce..e9f7239d 100644 --- a/flask/signals.py +++ b/flask/signals.py @@ -37,12 +37,12 @@ except ImportError: temporarily_connected_to = connected_to = _fail del _fail -# the namespace for code signals. If you are not flask code, do +# The namespace for code signals. If you are not flask code, do # not put signals in here. Create your own namespace instead. _signals = Namespace() -# core signals. For usage examples grep the sourcecode or consult +# Core signals. For usage examples grep the sourcecode or consult # the API documentation in docs/api.rst as well as docs/signals.rst template_rendered = _signals.signal('template-rendered') request_started = _signals.signal('request-started') From 6974d52815da9a1a00b49191b161e3bd12051bac Mon Sep 17 00:00:00 2001 From: max demian Date: Sat, 15 Mar 2014 14:44:27 +0100 Subject: [PATCH 18/23] Update views.py --- flask/views.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/flask/views.py b/flask/views.py index 607cb7a4..39642028 100644 --- a/flask/views.py +++ b/flask/views.py @@ -89,7 +89,7 @@ class View(object): for decorator in cls.decorators: view = decorator(view) - # we attach the view class to the view function for two reasons: + # We attach the view class to the view function for two reasons: # first of all it allows us to easily figure out what class-based # view this thing came from, secondly it's also used for instantiating # the view class so you can actually replace it with something else @@ -111,7 +111,7 @@ class MethodViewType(type): for key in d: if key in http_method_funcs: methods.add(key.upper()) - # if we have no method at all in there we don't want to + # If we have no method at all in there we don't want to # add a method list. (This is for instance the case for # the baseclass or another subclass of a base method view # that does not introduce new methods). @@ -141,8 +141,8 @@ class MethodView(with_metaclass(MethodViewType, View)): """ def dispatch_request(self, *args, **kwargs): meth = getattr(self, request.method.lower(), None) - # if the request method is HEAD and we don't have a handler for it - # retry with GET + # If the request method is HEAD and we don't have a handler for it + # retry with GET. if meth is None and request.method == 'HEAD': meth = getattr(self, 'get', None) assert meth is not None, 'Unimplemented method %r' % request.method From db12a8f5e4285cda4e7440b6a4c015632cb2b345 Mon Sep 17 00:00:00 2001 From: max demian Date: Sat, 15 Mar 2014 14:45:37 +0100 Subject: [PATCH 19/23] Update wrappers.py --- flask/wrappers.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/flask/wrappers.py b/flask/wrappers.py index 1d6fbef5..528e94f5 100644 --- a/flask/wrappers.py +++ b/flask/wrappers.py @@ -40,25 +40,25 @@ class Request(RequestBase): specific ones. """ - #: the internal URL rule that matched the request. This can be + #: The internal URL rule that matched the request. This can be #: useful to inspect which methods are allowed for the URL from #: a before/after handler (``request.url_rule.methods``) etc. #: #: .. versionadded:: 0.6 url_rule = None - #: a dict of view arguments that matched the request. If an exception + #: A dict of view arguments that matched the request. If an exception #: happened when matching, this will be `None`. view_args = None - #: if matching the URL failed, this is the exception that will be + #: If matching the URL failed, this is the exception that will be #: raised / was raised as part of the request handling. This is #: usually a :exc:`~werkzeug.exceptions.NotFound` exception or #: something similar. routing_exception = None - # switched by the request context until 1.0 to opt in deprecated - # module functionality + # Switched by the request context until 1.0 to opt in deprecated + # module functionality. _is_old_module = False @property @@ -179,7 +179,7 @@ class Request(RequestBase): def _load_form_data(self): RequestBase._load_form_data(self) - # in debug mode we're replacing the files multidict with an ad-hoc + # In debug mode we're replacing the files multidict with an ad-hoc # subclass that raises a different error for key errors. ctx = _request_ctx_stack.top if ctx is not None and ctx.app.debug and \ From 8cd66bf178cc72f5718f4113db9426723fe37ef5 Mon Sep 17 00:00:00 2001 From: Kyle Stevenson Date: Wed, 19 Mar 2014 10:23:17 -0700 Subject: [PATCH 20/23] Small punctuation change in unicode doc Just makes it easier on the eyes/brain. --- docs/unicode.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/unicode.rst b/docs/unicode.rst index 413ea84d..5aa6e25d 100644 --- a/docs/unicode.rst +++ b/docs/unicode.rst @@ -1,7 +1,7 @@ Unicode in Flask ================ -Flask like Jinja2 and Werkzeug is totally Unicode based when it comes to +Flask, like Jinja2 and Werkzeug, is totally Unicode based when it comes to text. Not only these libraries, also the majority of web related Python libraries that deal with text. If you don't know Unicode so far, you should probably read `The Absolute Minimum Every Software Developer From 2aa26fff04a98f2435e8e3015e92ef6108d3b485 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Fri, 21 Mar 2014 17:12:26 -0400 Subject: [PATCH 21/23] Revert "Merge pull request #859 from wvh/register_error_handler" This reverts commit 6347e75deea2eda444c60080fda3885c1fb7705d, reversing changes made to 3fd40e83e5df4dbde8531a76c42d26bf76674e95. --- flask/blueprints.py | 11 ----------- flask/testsuite/blueprints.py | 33 --------------------------------- 2 files changed, 44 deletions(-) diff --git a/flask/blueprints.py b/flask/blueprints.py index 4abc0ffa..45faf2c5 100644 --- a/flask/blueprints.py +++ b/flask/blueprints.py @@ -399,14 +399,3 @@ class Blueprint(_PackageBoundObject): self.name, code_or_exception, f)) return f return decorator - - def register_error_handler(self, code_or_exception, f): - """Non-decorator version of the :meth:`errorhandler` error attach - function, akin to the :meth:`~flask.Flask.register_error_handler` - application-wide function of the :class:`~flask.Flask` object but - for error handlers limited to this blueprint. - - .. versionadded:: 0.11 - """ - self.record_once(lambda s: s.app._register_error_handler( - self.name, code_or_exception, f)) diff --git a/flask/testsuite/blueprints.py b/flask/testsuite/blueprints.py index 8b3e530c..8a0e5a79 100644 --- a/flask/testsuite/blueprints.py +++ b/flask/testsuite/blueprints.py @@ -296,39 +296,6 @@ class BlueprintTestCase(FlaskTestCase): self.assert_equal(c.get('/backend-no').data, b'backend says no') self.assert_equal(c.get('/what-is-a-sideend').data, b'application itself says no') - def test_blueprint_specific_user_error_handling(self): - class MyDecoratorException(Exception): - pass - class MyFunctionException(Exception): - pass - - blue = flask.Blueprint('blue', __name__) - - @blue.errorhandler(MyDecoratorException) - def my_decorator_exception_handler(e): - self.assert_true(isinstance(e, MyDecoratorException)) - return 'boom' - - def my_function_exception_handler(e): - self.assert_true(isinstance(e, MyFunctionException)) - return 'bam' - blue.register_error_handler(MyFunctionException, my_function_exception_handler) - - @blue.route('/decorator') - def blue_deco_test(): - raise MyDecoratorException() - @blue.route('/function') - def blue_func_test(): - raise MyFunctionException() - - app = flask.Flask(__name__) - app.register_blueprint(blue) - - c = app.test_client() - - self.assert_equal(c.get('/decorator').data, b'boom') - self.assert_equal(c.get('/function').data, b'bam') - def test_blueprint_url_definitions(self): bp = flask.Blueprint('test', __name__) From d4fec1454488687b574c545761c2869d3bb97ca6 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Fri, 21 Mar 2014 17:15:31 -0400 Subject: [PATCH 22/23] Revert "Revert "Merge pull request #859 from wvh/register_error_handler"" This reverts commit 2aa26fff04a98f2435e8e3015e92ef6108d3b485. --- flask/blueprints.py | 11 +++++++++++ flask/testsuite/blueprints.py | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/flask/blueprints.py b/flask/blueprints.py index 45faf2c5..4abc0ffa 100644 --- a/flask/blueprints.py +++ b/flask/blueprints.py @@ -399,3 +399,14 @@ class Blueprint(_PackageBoundObject): self.name, code_or_exception, f)) return f return decorator + + def register_error_handler(self, code_or_exception, f): + """Non-decorator version of the :meth:`errorhandler` error attach + function, akin to the :meth:`~flask.Flask.register_error_handler` + application-wide function of the :class:`~flask.Flask` object but + for error handlers limited to this blueprint. + + .. versionadded:: 0.11 + """ + self.record_once(lambda s: s.app._register_error_handler( + self.name, code_or_exception, f)) diff --git a/flask/testsuite/blueprints.py b/flask/testsuite/blueprints.py index 8a0e5a79..8b3e530c 100644 --- a/flask/testsuite/blueprints.py +++ b/flask/testsuite/blueprints.py @@ -296,6 +296,39 @@ class BlueprintTestCase(FlaskTestCase): self.assert_equal(c.get('/backend-no').data, b'backend says no') self.assert_equal(c.get('/what-is-a-sideend').data, b'application itself says no') + def test_blueprint_specific_user_error_handling(self): + class MyDecoratorException(Exception): + pass + class MyFunctionException(Exception): + pass + + blue = flask.Blueprint('blue', __name__) + + @blue.errorhandler(MyDecoratorException) + def my_decorator_exception_handler(e): + self.assert_true(isinstance(e, MyDecoratorException)) + return 'boom' + + def my_function_exception_handler(e): + self.assert_true(isinstance(e, MyFunctionException)) + return 'bam' + blue.register_error_handler(MyFunctionException, my_function_exception_handler) + + @blue.route('/decorator') + def blue_deco_test(): + raise MyDecoratorException() + @blue.route('/function') + def blue_func_test(): + raise MyFunctionException() + + app = flask.Flask(__name__) + app.register_blueprint(blue) + + c = app.test_client() + + self.assert_equal(c.get('/decorator').data, b'boom') + self.assert_equal(c.get('/function').data, b'bam') + def test_blueprint_url_definitions(self): bp = flask.Blueprint('test', __name__) From 54688b26a9562c9a9c31541dbf32e0d8ee7a5926 Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Sat, 5 Apr 2014 11:38:28 +0200 Subject: [PATCH 23/23] Fix when release date is not today Also, some fixes for PyFlakes Original commit by @dongweiming at a05c4038706f3a95776adea376bc664c0714b426 --- scripts/make-release.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/make-release.py b/scripts/make-release.py index d6375820..ed933239 100644 --- a/scripts/make-release.py +++ b/scripts/make-release.py @@ -26,7 +26,6 @@ def parse_changelog(): match = re.search('^Version\s+(.*)', line.strip()) if match is None: continue - length = len(match.group(1)) version = match.group(1).strip() if lineiter.next().count('-') != len(match.group(0)): continue @@ -60,6 +59,7 @@ def parse_date(string): def set_filename_version(filename, version_number, pattern): changed = [] + def inject_version(match): before, old, after = match.groups() changed.append(True) @@ -133,7 +133,8 @@ def main(): if version in tags: fail('Version "%s" is already tagged', version) if release_date.date() != date.today(): - fail('Release date is not today (%s != %s)') + fail('Release date is not today (%s != %s)', + release_date.date(), date.today()) if not git_is_clean(): fail('You have uncommitted changes in git')