From d3d8a4694a9c1601e213d6b5f27fab34615609b7 Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Sat, 2 Apr 2016 21:06:30 +0200 Subject: [PATCH] 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 --- docs/extensiondev.rst | 26 ++++++++++++-------------- docs/extensions.rst | 7 ++++--- docs/upgrading.rst | 29 +++++++++++++++++++++++++---- flask/exthook.py | 25 ++++++++++++++++++++++++- 4 files changed, 65 insertions(+), 22 deletions(-) diff --git a/docs/extensiondev.rst b/docs/extensiondev.rst index 918187fe..9a4cd14c 100644 --- a/docs/extensiondev.rst +++ b/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 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 @@ -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/ diff --git a/docs/extensions.rst b/docs/extensions.rst index 748b11b3..1371f823 100644 --- a/docs/extensions.rst +++ b/docs/extensions.rst @@ -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 ---------------- @@ -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 diff --git a/docs/upgrading.rst b/docs/upgrading.rst index fca4d75b..40f8b0bc 100644 --- a/docs/upgrading.rst +++ b/docs/upgrading.rst @@ -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 @@ -37,9 +43,7 @@ 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:: @@ -47,8 +51,25 @@ of :func:`~flask.templating.render_template`. 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 +`_ that is supposed to +automatically rewrite your imports for this. .. _upgrading-to-010: diff --git a/flask/exthook.py b/flask/exthook.py index 05ac4e35..6522e063 100644 --- a/flask/exthook.py +++ b/flask/exthook.py @@ -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 @@ -49,13 +56,21 @@ class ExtensionImporter(object): 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: @@ -83,6 +98,14 @@ class ExtensionImporter(object): 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)