mirror of https://github.com/pallets/flask.git
Factor in code review comments and refactor functions to be more naturally split.
This commit is contained in:
parent
7a1a594b26
commit
48c2925664
119
flask/cli.py
119
flask/cli.py
|
|
@ -82,42 +82,67 @@ def find_best_app(script_info, module):
|
|||
)
|
||||
|
||||
|
||||
def call_factory(func, script_info):
|
||||
"""Checks if the given app factory function has an argument named
|
||||
``script_info`` or just a single argument and calls the function passing
|
||||
``script_info`` if so. Otherwise, calls the function without any arguments
|
||||
and returns the result.
|
||||
def call_factory(app_factory, script_info, arguments=()):
|
||||
"""Takes an app factory, a ``script_info` object and optionally a tuple
|
||||
of arguments. Checks for the existence of a script_info argument and calls
|
||||
the app_factory depending on that and the arguments provided.
|
||||
"""
|
||||
arguments = getargspec(func).args
|
||||
if 'script_info' in arguments:
|
||||
return func(script_info=script_info)
|
||||
elif len(arguments) == 1:
|
||||
return func(script_info)
|
||||
return func()
|
||||
|
||||
|
||||
def call_factory_from_regex(match, mod, script_info):
|
||||
"""Checks if the given regex match has specified arguments and if the
|
||||
function takes a ``script_info`` argument and calls the function with
|
||||
the appropriate arguments."""
|
||||
function_name = match.group(1)
|
||||
arguments = match.group(2)
|
||||
if arguments:
|
||||
arguments = ast.literal_eval(
|
||||
"({arguments}, )".format(arguments=arguments))
|
||||
else:
|
||||
arguments = ()
|
||||
app_factory = getattr(mod, function_name, None)
|
||||
app_factory_arg_names = getargspec(app_factory).args
|
||||
if 'script_info' in app_factory_arg_names:
|
||||
app = app_factory(*arguments, script_info=script_info)
|
||||
arg_names = getargspec(app_factory).args
|
||||
if 'script_info' in arg_names:
|
||||
return app_factory(*arguments, script_info=script_info)
|
||||
elif arguments:
|
||||
app = app_factory(*arguments)
|
||||
elif not arguments and len(app_factory_arg_names) == 1:
|
||||
app = app_factory(script_info)
|
||||
return app_factory(*arguments)
|
||||
elif not arguments and len(arg_names) == 1:
|
||||
return app_factory(script_info)
|
||||
return app_factory()
|
||||
|
||||
|
||||
def find_app_by_string(string, script_info, module):
|
||||
"""Checks if the given string is a variable name or a function. If it is
|
||||
a function, it checks for specified arguments and whether it takes
|
||||
a ``script_info`` argument and calls the function with the appropriate
|
||||
arguments. If it is a """
|
||||
from . import Flask
|
||||
function_regex = r'^(?P<name>\w+)(?:\((?P<args>.*)\))?$'
|
||||
match = re.match(function_regex, string)
|
||||
if match:
|
||||
name, args = match.groups()
|
||||
try:
|
||||
if args is not None:
|
||||
args = args.rstrip(' ,')
|
||||
if args:
|
||||
args = ast.literal_eval(
|
||||
"({args}, )".format(args=args))
|
||||
else:
|
||||
args = ()
|
||||
app_factory = getattr(module, name, None)
|
||||
app = call_factory(app_factory, script_info, args)
|
||||
else:
|
||||
attr = getattr(module, name, None)
|
||||
if inspect.isfunction(attr):
|
||||
app = call_factory(attr, script_info)
|
||||
else:
|
||||
app = attr
|
||||
|
||||
if isinstance(app, Flask):
|
||||
return app
|
||||
else:
|
||||
raise RuntimeError('Failed to find application in module '
|
||||
'"{name}"'.format(name=module))
|
||||
except TypeError as e:
|
||||
new_error = NoAppException(
|
||||
'{e}\nThe app factory "{factory}" in module "{module}" could'
|
||||
' not be called with the specified arguments (and a'
|
||||
' script_info argument automatically added if applicable).'
|
||||
' Did you make sure to use the right number of arguments as'
|
||||
' well as not using keyword arguments or'
|
||||
' non-literals?'.format(e=e, factory=string, module=module))
|
||||
reraise(NoAppException, new_error, sys.exc_info()[2])
|
||||
else:
|
||||
app = app_factory()
|
||||
return app
|
||||
raise NoAppException(
|
||||
'The provided string "{string}" is not a valid variable name'
|
||||
'or function expression.'.format(string=string))
|
||||
|
||||
|
||||
def prepare_exec_for_file(filename):
|
||||
"""Given a filename this will try to calculate the python path, add it
|
||||
|
|
@ -174,33 +199,9 @@ def locate_app(script_info, app_id):
|
|||
|
||||
mod = sys.modules[module]
|
||||
if app_obj is None:
|
||||
app = find_best_app(script_info, mod)
|
||||
return find_best_app(script_info, mod)
|
||||
else:
|
||||
function_regex = r'^([\w_][\w_\d]*)\((.*)\)$'
|
||||
match = re.match(function_regex, app_obj)
|
||||
try:
|
||||
if match:
|
||||
app = call_factory_from_regex(match, mod, script_info)
|
||||
else:
|
||||
attr = getattr(mod, app_obj, None)
|
||||
if inspect.isfunction(attr):
|
||||
app = call_factory(attr, script_info)
|
||||
else:
|
||||
app = attr
|
||||
except TypeError as e:
|
||||
new_error = NoAppException(
|
||||
'{e}\nThe app factory "{factory}" in module "{module}" could'
|
||||
' not be called with the specified arguments (and a'
|
||||
' script_info argument automatically added if applicable).'
|
||||
' Did you make sure to use the right number of arguments as'
|
||||
' well as not using keyword arguments or'
|
||||
' non-literals?'.format(e=e, factory=app_obj, module=module))
|
||||
reraise(NoAppException, new_error, sys.exc_info()[2])
|
||||
if app is None:
|
||||
raise RuntimeError('Failed to find application in module '
|
||||
'"{name}"'.format(name=module))
|
||||
|
||||
return app
|
||||
return find_app_by_string(app_obj, script_info, mod)
|
||||
|
||||
|
||||
def find_default_import_path():
|
||||
|
|
|
|||
|
|
@ -160,6 +160,9 @@ def test_locate_app(test_apps):
|
|||
assert locate_app(
|
||||
script_info, "cliapp.factory:create_app2('foo', 'bar')"
|
||||
).name == "create_app2_foo_bar"
|
||||
assert locate_app(
|
||||
script_info, "cliapp.factory:create_app2('foo', 'bar', )"
|
||||
).name == "create_app2_foo_bar"
|
||||
assert locate_app(
|
||||
script_info, "cliapp.factory:create_app3('baz', 'qux')"
|
||||
).name == "create_app3_baz_qux"
|
||||
|
|
@ -173,6 +176,9 @@ def test_locate_app(test_apps):
|
|||
pytest.raises(
|
||||
NoAppException, locate_app,
|
||||
script_info, "cliapp.factory:create_app2('foo')")
|
||||
pytest.raises(
|
||||
NoAppException, locate_app,
|
||||
script_info, "cliapp.factory:create_app ()")
|
||||
pytest.raises(
|
||||
NoAppException, locate_app, script_info, "cliapp.importerrorapp")
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue