Merge branch '1.0.x'

This commit is contained in:
David Lord 2019-05-16 12:18:36 -07:00
commit 2236ba980c
No known key found for this signature in database
GPG Key ID: 7A1C87E3F5BC42A8
18 changed files with 76 additions and 60 deletions

View File

@ -9,8 +9,9 @@ Support questions
Please, don't use the issue tracker for this. Use one of the following
resources for questions about your own code:
* The IRC channel ``#pocoo`` on FreeNode.
* The IRC channel ``#python`` on FreeNode for more general questions.
* The ``#get-help`` channel on our Discord chat: https://discord.gg/t6rrQZH
* The IRC channel ``#pocoo`` on FreeNode is linked to Discord, but
Discord is preferred.
* The mailing list flask@python.org for long term discussion or larger issues.
* Ask on `Stack Overflow`_. Search with Google first using:
``site:stackoverflow.com flask {search term, exception message, etc.}``
@ -81,14 +82,26 @@ First time setup
Start coding
~~~~~~~~~~~~
- Create a branch to identify the issue you would like to work on (e.g.
``2287-dry-test-suite``)
- Create a branch to identify the issue you would like to work on. If
you're submitting a bug or documentation fix, branch off of the
latest ".x" branch::
git checkout -b your-branch-name origin/1.0.x
If you're submitting a feature addition or change, branch off of the
"master" branch::
git checkout -b your-branch-name origin/master
- Using your favorite editor, make your changes, `committing as you go`_.
- Try to follow `PEP8`_, but you may ignore the line length limit if following
it would make the code uglier.
- Include tests that cover any code changes you make. Make sure the test fails
without your patch. `Run the tests. <contributing-testsuite_>`_.
- Push your commits to GitHub and `create a pull request`_.
- Push your commits to GitHub and `create a pull request`_ by using::
git push --set-upstream origin your-branch-name
- Celebrate 🎉
.. _committing as you go: https://dont-be-afraid-to-commit.readthedocs.io/en/latest/git/commandlinegit.html#commit-your-changes

View File

@ -75,6 +75,7 @@ Links
* Test status: https://dev.azure.com/pallets/pallets/_build?definitionId=2
* Test coverage: https://codecov.io/gh/pallets/flask
* Official chat: https://discord.gg/t6rrQZH
.. _WSGI: https://wsgi.readthedocs.io
.. _Werkzeug: https://www.palletsprojects.com/p/werkzeug/

View File

@ -726,7 +726,7 @@ requests, make sure the default route only handles ``GET``, as redirects
can't preserve form data. ::
@app.route('/region/', defaults={'id': 1})
@app.route('/region/<id>', methods=['GET', 'POST'])
@app.route('/region/<int:id>', methods=['GET', 'POST'])
def region(id):
pass

View File

@ -49,7 +49,7 @@ Typically, an application context will have the same lifetime as a
request.
See :doc:`/reqcontext` for more information about how the contexts work
and the full lifecycle of a request.
and the full life cycle of a request.
Manually Push a Context

View File

@ -97,6 +97,6 @@ Discuss with the community.
The Flask developers keep the framework accessible to users with codebases big
and small. If you find an obstacle in your way, caused by Flask, don't hesitate
to contact the developers on the mailinglist or IRC channel. The best way for
to contact the developers on the mailing list or IRC channel. The best way for
the Flask and Flask extension developers to improve the tools for larger
applications is getting feedback from users.

View File

