mirror of https://github.com/pallets/flask.git
deprecate passing script_info to factory
This commit is contained in:
parent
7e3b8abf99
commit
fcac7f11cf
|
@ -9,6 +9,9 @@ Unreleased
|
||||||
- JSON support no longer uses simplejson. To use another JSON module,
|
- JSON support no longer uses simplejson. To use another JSON module,
|
||||||
override ``app.json_encoder`` and ``json_decoder``. :issue:`3555`
|
override ``app.json_encoder`` and ``json_decoder``. :issue:`3555`
|
||||||
- The ``encoding`` option to JSON functions is deprecated. :pr:`3562`
|
- The ``encoding`` option to JSON functions is deprecated. :pr:`3562`
|
||||||
|
- Passing ``script_info`` to app factory functions is deprecated. This
|
||||||
|
was not portable outside the ``flask`` command. Use
|
||||||
|
``click.get_current_context().obj`` if it's needed. :issue:`3552`
|
||||||
- Add :meth:`sessions.SessionInterface.get_cookie_name` to allow
|
- Add :meth:`sessions.SessionInterface.get_cookie_name` to allow
|
||||||
setting the session cookie name dynamically. :pr:`3369`
|
setting the session cookie name dynamically. :pr:`3369`
|
||||||
- Add :meth:`Config.from_file` to load config using arbitrary file
|
- Add :meth:`Config.from_file` to load config using arbitrary file
|
||||||
|
|
10
docs/cli.rst
10
docs/cli.rst
|
@ -75,13 +75,9 @@ Within the given import, the command looks for an application instance named
|
||||||
found, the command looks for a factory function named ``create_app`` or
|
found, the command looks for a factory function named ``create_app`` or
|
||||||
``make_app`` that returns an instance.
|
``make_app`` that returns an instance.
|
||||||
|
|
||||||
When calling an application factory, if the factory takes an argument named
|
If parentheses follow the factory name, their contents are parsed as
|
||||||
``script_info``, then the :class:`~cli.ScriptInfo` instance is passed as a
|
Python literals and passed as arguments to the function. This means that
|
||||||
keyword argument. If the application factory takes only one argument and no
|
strings must still be in quotes.
|
||||||
parentheses follow the factory name, the :class:`~cli.ScriptInfo` instance
|
|
||||||
is passed as a positional argument. If parentheses follow the factory name,
|
|
||||||
their contents are parsed as Python literals and passes as arguments to the
|
|
||||||
function. This means that strings must still be in quotes.
|
|
||||||
|
|
||||||
|
|
||||||
Run the Development Server
|
Run the Development Server
|
||||||
|
|
|
@ -5,6 +5,7 @@ import platform
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
|
import warnings
|
||||||
from functools import update_wrapper
|
from functools import update_wrapper
|
||||||
from operator import attrgetter
|
from operator import attrgetter
|
||||||
from threading import Lock
|
from threading import Lock
|
||||||
|
@ -91,14 +92,22 @@ def call_factory(script_info, app_factory, arguments=()):
|
||||||
the app_factory depending on that and the arguments provided.
|
the app_factory depending on that and the arguments provided.
|
||||||
"""
|
"""
|
||||||
args_spec = inspect.getfullargspec(app_factory)
|
args_spec = inspect.getfullargspec(app_factory)
|
||||||
arg_names = args_spec.args
|
|
||||||
arg_defaults = args_spec.defaults
|
|
||||||
|
|
||||||
if "script_info" in arg_names:
|
if "script_info" in args_spec.args:
|
||||||
|
warnings.warn(
|
||||||
|
"The 'script_info' argument is deprecated and will not be"
|
||||||
|
" passed to the app factory function in 2.1.",
|
||||||
|
DeprecationWarning,
|
||||||
|
)
|
||||||
return app_factory(*arguments, script_info=script_info)
|
return app_factory(*arguments, script_info=script_info)
|
||||||
elif arguments:
|
elif arguments:
|
||||||
return app_factory(*arguments)
|
return app_factory(*arguments)
|
||||||
elif not arguments and len(arg_names) == 1 and arg_defaults is None:
|
elif not arguments and len(args_spec.args) == 1 and args_spec.defaults is None:
|
||||||
|
warnings.warn(
|
||||||
|
"Script info is deprecated and will not be passed as the"
|
||||||
|
" first argument to the app factory function in 2.1.",
|
||||||
|
DeprecationWarning,
|
||||||
|
)
|
||||||
return app_factory(script_info)
|
return app_factory(script_info)
|
||||||
|
|
||||||
return app_factory()
|
return app_factory()
|
||||||
|
@ -131,10 +140,8 @@ def _called_with_wrong_args(factory):
|
||||||
|
|
||||||
|
|
||||||
def find_app_by_string(script_info, module, app_name):
|
def find_app_by_string(script_info, module, app_name):
|
||||||
"""Checks if the given string is a variable name or a function. If it is a
|
"""Check if the given string is a variable name or a function. Call
|
||||||
function, it checks for specified arguments and whether it takes a
|
a function to get the app instance, or return the variable directly.
|
||||||
``script_info`` argument and calls the function with the appropriate
|
|
||||||
arguments.
|
|
||||||
"""
|
"""
|
||||||
from . import Flask
|
from . import Flask
|
||||||
|
|
||||||
|
|
|
@ -9,9 +9,5 @@ def create_app2(foo, bar):
|
||||||
return Flask("_".join(["app2", foo, bar]))
|
return Flask("_".join(["app2", foo, bar]))
|
||||||
|
|
||||||
|
|
||||||
def create_app3(foo, script_info):
|
|
||||||
return Flask("_".join(["app3", foo, script_info.data["test"]]))
|
|
||||||
|
|
||||||
|
|
||||||
def no_app():
|
def no_app():
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -67,32 +67,40 @@ def test_find_best_app(test_apps):
|
||||||
def create_app():
|
def create_app():
|
||||||
return Flask("appname")
|
return Flask("appname")
|
||||||
|
|
||||||
assert isinstance(find_best_app(script_info, Module), Flask)
|
app = find_best_app(script_info, Module)
|
||||||
assert find_best_app(script_info, Module).name == "appname"
|
assert isinstance(app, Flask)
|
||||||
|
assert app.name == "appname"
|
||||||
|
|
||||||
class Module:
|
class Module:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create_app(foo):
|
def create_app(foo):
|
||||||
return Flask("appname")
|
return Flask("appname")
|
||||||
|
|
||||||
assert isinstance(find_best_app(script_info, Module), Flask)
|
with pytest.deprecated_call(match="Script info"):
|
||||||
assert find_best_app(script_info, Module).name == "appname"
|
app = find_best_app(script_info, Module)
|
||||||
|
|
||||||
|
assert isinstance(app, Flask)
|
||||||
|
assert app.name == "appname"
|
||||||
|
|
||||||
class Module:
|
class Module:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create_app(foo=None, script_info=None):
|
def create_app(foo=None, script_info=None):
|
||||||
return Flask("appname")
|
return Flask("appname")
|
||||||
|
|
||||||
assert isinstance(find_best_app(script_info, Module), Flask)
|
with pytest.deprecated_call(match="script_info"):
|
||||||
assert find_best_app(script_info, Module).name == "appname"
|
app = find_best_app(script_info, Module)
|
||||||
|
|
||||||
|
assert isinstance(app, Flask)
|
||||||
|
assert app.name == "appname"
|
||||||
|
|
||||||
class Module:
|
class Module:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def make_app():
|
def make_app():
|
||||||
return Flask("appname")
|
return Flask("appname")
|
||||||
|
|
||||||
assert isinstance(find_best_app(script_info, Module), Flask)
|
app = find_best_app(script_info, Module)
|
||||||
assert find_best_app(script_info, Module).name == "appname"
|
assert isinstance(app, Flask)
|
||||||
|
assert app.name == "appname"
|
||||||
|
|
||||||
class Module:
|
class Module:
|
||||||
myapp = Flask("appname1")
|
myapp = Flask("appname1")
|
||||||
|
@ -199,15 +207,12 @@ def test_prepare_import(request, value, path, result):
|
||||||
("cliapp.factory", 'create_app2("foo", "bar")', "app2_foo_bar"),
|
("cliapp.factory", 'create_app2("foo", "bar")', "app2_foo_bar"),
|
||||||
# trailing comma space
|
# trailing comma space
|
||||||
("cliapp.factory", 'create_app2("foo", "bar", )', "app2_foo_bar"),
|
("cliapp.factory", 'create_app2("foo", "bar", )', "app2_foo_bar"),
|
||||||
# takes script_info
|
|
||||||
("cliapp.factory", 'create_app3("foo")', "app3_foo_spam"),
|
|
||||||
# strip whitespace
|
# strip whitespace
|
||||||
("cliapp.factory", " create_app () ", "app"),
|
("cliapp.factory", " create_app () ", "app"),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
def test_locate_app(test_apps, iname, aname, result):
|
def test_locate_app(test_apps, iname, aname, result):
|
||||||
info = ScriptInfo()
|
info = ScriptInfo()
|
||||||
info.data["test"] = "spam"
|
|
||||||
assert locate_app(info, iname, aname).name == result
|
assert locate_app(info, iname, aname).name == result
|
||||||
|
|
||||||
|
|
||||||
|
@ -286,7 +291,7 @@ def test_scriptinfo(test_apps, monkeypatch):
|
||||||
assert app.name == "testapp"
|
assert app.name == "testapp"
|
||||||
assert obj.load_app() is app
|
assert obj.load_app() is app
|
||||||
|
|
||||||
def create_app(info):
|
def create_app():
|
||||||
return Flask("createapp")
|
return Flask("createapp")
|
||||||
|
|
||||||
obj = ScriptInfo(create_app=create_app)
|
obj = ScriptInfo(create_app=create_app)
|
||||||
|
@ -324,7 +329,7 @@ def test_with_appcontext(runner):
|
||||||
def testcmd():
|
def testcmd():
|
||||||
click.echo(current_app.name)
|
click.echo(current_app.name)
|
||||||
|
|
||||||
obj = ScriptInfo(create_app=lambda info: Flask("testapp"))
|
obj = ScriptInfo(create_app=lambda: Flask("testapp"))
|
||||||
|
|
||||||
result = runner.invoke(testcmd, obj=obj)
|
result = runner.invoke(testcmd, obj=obj)
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
|
@ -350,7 +355,7 @@ def test_appgroup(runner):
|
||||||
def test2():
|
def test2():
|
||||||
click.echo(current_app.name)
|
click.echo(current_app.name)
|
||||||
|
|
||||||
obj = ScriptInfo(create_app=lambda info: Flask("testappgroup"))
|
obj = ScriptInfo(create_app=lambda: Flask("testappgroup"))
|
||||||
|
|
||||||
result = runner.invoke(cli, ["test"], obj=obj)
|
result = runner.invoke(cli, ["test"], obj=obj)
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
|
@ -364,7 +369,7 @@ def test_appgroup(runner):
|
||||||
def test_flaskgroup(runner):
|
def test_flaskgroup(runner):
|
||||||
"""Test FlaskGroup."""
|
"""Test FlaskGroup."""
|
||||||
|
|
||||||
def create_app(info):
|
def create_app():
|
||||||
return Flask("flaskgroup")
|
return Flask("flaskgroup")
|
||||||
|
|
||||||
@click.group(cls=FlaskGroup, create_app=create_app)
|
@click.group(cls=FlaskGroup, create_app=create_app)
|
||||||
|
@ -384,7 +389,7 @@ def test_flaskgroup(runner):
|
||||||
def test_flaskgroup_debug(runner, set_debug_flag):
|
def test_flaskgroup_debug(runner, set_debug_flag):
|
||||||
"""Test FlaskGroup debug flag behavior."""
|
"""Test FlaskGroup debug flag behavior."""
|
||||||
|
|
||||||
def create_app(info):
|
def create_app():
|
||||||
app = Flask("flaskgroup")
|
app = Flask("flaskgroup")
|
||||||
app.debug = True
|
app.debug = True
|
||||||
return app
|
return app
|
||||||
|
@ -405,7 +410,7 @@ def test_flaskgroup_debug(runner, set_debug_flag):
|
||||||
def test_print_exceptions(runner):
|
def test_print_exceptions(runner):
|
||||||
"""Print the stacktrace if the CLI."""
|
"""Print the stacktrace if the CLI."""
|
||||||
|
|
||||||
def create_app(info):
|
def create_app():
|
||||||
raise Exception("oh no")
|
raise Exception("oh no")
|
||||||
return Flask("flaskgroup")
|
return Flask("flaskgroup")
|
||||||
|
|
||||||
|
@ -422,7 +427,7 @@ def test_print_exceptions(runner):
|
||||||
class TestRoutes:
|
class TestRoutes:
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def invoke(self, runner):
|
def invoke(self, runner):
|
||||||
def create_app(info):
|
def create_app():
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
app.testing = True
|
app.testing = True
|
||||||
|
|
||||||
|
@ -441,7 +446,7 @@ class TestRoutes:
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def invoke_no_routes(self, runner):
|
def invoke_no_routes(self, runner):
|
||||||
def create_app(info):
|
def create_app():
|
||||||
app = Flask(__name__, static_folder=None)
|
app = Flask(__name__, static_folder=None)
|
||||||
app.testing = True
|
app.testing = True
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue