From 709289037ae149444b18a59975cf9dc6e93cd05a Mon Sep 17 00:00:00 2001 From: Augustus D'Souza Date: Sat, 18 Oct 2014 13:14:04 +0530 Subject: [PATCH 01/11] Corrected api docs http://flask.pocoo.org/docs/0.10/api/#flask.Request.get_json --- flask/wrappers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flask/wrappers.py b/flask/wrappers.py index e77b9c20..038ba6fc 100644 --- a/flask/wrappers.py +++ b/flask/wrappers.py @@ -115,8 +115,8 @@ class Request(RequestBase): but this can be overriden by the `force` parameter. :param force: if set to `True` the mimetype is ignored. - :param silent: if set to `False` this method will fail silently - and return `False`. + :param silent: if set to `True` this method will fail silently + and return `None`. :param cache: if set to `True` the parsed JSON data is remembered on the request. """ From c60b5b91e282ce4984fef7cede1a058e66c420df Mon Sep 17 00:00:00 2001 From: Philip House Date: Sun, 1 Feb 2015 15:53:35 -0600 Subject: [PATCH 02/11] Update api.rst, fixed spelling --- docs/api.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api.rst b/docs/api.rst index 48bb001e..272b193a 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -350,7 +350,7 @@ JSON Support Flask uses ``simplejson`` for the JSON implementation. Since simplejson is provided both by the standard library as well as extension Flask will try simplejson first and then fall back to the stdlib json module. On top -of that it will delegate access to the current application's JSOn encoders +of that it will delegate access to the current application's JSON encoders and decoders for easier customization. So for starters instead of doing:: From 5dfe918e4fafd63fc77664a3a1cda501bb0929f9 Mon Sep 17 00:00:00 2001 From: Zev Averbach Date: Fri, 26 Jun 2015 08:41:56 -0400 Subject: [PATCH 03/11] fixed some punctuation, fixed a few errors, in service of readability --- docs/patterns/wtforms.rst | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/patterns/wtforms.rst b/docs/patterns/wtforms.rst index 38e652e8..88602b6c 100644 --- a/docs/patterns/wtforms.rst +++ b/docs/patterns/wtforms.rst @@ -1,7 +1,7 @@ Form Validation with WTForms ============================ -When you have to work with form data submitted by a browser view code +When you have to work with form data submitted by a browser view, code quickly becomes very hard to read. There are libraries out there designed to make this process easier to manage. One of them is `WTForms`_ which we will handle here. If you find yourself in the situation of having many @@ -12,10 +12,10 @@ first. I recommend breaking up the application into multiple modules (:ref:`larger-applications`) for that and adding a separate module for the forms. -.. admonition:: Getting most of WTForms with an Extension +.. admonition:: Getting the most out of WTForms with an Extension - The `Flask-WTF`_ extension expands on this pattern and adds a few - handful little helpers that make working with forms and Flask more + The `Flask-WTF`_ extension expands on this pattern and adds a + few little helpers that make working with forms and Flask more fun. You can get it from `PyPI `_. @@ -54,8 +54,8 @@ In the view function, the usage of this form looks like this:: return redirect(url_for('login')) return render_template('register.html', form=form) -Notice that we are implying that the view is using SQLAlchemy here -(:ref:`sqlalchemy-pattern`) but this is no requirement of course. Adapt +Notice we're implying that the view is using SQLAlchemy here +(:ref:`sqlalchemy-pattern`), but that's not a requirement, of course. Adapt the code as necessary. Things to remember: @@ -64,14 +64,14 @@ Things to remember: the data is submitted via the HTTP ``POST`` method and :attr:`~flask.request.args` if the data is submitted as ``GET``. 2. to validate the data, call the :func:`~wtforms.form.Form.validate` - method which will return ``True`` if the data validates, ``False`` + method, which will return ``True`` if the data validates, ``False`` otherwise. 3. to access individual values from the form, access `form..data`. Forms in Templates ------------------ -Now to the template side. When you pass the form to the templates you can +Now to the template side. When you pass the form to the templates, you can easily render them there. Look at the following example template to see how easy this is. WTForms does half the form generation for us already. To make it even nicer, we can write a macro that renders a field with @@ -95,14 +95,14 @@ Here's an example :file:`_formhelpers.html` template with such a macro: {% endmacro %} This macro accepts a couple of keyword arguments that are forwarded to -WTForm's field function that renders the field for us. The keyword -arguments will be inserted as HTML attributes. So for example you can +WTForm's field function, which renders the field for us. The keyword +arguments will be inserted as HTML attributes. So, for example, you can call ``render_field(form.username, class='username')`` to add a class to the input element. Note that WTForms returns standard Python unicode -strings, so we have to tell Jinja2 that this data is already HTML escaped +strings, so we have to tell Jinja2 that this data is already HTML-escaped with the ``|safe`` filter. -Here the :file:`register.html` template for the function we used above which +Here is the :file:`register.html` template for the function we used above, which takes advantage of the :file:`_formhelpers.html` template: .. sourcecode:: html+jinja From 8ba986e45e5b8f73f3f18da9d145b06722e5ceca Mon Sep 17 00:00:00 2001 From: Aayush Kasurde Date: Sun, 12 Jul 2015 21:08:16 +0530 Subject: [PATCH 04/11] Added fix for issue 1529 Signed-off-by: Aayush Kasurde --- examples/jqueryexample/jqueryexample.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/examples/jqueryexample/jqueryexample.py b/examples/jqueryexample/jqueryexample.py index d1fca62b..39b81951 100644 --- a/examples/jqueryexample/jqueryexample.py +++ b/examples/jqueryexample/jqueryexample.py @@ -23,3 +23,6 @@ def add_numbers(): @app.route('/') def index(): return render_template('index.html') + +if __name__ == '__main__': + app.run() From 05c2e7c276ba14c8e8abce4dbb86e0d35c5268ba Mon Sep 17 00:00:00 2001 From: Wayne Ye Date: Tue, 14 Jul 2015 12:36:01 -0700 Subject: [PATCH 05/11] Fixed gevent introduction to use libev instead of libevent --- docs/deploying/wsgi-standalone.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/deploying/wsgi-standalone.rst b/docs/deploying/wsgi-standalone.rst index 5bdd0483..bd7b1006 100644 --- a/docs/deploying/wsgi-standalone.rst +++ b/docs/deploying/wsgi-standalone.rst @@ -31,7 +31,7 @@ Gevent ------- `Gevent`_ is a coroutine-based Python networking library that uses -`greenlet`_ to provide a high-level synchronous API on top of `libevent`_ +`greenlet`_ to provide a high-level synchronous API on top of `libev`_ event loop:: from gevent.wsgi import WSGIServer @@ -42,7 +42,7 @@ event loop:: .. _Gevent: http://www.gevent.org/ .. _greenlet: http://greenlet.readthedocs.org/en/latest/ -.. _libevent: http://libevent.org/ +.. _libev: http://software.schmorp.de/pkg/libev.html Twisted Web ----------- From 93fe1d54bd44b190aa0f58990bc397bf22324452 Mon Sep 17 00:00:00 2001 From: Christian Becker Date: Thu, 16 Jul 2015 02:45:56 +0200 Subject: [PATCH 06/11] make external_url_handler example py3 compliant - a raises statement with multiple values is no longer allowed in python 3 --- flask/helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flask/helpers.py b/flask/helpers.py index 861b21ab..ad7b1507 100644 --- a/flask/helpers.py +++ b/flask/helpers.py @@ -219,7 +219,7 @@ def url_for(endpoint, **values): # Re-raise the BuildError, in context of original traceback. exc_type, exc_value, tb = sys.exc_info() if exc_value is error: - raise exc_type, exc_value, tb + raise exc_type(exc_value, endpoint, values).with_traceback(tb) else: raise error # url_for will use this result, instead of raising BuildError. From 5da31f8af36012a4f76c3bd0d536ae107e0519b5 Mon Sep 17 00:00:00 2001 From: Christian Becker Date: Wed, 15 Jul 2015 01:20:39 +0200 Subject: [PATCH 07/11] fix UnboundLocalError in handle_url_build_error - caused by changes in the execution model of python 3 where the alias of an except clause is cleared on exit of the except --- flask/app.py | 5 +++-- flask/testsuite/basic.py | 11 +++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/flask/app.py b/flask/app.py index cc3fc1d9..e073798a 100644 --- a/flask/app.py +++ b/flask/app.py @@ -1631,8 +1631,9 @@ class Flask(_PackageBoundObject): rv = handler(error, endpoint, values) if rv is not None: return rv - except BuildError as error: - pass + except BuildError as e: + # make error available outside except block (py3) + error = e # At this point we want to reraise the exception. If the error is # still the same one we can reraise it with the original traceback, diff --git a/flask/testsuite/basic.py b/flask/testsuite/basic.py index 31fade13..803a008c 100644 --- a/flask/testsuite/basic.py +++ b/flask/testsuite/basic.py @@ -772,6 +772,17 @@ class BasicFunctionalityTestCase(FlaskTestCase): with app.test_request_context(): self.assert_equal(flask.url_for('spam'), '/test_handler/') + def test_build_error_handler_reraise(self): + app = flask.Flask(__name__) + + # Test a custom handler which reraises the BuildError + def handler_raises_build_error(error, endpoint, values): + raise error + app.url_build_error_handlers.append(handler_raises_build_error) + + with app.test_request_context(): + self.assertRaises(BuildError, flask.url_for, 'not.existing') + def test_custom_converters(self): from werkzeug.routing import BaseConverter class ListConverter(BaseConverter): From 765f851a7c880fc654eada6aefb4ce7aa5b14525 Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Thu, 16 Jul 2015 12:01:25 +0200 Subject: [PATCH 08/11] Changelog for #1533 --- CHANGES | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES b/CHANGES index a67937ff..89de874f 100644 --- a/CHANGES +++ b/CHANGES @@ -23,6 +23,8 @@ Version 0.10.2 - Changed logic of before first request handlers to flip the flag after invoking. This will allow some uses that are potentially dangerous but should probably be permitted. +- Fixed Python 3 bug when a handler from `app.url_build_error_handlers` + reraises the `BuildError`. Version 0.10.1 -------------- From 128bc76af0f6c16ba71b41851be800ccdf354752 Mon Sep 17 00:00:00 2001 From: lobeck Date: Thu, 16 Jul 2015 13:53:59 +0200 Subject: [PATCH 09/11] Revert "make external_url_handler example py3 compliant" --- flask/helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flask/helpers.py b/flask/helpers.py index ad7b1507..861b21ab 100644 --- a/flask/helpers.py +++ b/flask/helpers.py @@ -219,7 +219,7 @@ def url_for(endpoint, **values): # Re-raise the BuildError, in context of original traceback. exc_type, exc_value, tb = sys.exc_info() if exc_value is error: - raise exc_type(exc_value, endpoint, values).with_traceback(tb) + raise exc_type, exc_value, tb else: raise error # url_for will use this result, instead of raising BuildError. From c8f19f0afc8d49a68ec969097e6127d17706b6dc Mon Sep 17 00:00:00 2001 From: "Mathias J. Hennig" Date: Wed, 22 Jul 2015 23:35:13 +0200 Subject: [PATCH 10/11] Reimplement function with_metaclass() --- flask/_compat.py | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/flask/_compat.py b/flask/_compat.py index 8ea7719f..fbbf914f 100644 --- a/flask/_compat.py +++ b/flask/_compat.py @@ -56,21 +56,13 @@ else: def with_metaclass(meta, *bases): # This requires a bit of explanation: the basic idea is to make a # dummy metaclass for one level of class instantiation that replaces - # itself with the actual metaclass. Because of internal type checks - # we also need to make sure that we downgrade the custom metaclass - # for one level to something closer to type (that's why __call__ and - # __init__ comes back from type etc.). + # itself with the actual metaclass. # # This has the advantage over six.with_metaclass in that it does not # introduce dummy classes into the final MRO. - class metaclass(meta): - __call__ = type.__call__ - __init__ = type.__init__ - def __new__(cls, name, this_bases, d): - if this_bases is None: - return type.__new__(cls, name, (), d) - return meta(name, bases, d) - return metaclass('temporary_class', None, {}) + constructor = lambda c, name, b, dct: meta(name, bases, dct) + metaclass = type('with_metaclass', (type,), {'__new__': constructor}) + return type.__new__(metaclass, 'temporary_class', (object,), {}) # Certain versions of pypy have a bug where clearing the exception stack From b3767ae59f8d916333ebc2cc04d962fa33f76580 Mon Sep 17 00:00:00 2001 From: "Mathias J. Hennig" Date: Mon, 27 Jul 2015 15:32:23 +0200 Subject: [PATCH 11/11] Addressing feedback from pull request --- flask/_compat.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/flask/_compat.py b/flask/_compat.py index fbbf914f..bfe607d6 100644 --- a/flask/_compat.py +++ b/flask/_compat.py @@ -54,15 +54,14 @@ else: def with_metaclass(meta, *bases): + """Create a base class with a metaclass.""" # This requires a bit of explanation: the basic idea is to make a # dummy metaclass for one level of class instantiation that replaces # itself with the actual metaclass. - # - # This has the advantage over six.with_metaclass in that it does not - # introduce dummy classes into the final MRO. - constructor = lambda c, name, b, dct: meta(name, bases, dct) - metaclass = type('with_metaclass', (type,), {'__new__': constructor}) - return type.__new__(metaclass, 'temporary_class', (object,), {}) + class metaclass(type): + def __new__(cls, name, this_bases, d): + return meta(name, bases, d) + return type.__new__(metaclass, 'temporary_class', (), {}) # Certain versions of pypy have a bug where clearing the exception stack