diff --git a/IPython/ipapi.py b/IPython/ipapi.py index 5f54e82..57f9ae1 100644 --- a/IPython/ipapi.py +++ b/IPython/ipapi.py @@ -80,6 +80,22 @@ class TryNext(Exception): self.args = args self.kwargs = kwargs +class IPyAutocall: + """ Instances of this class are always autocalled + + This happens regardless of 'autocall' variable state. Use this to + develop macro-like mechanisms. + """ + + def set_ip(self,ip): + """ Will be used to set _ip point to current ipython instance b/f call + + Override this method if you don't want this to happen. + + """ + self._ip = ip + + # contains the most recently instantiated IPApi class IPythonNotRunning: diff --git a/IPython/iplib.py b/IPython/iplib.py index fa611ec..9b601d5 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 2344 2007-05-15 15:09:39Z vivainio $ +$Id: iplib.py 2350 2007-05-15 16:56:44Z vivainio $ """ #***************************************************************************** @@ -2182,6 +2182,13 @@ want to merge them back into the new files.""" % locals() if line.endswith('# PYTHON-MODE'): return self.handle_emacs(line,continue_prompt) + # instances of IPyAutocall in user_ns get autocalled immediately + obj = self.user_ns.get(iFun,None) + if isinstance(obj, IPython.ipapi.IPyAutocall): + obj.set_ip(self.api) + return self.handle_auto(line,continue_prompt, + pre,iFun,theRest,obj) + # Let's try to find if the input line is a magic fn oinfo = None if hasattr(self,'magic_'+iFun): @@ -2359,6 +2366,7 @@ want to merge them back into the new files.""" % locals() self.log(line,line,continue_prompt) return line + force_auto = isinstance(obj, IPython.ipapi.IPyAutocall) auto_rewrite = True if pre == self.ESC_QUOTE: @@ -2374,11 +2382,11 @@ want to merge them back into the new files.""" % locals() # We only apply it to argument-less calls if the autocall # parameter is set to 2. We only need to check that autocall is < # 2, since this function isn't called unless it's at least 1. - if not theRest and (self.rc.autocall < 2): + if not theRest and (self.rc.autocall < 2) and not force_auto: newcmd = '%s %s' % (iFun,theRest) auto_rewrite = False else: - if theRest.startswith('['): + if not force_auto and theRest.startswith('['): if hasattr(obj,'__getitem__'): # Don't autocall in this case: item access for an object # which is BOTH callable and implements __getitem__. diff --git a/IPython/macro.py b/IPython/macro.py index 51887f7..fec044c 100644 --- a/IPython/macro.py +++ b/IPython/macro.py @@ -11,9 +11,9 @@ import IPython.ipapi from IPython.genutils import Term +from IPython.ipapi import IPyAutocall - -class Macro: +class Macro(IPyAutocall): """Simple class to store the value of macros as strings. Macro is just a callable that executes a string of IPython @@ -34,5 +34,5 @@ class Macro: def __call__(self): Term.cout.flush() - ip = IPython.ipapi.get() - ip.runlines(self.value) \ No newline at end of file + + self._ip.runlines(self.value) \ No newline at end of file diff --git a/doc/ChangeLog b/doc/ChangeLog index c65d3e7..b2360fb 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -10,6 +10,10 @@ * Magic.py, ipy_rehashdir.py, ipy_profile_sh.py: System command aliases are now lower case on windows (MyCommand.exe => mycommand). + + * macro.py, ipapi.py, iplib.py, Prompts.py: Macro system rehaul. + Macros are now callable objects that inherit from ipapi.IPyAutocall, + i.e. get autocalled regardless of system autocall setting. 2007-05-10 Fernando Perez