diff --git a/IPython/Extensions/envpersist.py b/IPython/Extensions/envpersist.py index 9153363..a0523ba 100644 --- a/IPython/Extensions/envpersist.py +++ b/IPython/Extensions/envpersist.py @@ -7,13 +7,11 @@ ip = IPython.ipapi.get() import os,sys -def restore_env(self): +def restore_env(self): ip = self.getapi() env = ip.db.get('stored_env', {'set' : {}, 'add' : [], 'pre' : []}) for k,v in env['set'].items(): - #print "restore alias",k,v # dbg os.environ[k] = v - self.alias_table[k] = v for k,v in env['add']: os.environ[k] = os.environ.get(k,"") + v for k,v in env['pre']: diff --git a/IPython/Extensions/ipy_profile_sh.py b/IPython/Extensions/ipy_profile_sh.py index 4064038..6c5f29c 100644 --- a/IPython/Extensions/ipy_profile_sh.py +++ b/IPython/Extensions/ipy_profile_sh.py @@ -90,9 +90,11 @@ def main(): def mapper(s): return s.lower() for cmd in syscmds: - #print "al",cmd + # print "sys",cmd #dbg noext, ext = os.path.splitext(cmd) - ip.IP.alias_table[mapper(noext)] = (0,cmd) + key = mapper(noext) + if key not in ip.IP.alias_table: + ip.defalias(key, cmd) if 'ls' in syscmds: # use the colors of cygwin ls (recommended) diff --git a/IPython/ipapi.py b/IPython/ipapi.py index 36256b8..215eda4 100644 --- a/IPython/ipapi.py +++ b/IPython/ipapi.py @@ -184,6 +184,9 @@ class IPApi: self.IP = ip self.extensions = {} + + self.dbg = DebugTools(self) + global _recent _recent = self @@ -222,6 +225,11 @@ class IPApi: import new im = new.instancemethod(func,self.IP, self.IP.__class__) + old = getattr(self.IP, "magic_" + magicname, None) + if old: + self.dbg.debug_stack("Magic redefinition '%s', old %s" % (magicname, + old)) + setattr(self.IP, "magic_" + magicname, im) def ex(self,cmd): @@ -355,7 +363,15 @@ class IPApi: Creates a new alias named 'bb' in ipython user namespace """ + + self.dbg.check_hotname(name) + + if name in self.IP.alias_table: + self.dbg.debug_stack("Alias redefinition: '%s' => '%s' (old '%s')" % + (name, cmd, self.IP.alias_table[name])) + + if callable(cmd): self.IP.alias_table[name] = cmd import IPython.shadowns @@ -368,7 +384,11 @@ class IPApi: raise Exception('The %s and %l specifiers are mutually exclusive ' 'in alias definitions.') - self.IP.alias_table[name] = (nargs,cmd) + self.IP.alias_table[name] = (nargs,cmd) + return + + # just put it in - it's probably (0,'foo') + self.IP.alias_table[name] = cmd def defmacro(self, *args): """ Define a new macro @@ -419,7 +439,35 @@ class IPApi: m.init_ipython(self) self.extensions[mod] = m return m + + +class DebugTools: + """ Used for debugging mishaps in api usage + + So far, tracing redefinitions is supported. + """ + + def __init__(self, ip): + self.ip = ip + self.debugmode = False + self.hotnames = set() + + + def hotname(self, name_to_catch): + self.hotnames.add(name_to_catch) + + def debug_stack(self, msg = None): + if not self.debugmode: + return + import traceback + if msg is not None: + print '====== %s ========' % msg + traceback.print_stack() + + def check_hotname(self,name): + if name in self.hotnames: + self.debug_stack( "HotName '%s' caught" % name) def launch_new_instance(user_ns = None): """ Make and start a new ipython instance. diff --git a/IPython/iplib.py b/IPython/iplib.py index a848ae1..d8c4d3f 100644 --- a/IPython/iplib.py +++ b/IPython/iplib.py @@ -6,7 +6,7 @@ Requires Python 2.3 or newer. This file contains all the classes and helper functions specific to IPython. -$Id: iplib.py 2637 2007-08-17 16:18:05Z vivainio $ +$Id: iplib.py 2646 2007-08-20 16:28:48Z vivainio $ """ #***************************************************************************** @@ -579,12 +579,13 @@ class InteractiveShell(object,Magic): else: auto_alias = () self.auto_alias = [s.split(None,1) for s in auto_alias] - # Call the actual (public) initializer - self.init_auto_alias() # Produce a public API instance self.api = IPython.ipapi.IPApi(self) + # Call the actual (public) initializer + self.init_auto_alias() + # track which builtins we add, so we can clean up later self.builtins_added = {} # This method will add the necessary builtins for operation, but @@ -1017,7 +1018,8 @@ class InteractiveShell(object,Magic): These are ALL parameter-less aliases""" for alias,cmd in self.auto_alias: - self.alias_table[alias] = (0,cmd) + self.getapi().defalias(alias,cmd) + def alias_table_validate(self,verbose=0): """Update information about the alias table. @@ -1268,7 +1270,9 @@ want to merge them back into the new files.""" % locals() def init_readline(self): """Command history completion/saving/reloading.""" + import IPython.rlineimpl as readline + if not readline.have_readline: self.has_readline = 0 self.readline = None @@ -1618,7 +1622,7 @@ want to merge them back into the new files.""" % locals() # Mark activity in the builtins __builtin__.__dict__['__IPYTHON__active'] += 1 - if readline.have_readline: + if self.has_readline: self.readline_startup_hook(self.pre_readline) # exit_now is set by a call to %Exit or %Quit