diff --git a/django_extensions/management/commands/shell_plus.py b/django_extensions/management/commands/shell_plus.py index b4ad275cf..b537311c5 100644 --- a/django_extensions/management/commands/shell_plus.py +++ b/django_extensions/management/commands/shell_plus.py @@ -333,24 +333,9 @@ def run_jupyterlab(): def get_plain(self, options): # Using normal Python shell import code + + # Set up a dictionary to serve as the environment for the shell. imported_objects = self.get_imported_objects(options) - try: - # Try activating rlcompleter, because it's handy. - import readline - except ImportError: - pass - else: - # We don't have to wrap the following import in a 'try', because - # we already know 'readline' was imported successfully. - import rlcompleter - readline.set_completer(rlcompleter.Completer(imported_objects).complete) - # Enable tab completion on systems using libedit (e.g. macOS). - # These lines are copied from Lib/site.py on Python 3.4. - readline_doc = getattr(readline, '__doc__', '') - if readline_doc is not None and 'libedit' in readline_doc: - readline.parse_and_bind("bind ^I rl_complete") - else: - readline.parse_and_bind("tab:complete") use_pythonrc = options['use_pythonrc'] no_startup = options['no_startup'] @@ -374,6 +359,43 @@ def get_plain(self, options): if self.tests_mode: raise + # By default, this will set up readline to do tab completion and to read and + # write history to the .python_history file, but this can be overridden by + # $PYTHONSTARTUP or ~/.pythonrc.py. + try: + hook = sys.__interactivehook__ + except AttributeError: + # Match the behavior of the cpython shell where a missing + # sys.__interactivehook__ is ignored. + pass + else: + try: + hook() + except Exception: + # Match the behavior of the cpython shell where an error in + # sys.__interactivehook__ prints a warning and the exception + # and continues. + print("Failed calling sys.__interactivehook__") + traceback.print_exc() + + try: + # Try activating rlcompleter, because it's handy. + import readline + except ImportError: + pass + else: + # We don't have to wrap the following import in a 'try', because + # we already know 'readline' was imported successfully. + import rlcompleter + readline.set_completer(rlcompleter.Completer(imported_objects).complete) + # Enable tab completion on systems using libedit (e.g. macOS). + # These lines are copied from Lib/site.py on Python 3.4. + readline_doc = getattr(readline, '__doc__', '') + if readline_doc is not None and 'libedit' in readline_doc: + readline.parse_and_bind("bind ^I rl_complete") + else: + readline.parse_and_bind("tab:complete") + def run_plain(): code.interact(local=imported_objects) return run_plain