@ -246,7 +246,7 @@ was dispatched to any other admin blueprint endpoint.
Error Handlers
--------------
Blueprints support the errorhandler decorator just like the :class:`Flask`
Blueprints support the ``errorhandler`` decorator just like the :class:`Flask`
application object, so it is easy to make Blueprint-specific custom error
pages.
@ -258,14 +258,13 @@ Here is an example for a "404 Page Not Found" exception::
Most errorhandlers will simply work as expected; however, there is a caveat
concerning handlers for 404 and 405 exceptions. These errorhandlers are only
invoked from an appropriate ``raise`` statement or a call to ``abort``
in another of the blueprint's view functions; they are not invoked by,
e.g., an invalid URL access. This is because the blueprint does not
"own" a certain URL space, so the application instance has no way of
knowing which blueprint errorhandler it should run if given an invalid URL.
If you would like to execute different handling strategies for these errors
based on URL prefixes, they may be defined at the application level using
the ``request`` proxy object::
invoked from an appropriate ``raise`` statement or a call to ``abort`` in another
of the blueprint's view functions; they are not invoked by, e.g., an invalid URL
access. This is because the blueprint does not "own" a certain URL space, so
the application instance has no way of knowing which blueprint error handler it
should run if given an invalid URL. If you would like to execute different
handling strategies for these errors based on URL prefixes, they may be defined
at the application level using the ``request`` proxy object::
@app.errorhandler(404)
@app.errorhandler(405)

View File

@ -68,9 +68,9 @@ parts:
The ``create_app`` factory in ``hello`` is called with the string ``'dev'``
as the argument.
If ``FLASK_APP`` is not set, the command will look for a file called
:file:`wsgi.py` or :file:`app.py` and try to detect an application instance or
factory.
If ``FLASK_APP`` is not set, the command will try to import "app" or
"wsgi" (as a ".py" file, or package) and try to detect an application
instance or factory.
Within the given import, the command looks for an application instance named
``app`` or ``application``, then any application instance. If no instance is

View File

@ -9,7 +9,7 @@ toggling the debug mode, setting the secret key, and other such
environment-specific things.
The way Flask is designed usually requires the configuration to be
available when the application starts up. You can hardcode the
available when the application starts up. You can hard code the
configuration in the code, which for many small applications is not
actually that bad, but there are better ways.
@ -437,6 +437,7 @@ methods on the config object as well to load from individual files. For a
complete reference, read the :class:`~flask.Config` object's
documentation.
Configuring from Environment Variables
--------------------------------------
@ -448,15 +449,13 @@ Environment variables can be set on Linux or OS X with the export command in
the shell before starting the server::
$ export SECRET_KEY='5f352379324c22463451387a0aec5d2f'
$ export DEBUG=False
$ export MAIL_ENABLED=false
$ python run-app.py
* Running on http://127.0.0.1:5000/
* Restarting with reloader...
On Windows systems use the `set` builtin instead::
On Windows systems use the ``set`` builtin instead::
> set SECRET_KEY='5f352379324c22463451387a0aec5d2f'
> set DEBUG=False
While this approach is straightforward to use, it is important to remember that
environment variables are strings -- they are not automatically deserialized
@ -464,17 +463,15 @@ into Python types.
Here is an example of a configuration file that uses environment variables::
# Example configuration
import os
ENVIRONMENT_DEBUG = os.environ.get("DEBUG", default=False)
if ENVIRONMENT_DEBUG.lower() in ("f", "false"):
ENVIRONMENT_DEBUG = False
_mail_enabled = os.environ.get("MAIL_ENABLED", default="true")
MAIL_ENABLED = _mail_enabled.lower() in {"1", "t", "true"}
SECRET_KEY = os.environ.get("SECRET_KEY")
DEBUG = ENVIRONMENT_DEBUG
SECRET_KEY = os.environ.get("SECRET_KEY", default=None)
if not SECRET_KEY:
raise ValueError("No secret key set for Flask application")
raise ValueError("No SECRET_KEY set for Flask application")
Notice that any value besides an empty string will be interpreted as a boolean
@ -486,6 +483,7 @@ ability to access the configuration when starting up. There are other methods
on the config object as well to load from individual files. For a complete
reference, read the :class:`~flask.Config` class documentation.
Configuration Best Practices
----------------------------
@ -496,7 +494,7 @@ that experience:
1. Create your application in a function and register blueprints on it.
That way you can create multiple instances of your application with
different configurations attached which makes unittesting a lot
different configurations attached which makes unit testing a lot
easier. You can use this to pass in configuration as needed.
2. Do not write code that needs the configuration at import time. If you
@ -529,7 +527,7 @@ the config file by adding ``from yourapplication.default_settings
import *`` to the top of the file and then overriding the changes by hand.
You could also inspect an environment variable like
``YOURAPPLICATION_MODE`` and set that to `production`, `development` etc
and import different hardcoded files based on that.
and import different hard-coded files based on that.
An interesting pattern is also to use classes and inheritance for
configuration::

