mirror of https://github.com/pallets/flask.git
remove Python 2 from docs
This commit is contained in:
parent
96b4dcafc3
commit
7673835b3d
15
CHANGES.rst
15
CHANGES.rst
|
@ -452,7 +452,7 @@ Released 2016-05-29, codename Absinthe
|
||||||
|
|
||||||
- Added support to serializing top-level arrays to
|
- Added support to serializing top-level arrays to
|
||||||
:func:`flask.jsonify`. This introduces a security risk in ancient
|
:func:`flask.jsonify`. This introduces a security risk in ancient
|
||||||
browsers. See :ref:`json-security` for details.
|
browsers.
|
||||||
- Added before_render_template signal.
|
- Added before_render_template signal.
|
||||||
- Added ``**kwargs`` to :meth:`flask.Test.test_client` to support
|
- Added ``**kwargs`` to :meth:`flask.Test.test_client` to support
|
||||||
passing additional keyword arguments to the constructor of
|
passing additional keyword arguments to the constructor of
|
||||||
|
@ -567,8 +567,7 @@ Version 0.10
|
||||||
Released 2013-06-13, codename Limoncello
|
Released 2013-06-13, codename Limoncello
|
||||||
|
|
||||||
- Changed default cookie serialization format from pickle to JSON to
|
- Changed default cookie serialization format from pickle to JSON to
|
||||||
limit the impact an attacker can do if the secret key leaks. See
|
limit the impact an attacker can do if the secret key leaks.
|
||||||
:ref:`upgrading-to-010` for more information.
|
|
||||||
- Added ``template_test`` methods in addition to the already existing
|
- Added ``template_test`` methods in addition to the already existing
|
||||||
``template_filter`` method family.
|
``template_filter`` method family.
|
||||||
- Added ``template_global`` methods in addition to the already
|
- Added ``template_global`` methods in addition to the already
|
||||||
|
@ -597,8 +596,7 @@ Released 2013-06-13, codename Limoncello
|
||||||
- Added an option to generate non-ascii encoded JSON which should
|
- Added an option to generate non-ascii encoded JSON which should
|
||||||
result in less bytes being transmitted over the network. It's
|
result in less bytes being transmitted over the network. It's
|
||||||
disabled by default to not cause confusion with existing libraries
|
disabled by default to not cause confusion with existing libraries
|
||||||
that might expect ``flask.json.dumps`` to return bytestrings by
|
that might expect ``flask.json.dumps`` to return bytes by default.
|
||||||
default.
|
|
||||||
- ``flask.g`` is now stored on the app context instead of the request
|
- ``flask.g`` is now stored on the app context instead of the request
|
||||||
context.
|
context.
|
||||||
- ``flask.g`` now gained a ``get()`` method for not erroring out on
|
- ``flask.g`` now gained a ``get()`` method for not erroring out on
|
||||||
|
@ -762,7 +760,7 @@ Released 2011-09-29, codename Rakija
|
||||||
designated place to drop files that are modified at runtime (uploads
|
designated place to drop files that are modified at runtime (uploads
|
||||||
etc.). Also this is conceptually only instance depending and outside
|
etc.). Also this is conceptually only instance depending and outside
|
||||||
version control so it's the perfect place to put configuration files
|
version control so it's the perfect place to put configuration files
|
||||||
etc. For more information see :ref:`instance-folders`.
|
etc.
|
||||||
- Added the ``APPLICATION_ROOT`` configuration variable.
|
- Added the ``APPLICATION_ROOT`` configuration variable.
|
||||||
- Implemented :meth:`~flask.testing.TestClient.session_transaction` to
|
- Implemented :meth:`~flask.testing.TestClient.session_transaction` to
|
||||||
easily modify sessions from the test environment.
|
easily modify sessions from the test environment.
|
||||||
|
@ -842,8 +840,7 @@ Released 2011-06-28, codename Grappa
|
||||||
- Added ``teardown_request`` decorator, for functions that should run
|
- Added ``teardown_request`` decorator, for functions that should run
|
||||||
at the end of a request regardless of whether an exception occurred.
|
at the end of a request regardless of whether an exception occurred.
|
||||||
Also the behavior for ``after_request`` was changed. It's now no
|
Also the behavior for ``after_request`` was changed. It's now no
|
||||||
longer executed when an exception is raised. See
|
longer executed when an exception is raised.
|
||||||
:ref:`upgrading-to-new-teardown-handling`
|
|
||||||
- Implemented :func:`flask.has_request_context`
|
- Implemented :func:`flask.has_request_context`
|
||||||
- Deprecated ``init_jinja_globals``. Override the
|
- Deprecated ``init_jinja_globals``. Override the
|
||||||
:meth:`~flask.Flask.create_jinja_environment` method instead to
|
:meth:`~flask.Flask.create_jinja_environment` method instead to
|
||||||
|
@ -860,7 +857,7 @@ Released 2011-06-28, codename Grappa
|
||||||
errors that might occur during request processing (for instance
|
errors that might occur during request processing (for instance
|
||||||
database connection errors, timeouts from remote resources etc.).
|
database connection errors, timeouts from remote resources etc.).
|
||||||
- Blueprints can provide blueprint specific error handlers.
|
- Blueprints can provide blueprint specific error handlers.
|
||||||
- Implemented generic :ref:`views` (class-based views).
|
- Implemented generic class-based views.
|
||||||
|
|
||||||
|
|
||||||
Version 0.6.1
|
Version 0.6.1
|
||||||
|
|
|
@ -135,8 +135,9 @@ depends on which part of Flask you're working on. Travis-CI will run the full
|
||||||
suite when you submit your pull request.
|
suite when you submit your pull request.
|
||||||
|
|
||||||
The full test suite takes a long time to run because it tests multiple
|
The full test suite takes a long time to run because it tests multiple
|
||||||
combinations of Python and dependencies. You need to have Python 2.7, 3.4,
|
combinations of Python and dependencies. If you don't have a Python
|
||||||
3.5, 3.6, 3.7 and PyPy 2.7 installed to run all of the environments. Then run::
|
version installed, it will be skipped with a warning message at the end.
|
||||||
|
Run::
|
||||||
|
|
||||||
tox
|
tox
|
||||||
|
|
||||||
|
|
|
@ -161,8 +161,8 @@ The following configuration values are used internally by Flask:
|
||||||
|
|
||||||
A secret key that will be used for securely signing the session cookie
|
A secret key that will be used for securely signing the session cookie
|
||||||
and can be used for any other security related needs by extensions or your
|
and can be used for any other security related needs by extensions or your
|
||||||
application. It should be a long random string of bytes, although unicode
|
application. It should be a long random ``bytes`` or ``str``. For
|
||||||
is accepted too. For example, copy the output of this to your config::
|
example, copy the output of this to your config::
|
||||||
|
|
||||||
$ python -c 'import os; print(os.urandom(16))'
|
$ python -c 'import os; print(os.urandom(16))'
|
||||||
b'_5#y2L"F4Q8z\n\xec]/'
|
b'_5#y2L"F4Q8z\n\xec]/'
|
||||||
|
@ -302,10 +302,10 @@ The following configuration values are used internally by Flask:
|
||||||
|
|
||||||
.. py:data:: JSON_AS_ASCII
|
.. py:data:: JSON_AS_ASCII
|
||||||
|
|
||||||
Serialize objects to ASCII-encoded JSON. If this is disabled, the JSON
|
Serialize objects to ASCII-encoded JSON. If this is disabled, the
|
||||||
will be returned as a Unicode string, or encoded as ``UTF-8`` by
|
JSON returned from ``jsonify`` will contain Unicode characters. This
|
||||||
``jsonify``. This has security implications when rendering the JSON into
|
has security implications when rendering the JSON into JavaScript in
|
||||||
JavaScript in templates, and should typically remain enabled.
|
templates, and should typically remain enabled.
|
||||||
|
|
||||||
Default: ``True``
|
Default: ``True``
|
||||||
|
|
||||||
|
@ -678,7 +678,7 @@ locations are used:
|
||||||
|
|
||||||
- Installed module or package::
|
- Installed module or package::
|
||||||
|
|
||||||
$PREFIX/lib/python2.X/site-packages/myapp
|
$PREFIX/lib/pythonX.Y/site-packages/myapp
|
||||||
$PREFIX/var/myapp-instance
|
$PREFIX/var/myapp-instance
|
||||||
|
|
||||||
``$PREFIX`` is the prefix of your Python installation. This can be
|
``$PREFIX`` is the prefix of your Python installation. This can be
|
||||||
|
|
|
@ -210,11 +210,6 @@ you have to modify your ``.wsgi`` file slightly.
|
||||||
|
|
||||||
Add the following lines to the top of your ``.wsgi`` file::
|
Add the following lines to the top of your ``.wsgi`` file::
|
||||||
|
|
||||||
activate_this = '/path/to/env/bin/activate_this.py'
|
|
||||||
execfile(activate_this, dict(__file__=activate_this))
|
|
||||||
|
|
||||||
For Python 3 add the following lines to the top of your ``.wsgi`` file::
|
|
||||||
|
|
||||||
activate_this = '/path/to/env/bin/activate_this.py'
|
activate_this = '/path/to/env/bin/activate_this.py'
|
||||||
with open(activate_this) as file_:
|
with open(activate_this) as file_:
|
||||||
exec(file_.read(), dict(__file__=activate_this))
|
exec(file_.read(), dict(__file__=activate_this))
|
||||||
|
|
|
@ -109,14 +109,14 @@ has a certain understanding about how things work. On the surface they
|
||||||
all work the same: you tell the engine to evaluate a template with a set
|
all work the same: you tell the engine to evaluate a template with a set
|
||||||
of variables and take the return value as string.
|
of variables and take the return value as string.
|
||||||
|
|
||||||
But that's about where similarities end. Jinja2 for example has an
|
But that's about where similarities end. Jinja2 for example has an
|
||||||
extensive filter system, a certain way to do template inheritance, support
|
extensive filter system, a certain way to do template inheritance,
|
||||||
for reusable blocks (macros) that can be used from inside templates and
|
support for reusable blocks (macros) that can be used from inside
|
||||||
also from Python code, uses Unicode for all operations, supports
|
templates and also from Python code, supports iterative template
|
||||||
iterative template rendering, configurable syntax and more. On the other
|
rendering, configurable syntax and more. On the other hand an engine
|
||||||
hand an engine like Genshi is based on XML stream evaluation, template
|
like Genshi is based on XML stream evaluation, template inheritance by
|
||||||
inheritance by taking the availability of XPath into account and more.
|
taking the availability of XPath into account and more. Mako on the
|
||||||
Mako on the other hand treats templates similar to Python modules.
|
other hand treats templates similar to Python modules.
|
||||||
|
|
||||||
When it comes to connecting a template engine with an application or
|
When it comes to connecting a template engine with an application or
|
||||||
framework there is more than just rendering templates. For instance,
|
framework there is more than just rendering templates. For instance,
|
||||||
|
|
|
@ -84,10 +84,7 @@ Design notes, legal information and changelog are here for the interested.
|
||||||
design
|
design
|
||||||
htmlfaq
|
htmlfaq
|
||||||
security
|
security
|
||||||
unicode
|
|
||||||
extensiondev
|
extensiondev
|
||||||
styleguide
|
|
||||||
upgrading
|
|
||||||
changelog
|
changelog
|
||||||
license
|
license
|
||||||
contributing
|
contributing
|
||||||
|
|
|
@ -3,11 +3,13 @@
|
||||||
Installation
|
Installation
|
||||||
============
|
============
|
||||||
|
|
||||||
|
|
||||||
Python Version
|
Python Version
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
We recommend using the latest version of Python 3. Flask supports Python 3.5
|
We recommend using the latest version of Python. Flask supports Python
|
||||||
and newer, Python 2.7, and PyPy.
|
3.6 and newer.
|
||||||
|
|
||||||
|
|
||||||
Dependencies
|
Dependencies
|
||||||
------------
|
------------
|
||||||
|
@ -31,6 +33,7 @@ These distributions will be installed automatically when installing Flask.
|
||||||
.. _ItsDangerous: https://palletsprojects.com/p/itsdangerous/
|
.. _ItsDangerous: https://palletsprojects.com/p/itsdangerous/
|
||||||
.. _Click: https://palletsprojects.com/p/click/
|
.. _Click: https://palletsprojects.com/p/click/
|
||||||
|
|
||||||
|
|
||||||
Optional dependencies
|
Optional dependencies
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -51,6 +54,7 @@ use them if you install them.
|
||||||
.. _python-dotenv: https://github.com/theskumar/python-dotenv#readme
|
.. _python-dotenv: https://github.com/theskumar/python-dotenv#readme
|
||||||
.. _watchdog: https://pythonhosted.org/watchdog/
|
.. _watchdog: https://pythonhosted.org/watchdog/
|
||||||
|
|
||||||
|
|
||||||
Virtual environments
|
Virtual environments
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
|
@ -66,13 +70,9 @@ Virtual environments are independent groups of Python libraries, one for each
|
||||||
project. Packages installed for one project will not affect other projects or
|
project. Packages installed for one project will not affect other projects or
|
||||||
the operating system's packages.
|
the operating system's packages.
|
||||||
|
|
||||||
Python 3 comes bundled with the :mod:`venv` module to create virtual
|
Python comes bundled with the :mod:`venv` module to create virtual
|
||||||
environments. If you're using a modern version of Python, you can continue on
|
environments.
|
||||||
to the next section.
|
|
||||||
|
|
||||||
If you're using Python 2, see :ref:`install-install-virtualenv` first.
|
|
||||||
|
|
||||||
.. _install-create-env:
|
|
||||||
|
|
||||||
Create an environment
|
Create an environment
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -91,18 +91,6 @@ On Windows:
|
||||||
|
|
||||||
$ py -3 -m venv venv
|
$ py -3 -m venv venv
|
||||||
|
|
||||||
If you needed to install virtualenv because you are using Python 2, use
|
|
||||||
the following command instead:
|
|
||||||
|
|
||||||
.. code-block:: sh
|
|
||||||
|
|
||||||
$ python2 -m virtualenv venv
|
|
||||||
|
|
||||||
On Windows:
|
|
||||||
|
|
||||||
.. code-block:: bat
|
|
||||||
|
|
||||||
> \Python27\Scripts\virtualenv.exe venv
|
|
||||||
|
|
||||||
.. _install-activate-env:
|
.. _install-activate-env:
|
||||||
|
|
||||||
|
@ -121,12 +109,15 @@ On Windows:
|
||||||
|
|
||||||
> venv\Scripts\activate
|
> venv\Scripts\activate
|
||||||
|
|
||||||
Your shell prompt will change to show the name of the activated environment.
|
Your shell prompt will change to show the name of the activated
|
||||||
|
environment.
|
||||||
|
|
||||||
|
|
||||||
Install Flask
|
Install Flask
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
Within the activated environment, use the following command to install Flask:
|
Within the activated environment, use the following command to install
|
||||||
|
Flask:
|
||||||
|
|
||||||
.. code-block:: sh
|
.. code-block:: sh
|
||||||
|
|
||||||
|
@ -134,53 +125,3 @@ Within the activated environment, use the following command to install Flask:
|
||||||
|
|
||||||
Flask is now installed. Check out the :doc:`/quickstart` or go to the
|
Flask is now installed. Check out the :doc:`/quickstart` or go to the
|
||||||
:doc:`Documentation Overview </index>`.
|
:doc:`Documentation Overview </index>`.
|
||||||
|
|
||||||
Living on the edge
|
|
||||||
~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
If you want to work with the latest Flask code before it's released, install or
|
|
||||||
update the code from the master branch:
|
|
||||||
|
|
||||||
.. code-block:: sh
|
|
||||||
|
|
||||||
$ pip install -U https://github.com/pallets/flask/archive/master.tar.gz
|
|
||||||
|
|
||||||
.. _install-install-virtualenv:
|
|
||||||
|
|
||||||
Install virtualenv
|
|
||||||
------------------
|
|
||||||
|
|
||||||
If you are using Python 2, the venv module is not available. Instead,
|
|
||||||
install `virtualenv`_.
|
|
||||||
|
|
||||||
On Linux, virtualenv is provided by your package manager:
|
|
||||||
|
|
||||||
.. code-block:: sh
|
|
||||||
|
|
||||||
# Debian, Ubuntu
|
|
||||||
$ sudo apt-get install python-virtualenv
|
|
||||||
|
|
||||||
# CentOS, Fedora
|
|
||||||
$ sudo yum install python-virtualenv
|
|
||||||
|
|
||||||
# Arch
|
|
||||||
$ sudo pacman -S python-virtualenv
|
|
||||||
|
|
||||||
If you are on Mac OS X or Windows, download `get-pip.py`_, then:
|
|
||||||
|
|
||||||
.. code-block:: sh
|
|
||||||
|
|
||||||
$ sudo python2 Downloads/get-pip.py
|
|
||||||
$ sudo python2 -m pip install virtualenv
|
|
||||||
|
|
||||||
On Windows, as an administrator:
|
|
||||||
|
|
||||||
.. code-block:: bat
|
|
||||||
|
|
||||||
> \Python27\python.exe Downloads\get-pip.py
|
|
||||||
> \Python27\python.exe -m pip install virtualenv
|
|
||||||
|
|
||||||
Now you can return above and :ref:`install-create-env`.
|
|
||||||
|
|
||||||
.. _virtualenv: https://virtualenv.pypa.io/
|
|
||||||
.. _get-pip.py: https://bootstrap.pypa.io/get-pip.py
|
|
||||||
|
|
|
@ -19,10 +19,6 @@ complex constructs that make larger applications easier to distribute:
|
||||||
other package.
|
other package.
|
||||||
- **installation manager**: :command:`pip` can install other libraries for you.
|
- **installation manager**: :command:`pip` can install other libraries for you.
|
||||||
|
|
||||||
If you have Python 2 (>=2.7.9) or Python 3 (>=3.4) installed from python.org,
|
|
||||||
you will already have pip and setuptools on your system. Otherwise, you
|
|
||||||
will need to install them yourself.
|
|
||||||
|
|
||||||
Flask itself, and all the libraries you can find on PyPI are distributed with
|
Flask itself, and all the libraries you can find on PyPI are distributed with
|
||||||
either setuptools or distutils.
|
either setuptools or distutils.
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ Here's the example :file:`database.py` module for your application::
|
||||||
from sqlalchemy.orm import scoped_session, sessionmaker
|
from sqlalchemy.orm import scoped_session, sessionmaker
|
||||||
from sqlalchemy.ext.declarative import declarative_base
|
from sqlalchemy.ext.declarative import declarative_base
|
||||||
|
|
||||||
engine = create_engine('sqlite:////tmp/test.db', convert_unicode=True)
|
engine = create_engine('sqlite:////tmp/test.db')
|
||||||
db_session = scoped_session(sessionmaker(autocommit=False,
|
db_session = scoped_session(sessionmaker(autocommit=False,
|
||||||
autoflush=False,
|
autoflush=False,
|
||||||
bind=engine))
|
bind=engine))
|
||||||
|
@ -127,7 +127,7 @@ Here is an example :file:`database.py` module for your application::
|
||||||
from sqlalchemy import create_engine, MetaData
|
from sqlalchemy import create_engine, MetaData
|
||||||
from sqlalchemy.orm import scoped_session, sessionmaker
|
from sqlalchemy.orm import scoped_session, sessionmaker
|
||||||
|
|
||||||
engine = create_engine('sqlite:////tmp/test.db', convert_unicode=True)
|
engine = create_engine('sqlite:////tmp/test.db')
|
||||||
metadata = MetaData()
|
metadata = MetaData()
|
||||||
db_session = scoped_session(sessionmaker(autocommit=False,
|
db_session = scoped_session(sessionmaker(autocommit=False,
|
||||||
autoflush=False,
|
autoflush=False,
|
||||||
|
@ -179,7 +179,7 @@ you basically only need the engine::
|
||||||
|
|
||||||
from sqlalchemy import create_engine, MetaData, Table
|
from sqlalchemy import create_engine, MetaData, Table
|
||||||
|
|
||||||
engine = create_engine('sqlite:////tmp/test.db', convert_unicode=True)
|
engine = create_engine('sqlite:////tmp/test.db')
|
||||||
metadata = MetaData(bind=engine)
|
metadata = MetaData(bind=engine)
|
||||||
|
|
||||||
Then you can either declare the tables in your code like in the examples
|
Then you can either declare the tables in your code like in the examples
|
||||||
|
|
|
@ -98,9 +98,9 @@ This macro accepts a couple of keyword arguments that are forwarded to
|
||||||
WTForm's field function, which renders the field for us. The keyword
|
WTForm's field function, which renders the field for us. The keyword
|
||||||
arguments will be inserted as HTML attributes. So, for example, you can
|
arguments will be inserted as HTML attributes. So, for example, you can
|
||||||
call ``render_field(form.username, class='username')`` to add a class to
|
call ``render_field(form.username, class='username')`` to add a class to
|
||||||
the input element. Note that WTForms returns standard Python unicode
|
the input element. Note that WTForms returns standard Python strings,
|
||||||
strings, so we have to tell Jinja2 that this data is already HTML-escaped
|
so we have to tell Jinja2 that this data is already HTML-escaped with
|
||||||
with the ``|safe`` filter.
|
the ``|safe`` filter.
|
||||||
|
|
||||||
Here is 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:
|
takes advantage of the :file:`_formhelpers.html` template:
|
||||||
|
|
|
@ -293,8 +293,7 @@ Why would you want to build URLs using the URL reversing function
|
||||||
1. Reversing is often more descriptive than hard-coding the URLs.
|
1. Reversing is often more descriptive than hard-coding the URLs.
|
||||||
2. You can change your URLs in one go instead of needing to remember to
|
2. You can change your URLs in one go instead of needing to remember to
|
||||||
manually change hard-coded URLs.
|
manually change hard-coded URLs.
|
||||||
3. URL building handles escaping of special characters and Unicode data
|
3. URL building handles escaping of special characters transparently.
|
||||||
transparently.
|
|
||||||
4. The generated paths are always absolute, avoiding unexpected behavior
|
4. The generated paths are always absolute, avoiding unexpected behavior
|
||||||
of relative paths in browsers.
|
of relative paths in browsers.
|
||||||
5. If your application is placed outside the URL root, for example, in
|
5. If your application is placed outside the URL root, for example, in
|
||||||
|
|
|
@ -1,200 +0,0 @@
|
||||||
Pocoo Styleguide
|
|
||||||
================
|
|
||||||
|
|
||||||
The Pocoo styleguide is the styleguide for all Pocoo Projects, including
|
|
||||||
Flask. This styleguide is a requirement for Patches to Flask and a
|
|
||||||
recommendation for Flask extensions.
|
|
||||||
|
|
||||||
In general the Pocoo Styleguide closely follows :pep:`8` with some small
|
|
||||||
differences and extensions.
|
|
||||||
|
|
||||||
General Layout
|
|
||||||
--------------
|
|
||||||
|
|
||||||
Indentation:
|
|
||||||
4 real spaces. No tabs, no exceptions.
|
|
||||||
|
|
||||||
Maximum line length:
|
|
||||||
79 characters with a soft limit for 84 if absolutely necessary. Try
|
|
||||||
to avoid too nested code by cleverly placing `break`, `continue` and
|
|
||||||
`return` statements.
|
|
||||||
|
|
||||||
Continuing long statements:
|
|
||||||
To continue a statement you can use backslashes in which case you should
|
|
||||||
align the next line with the last dot or equal sign, or indent four
|
|
||||||
spaces::
|
|
||||||
|
|
||||||
this_is_a_very_long(function_call, 'with many parameters') \
|
|
||||||
.that_returns_an_object_with_an_attribute
|
|
||||||
|
|
||||||
MyModel.query.filter(MyModel.scalar > 120) \
|
|
||||||
.order_by(MyModel.name.desc()) \
|
|
||||||
.limit(10)
|
|
||||||
|
|
||||||
If you break in a statement with parentheses or braces, align to the
|
|
||||||
braces::
|
|
||||||
|
|
||||||
this_is_a_very_long(function_call, 'with many parameters',
|
|
||||||
23, 42, 'and even more')
|
|
||||||
|
|
||||||
For lists or tuples with many items, break immediately after the
|
|
||||||
opening brace::
|
|
||||||
|
|
||||||
items = [
|
|
||||||
'this is the first', 'set of items', 'with more items',
|
|
||||||
'to come in this line', 'like this'
|
|
||||||
]
|
|
||||||
|
|
||||||
Blank lines:
|
|
||||||
Top level functions and classes are separated by two lines, everything
|
|
||||||
else by one. Do not use too many blank lines to separate logical
|
|
||||||
segments in code. Example::
|
|
||||||
|
|
||||||
def hello(name):
|
|
||||||
print f'Hello {name}!'
|
|
||||||
|
|
||||||
|
|
||||||
def goodbye(name):
|
|
||||||
print f'See you {name}.'
|
|
||||||
|
|
||||||
|
|
||||||
class MyClass(object):
|
|
||||||
"""This is a simple docstring"""
|
|
||||||
|
|
||||||
def __init__(self, name):
|
|
||||||
self.name = name
|
|
||||||
|
|
||||||
def get_annoying_name(self):
|
|
||||||
return self.name.upper() + '!!!!111'
|
|
||||||
|
|
||||||
Expressions and Statements
|
|
||||||
--------------------------
|
|
||||||
|
|
||||||
General whitespace rules:
|
|
||||||
- No whitespace for unary operators that are not words
|
|
||||||
(e.g.: ``-``, ``~`` etc.) as well on the inner side of parentheses.
|
|
||||||
- Whitespace is placed between binary operators.
|
|
||||||
|
|
||||||
Good::
|
|
||||||
|
|
||||||
exp = -1.05
|
|
||||||
value = (item_value / item_count) * offset / exp
|
|
||||||
value = my_list[index]
|
|
||||||
value = my_dict['key']
|
|
||||||
|
|
||||||
Bad::
|
|
||||||
|
|
||||||
exp = - 1.05
|
|
||||||
value = ( item_value / item_count ) * offset / exp
|
|
||||||
value = (item_value/item_count)*offset/exp
|
|
||||||
value=( item_value/item_count ) * offset/exp
|
|
||||||
value = my_list[ index ]
|
|
||||||
value = my_dict ['key']
|
|
||||||
|
|
||||||
Yoda statements are a no-go:
|
|
||||||
Never compare constant with variable, always variable with constant:
|
|
||||||
|
|
||||||
Good::
|
|
||||||
|
|
||||||
if method == 'md5':
|
|
||||||
pass
|
|
||||||
|
|
||||||
Bad::
|
|
||||||
|
|
||||||
if 'md5' == method:
|
|
||||||
pass
|
|
||||||
|
|
||||||
Comparisons:
|
|
||||||
- against arbitrary types: ``==`` and ``!=``
|
|
||||||
- against singletons with ``is`` and ``is not`` (eg: ``foo is not
|
|
||||||
None``)
|
|
||||||
- never compare something with ``True`` or ``False`` (for example never
|
|
||||||
do ``foo == False``, do ``not foo`` instead)
|
|
||||||
|
|
||||||
Negated containment checks:
|
|
||||||
use ``foo not in bar`` instead of ``not foo in bar``
|
|
||||||
|
|
||||||
Instance checks:
|
|
||||||
``isinstance(a, C)`` instead of ``type(A) is C``, but try to avoid
|
|
||||||
instance checks in general. Check for features.
|
|
||||||
|
|
||||||
|
|
||||||
Naming Conventions
|
|
||||||
------------------
|
|
||||||
|
|
||||||
- Class names: ``CamelCase``, with acronyms kept uppercase (``HTTPWriter``
|
|
||||||
and not ``HttpWriter``)
|
|
||||||
- Variable names: ``lowercase_with_underscores``
|
|
||||||
- Method and function names: ``lowercase_with_underscores``
|
|
||||||
- Constants: ``UPPERCASE_WITH_UNDERSCORES``
|
|
||||||
- precompiled regular expressions: ``name_re``
|
|
||||||
|
|
||||||
Protected members are prefixed with a single underscore. Double
|
|
||||||
underscores are reserved for mixin classes.
|
|
||||||
|
|
||||||
On classes with keywords, trailing underscores are appended. Clashes with
|
|
||||||
builtins are allowed and **must not** be resolved by appending an
|
|
||||||
underline to the variable name. If the function needs to access a
|
|
||||||
shadowed builtin, rebind the builtin to a different name instead.
|
|
||||||
|
|
||||||
Function and method arguments:
|
|
||||||
- class methods: ``cls`` as first parameter
|
|
||||||
- instance methods: ``self`` as first parameter
|
|
||||||
- lambdas for properties might have the first parameter replaced
|
|
||||||
with ``x`` like in ``display_name = property(lambda x: x.real_name
|
|
||||||
or x.username)``
|
|
||||||
|
|
||||||
|
|
||||||
Docstrings
|
|
||||||
----------
|
|
||||||
|
|
||||||
Docstring conventions:
|
|
||||||
All docstrings are formatted with reStructuredText as understood by
|
|
||||||
Sphinx. Depending on the number of lines in the docstring, they are
|
|
||||||
laid out differently. If it's just one line, the closing triple
|
|
||||||
quote is on the same line as the opening, otherwise the text is on
|
|
||||||
the same line as the opening quote and the triple quote that closes
|
|
||||||
the string on its own line::
|
|
||||||
|
|
||||||
def foo():
|
|
||||||
"""This is a simple docstring"""
|
|
||||||
|
|
||||||
|
|
||||||
def bar():
|
|
||||||
"""This is a longer docstring with so much information in there
|
|
||||||
that it spans three lines. In this case the closing triple quote
|
|
||||||
is on its own line.
|
|
||||||
"""
|
|
||||||
|
|
||||||
Module header:
|
|
||||||
The module header consists of a utf-8 encoding declaration (if non
|
|
||||||
ASCII letters are used, but it is recommended all the time) and a
|
|
||||||
standard docstring::
|
|
||||||
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
"""
|
|
||||||
package.module
|
|
||||||
~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
A brief description goes here.
|
|
||||||
|
|
||||||
:copyright: (c) YEAR by AUTHOR.
|
|
||||||
:license: LICENSE_NAME, see LICENSE_FILE for more details.
|
|
||||||
"""
|
|
||||||
|
|
||||||
Please keep in mind that proper copyrights and license files are a
|
|
||||||
requirement for approved Flask extensions.
|
|
||||||
|
|
||||||
|
|
||||||
Comments
|
|
||||||
--------
|
|
||||||
|
|
||||||
Rules for comments are similar to docstrings. Both are formatted with
|
|
||||||
reStructuredText. If a comment is used to document an attribute, put a
|
|
||||||
colon after the opening pound sign (``#``)::
|
|
||||||
|
|
||||||
class User(object):
|
|
||||||
#: the name of the user as unicode string
|
|
||||||
name = Column(String)
|
|
||||||
#: the sha1 hash of the password + inline salt
|
|
||||||
pw_hash = Column(String)
|
|
|
@ -301,8 +301,8 @@ URL when the register view redirects to the login view.
|
||||||
|
|
||||||
:attr:`~Response.data` contains the body of the response as bytes. If
|
:attr:`~Response.data` contains the body of the response as bytes. If
|
||||||
you expect a certain value to render on the page, check that it's in
|
you expect a certain value to render on the page, check that it's in
|
||||||
``data``. Bytes must be compared to bytes. If you want to compare
|
``data``. Bytes must be compared to bytes. If you want to compare text,
|
||||||
Unicode text, use :meth:`get_data(as_text=True) <werkzeug.wrappers.BaseResponse.get_data>`
|
use :meth:`get_data(as_text=True) <werkzeug.wrappers.BaseResponse.get_data>`
|
||||||
instead.
|
instead.
|
||||||
|
|
||||||
``pytest.mark.parametrize`` tells Pytest to run the same test function
|
``pytest.mark.parametrize`` tells Pytest to run the same test function
|
||||||
|
|
107
docs/unicode.rst
107
docs/unicode.rst
|
@ -1,107 +0,0 @@
|
||||||
Unicode in Flask
|
|
||||||
================
|
|
||||||
|
|
||||||
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
|
|
||||||
Absolutely, Positively Must Know About Unicode and Character Sets
|
|
||||||
<https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/>`_.
|
|
||||||
This part of the documentation just tries to cover the very basics so
|
|
||||||
that you have a pleasant experience with Unicode related things.
|
|
||||||
|
|
||||||
Automatic Conversion
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
Flask has a few assumptions about your application (which you can change
|
|
||||||
of course) that give you basic and painless Unicode support:
|
|
||||||
|
|
||||||
- the encoding for text on your website is UTF-8
|
|
||||||
- internally you will always use Unicode exclusively for text except
|
|
||||||
for literal strings with only ASCII character points.
|
|
||||||
- encoding and decoding happens whenever you are talking over a protocol
|
|
||||||
that requires bytes to be transmitted.
|
|
||||||
|
|
||||||
So what does this mean to you?
|
|
||||||
|
|
||||||
HTTP is based on bytes. Not only the protocol, also the system used to
|
|
||||||
address documents on servers (so called URIs or URLs). However HTML which
|
|
||||||
is usually transmitted on top of HTTP supports a large variety of
|
|
||||||
character sets and which ones are used, are transmitted in an HTTP header.
|
|
||||||
To not make this too complex Flask just assumes that if you are sending
|
|
||||||
Unicode out you want it to be UTF-8 encoded. Flask will do the encoding
|
|
||||||
and setting of the appropriate headers for you.
|
|
||||||
|
|
||||||
The same is true if you are talking to databases with the help of
|
|
||||||
SQLAlchemy or a similar ORM system. Some databases have a protocol that
|
|
||||||
already transmits Unicode and if they do not, SQLAlchemy or your other ORM
|
|
||||||
should take care of that.
|
|
||||||
|
|
||||||
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 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`.
|
|
||||||
(like ``u'Hänsel und Gretel'``)
|
|
||||||
- if you are using non-Unicode characters in your Python files you have
|
|
||||||
to tell Python which encoding your file uses. Again, I recommend
|
|
||||||
UTF-8 for this purpose. To tell the interpreter your encoding you can
|
|
||||||
put the ``# -*- coding: utf-8 -*-`` into the first or second line of
|
|
||||||
your Python source file.
|
|
||||||
- Jinja is configured to decode the template files from UTF-8. So make
|
|
||||||
sure to tell your editor to save the file as UTF-8 there as well.
|
|
||||||
|
|
||||||
Encoding and Decoding Yourself
|
|
||||||
------------------------------
|
|
||||||
|
|
||||||
If you are talking with a filesystem or something that is not really based
|
|
||||||
on Unicode you will have to ensure that you decode properly when working
|
|
||||||
with Unicode interface. So for example if you want to load a file on the
|
|
||||||
filesystem and embed it into a Jinja2 template you will have to decode it
|
|
||||||
from the encoding of that file. Here the old problem that text files do
|
|
||||||
not specify their encoding comes into play. So do yourself a favour and
|
|
||||||
limit yourself to UTF-8 for text files as well.
|
|
||||||
|
|
||||||
Anyways. To load such a file with Unicode you can use the built-in
|
|
||||||
:meth:`str.decode` method::
|
|
||||||
|
|
||||||
def read_file(filename, charset='utf-8'):
|
|
||||||
with open(filename, 'r') as f:
|
|
||||||
return f.read().decode(charset)
|
|
||||||
|
|
||||||
To go from Unicode into a specific charset such as UTF-8 you can use the
|
|
||||||
:meth:`unicode.encode` method::
|
|
||||||
|
|
||||||
def write_file(filename, contents, charset='utf-8'):
|
|
||||||
with open(filename, 'w') as f:
|
|
||||||
f.write(contents.encode(charset))
|
|
||||||
|
|
||||||
Configuring Editors
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
Most editors save as UTF-8 by default nowadays but in case your editor is
|
|
||||||
not configured to do this you have to change it. Here some common ways to
|
|
||||||
set your editor to store as UTF-8:
|
|
||||||
|
|
||||||
- Vim: put ``set enc=utf-8`` to your ``.vimrc`` file.
|
|
||||||
|
|
||||||
- Emacs: either use an encoding cookie or put this into your ``.emacs``
|
|
||||||
file::
|
|
||||||
|
|
||||||
(prefer-coding-system 'utf-8)
|
|
||||||
(setq default-buffer-file-coding-system 'utf-8)
|
|
||||||
|
|
||||||
- Notepad++:
|
|
||||||
|
|
||||||
1. Go to *Settings -> Preferences ...*
|
|
||||||
2. Select the "New Document/Default Directory" tab
|
|
||||||
3. Select "UTF-8 without BOM" as encoding
|
|
||||||
|
|
||||||
It is also recommended to use the Unix newline format, you can select
|
|
||||||
it in the same panel but this is not a requirement.
|
|
|
@ -1,472 +0,0 @@
|
||||||
Upgrading to Newer Releases
|
|
||||||
===========================
|
|
||||||
|
|
||||||
Flask itself is changing like any software is changing over time. Most of
|
|
||||||
the changes are the nice kind, the kind where you don't have to change
|
|
||||||
anything in your code to profit from a new release.
|
|
||||||
|
|
||||||
However every once in a while there are changes that do require some
|
|
||||||
changes in your code or there are changes that make it possible for you to
|
|
||||||
improve your own code quality by taking advantage of new features in
|
|
||||||
Flask.
|
|
||||||
|
|
||||||
This section of the documentation enumerates all the changes in Flask from
|
|
||||||
release to release and how you can change your code to have a painless
|
|
||||||
updating experience.
|
|
||||||
|
|
||||||
Use the :command:`pip` command to upgrade your existing Flask installation by
|
|
||||||
providing the ``--upgrade`` parameter::
|
|
||||||
|
|
||||||
$ pip install --upgrade Flask
|
|
||||||
|
|
||||||
.. _upgrading-to-012:
|
|
||||||
|
|
||||||
Version 0.12
|
|
||||||
------------
|
|
||||||
|
|
||||||
Changes to send_file
|
|
||||||
````````````````````
|
|
||||||
|
|
||||||
The ``filename`` is no longer automatically inferred from file-like objects.
|
|
||||||
This means that the following code will no longer automatically have
|
|
||||||
``X-Sendfile`` support, etag generation or MIME-type guessing::
|
|
||||||
|
|
||||||
response = send_file(open('/path/to/file.txt'))
|
|
||||||
|
|
||||||
Any of the following is functionally equivalent::
|
|
||||||
|
|
||||||
fname = '/path/to/file.txt'
|
|
||||||
|
|
||||||
# Just pass the filepath directly
|
|
||||||
response = send_file(fname)
|
|
||||||
|
|
||||||
# Set the MIME-type and ETag explicitly
|
|
||||||
response = send_file(open(fname), mimetype='text/plain')
|
|
||||||
response.set_etag(...)
|
|
||||||
|
|
||||||
# Set `attachment_filename` for MIME-type guessing
|
|
||||||
# ETag still needs to be manually set
|
|
||||||
response = send_file(open(fname), attachment_filename=fname)
|
|
||||||
response.set_etag(...)
|
|
||||||
|
|
||||||
The reason for this is that some file-like objects have an invalid or even
|
|
||||||
misleading ``name`` attribute. Silently swallowing errors in such cases was not
|
|
||||||
a satisfying solution.
|
|
||||||
|
|
||||||
Additionally the default of falling back to ``application/octet-stream`` has
|
|
||||||
been restricted. If Flask can't guess one or the user didn't provide one, the
|
|
||||||
function fails if no filename information was provided.
|
|
||||||
|
|
||||||
.. _upgrading-to-011:
|
|
||||||
|
|
||||||
Version 0.11
|
|
||||||
------------
|
|
||||||
|
|
||||||
0.11 is an odd release in the Flask release cycle because it was supposed
|
|
||||||
to be the 1.0 release. However because there was such a long lead time up
|
|
||||||
to the release we decided to push out a 0.11 release first with some
|
|
||||||
changes removed to make the transition easier. If you have been tracking
|
|
||||||
the master branch which was 1.0 you might see some unexpected changes.
|
|
||||||
|
|
||||||
In case you did track the master branch you will notice that
|
|
||||||
:command:`flask --app` is removed now.
|
|
||||||
You need to use the environment variable to specify an application.
|
|
||||||
|
|
||||||
Debugging
|
|
||||||
`````````
|
|
||||||
|
|
||||||
Flask 0.11 removed the ``debug_log_format`` attribute from Flask
|
|
||||||
applications. Instead the new ``LOGGER_HANDLER_POLICY`` configuration can
|
|
||||||
be used to disable the default log handlers and custom log handlers can be
|
|
||||||
set up.
|
|
||||||
|
|
||||||
Error handling
|
|
||||||
``````````````
|
|
||||||
|
|
||||||
The behavior of error handlers was changed.
|
|
||||||
The precedence of handlers used to be based on the decoration/call order of
|
|
||||||
:meth:`~flask.Flask.errorhandler` and
|
|
||||||
:meth:`~flask.Flask.register_error_handler`, respectively.
|
|
||||||
Now the inheritance hierarchy takes precedence and handlers for more
|
|
||||||
specific exception classes are executed instead of more general ones.
|
|
||||||
See :ref:`error-handlers` for specifics.
|
|
||||||
|
|
||||||
Trying to register a handler on an instance now raises :exc:`ValueError`.
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
There used to be a logic error allowing you to register handlers
|
|
||||||
only for exception *instances*. This was unintended and plain wrong,
|
|
||||||
and therefore was replaced with the intended behavior of registering
|
|
||||||
handlers only using exception classes and HTTP error codes.
|
|
||||||
|
|
||||||
Templating
|
|
||||||
``````````
|
|
||||||
|
|
||||||
The :func:`~flask.templating.render_template_string` function has changed to
|
|
||||||
autoescape template variables by default. This better matches the behavior
|
|
||||||
of :func:`~flask.templating.render_template`.
|
|
||||||
|
|
||||||
Extension imports
|
|
||||||
`````````````````
|
|
||||||
|
|
||||||
Extension imports of the form ``flask.ext.foo`` are deprecated, you should use
|
|
||||||
``flask_foo``.
|
|
||||||
|
|
||||||
The old form still works, but Flask will issue a
|
|
||||||
``flask.exthook.ExtDeprecationWarning`` for each extension you import the old
|
|
||||||
way. We also provide a migration utility called `flask-ext-migrate
|
|
||||||
<https://github.com/pallets/flask-ext-migrate>`_ that is supposed to
|
|
||||||
automatically rewrite your imports for this.
|
|
||||||
|
|
||||||
.. _upgrading-to-010:
|
|
||||||
|
|
||||||
Version 0.10
|
|
||||||
------------
|
|
||||||
|
|
||||||
The biggest change going from 0.9 to 0.10 is that the cookie serialization
|
|
||||||
format changed from pickle to a specialized JSON format. This change has
|
|
||||||
been done in order to avoid the damage an attacker can do if the secret
|
|
||||||
key is leaked. When you upgrade you will notice two major changes: all
|
|
||||||
sessions that were issued before the upgrade are invalidated and you can
|
|
||||||
only store a limited amount of types in the session. The new sessions are
|
|
||||||
by design much more restricted to only allow JSON with a few small
|
|
||||||
extensions for tuples and strings with HTML markup.
|
|
||||||
|
|
||||||
In order to not break people's sessions it is possible to continue using
|
|
||||||
the old session system by using the `Flask-OldSessions`_ extension.
|
|
||||||
|
|
||||||
Flask also started storing the :data:`flask.g` object on the application
|
|
||||||
context instead of the request context. This change should be transparent
|
|
||||||
for you but it means that you now can store things on the ``g`` object
|
|
||||||
when there is no request context yet but an application context. The old
|
|
||||||
``flask.Flask.request_globals_class`` attribute was renamed to
|
|
||||||
:attr:`flask.Flask.app_ctx_globals_class`.
|
|
||||||
|
|
||||||
.. _Flask-OldSessions: https://pythonhosted.org/Flask-OldSessions/
|
|
||||||
|
|
||||||
Version 0.9
|
|
||||||
-----------
|
|
||||||
|
|
||||||
The behavior of returning tuples from a function was simplified. If you
|
|
||||||
return a tuple it no longer defines the arguments for the response object
|
|
||||||
you're creating, it's now always a tuple in the form ``(response, status,
|
|
||||||
headers)`` where at least one item has to be provided. If you depend on
|
|
||||||
the old behavior, you can add it easily by subclassing Flask::
|
|
||||||
|
|
||||||
class TraditionalFlask(Flask):
|
|
||||||
def make_response(self, rv):
|
|
||||||
if isinstance(rv, tuple):
|
|
||||||
return self.response_class(*rv)
|
|
||||||
return Flask.make_response(self, rv)
|
|
||||||
|
|
||||||
If you maintain an extension that was using :data:`~flask._request_ctx_stack`
|
|
||||||
before, please consider changing to :data:`~flask._app_ctx_stack` if it makes
|
|
||||||
sense for your extension. For instance, the app context stack makes sense for
|
|
||||||
extensions which connect to databases. Using the app context stack instead of
|
|
||||||
the request context stack will make extensions more readily handle use cases
|
|
||||||
outside of requests.
|
|
||||||
|
|
||||||
Version 0.8
|
|
||||||
-----------
|
|
||||||
|
|
||||||
Flask introduced a new session interface system. We also noticed that
|
|
||||||
there was a naming collision between ``flask.session`` the module that
|
|
||||||
implements sessions and :data:`flask.session` which is the global session
|
|
||||||
object. With that introduction we moved the implementation details for
|
|
||||||
the session system into a new module called :mod:`flask.sessions`. If you
|
|
||||||
used the previously undocumented session support we urge you to upgrade.
|
|
||||||
|
|
||||||
If invalid JSON data was submitted Flask will now raise a
|
|
||||||
:exc:`~werkzeug.exceptions.BadRequest` exception instead of letting the
|
|
||||||
default :exc:`ValueError` bubble up. This has the advantage that you no
|
|
||||||
longer have to handle that error to avoid an internal server error showing
|
|
||||||
up for the user. If you were catching this down explicitly in the past
|
|
||||||
as :exc:`ValueError` you will need to change this.
|
|
||||||
|
|
||||||
Due to a bug in the test client Flask 0.7 did not trigger teardown
|
|
||||||
handlers when the test client was used in a with statement. This was
|
|
||||||
since fixed but might require some changes in your test suites if you
|
|
||||||
relied on this behavior.
|
|
||||||
|
|
||||||
Version 0.7
|
|
||||||
-----------
|
|
||||||
|
|
||||||
In Flask 0.7 we cleaned up the code base internally a lot and did some
|
|
||||||
backwards incompatible changes that make it easier to implement larger
|
|
||||||
applications with Flask. Because we want to make upgrading as easy as
|
|
||||||
possible we tried to counter the problems arising from these changes by
|
|
||||||
providing a script that can ease the transition.
|
|
||||||
|
|
||||||
The script scans your whole application and generates a unified diff with
|
|
||||||
changes it assumes are safe to apply. However as this is an automated
|
|
||||||
tool it won't be able to find all use cases and it might miss some. We
|
|
||||||
internally spread a lot of deprecation warnings all over the place to make
|
|
||||||
it easy to find pieces of code that it was unable to upgrade.
|
|
||||||
|
|
||||||
We strongly recommend that you hand review the generated patchfile and
|
|
||||||
only apply the chunks that look good.
|
|
||||||
|
|
||||||
If you are using git as version control system for your project we
|
|
||||||
recommend applying the patch with ``path -p1 < patchfile.diff`` and then
|
|
||||||
using the interactive commit feature to only apply the chunks that look
|
|
||||||
good.
|
|
||||||
|
|
||||||
To apply the upgrade script do the following:
|
|
||||||
|
|
||||||
1. Download the script: `flask-07-upgrade.py
|
|
||||||
<https://raw.githubusercontent.com/pallets/flask/0.12.3/scripts/flask-07-upgrade.py>`_
|
|
||||||
2. Run it in the directory of your application::
|
|
||||||
|
|
||||||
$ python flask-07-upgrade.py > patchfile.diff
|
|
||||||
|
|
||||||
3. Review the generated patchfile.
|
|
||||||
4. Apply the patch::
|
|
||||||
|
|
||||||
$ patch -p1 < patchfile.diff
|
|
||||||
|
|
||||||
5. If you were using per-module template folders you need to move some
|
|
||||||
templates around. Previously if you had a folder named :file:`templates`
|
|
||||||
next to a blueprint named ``admin`` the implicit template path
|
|
||||||
automatically was :file:`admin/index.html` for a template file called
|
|
||||||
:file:`templates/index.html`. This no longer is the case. Now you need
|
|
||||||
to name the template :file:`templates/admin/index.html`. The tool will
|
|
||||||
not detect this so you will have to do that on your own.
|
|
||||||
|
|
||||||
Please note that deprecation warnings are disabled by default starting
|
|
||||||
with Python 2.7. In order to see the deprecation warnings that might be
|
|
||||||
emitted you have to enabled them with the :mod:`warnings` module.
|
|
||||||
|
|
||||||
If you are working with windows and you lack the ``patch`` command line
|
|
||||||
utility you can get it as part of various Unix runtime environments for
|
|
||||||
windows including cygwin, msysgit or ming32. Also source control systems
|
|
||||||
like svn, hg or git have builtin support for applying unified diffs as
|
|
||||||
generated by the tool. Check the manual of your version control system
|
|
||||||
for more information.
|
|
||||||
|
|
||||||
Bug in Request Locals
|
|
||||||
`````````````````````
|
|
||||||
|
|
||||||
Due to a bug in earlier implementations the request local proxies now
|
|
||||||
raise a :exc:`RuntimeError` instead of an :exc:`AttributeError` when they
|
|
||||||
are unbound. If you caught these exceptions with :exc:`AttributeError`
|
|
||||||
before, you should catch them with :exc:`RuntimeError` now.
|
|
||||||
|
|
||||||
Additionally the :func:`~flask.send_file` function is now issuing
|
|
||||||
deprecation warnings if you depend on functionality that will be removed
|
|
||||||
in Flask 0.11. Previously it was possible to use etags and mimetypes
|
|
||||||
when file objects were passed. This was unreliable and caused issues
|
|
||||||
for a few setups. If you get a deprecation warning, make sure to
|
|
||||||
update your application to work with either filenames there or disable
|
|
||||||
etag attaching and attach them yourself.
|
|
||||||
|
|
||||||
Old code::
|
|
||||||
|
|
||||||
return send_file(my_file_object)
|
|
||||||
return send_file(my_file_object)
|
|
||||||
|
|
||||||
New code::
|
|
||||||
|
|
||||||
return send_file(my_file_object, add_etags=False)
|
|
||||||
|
|
||||||
.. _upgrading-to-new-teardown-handling:
|
|
||||||
|
|
||||||
Upgrading to new Teardown Handling
|
|
||||||
``````````````````````````````````
|
|
||||||
|
|
||||||
We streamlined the behavior of the callbacks for request handling. For
|
|
||||||
things that modify the response the :meth:`~flask.Flask.after_request`
|
|
||||||
decorators continue to work as expected, but for things that absolutely
|
|
||||||
must happen at the end of request we introduced the new
|
|
||||||
:meth:`~flask.Flask.teardown_request` decorator. Unfortunately that
|
|
||||||
change also made after-request work differently under error conditions.
|
|
||||||
It's not consistently skipped if exceptions happen whereas previously it
|
|
||||||
might have been called twice to ensure it is executed at the end of the
|
|
||||||
request.
|
|
||||||
|
|
||||||
If you have database connection code that looks like this::
|
|
||||||
|
|
||||||
@app.after_request
|
|
||||||
def after_request(response):
|
|
||||||
g.db.close()
|
|
||||||
return response
|
|
||||||
|
|
||||||
You are now encouraged to use this instead::
|
|
||||||
|
|
||||||
@app.teardown_request
|
|
||||||
def after_request(exception):
|
|
||||||
if hasattr(g, 'db'):
|
|
||||||
g.db.close()
|
|
||||||
|
|
||||||
On the upside this change greatly improves the internal code flow and
|
|
||||||
makes it easier to customize the dispatching and error handling. This
|
|
||||||
makes it now a lot easier to write unit tests as you can prevent closing
|
|
||||||
down of database connections for a while. You can take advantage of the
|
|
||||||
fact that the teardown callbacks are called when the response context is
|
|
||||||
removed from the stack so a test can query the database after request
|
|
||||||
handling::
|
|
||||||
|
|
||||||
with app.test_client() as client:
|
|
||||||
resp = client.get('/')
|
|
||||||
# g.db is still bound if there is such a thing
|
|
||||||
|
|
||||||
# and here it's gone
|
|
||||||
|
|
||||||
Manual Error Handler Attaching
|
|
||||||
``````````````````````````````
|
|
||||||
|
|
||||||
While it is still possible to attach error handlers to
|
|
||||||
:attr:`Flask.error_handlers` it's discouraged to do so and in fact
|
|
||||||
deprecated. In general we no longer recommend custom error handler
|
|
||||||
attaching via assignments to the underlying dictionary due to the more
|
|
||||||
complex internal handling to support arbitrary exception classes and
|
|
||||||
blueprints. See :meth:`Flask.errorhandler` for more information.
|
|
||||||
|
|
||||||
The proper upgrade is to change this::
|
|
||||||
|
|
||||||
app.error_handlers[403] = handle_error
|
|
||||||
|
|
||||||
Into this::
|
|
||||||
|
|
||||||
app.register_error_handler(403, handle_error)
|
|
||||||
|
|
||||||
Alternatively you should just attach the function with a decorator::
|
|
||||||
|
|
||||||
@app.errorhandler(403)
|
|
||||||
def handle_error(e):
|
|
||||||
...
|
|
||||||
|
|
||||||
(Note that :meth:`register_error_handler` is new in Flask 0.7)
|
|
||||||
|
|
||||||
Blueprint Support
|
|
||||||
`````````````````
|
|
||||||
|
|
||||||
Blueprints replace the previous concept of “Modules” in Flask. They
|
|
||||||
provide better semantics for various features and work better with large
|
|
||||||
applications. The update script provided should be able to upgrade your
|
|
||||||
applications automatically, but there might be some cases where it fails
|
|
||||||
to upgrade. What changed?
|
|
||||||
|
|
||||||
- Blueprints need explicit names. Modules had an automatic name
|
|
||||||
guessing scheme where the shortname for the module was taken from the
|
|
||||||
last part of the import module. The upgrade script tries to guess
|
|
||||||
that name but it might fail as this information could change at
|
|
||||||
runtime.
|
|
||||||
- Blueprints have an inverse behavior for :meth:`url_for`. Previously
|
|
||||||
``.foo`` told :meth:`url_for` that it should look for the endpoint
|
|
||||||
``foo`` on the application. Now it means “relative to current module”.
|
|
||||||
The script will inverse all calls to :meth:`url_for` automatically for
|
|
||||||
you. It will do this in a very eager way so you might end up with
|
|
||||||
some unnecessary leading dots in your code if you're not using
|
|
||||||
modules.
|
|
||||||
- Blueprints do not automatically provide static folders. They will
|
|
||||||
also no longer automatically export templates from a folder called
|
|
||||||
:file:`templates` next to their location however but it can be enabled from
|
|
||||||
the constructor. Same with static files: if you want to continue
|
|
||||||
serving static files you need to tell the constructor explicitly the
|
|
||||||
path to the static folder (which can be relative to the blueprint's
|
|
||||||
module path).
|
|
||||||
- Rendering templates was simplified. Now the blueprints can provide
|
|
||||||
template folders which are added to a general template searchpath.
|
|
||||||
This means that you need to add another subfolder with the blueprint's
|
|
||||||
name into that folder if you want :file:`blueprintname/template.html` as
|
|
||||||
the template name.
|
|
||||||
|
|
||||||
If you continue to use the ``Module`` object which is deprecated, Flask will
|
|
||||||
restore the previous behavior as good as possible. However we strongly
|
|
||||||
recommend upgrading to the new blueprints as they provide a lot of useful
|
|
||||||
improvement such as the ability to attach a blueprint multiple times,
|
|
||||||
blueprint specific error handlers and a lot more.
|
|
||||||
|
|
||||||
|
|
||||||
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 post-processing. If you
|
|
||||||
depend on the order of execution of post-request functions, be sure to
|
|
||||||
change the order.
|
|
||||||
|
|
||||||
Another change that breaks backwards compatibility is that context
|
|
||||||
processors will no longer override values passed directly to the template
|
|
||||||
rendering function. If for example ``request`` is as variable passed
|
|
||||||
directly to the template, the default context processor will not override
|
|
||||||
it with the current request object. This makes it easier to extend
|
|
||||||
context processors later to inject additional variables without breaking
|
|
||||||
existing template not expecting them.
|
|
||||||
|
|
||||||
Version 0.5
|
|
||||||
-----------
|
|
||||||
|
|
||||||
Flask 0.5 is the first release that comes as a Python package instead of a
|
|
||||||
single module. There were a couple of internal refactoring so if you
|
|
||||||
depend on undocumented internal details you probably have to adapt the
|
|
||||||
imports.
|
|
||||||
|
|
||||||
The following changes may be relevant to your application:
|
|
||||||
|
|
||||||
- autoescaping no longer happens for all templates. Instead it is
|
|
||||||
configured to only happen on files ending with ``.html``, ``.htm``,
|
|
||||||
``.xml`` and ``.xhtml``. If you have templates with different
|
|
||||||
extensions you should override the
|
|
||||||
:meth:`~flask.Flask.select_jinja_autoescape` method.
|
|
||||||
- Flask no longer supports zipped applications in this release. This
|
|
||||||
functionality might come back in future releases if there is demand
|
|
||||||
for this feature. Removing support for this makes the Flask internal
|
|
||||||
code easier to understand and fixes a couple of small issues that make
|
|
||||||
debugging harder than necessary.
|
|
||||||
- The ``create_jinja_loader`` function is gone. If you want to customize
|
|
||||||
the Jinja loader now, use the
|
|
||||||
:meth:`~flask.Flask.create_jinja_environment` method instead.
|
|
||||||
|
|
||||||
Version 0.4
|
|
||||||
-----------
|
|
||||||
|
|
||||||
For application developers there are no changes that require changes in
|
|
||||||
your code. In case you are developing on a Flask extension however, and
|
|
||||||
that extension has a unittest-mode you might want to link the activation
|
|
||||||
of that mode to the new ``TESTING`` flag.
|
|
||||||
|
|
||||||
Version 0.3
|
|
||||||
-----------
|
|
||||||
|
|
||||||
Flask 0.3 introduces configuration support and logging as well as
|
|
||||||
categories for flashing messages. All these are features that are 100%
|
|
||||||
backwards compatible but you might want to take advantage of them.
|
|
||||||
|
|
||||||
Configuration Support
|
|
||||||
`````````````````````
|
|
||||||
|
|
||||||
The configuration support makes it easier to write any kind of application
|
|
||||||
that requires some sort of configuration. (Which most likely is the case
|
|
||||||
for any application out there).
|
|
||||||
|
|
||||||
If you previously had code like this::
|
|
||||||
|
|
||||||
app.debug = DEBUG
|
|
||||||
app.secret_key = SECRET_KEY
|
|
||||||
|
|
||||||
You no longer have to do that, instead you can just load a configuration
|
|
||||||
into the config object. How this works is outlined in :ref:`config`.
|
|
||||||
|
|
||||||
Logging Integration
|
|
||||||
```````````````````
|
|
||||||
|
|
||||||
Flask now configures a logger for you with some basic and useful defaults.
|
|
||||||
If you run your application in production and want to profit from
|
|
||||||
automatic error logging, you might be interested in attaching a proper log
|
|
||||||
handler. Also you can start logging warnings and errors into the logger
|
|
||||||
when appropriately. For more information on that, read
|
|
||||||
:ref:`application-errors`.
|
|
||||||
|
|
||||||
Categories for Flash Messages
|
|
||||||
`````````````````````````````
|
|
||||||
|
|
||||||
Flash messages can now have categories attached. This makes it possible
|
|
||||||
to render errors, warnings or regular messages differently for example.
|
|
||||||
This is an opt-in feature because it requires some rethinking in the code.
|
|
||||||
|
|
||||||
Read all about that in the :ref:`message-flashing-pattern` pattern.
|
|
|
@ -191,11 +191,9 @@ class Flask(_PackageBoundObject):
|
||||||
for loading the config are assumed to
|
for loading the config are assumed to
|
||||||
be relative to the instance path instead
|
be relative to the instance path instead
|
||||||
of the application root.
|
of the application root.
|
||||||
:param root_path: Flask by default will automatically calculate the path
|
:param root_path: The path to the root of the application files.
|
||||||
to the root of the application. In certain situations
|
This should only be set manually when it can't be detected
|
||||||
this cannot be achieved (for instance if the package
|
automatically, such as for namespace packages.
|
||||||
is a Python 3 namespace package) and needs to be
|
|
||||||
manually defined.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#: The class that is used for request objects. See :class:`~flask.Request`
|
#: The class that is used for request objects. See :class:`~flask.Request`
|
||||||
|
@ -2026,11 +2024,11 @@ class Flask(_PackageBoundObject):
|
||||||
without returning, is not allowed. The following types are allowed
|
without returning, is not allowed. The following types are allowed
|
||||||
for ``view_rv``:
|
for ``view_rv``:
|
||||||
|
|
||||||
``str`` (``unicode`` in Python 2)
|
``str``
|
||||||
A response object is created with the string encoded to UTF-8
|
A response object is created with the string encoded to UTF-8
|
||||||
as the body.
|
as the body.
|
||||||
|
|
||||||
``bytes`` (``str`` in Python 2)
|
``bytes``
|
||||||
A response object is created with the bytes as the body.
|
A response object is created with the bytes as the body.
|
||||||
|
|
||||||
``dict``
|
``dict``
|
||||||
|
|
|
@ -909,8 +909,8 @@ def _find_package_path(root_mod_name):
|
||||||
package_path = os.path.abspath(os.path.dirname(filename))
|
package_path = os.path.abspath(os.path.dirname(filename))
|
||||||
|
|
||||||
# In case the root module is a package we need to chop of the
|
# In case the root module is a package we need to chop of the
|
||||||
# rightmost part. This needs to go through a helper function
|
# rightmost part. This needs to go through a helper function
|
||||||
# because of python 3.3 namespace packages.
|
# because of namespace packages.
|
||||||
if _matching_loader_thinks_module_is_package(loader, root_mod_name):
|
if _matching_loader_thinks_module_is_package(loader, root_mod_name):
|
||||||
package_path = os.path.dirname(package_path)
|
package_path = os.path.dirname(package_path)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue