Browse Source

Merge remote-tracking branch 'pallets/master' into 2313-refactor-gevent-tests-into-class

pull/2324/head
Rene A. Zelaya 7 years ago
parent
commit
f40617029a
  1. 5
      CHANGES
  2. 9
      docs/quickstart.rst
  3. 2
      flask/_compat.py
  4. 28
      flask/cli.py
  5. 2
      setup.py
  6. 62
      tests/test_cli.py
  7. 8
      tox.ini

5
CHANGES

@ -42,6 +42,10 @@ Major release, unreleased
(`#2282`_)
- Auto-detect zero-argument app factory called ``create_app`` or ``make_app``
from ``FLASK_APP``. (`#2297`_)
- Factory functions are not required to take a ``script_info`` parameter to
work with the ``flask`` command. If they take a single parameter or a
parameter named ``script_info``, the ``ScriptInfo`` object will be passed.
(`#2319`_)
.. _#1489: https://github.com/pallets/flask/pull/1489
.. _#1898: https://github.com/pallets/flask/pull/1898
@ -53,6 +57,7 @@ Major release, unreleased
.. _#2259: https://github.com/pallets/flask/pull/2259
.. _#2282: https://github.com/pallets/flask/pull/2282
.. _#2297: https://github.com/pallets/flask/pull/2297
.. _#2319: https://github.com/pallets/flask/pull/2319
Version 0.12.2
--------------

9
docs/quickstart.rst

@ -50,7 +50,14 @@ to tell your terminal the application to work with by exporting the
$ flask run
* Running on http://127.0.0.1:5000/
If you are on Windows you need to use ``set`` instead of ``export``.
If you are on Windows, the environment variable syntax depends on command line
interpreter. On Command Prompt::
C:\path\to\app>set FLASK_APP=hello.py
And on PowerShell::
PS C:\path\to\app> $env:FLASK_APP = "hello.py"
Alternatively you can use :command:`python -m flask`::

2
flask/_compat.py

@ -25,6 +25,7 @@ if not PY2:
itervalues = lambda d: iter(d.values())
iteritems = lambda d: iter(d.items())
from inspect import getfullargspec as getargspec
from io import StringIO
def reraise(tp, value, tb=None):
@ -43,6 +44,7 @@ else:
itervalues = lambda d: d.itervalues()
iteritems = lambda d: d.iteritems()
from inspect import getargspec
from cStringIO import StringIO
exec('def reraise(tp, value, tb=None):\n raise tp, value, tb')

28
flask/cli.py

