remove Python 2 from docs

This commit is contained in:
David Lord 2020-04-03 11:58:16 -07:00
parent 96b4dcafc3
commit 7673835b3d
No known key found for this signature in database
GPG Key ID: 7A1C87E3F5BC42A8
17 changed files with 53 additions and 908 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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))

View File

@ -110,13 +110,13 @@ 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,

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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``

View File

@ -910,7 +910,7 @@ def _find_package_path(root_mod_name):
# 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)