Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecate flask.ext #1484

Merged
merged 4 commits into from
Apr 2, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 12 additions & 14 deletions docs/extensiondev.rst
Original file line number Diff line number Diff line change
Expand Up @@ -360,8 +360,7 @@ extension to be approved you have to follow these guidelines:
find a new maintainer including full source hosting transition and PyPI
access. If no maintainer is available, give access to the Flask core team.
1. An approved Flask extension must provide exactly one package or module
named ``flask_extensionname``. They might also reside inside a
``flaskext`` namespace packages though this is discouraged now.
named ``flask_extensionname``.
2. It must ship a testing suite that can either be invoked with ``make test``
or ``python setup.py test``. For test suites invoked with ``make
test`` the extension has to ensure that all dependencies for the test
Expand Down Expand Up @@ -399,20 +398,19 @@ extension to be approved you have to follow these guidelines:
Extension Import Transition
---------------------------

For a while we recommended using namespace packages for Flask extensions.
This turned out to be problematic in practice because many different
competing namespace package systems exist and pip would automatically
switch between different systems and this caused a lot of problems for
users.
In early versions of Flask we recommended using namespace packages for Flask
extensions, of the form ``flaskext.foo``. This turned out to be problematic in
practice because it meant that multiple ``flaskext`` packages coexist.
Consequently we have recommended to name extensions ``flask_foo`` over
``flaskext.foo`` for a long time.

Instead we now recommend naming packages ``flask_foo`` instead of the now
deprecated ``flaskext.foo``. Flask 0.8 introduces a redirect import
system that lets uses import from ``flask.ext.foo`` and it will try
``flask_foo`` first and if that fails ``flaskext.foo``.
Flask 0.8 introduced a redirect import system as a compatibility aid for app
developers: Importing ``flask.ext.foo`` would try ``flask_foo`` and
``flaskext.foo`` in that order.

Flask extensions should urge users to import from ``flask.ext.foo``
instead of ``flask_foo`` or ``flaskext_foo`` so that extensions can
transition to the new package name without affecting users.
As of Flask 1.0, most Flask extensions have transitioned to the new naming
schema. The ``flask.ext.foo`` compatibility alias is still in Flask 1.0 but is
now deprecated -- you should use ``flask_foo``.


.. _OAuth extension: http://pythonhosted.org/Flask-OAuth/
Expand Down
7 changes: 4 additions & 3 deletions docs/extensions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ Using Extensions
Extensions typically have documentation that goes along that shows how to
use it. There are no general rules in how extensions are supposed to
behave but they are imported from common locations. If you have an
extension called ``Flask-Foo`` or ``Foo-Flask`` it will be always
importable from ``flask.ext.foo``::
extension called ``Flask-Foo`` or ``Foo-Flask`` it should be always
importable from ``flask_foo``::

from flask.ext import foo
import flask_foo

Flask Before 0.8
----------------
Expand All @@ -44,5 +44,6 @@ And here is how you can use it::
Once the ``flaskext_compat`` module is activated the :data:`flask.ext` will
exist and you can start importing from there.


.. _Flask Extension Registry: http://flask.pocoo.org/extensions/
.. _flaskext_compat.py: https://raw.githubusercontent.com/mitsuhiko/flask/master/scripts/flaskext_compat.py
29 changes: 25 additions & 4 deletions docs/upgrading.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,17 @@ installation, make sure to pass it the :option:`-U` parameter::
Version 1.0
-----------

Debugging
+++++++++

Flask 1.0 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
Expand All @@ -37,18 +43,33 @@ 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.

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

Trying to register a handler on an instance now raises :exc:`ValueError`.
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/pocoo/flask-ext-migrate>`_ that is supposed to
automatically rewrite your imports for this.

.. _upgrading-to-010:

Expand Down
25 changes: 24 additions & 1 deletion flask/exthook.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,16 @@
"""
import sys
import os
import warnings
from ._compat import reraise


class ExtDeprecationWarning(DeprecationWarning):
pass

warnings.simplefilter('always', ExtDeprecationWarning)


class ExtensionImporter(object):
"""This importer redirects imports from this submodule to other locations.
This makes it possible to transition from the old flaskext.name to the
Expand All @@ -49,13 +56,21 @@ def install(self):
sys.meta_path[:] = [x for x in sys.meta_path if self != x] + [self]

def find_module(self, fullname, path=None):
if fullname.startswith(self.prefix):
if fullname.startswith(self.prefix) and \
fullname != 'flask.ext.ExtDeprecationWarning':
return self

def load_module(self, fullname):
if fullname in sys.modules:
return sys.modules[fullname]

modname = fullname.split('.', self.prefix_cutoff)[self.prefix_cutoff]

warnings.warn(
"Importing flask.ext.{x} is deprecated, use flask_{x} instead."
.format(x=modname), ExtDeprecationWarning
)

for path in self.module_choices:
realname = path % modname
try:
Expand Down Expand Up @@ -83,6 +98,14 @@ def load_module(self, fullname):
module = sys.modules[fullname] = sys.modules[realname]
if '.' not in modname:
setattr(sys.modules[self.wrapper_module], modname, module)

if realname.startswith('flaskext.'):
warnings.warn(
"Detected extension named flaskext.{x}, please rename it "
"to flask_{x}. The old form is deprecated."
.format(x=modname), ExtDeprecationWarning
)

return module
raise ImportError('No module named %s' % fullname)

Expand Down