diff --git a/src/flask/cli.py b/src/flask/cli.py index f7e1f293..d159b669 100644 --- a/src/flask/cli.py +++ b/src/flask/cli.py @@ -30,55 +30,46 @@ class NoAppException(click.UsageError): def find_best_app(module): - """Given a module instance this tries to find the best possible + """Given a module instance, this function tries to find the best possible application in the module or raises an exception. """ - from . import Flask - # Search for the most common names first. - for attr_name in ("app", "application"): - app = getattr(module, attr_name, None) + def find_app_by_attribute(attr_name): + return getattr(module, attr_name, None) - if isinstance(app, Flask): - return app + def find_app_by_instance(): + matches = [v for v in module.__dict__.values() if isinstance(v, Flask)] + return matches[0] if len(matches) == 1 else None - # Otherwise find the only object that is a Flask instance. - matches = [v for v in module.__dict__.values() if isinstance(v, Flask)] - - if len(matches) == 1: - return matches[0] - elif len(matches) > 1: - raise NoAppException( - "Detected multiple Flask applications in module" - f" '{module.__name__}'. Use '{module.__name__}:name'" - " to specify the correct one." - ) - - # Search for app factory functions. - for attr_name in ("create_app", "make_app"): + def find_app_by_factory(attr_name): app_factory = getattr(module, attr_name, None) - if inspect.isfunction(app_factory): try: app = app_factory() - - if isinstance(app, Flask): - return app + return app if isinstance(app, Flask) else None except TypeError as e: if not _called_with_wrong_args(app_factory): raise - raise NoAppException( - f"Detected factory '{attr_name}' in module '{module.__name__}'," - " but could not call it without arguments. Use" - f" '{module.__name__}:{attr_name}(args)'" - " to specify arguments." - ) from e + app = None + + for attr_name in ("app", "application"): + app = find_app_by_attribute(attr_name) + if isinstance(app, Flask): + return app + + app = find_app_by_instance() + if app: + return app + + for attr_name in ("create_app", "make_app"): + app = find_app_by_factory(attr_name) + if app: + return app raise NoAppException( - "Failed to find Flask application or factory in module" - f" '{module.__name__}'. Use '{module.__name__}:name'" - " to specify one." + f"Failed to find Flask application or factory in module '{module.__name__}'." + f" Use '{module.__name__}:name' to specify one." )