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
|
||||
:func:`flask.jsonify`. This introduces a security risk in ancient
|
||||
browsers. See :ref:`json-security` for details.
|
||||
browsers.
|
||||
- Added before_render_template signal.
|
||||
- Added ``**kwargs`` to :meth:`flask.Test.test_client` to support
|
||||
passing additional keyword arguments to the constructor of
|
||||
|
@ -567,8 +567,7 @@ Version 0.10
|
|||
Released 2013-06-13, codename Limoncello
|
||||
|
||||
- Changed default cookie serialization format from pickle to JSON to
|
||||
limit the impact an attacker can do if the secret key leaks. See
|
||||
:ref:`upgrading-to-010` for more information.
|
||||
limit the impact an attacker can do if the secret key leaks.
|
||||
- Added ``template_test`` methods in addition to the already existing
|
||||
``template_filter`` method family.
|
||||
- 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
|
||||
result in less bytes being transmitted over the network. It's
|
||||
disabled by default to not cause confusion with existing libraries
|
||||
that might expect ``flask.json.dumps`` to return bytestrings by
|
||||
default.
|
||||
that might expect ``flask.json.dumps`` to return bytes by default.
|
||||
- ``flask.g`` is now stored on the app context instead of the request
|
||||
context.
|
||||
- ``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
|
||||
etc.). Also this is conceptually only instance depending and outside
|
||||
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.
|
||||
- Implemented :meth:`~flask.testing.TestClient.session_transaction` to
|
||||
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
|
||||
at the end of a request regardless of whether an exception occurred.
|
||||
Also the behavior for ``after_request`` was changed. It's now no
|
||||
longer executed when an exception is raised. See
|
||||
:ref:`upgrading-to-new-teardown-handling`
|
||||
longer executed when an exception is raised.
|
||||
- Implemented :func:`flask.has_request_context`
|
||||
- Deprecated ``init_jinja_globals``. Override the
|
||||
: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
|
||||
database connection errors, timeouts from remote resources etc.).
|
||||
- Blueprints can provide blueprint specific error handlers.
|
||||
- Implemented generic :ref:`views` (class-based views).
|
||||
- Implemented generic class-based views.
|
||||
|
||||
|
||||
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.
|
||||
|
||||
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,
|
||||
3.5, 3.6, 3.7 and PyPy 2.7 installed to run all of the environments. Then run::
|
||||
combinations of Python and dependencies. If you don't have a Python
|
||||
version installed, it will be skipped with a warning message at the end.
|
||||
Run::
|
||||
|
||||
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
|
||||
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
|
||||
is accepted too. For example, copy the output of this to your config::
|
||||
application. It should be a long random ``bytes`` or ``str``. For
|
||||
example, copy the output of this to your config::
|
||||
|
||||
$ python -c 'import os; print(os.urandom(16))'
|
||||
b'_5#y2L"F4Q8z\n\xec]/'
|
||||
|
@ -302,10 +302,10 @@ The following configuration values are used internally by Flask:
|
|||
|
||||
.. py:data:: JSON_AS_ASCII
|
||||
|
||||
Serialize objects to ASCII-encoded JSON. If this is disabled, the JSON
|
||||
will be returned as a Unicode string, or encoded as ``UTF-8`` by
|
||||
``jsonify``. This has security implications when rendering the JSON into
|
||||
JavaScript in templates, and should typically remain enabled.
|
||||
Serialize objects to ASCII-encoded JSON. If this is disabled, the
|
||||
JSON returned from ``jsonify`` will contain Unicode characters. This
|
||||
has security implications when rendering the JSON into JavaScript in
|
||||
templates, and should typically remain enabled.
|
||||
|
||||
Default: ``True``
|
||||
|
||||
|
@ -678,7 +678,7 @@ locations are used:
|
|||
|
||||
- Installed module or package::
|
||||
|
||||
$PREFIX/lib/python2.X/site-packages/myapp
|
||||
$PREFIX/lib/pythonX.Y/site-packages/myapp
|
||||
$PREFIX/var/myapp-instance
|
||||
|
||||
``$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::
|
||||
|
||||
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'
|
||||
with open(activate_this) as file_:
|
||||
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
|
||||
of variables and take the return value as string.
|
||||
|
||||
But that's about where similarities end. Jinja2 for example has an
|
||||
extensive filter system, a certain way to do template inheritance, support
|
||||
for reusable blocks (macros) that can be used from inside templates and
|
||||
also from Python code, uses Unicode for all operations, supports
|
||||
iterative template rendering, configurable syntax and more. On the other
|
||||
hand an engine like Genshi is based on XML stream evaluation, template
|
||||
inheritance by taking the availability of XPath into account and more.
|
||||
Mako on the other hand treats templates similar to Python modules.
|
||||
But that's about where similarities end. Jinja2 for example has an
|
||||
extensive filter system, a certain way to do template inheritance,
|
||||
support for reusable blocks (macros) that can be used from inside
|
||||
templates and also from Python code, supports iterative template
|
||||
rendering, configurable syntax and more. On the other hand an engine
|
||||
like Genshi is based on XML stream evaluation, template inheritance by
|
||||
taking the availability of XPath into account and more. Mako on the
|
||||
other hand treats templates similar to Python modules.
|
||||
|
||||
When it comes to connecting a template engine with an application or
|
||||
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
|
||||
htmlfaq
|
||||
security
|
||||
unicode
|
||||
extensiondev
|
||||
styleguide
|
||||
upgrading
|
||||
changelog
|
||||
license
|
||||
contributing
|
||||
|
|
|
@ -3,11 +3,13 @@
|
|||
Installation
|
||||
============
|
||||
|
||||
|
||||
Python Version
|
||||
--------------
|
||||
|
||||
We recommend using the latest version of Python 3. Flask supports Python 3.5
|
||||
and newer, Python 2.7, and PyPy.
|
||||
We recommend using the latest version of Python. Flask supports Python
|
||||
3.6 and newer.
|
||||
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
@ -31,6 +33,7 @@ These distributions will be installed automatically when installing Flask.
|
|||
.. _ItsDangerous: https://palletsprojects.com/p/itsdangerous/
|
||||
.. _Click: https://palletsprojects.com/p/click/
|
||||
|
||||
|
||||
Optional dependencies
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
@ -51,6 +54,7 @@ use them if you install them.
|
|||
.. _python-dotenv: https://github.com/theskumar/python-dotenv#readme
|
||||
.. _watchdog: https://pythonhosted.org/watchdog/
|
||||
|
||||
|
||||
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
|
||||
the operating system's packages.
|
||||
|
||||
Python 3 comes bundled with the :mod:`venv` module to create virtual
|
||||
environments. If you're using a modern version of Python, you can continue on
|
||||
to the next section.
|
||||
Python comes bundled with the :mod:`venv` module to create virtual
|
||||
environments.
|
||||
|
||||
If you're using Python 2, see :ref:`install-install-virtualenv` first.
|
||||
|
||||
.. _install-create-env:
|
||||
|
||||
Create an environment
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -91,18 +91,6 @@ On Windows:
|
|||
|
||||
$ 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:
|
||||
|
||||
|
@ -121,12 +109,15 @@ On Windows:
|
|||
|
||||
> 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
|
||||
-------------
|
||||
|
||||
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
|
||||
|
||||
|
@ -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
|
||||
: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.
|
||||
- **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
|
||||
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.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,
|
||||
autoflush=False,
|
||||
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.orm import scoped_session, sessionmaker
|
||||
|
||||
engine = create_engine('sqlite:////tmp/test.db', convert_unicode=True)
|
||||
engine = create_engine('sqlite:////tmp/test.db')
|
||||
metadata = MetaData()
|
||||
db_session = scoped_session(sessionmaker(autocommit=False,
|
||||
autoflush=False,
|
||||
|
@ -179,7 +179,7 @@ you basically only need the engine::
|
|||
|
||||
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)
|
||||
|
||||
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
|
||||
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
|
||||
with the ``|safe`` filter.
|
||||
the input element. Note that WTForms returns standard Python strings,
|
||||
so we have to tell Jinja2 that this data is already HTML-escaped with
|
||||
the ``|safe`` filter.
|
||||
|
||||
Here is the :file:`register.html` template for the function we used above, which
|
||||
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.
|
||||
2. You can change your URLs in one go instead of needing to remember to
|
||||
manually change hard-coded URLs.
|
||||
3. URL building handles escaping of special characters and Unicode data
|
||||
transparently.
|
||||
3. URL building handles escaping of special characters transparently.
|
||||
4. The generated paths are always absolute, avoiding unexpected behavior
|
||||
of relative paths in browsers.
|
||||
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
|
||||
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
|
||||
Unicode text, use :meth:`get_data(as_text=True) <werkzeug.wrappers.BaseResponse.get_data>`
|
||||
``data``. Bytes must be compared to bytes. If you want to compare text,
|
||||
use :meth:`get_data(as_text=True) <werkzeug.wrappers.BaseResponse.get_data>`
|
||||
instead.
|
||||
|
||||
``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
|
||||
be relative to the instance path instead
|
||||
of the application root.
|
||||
:param root_path: Flask by default will automatically calculate the path
|
||||
to the root of the application. In certain situations
|
||||
this cannot be achieved (for instance if the package
|
||||
is a Python 3 namespace package) and needs to be
|
||||
manually defined.
|
||||
:param root_path: The path to the root of the application files.
|
||||
This should only be set manually when it can't be detected
|
||||
automatically, such as for namespace packages.
|
||||
"""
|
||||
|
||||
#: 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
|
||||
for ``view_rv``:
|
||||
|
||||
``str`` (``unicode`` in Python 2)
|
||||
``str``
|
||||
A response object is created with the string encoded to UTF-8
|
||||
as the body.
|
||||
|
||||
``bytes`` (``str`` in Python 2)
|
||||
``bytes``
|
||||
A response object is created with the bytes as the body.
|
||||
|
||||
``dict``
|
||||
|
|
|
@ -909,8 +909,8 @@ def _find_package_path(root_mod_name):
|
|||
package_path = os.path.abspath(os.path.dirname(filename))
|
||||
|
||||
# In case the root module is a package we need to chop of the
|
||||
# rightmost part. This needs to go through a helper function
|
||||
# because of python 3.3 namespace packages.
|
||||
# rightmost part. This needs to go through a helper function
|
||||
# because of namespace packages.
|
||||
if _matching_loader_thinks_module_is_package(loader, root_mod_name):
|
||||
package_path = os.path.dirname(package_path)
|
||||
|
||||
|
|
Loading…
Reference in New Issue