Browse Source

Deprecate flask.ext

* Add deprecation warning to ext pkg

* Add docs on deprecation of flask.ext

* Improve deprecation warnings

* Add headers for better distinction, fix ordering issue of paragraphs
pull/1631/head
Markus Unterwaditzer 9 years ago
parent
commit
d3d8a4694a
  1. 26
      docs/extensiondev.rst
  2. 7
      docs/extensions.rst
  3. 29
      docs/upgrading.rst
  4. 25
      flask/exthook.py

26
docs/extensiondev.rst

@ -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 find a new maintainer including full source hosting transition and PyPI
access. If no maintainer is available, give access to the Flask core team. 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 1. An approved Flask extension must provide exactly one package or module
named ``flask_extensionname``. They might also reside inside a named ``flask_extensionname``.
``flaskext`` namespace packages though this is discouraged now.
2. It must ship a testing suite that can either be invoked with ``make test`` 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 or ``python setup.py test``. For test suites invoked with ``make
test`` the extension has to ensure that all dependencies for the test test`` the extension has to ensure that all dependencies for the test
@ -399,20 +398,19 @@ extension to be approved you have to follow these guidelines:
Extension Import Transition Extension Import Transition
--------------------------- ---------------------------
For a while we recommended using namespace packages for Flask extensions. In early versions of Flask we recommended using namespace packages for Flask
This turned out to be problematic in practice because many different extensions, of the form ``flaskext.foo``. This turned out to be problematic in
competing namespace package systems exist and pip would automatically practice because it meant that multiple ``flaskext`` packages coexist.
switch between different systems and this caused a lot of problems for Consequently we have recommended to name extensions ``flask_foo`` over
users. ``flaskext.foo`` for a long time.
Instead we now recommend naming packages ``flask_foo`` instead of the now Flask 0.8 introduced a redirect import system as a compatibility aid for app
deprecated ``flaskext.foo``. Flask 0.8 introduces a redirect import developers: Importing ``flask.ext.foo`` would try ``flask_foo`` and
system that lets uses import from ``flask.ext.foo`` and it will try ``flaskext.foo`` in that order.
``flask_foo`` first and if that fails ``flaskext.foo``.
Flask extensions should urge users to import from ``flask.ext.foo`` As of Flask 1.0, most Flask extensions have transitioned to the new naming
instead of ``flask_foo`` or ``flaskext_foo`` so that extensions can schema. The ``flask.ext.foo`` compatibility alias is still in Flask 1.0 but is
transition to the new package name without affecting users. now deprecated -- you should use ``flask_foo``.
.. _OAuth extension: http://pythonhosted.org/Flask-OAuth/ .. _OAuth extension: http://pythonhosted.org/Flask-OAuth/

7
docs/extensions.rst

@ -18,10 +18,10 @@ Using Extensions
Extensions typically have documentation that goes along that shows how to Extensions typically have documentation that goes along that shows how to
use it. There are no general rules in how extensions are supposed 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 behave but they are imported from common locations. If you have an
extension called ``Flask-Foo`` or ``Foo-Flask`` it will be always extension called ``Flask-Foo`` or ``Foo-Flask`` it should be always
importable from ``flask.ext.foo``:: importable from ``flask_foo``::
from flask.ext import foo import flask_foo
Flask Before 0.8 Flask Before 0.8
---------------- ----------------
@ -44,5 +44,6 @@ And here is how you can use it::
Once the ``flaskext_compat`` module is activated the :data:`flask.ext` will Once the ``flaskext_compat`` module is activated the :data:`flask.ext` will
exist and you can start importing from there. exist and you can start importing from there.
.. _Flask Extension Registry: http://flask.pocoo.org/extensions/ .. _Flask Extension Registry: http://flask.pocoo.org/extensions/
.. _flaskext_compat.py: https://raw.githubusercontent.com/mitsuhiko/flask/master/scripts/flaskext_compat.py .. _flaskext_compat.py: https://raw.githubusercontent.com/mitsuhiko/flask/master/scripts/flaskext_compat.py

29
docs/upgrading.rst

@ -24,11 +24,17 @@ installation, make sure to pass it the :option:`-U` parameter::
Version 1.0 Version 1.0
----------- -----------
Debugging
+++++++++
Flask 1.0 removed the ``debug_log_format`` attribute from Flask Flask 1.0 removed the ``debug_log_format`` attribute from Flask
applications. Instead the new ``LOGGER_HANDLER_POLICY`` configuration can applications. Instead the new ``LOGGER_HANDLER_POLICY`` configuration can
be used to disable the default log handlers and custom log handlers can be be used to disable the default log handlers and custom log handlers can be
set up. set up.
Error handling
++++++++++++++
The behavior of error handlers was changed. The behavior of error handlers was changed.
The precedence of handlers used to be based on the decoration/call order of The precedence of handlers used to be based on the decoration/call order of
:meth:`~flask.Flask.errorhandler` and :meth:`~flask.Flask.errorhandler` and
@ -37,9 +43,7 @@ Now the inheritance hierarchy takes precedence and handlers for more
specific exception classes are executed instead of more general ones. specific exception classes are executed instead of more general ones.
See :ref:`error-handlers` for specifics. See :ref:`error-handlers` for specifics.
The :func:`~flask.templating.render_template_string` function has changed to Trying to register a handler on an instance now raises :exc:`ValueError`.
autoescape template variables by default. This better matches the behavior
of :func:`~flask.templating.render_template`.
.. note:: .. note::
@ -47,8 +51,25 @@ of :func:`~flask.templating.render_template`.
only for exception *instances*. This was unintended and plain wrong, only for exception *instances*. This was unintended and plain wrong,
and therefore was replaced with the intended behavior of registering and therefore was replaced with the intended behavior of registering
handlers only using exception classes and HTTP error codes. 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: .. _upgrading-to-010:

25
flask/exthook.py

@ -21,9 +21,16 @@
""" """
import sys import sys
import os import os
import warnings
from ._compat import reraise from ._compat import reraise
class ExtDeprecationWarning(DeprecationWarning):
pass
warnings.simplefilter('always', ExtDeprecationWarning)
class ExtensionImporter(object): class ExtensionImporter(object):
"""This importer redirects imports from this submodule to other locations. """This importer redirects imports from this submodule to other locations.
This makes it possible to transition from the old flaskext.name to the This makes it possible to transition from the old flaskext.name to the
@ -49,13 +56,21 @@ class ExtensionImporter(object):
sys.meta_path[:] = [x for x in sys.meta_path if self != x] + [self] sys.meta_path[:] = [x for x in sys.meta_path if self != x] + [self]
def find_module(self, fullname, path=None): def find_module(self, fullname, path=None):
if fullname.startswith(self.prefix): if fullname.startswith(self.prefix) and \
fullname != 'flask.ext.ExtDeprecationWarning':
return self return self
def load_module(self, fullname): def load_module(self, fullname):
if fullname in sys.modules: if fullname in sys.modules:
return sys.modules[fullname] return sys.modules[fullname]
modname = fullname.split('.', self.prefix_cutoff)[self.prefix_cutoff] 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: for path in self.module_choices:
realname = path % modname realname = path % modname
try: try:
@ -83,6 +98,14 @@ class ExtensionImporter(object):
module = sys.modules[fullname] = sys.modules[realname] module = sys.modules[fullname] = sys.modules[realname]
if '.' not in modname: if '.' not in modname:
setattr(sys.modules[self.wrapper_module], modname, module) 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 return module
raise ImportError('No module named %s' % fullname) raise ImportError('No module named %s' % fullname)

Loading…
Cancel
Save