View File

@ -23,9 +23,15 @@ For example, to run a Flask application with 4 worker processes (``-w
$ gunicorn -w 4 -b 127.0.0.1:4000 myproject:app
The ``gunicorn`` command expects the names of your application module or
package and the application instance within the module. If you use the
application factory pattern, you can pass a call to that::
$ gunicorn "myproject:create_app()"
.. _Gunicorn: https://gunicorn.org/
.. _eventlet: https://eventlet.net/
.. _greenlet: https://greenlet.readthedocs.io/en/latest/
uWSGI
--------
@ -123,8 +129,8 @@ If your httpd is not providing these headers, the most common setup invokes the
host being set from ``X-Forwarded-Host`` and the remote address from
``X-Forwarded-For``::
from werkzeug.contrib.fixers import ProxyFix
app.wsgi_app = ProxyFix(app.wsgi_app)
from werkzeug.middleware.proxy_fix import ProxyFix
app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1, x_host=1)
.. admonition:: Trusting Headers

View File

@ -41,7 +41,7 @@ the time. There are ways to fake multiple applications with a single
application object, like maintaining a stack of applications, but this
causes some problems I won't outline here in detail. Now the question is:
when does a microframework need more than one application at the same
time? A good example for this is unittesting. When you want to test
time? A good example for this is unit testing. When you want to test
something it can be very helpful to create a minimal application to test
specific behavior. When the application object is deleted everything it
allocated will be freed again.
@ -76,7 +76,7 @@ there are better ways to do that so that you do not lose the reference
to the application object :meth:`~flask.Flask.wsgi_app`).
Furthermore this design makes it possible to use a factory function to
create the application which is very helpful for unittesting and similar
create the application which is very helpful for unit testing and similar
things (:ref:`app-factories`).
The Routing System

View File

@ -287,7 +287,7 @@ also avoids having multiple developers working in isolation on pretty much the
same problem.
Remember: good API design is hard, so introduce your project on the
mailinglist, and let other developers give you a helping hand with
mailing list, and let other developers give you a helping hand with
designing the API.
The best Flask extensions are extensions that share common idioms for the

View File

@ -6,7 +6,7 @@ Extensions
Extensions are extra packages that add functionality to a Flask
application. For example, an extension might add support for sending
email or connecting to a database. Some extensions add entire new
frameworks to help build certain types of applications, like a ReST API.
frameworks to help build certain types of applications, like a REST API.
Finding Extensions

View File