@ -22,13 +22,14 @@ from . import __version__
from ._compat import iteritems, reraise
from .globals import current_app
from .helpers import get_debug_flag
from ._compat import getargspec
class NoAppException(click.UsageError):
"""Raised if an application cannot be found or loaded."""
def find_best_app(module):
def find_best_app(script_info, module):
"""Given a module instance this tries to find the best possible
application in the module or raises an exception.
"""
@ -60,8 +61,7 @@ def find_best_app(module):
if callable(app_factory):
try:
app = app_factory()
app = call_factory(app_factory, script_info)
if isinstance(app, Flask):
return app
except TypeError:
@ -79,6 +79,20 @@ def find_best_app(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.
"""
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 prepare_exec_for_file(filename):
"""Given a filename this will try to calculate the python path, add it
to the search path and return the actual module name that is expected.
@ -108,7 +122,7 @@ def prepare_exec_for_file(filename):
return '.'.join(module[::-1])
def locate_app(app_id):
def locate_app(script_info, app_id):
"""Attempts to locate the application."""
__traceback_hide__ = True
if ':' in app_id:
@ -134,7 +148,7 @@ def locate_app(app_id):
mod = sys.modules[module]
if app_obj is None:
app = find_best_app(mod)
app = find_best_app(script_info, mod)
else:
app = getattr(mod, app_obj, None)
if app is None:
@ -259,7 +273,7 @@ class ScriptInfo(object):
if self._loaded_app is not None:
return self._loaded_app
if self.create_app is not None:
rv = self.create_app(self)
rv = call_factory(self.create_app, self)
else:
if not self.app_import_path:
raise NoAppException(
@ -267,7 +281,7 @@ class ScriptInfo(object):
'the FLASK_APP environment variable.\n\nFor more '
'information see '
'http://flask.pocoo.org/docs/latest/quickstart/')
rv = locate_app(self.app_import_path)
rv = locate_app(self, self.app_import_path)
debug = get_debug_flag()
if debug is not None:
rv.debug = debug

2
setup.py

@ -74,7 +74,7 @@ setup(
'Werkzeug>=0.7',
'Jinja2>=2.4',
'itsdangerous>=0.21',
'click>=2.0',
'click>=4.0',
],
classifiers=[
'Development Status :: 4 - Beta',

62
tests/test_cli.py

@ -39,60 +39,75 @@ def test_cli_name(test_apps):
def test_find_best_app(test_apps):
"""Test if `find_best_app` behaves as expected with different combinations of input."""
script_info = ScriptInfo()
class Module:
app = Flask('appname')
assert find_best_app(Module) == Module.app
assert find_best_app(script_info, Module) == Module.app
class Module:
application = Flask('appname')
assert find_best_app(Module) == Module.application
assert find_best_app(script_info, Module) == Module.application
class Module:
myapp = Flask('appname')
assert find_best_app(Module) == Module.myapp
assert find_best_app(script_info, Module) == Module.myapp
class Module:
@staticmethod
def create_app():
return Flask('appname')
assert isinstance(find_best_app(Module), Flask)
assert find_best_app(Module).name == 'appname'
assert isinstance(find_best_app(script_info, Module), Flask)
assert find_best_app(script_info, Module).name == 'appname'
class Module:
@staticmethod
def create_app(foo):
return Flask('appname')
assert isinstance(find_best_app(script_info, Module), Flask)
assert find_best_app(script_info, Module).name == 'appname'
class Module:
@staticmethod
def create_app(foo=None, script_info=None):
return Flask('appname')
assert isinstance(find_best_app(script_info, Module), Flask)
assert find_best_app(script_info, Module).name == 'appname'
class Module:
@staticmethod
def make_app():
return Flask('appname')
assert isinstance(find_best_app(Module), Flask)
assert find_best_app(Module).name == 'appname'
assert isinstance(find_best_app(script_info, Module), Flask)
assert find_best_app(script_info, Module).name == 'appname'
class Module:
myapp = Flask('appname1')
@staticmethod
def create_app():
return Flask('appname2')
assert find_best_app(Module) == Module.myapp
assert find_best_app(script_info, Module) == Module.myapp
class Module:
myapp = Flask('appname1')
@staticmethod
def create_app(foo):
def create_app():
return Flask('appname2')
assert find_best_app(Module) == Module.myapp
assert find_best_app(script_info, Module) == Module.myapp
class Module:
pass
pytest.raises(NoAppException, find_best_app, Module)
pytest.raises(NoAppException, find_best_app, script_info, Module)
class Module:
myapp1 = Flask('appname1')
myapp2 = Flask('appname2')
pytest.raises(NoAppException, find_best_app, Module)
pytest.raises(NoAppException, find_best_app, script_info, Module)
class Module:
@staticmethod
def create_app(foo):
def create_app(foo, bar):
return Flask('appname2')
pytest.raises(NoAppException, find_best_app, Module)
pytest.raises(NoAppException, find_best_app, script_info, Module)
def test_prepare_exec_for_file(test_apps):
@ -117,13 +132,18 @@ def test_prepare_exec_for_file(test_apps):
def test_locate_app(test_apps):
"""Test of locate_app."""
assert locate_app("cliapp.app").name == "testapp"
assert locate_app("cliapp.app:testapp").name == "testapp"
assert locate_app("cliapp.multiapp:app1").name == "app1"
pytest.raises(NoAppException, locate_app, "notanpp.py")
pytest.raises(NoAppException, locate_app, "cliapp/app")
pytest.raises(RuntimeError, locate_app, "cliapp.app:notanapp")
pytest.raises(NoAppException, locate_app, "cliapp.importerrorapp")
script_info = ScriptInfo()
assert locate_app(script_info, "cliapp.app").name == "testapp"
assert locate_app(script_info, "cliapp.app:testapp").name == "testapp"
assert locate_app(script_info, "cliapp.multiapp:app1").name == "app1"
pytest.raises(NoAppException, locate_app,
script_info, "notanpp.py")
pytest.raises(NoAppException, locate_app,
script_info, "cliapp/app")
pytest.raises(RuntimeError, locate_app,
script_info, "cliapp.app:notanapp")
pytest.raises(NoAppException, locate_app,
script_info, "cliapp.importerrorapp")
def test_find_default_import_path(test_apps, monkeypatch, tmpdir):

8
tox.ini

@ -1,8 +1,6 @@
[tox]
envlist = {py26,py27,pypy}-{lowest,release,devel}{,-simplejson}, {py33,py34,py35,py36}-{release,devel}{,-simplejson}
[testenv]
passenv = LANG
usedevelop=true
@ -20,12 +18,18 @@ deps=
lowest: Werkzeug==0.7
lowest: Jinja2==2.4
lowest: itsdangerous==0.21
lowest: Click==4.0
lowest: blinker==1.0
release: blinker
devel: git+https://github.com/pallets/werkzeug.git
devel: git+https://github.com/pallets/markupsafe.git
devel: git+https://github.com/pallets/jinja.git
devel: git+https://github.com/pallets/itsdangerous.git
devel: git+https://github.com/pallets/click.git
devel: git+https://github.com/jek/blinker.git
simplejson: simplejson
[testenv:docs]

Loading…
Cancel
Save