From bad8f4f8a251c26d8d134a864a15dbaf7b17e83f 2010-09-05 22:25:17 From: Fernando Perez Date: 2010-09-05 22:25:17 Subject: [PATCH] Simplify completer handling by isolating readline-specific logic more. Also, I removed a hack we were using of storing the completer globally inside sys. This was used for the rare case of embedding ipython-inside-ipython, something which is more of a party trick. If we ever want to support that well, we can write a cleaner solution than polluting sys with 'ipcompleter'. But for now, I'm trying to simplify our completer machinery and remove buggy and/or error-prone hacks. Note that the normal use of embedded ipython inside of user's programs isn't affected by this. --- diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py index c747915..b6050ff 100644 --- a/IPython/core/interactiveshell.py +++ b/IPython/core/interactiveshell.py @@ -494,10 +494,6 @@ class InteractiveShell(Configurable, Magic): setattr(sys, k, v) except AttributeError: pass - try: - delattr(sys, 'ipcompleter') - except AttributeError: - pass # Reset what what done in self.init_sys_modules try: sys.modules[self.user_ns['__name__']] = self._orig_sys_modules_main_name @@ -1458,7 +1454,7 @@ class InteractiveShell(Configurable, Magic): # the code computing the traceback. if self.InteractiveTB.call_pdb: # pdb mucks up readline, fix it back - self.set_completer() + self.set_readline_completer() # Actually show the traceback self._showtraceback(etype, value, stb) @@ -1569,7 +1565,7 @@ class InteractiveShell(Configurable, Magic): self.Completer.__class__) self.Completer.matchers.insert(pos,newcomp) - def set_completer(self): + def set_readline_completer(self): """Reset readline's completer to be our own.""" self.readline.set_completer(self.Completer.rlcomplete) @@ -1601,7 +1597,7 @@ class InteractiveShell(Configurable, Magic): # Set a number of methods that depend on readline to be no-op self.savehist = no_op self.reloadhist = no_op - self.set_completer = no_op + self.set_readline_completer = no_op self.set_custom_completer = no_op self.set_completer_frame = no_op warn('Readline services not available or not loaded.') @@ -1610,6 +1606,8 @@ class InteractiveShell(Configurable, Magic): self.readline = readline sys.modules['readline'] = readline import atexit + ### + from IPython.core.completer import IPCompleter self.Completer = IPCompleter(self, self.user_ns, @@ -1619,6 +1617,7 @@ class InteractiveShell(Configurable, Magic): sdisp = self.strdispatchers.get('complete_command', StrDispatch()) self.strdispatchers['complete_command'] = sdisp self.Completer.custom_completers = sdisp + # Platform-specific configuration if os.name == 'nt': self.readline_startup_hook = readline.set_pre_input_hook @@ -1642,9 +1641,7 @@ class InteractiveShell(Configurable, Magic): warn('Problems reading readline initialization file <%s>' % inputrc_name) - # save this in sys so embedded copies can restore it properly - sys.ipcompleter = self.Completer.rlcomplete - self.set_completer() + self.set_readline_completer() # Configure readline according to user's prefs # This is only done if GNU readline is being used. If libedit diff --git a/IPython/frontend/terminal/embed.py b/IPython/frontend/terminal/embed.py index 94a271f..10d0213 100755 --- a/IPython/frontend/terminal/embed.py +++ b/IPython/frontend/terminal/embed.py @@ -74,8 +74,6 @@ class InteractiveShellEmbed(TerminalInteractiveShell): usage=None, banner1=None, banner2=None, display_banner=None, exit_msg=u''): - self.save_sys_ipcompleter() - super(InteractiveShellEmbed,self).__init__( config=config, ipython_dir=ipython_dir, user_ns=user_ns, user_global_ns=user_global_ns, custom_exceptions=custom_exceptions, @@ -92,31 +90,9 @@ class InteractiveShellEmbed(TerminalInteractiveShell): mode=self.xmode, call_pdb=self.pdb) - self.restore_sys_ipcompleter() - def init_sys_modules(self): pass - def save_sys_ipcompleter(self): - """Save readline completer status.""" - try: - #print 'Save completer',sys.ipcompleter # dbg - self.sys_ipcompleter_orig = sys.ipcompleter - except: - pass # not nested with IPython - - def restore_sys_ipcompleter(self): - """Restores the readline completer which was in place. - - This allows embedded IPython within IPython not to disrupt the - parent's completion. - """ - try: - self.readline.set_completer(self.sys_ipcompleter_orig) - sys.ipcompleter = self.sys_ipcompleter_orig - except: - pass - def __call__(self, header='', local_ns=None, global_ns=None, dummy=None, stack_depth=1): """Activate the interactive interpreter. @@ -169,8 +145,6 @@ class InteractiveShellEmbed(TerminalInteractiveShell): if self.exit_msg is not None: print self.exit_msg - self.restore_sys_ipcompleter() - def mainloop(self, local_ns=None, global_ns=None, stack_depth=0, display_banner=None): """Embeds IPython into a running python program.