@ -2,14 +2,14 @@ Adding HTTP Method Overrides
============================
Some HTTP proxies do not support arbitrary HTTP methods or newer HTTP
methods (such as PATCH). In that case it's possible to “proxy” HTTP
methods (such as PATCH). In that case it's possible to "proxy" HTTP
methods through another HTTP method in total violation of the protocol.
The way this works is by letting the client do an HTTP POST request and
set the ``X-HTTP-Method-Override`` header and set the value to the
intended HTTP method (such as ``PATCH``).
set the ``X-HTTP-Method-Override`` header. Then the method is replaced
with the header value before being passed to Flask.
This can easily be accomplished with an HTTP middleware::
This can be accomplished with an HTTP middleware::
class HTTPMethodOverrideMiddleware(object):
allowed_methods = frozenset([
@ -29,13 +29,12 @@ This can easily be accomplished with an HTTP middleware::
def __call__(self, environ, start_response):
method = environ.get('HTTP_X_HTTP_METHOD_OVERRIDE', '').upper()
if method in self.allowed_methods:
method = method.encode('ascii', 'replace')
environ['REQUEST_METHOD'] = method
if method in self.bodyless_methods:
environ['CONTENT_LENGTH'] = '0'
return self.app(environ, start_response)
To use this with Flask this is all that is necessary::
To use this with Flask, wrap the app object with the middleware::
from flask import Flask

View File

@ -203,7 +203,7 @@ of the argument like ``<converter:variable_name>``. ::
@app.route('/user/<username>')
def show_user_profile(username):
# show the user profile for that user
return 'User %s' % username
return 'User %s' % escape(username)
@app.route('/post/<int:post_id>')
def show_post(post_id):
@ -213,7 +213,7 @@ of the argument like ``<converter:variable_name>``. ::
@app.route('/path/<path:subpath>')
def show_subpath(subpath):
# show the subpath after /path/
return 'Subpath %s' % subpath
return 'Subpath %s' % escape(subpath)
Converter types:
@ -281,7 +281,7 @@ Python shell. See :ref:`context-locals`.
.. code-block:: python
from flask import Flask, url_for
from flask import Flask, escape, url_for
app = Flask(__name__)
@ -295,7 +295,7 @@ Python shell. See :ref:`context-locals`.
@app.route('/user/<username>')
def profile(username):
return '{}\'s profile'.format(username)
return '{}\'s profile'.format(escape(username))
with app.test_request_context():
print(url_for('index'))
@ -690,10 +690,10 @@ response objects is as follows:
returned from the view.
2. If it's a string, a response object is created with that data and the
default parameters.
3. If a tuple is returned the items in the tuple can provide extra
information. Such tuples have to be in the form ``(response, status,
headers)`` or ``(response, headers)`` where at least one item has
to be in the tuple. The ``status`` value will override the status code
3. If a tuple is returned the items in the tuple can provide extra information.
Such tuples have to be in the form ``(response, status, headers)``,
``(response, headers)`` or ``(response, status)`` where at least one item
has to be in the tuple. The ``status`` value will override the status code
and ``headers`` can be a list or dictionary of additional header values.
4. If none of that works, Flask will assume the return value is a
valid WSGI application and convert that into a response object.

View File

@ -20,7 +20,7 @@ can you do?
This is where some helper functions come in handy. Keep in mind however
that these functions are not only there for interactive shell usage, but
also for unittesting and other situations that require a faked request
also for unit testing and other situations that require a faked request
context.
Generally it's recommended that you read the :ref:`request-context`

View File

@ -43,8 +43,8 @@ The Golden Rule
So the rule of thumb: if you are not dealing with binary data, work with
Unicode. What does working with Unicode in Python 2.x mean?
- as long as you are using ASCII charpoints only (basically numbers,
some special characters of latin letters without umlauts or anything
- as long as you are using ASCII code points only (basically numbers,
some special characters of Latin letters without umlauts or anything
fancy) you can use regular string literals (``'Hello World'``).
- if you need anything else than ASCII in a string you have to mark
this string as Unicode string by prefixing it with a lowercase `u`.

View File

@ -175,7 +175,7 @@ def has_request_context():
self.remote_addr = remote_addr
Alternatively you can also just test any of the context bound objects
(such as :class:`request` or :class:`g` for truthness)::
(such as :class:`request` or :class:`g`) for truthness::
class User(db.Model):

View File

@ -278,7 +278,7 @@ def url_for(endpoint, **values):
:param values: the variable arguments of the URL rule
:param _external: if set to ``True``, an absolute URL is generated. Server
address can be changed via ``SERVER_NAME`` configuration variable which
defaults to `localhost`.
falls back to the `Host` header, then to the IP and port of the request.
:param _scheme: a string specifying the desired URL scheme. The `_external`
parameter must be set to ``True`` or a :exc:`ValueError` is raised. The default
behavior uses the same scheme as the current request, or