From c38499bbf26cfa9683e30c52139a94dc5a50dcc4 Mon Sep 17 00:00:00 2001 From: garenchan <1412950785@qq.com> Date: Wed, 24 Oct 2018 21:13:11 +0800 Subject: [PATCH] ignore colon with slash when split app_import_path Flask currently supports importing app through a combination of module path and app variable name, such as '/usr/app.py:my_app'. When the module path contains a colon, it will conflict with this import way and a `flask.cli.NoAppException` will be raised. A file path on a Windows system may contain a colon followed by a slash. So we solved this problem on Windows by ignoring the colon followed by a slash when we split app_import_path. Fix issue #2961. --- flask/cli.py | 2 +- tests/test_cli.py | 19 ++++++++++++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/flask/cli.py b/flask/cli.py index 9f913d9c..f55f31c7 100644 --- a/flask/cli.py +++ b/flask/cli.py @@ -369,7 +369,7 @@ class ScriptInfo(object): app = call_factory(self, self.create_app) else: if self.app_import_path: - path, name = (self.app_import_path.split(':', 1) + [None])[:2] + path, name = (re.split(r':(?![\\/])', self.app_import_path, 1) + [None])[:2] import_name = prepare_import(path) app = locate_app(self, import_name, name) else: diff --git a/tests/test_cli.py b/tests/test_cli.py index 5f2fc48a..18d3aa2b 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -261,8 +261,21 @@ def test_get_version(test_apps, capsys): def test_scriptinfo(test_apps, monkeypatch): """Test of ScriptInfo.""" obj = ScriptInfo(app_import_path="cliapp.app:testapp") - assert obj.load_app().name == "testapp" - assert obj.load_app().name == "testapp" + app = obj.load_app() + assert app.name == "testapp" + assert obj.load_app() is app + + # import app with module's absolute path + cli_app_path = os.path.abspath(os.path.join( + os.path.dirname(__file__), 'test_apps', 'cliapp', 'app.py')) + obj = ScriptInfo(app_import_path=cli_app_path) + app = obj.load_app() + assert app.name == 'testapp' + assert obj.load_app() is app + obj = ScriptInfo(app_import_path=cli_app_path + ':testapp') + app = obj.load_app() + assert app.name == 'testapp' + assert obj.load_app() is app def create_app(info): return Flask("createapp") @@ -270,7 +283,7 @@ def test_scriptinfo(test_apps, monkeypatch): obj = ScriptInfo(create_app=create_app) app = obj.load_app() assert app.name == "createapp" - assert obj.load_app() == app + assert obj.load_app() is app obj = ScriptInfo() pytest.raises(NoAppException, obj.load_app)