diff --git a/IPython/core/autocall.py b/IPython/core/autocall.py index ff2d3a6..11c3c56 100644 --- a/IPython/core/autocall.py +++ b/IPython/core/autocall.py @@ -7,6 +7,7 @@ Authors: * Brian Granger * Fernando Perez +* Thomas Kluyver Notes ----- @@ -34,8 +35,12 @@ class IPyAutocall(object): This happens regardless of 'autocall' variable state. Use this to develop macro-like mechanisms. """ + _ip = None + rewrite = True + def __init__(self, ip=None): + self._ip = ip - def set_ip(self,ip): + 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. @@ -43,3 +48,24 @@ class IPyAutocall(object): """ self._ip = ip + +class ExitAutocall(IPyAutocall): + """An autocallable object which will be added to the user namespace so that + exit, exit(), quit or quit() are all valid ways to close the shell.""" + rewrite = False + + def __call__(self): + self._ip.ask_exit() + +class ZMQExitAutocall(ExitAutocall): + """Exit IPython. Autocallable, so it needn't be explicitly called. + + Parameters + ---------- + keep_kernel : bool + If True, leave the kernel alive. Otherwise, tell the kernel to exit too + (default). + """ + def __call__(self, keep_kernel=False): + self._ip.keepkernel_on_exit = keep_kernel + self._ip.ask_exit() diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py index ccbda3c..fd2ff9e 100644 --- a/IPython/core/interactiveshell.py +++ b/IPython/core/interactiveshell.py @@ -39,6 +39,7 @@ from IPython.core import prefilter from IPython.core import shadowns from IPython.core import ultratb from IPython.core.alias import AliasManager +from IPython.core.autocall import ExitAutocall from IPython.core.builtin_trap import BuiltinTrap from IPython.core.compilerop import CachingCompiler from IPython.core.display_trap import DisplayTrap @@ -198,6 +199,9 @@ class InteractiveShell(Configurable, Magic): display_pub_class = Type(DisplayPublisher) exit_now = CBool(False) + exiter = Instance(ExitAutocall) + def _exiter_default(self): + return ExitAutocall(self) # Monotonically increasing execution counter execution_count = Int(1) filename = Unicode("") @@ -1023,6 +1027,9 @@ class InteractiveShell(Configurable, Magic): # Store myself as the public api!!! ns['get_ipython'] = self.get_ipython + + ns['exit'] = self.exiter + ns['quit'] = self.exiter # Sync what we've added so far to user_ns_hidden so these aren't seen # by %who diff --git a/IPython/core/magic.py b/IPython/core/magic.py index 042618b..f6febd4 100644 --- a/IPython/core/magic.py +++ b/IPython/core/magic.py @@ -2503,14 +2503,6 @@ Defaulting color scheme to 'NoColor'""" ptformatter.pprint = bool(1 - ptformatter.pprint) print 'Pretty printing has been turned', \ ['OFF','ON'][ptformatter.pprint] - - def magic_Exit(self, parameter_s=''): - """Exit IPython.""" - - self.shell.ask_exit() - - # Add aliases as magics so all common forms work: exit, quit, Exit, Quit. - magic_exit = magic_quit = magic_Quit = magic_Exit #...................................................................... # Functions to implement unix shell-type things diff --git a/IPython/core/prefilter.py b/IPython/core/prefilter.py index 7bae693..d138bea 100755 --- a/IPython/core/prefilter.py +++ b/IPython/core/prefilter.py @@ -894,7 +894,7 @@ class AutoHandler(PrefilterHandler): return line force_auto = isinstance(obj, IPyAutocall) - auto_rewrite = True + auto_rewrite = getattr(obj, 'rewrite', True) if pre == ESC_QUOTE: # Auto-quote splitting on whitespace diff --git a/IPython/lib/tests/test_irunner.py b/IPython/lib/tests/test_irunner.py index 049cb25..2be81f8 100755 --- a/IPython/lib/tests/test_irunner.py +++ b/IPython/lib/tests/test_irunner.py @@ -77,7 +77,7 @@ for i in range(5): print "that's all folks!" -%Exit +exit """ output = """\ In [1]: print 'hello, this is python' @@ -124,7 +124,7 @@ In [11]: print "that's all folks!" that's all folks! -In [12]: %Exit +In [12]: exit """ runner = irunner.IPythonRunner(out=self.out) self._test_runner(runner,source,output) diff --git a/IPython/zmq/zmqshell.py b/IPython/zmq/zmqshell.py index 412077b..8793441 100644 --- a/IPython/zmq/zmqshell.py +++ b/IPython/zmq/zmqshell.py @@ -24,6 +24,7 @@ from IPython.core.interactiveshell import ( InteractiveShell, InteractiveShellABC ) from IPython.core import page +from IPython.core.autocall import ZMQExitAutocall from IPython.core.displayhook import DisplayHook from IPython.core.displaypub import DisplayPublisher from IPython.core.macro import Macro @@ -104,6 +105,10 @@ class ZMQInteractiveShell(InteractiveShell): displayhook_class = Type(ZMQDisplayHook) display_pub_class = Type(ZMQDisplayPublisher) + + exiter = Instance(ZMQExitAutocall) + def _exiter_default(self): + return ZMQExitAutocall(self) keepkernel_on_exit = None @@ -592,16 +597,5 @@ class ZMQInteractiveShell(InteractiveShell): text=content ) self.payload_manager.write_payload(payload) - - def magic_Exit(self, parameter_s=''): - """Exit IPython. If the -k option is provided, the kernel will be left - running. Otherwise, it will shutdown without prompting. - """ - opts,args = self.parse_options(parameter_s,'k') - self.shell.keepkernel_on_exit = opts.has_key('k') - self.shell.ask_exit() - - # Add aliases as magics so all common forms work: exit, quit, Exit, Quit. - magic_exit = magic_quit = magic_Quit = magic_Exit InteractiveShellABC.register(ZMQInteractiveShell)