diff --git a/CHANGES.rst b/CHANGES.rst index 8c615d5f..2657dae9 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -70,6 +70,8 @@ Unreleased - Support async views, error handlers, before and after request, and teardown functions. :pr:`3412` - Support nesting blueprints. :issue:`593, 1548`, :pr:`3923` +- ``flask shell`` sets up tab and history completion like the default + ``python`` shell if ``readline`` is installed. :issue:`3941` Version 1.1.2 diff --git a/src/flask/cli.py b/src/flask/cli.py index c7b88135..a5971d60 100644 --- a/src/flask/cli.py +++ b/src/flask/cli.py @@ -887,6 +887,24 @@ def shell_command(): ctx.update(app.make_shell_context()) + # Site, customize, or startup script can set a hook to call when + # entering interactive mode. The default one sets up readline with + # tab and history completion. + interactive_hook = getattr(sys, "__interactivehook__", None) + + if interactive_hook is not None: + try: + import readline + from rlcompleter import Completer + except ImportError: + pass + else: + # rlcompleter uses __main__.__dict__ by default, which is + # flask.__main__. Use the shell context instead. + readline.set_completer(Completer(ctx).complete) + + interactive_hook() + code.interact(banner=banner, local=ctx)