##// END OF EJS Templates
Merge branch 'qt-exiting' of http://github.com/eteq/ipython into eteq-qt-exiting
Fernando Perez -
r3192:69694413 merge
parent child Browse files
Show More
@@ -21,7 +21,6 b' Authors:'
21 21 import __builtin__
22 22
23 23 from IPython.config.configurable import Configurable
24 from IPython.core.quitter import Quitter
25 24
26 25 from IPython.utils.traitlets import Instance
27 26
@@ -32,6 +31,9 b' from IPython.utils.traitlets import Instance'
32 31 class __BuiltinUndefined(object): pass
33 32 BuiltinUndefined = __BuiltinUndefined()
34 33
34 class __HideBuiltin(object): pass
35 HideBuiltin = __HideBuiltin()
36
35 37
36 38 class BuiltinTrap(Configurable):
37 39
@@ -44,9 +46,10 b' class BuiltinTrap(Configurable):'
44 46 # Only turn off the trap when the outermost call to __exit__ is made.
45 47 self._nested_level = 0
46 48 self.shell = shell
47 # builtins we always add
48 self.auto_builtins = {'exit': Quitter(self.shell, 'exit'),
49 'quit': Quitter(self.shell, 'quit'),
49 # builtins we always add - if set to HideBuiltin, they will just
50 # be removed instead of being replaced by something else
51 self.auto_builtins = {'exit': HideBuiltin,
52 'quit': HideBuiltin,
50 53 'get_ipython': self.shell.get_ipython,
51 54 }
52 55 # Recursive reload function
@@ -77,8 +80,13 b' class BuiltinTrap(Configurable):'
77 80 """Add a builtin and save the original."""
78 81 bdict = __builtin__.__dict__
79 82 orig = bdict.get(key, BuiltinUndefined)
80 self._orig_builtins[key] = orig
81 bdict[key] = value
83 if value is HideBuiltin:
84 if orig is not BuiltinUndefined: #same as 'key in bdict'
85 self._orig_builtins[key] = orig
86 del bdict[key]
87 else:
88 self._orig_builtins[key] = orig
89 bdict[key] = value
82 90
83 91 def remove_builtin(self, key):
84 92 """Remove an added builtin and re-set the original."""
1 NO CONTENT: file renamed from IPython/core/quitter.py to IPython/deathrow/quitter.py
@@ -546,8 +546,16 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):'
546 546 """ Process a reply for an execution request that resulted in an error.
547 547 """
548 548 content = msg['content']
549 traceback = ''.join(content['traceback'])
550 self._append_plain_text(traceback)
549 # If a SystemExit is passed along, this means exit() was called - also
550 # all the ipython %exit magic syntax of '-k' to be used to keep
551 # the kernel running
552 if content['ename']=='SystemExit':
553 keepkernel = content['evalue']=='-k' or content['evalue']=='True'
554 self._keep_kernel_on_exit = keepkernel
555 self.exit_requested.emit()
556 else:
557 traceback = ''.join(content['traceback'])
558 self._append_plain_text(traceback)
551 559
552 560 def _process_execute_ok(self, msg):
553 561 """ Process a reply for a successful execution equest.
@@ -111,6 +111,7 b' class IPythonWidget(FrontendWidget):'
111 111 self._payload_source_page : self._handle_payload_page,
112 112 self._payload_source_loadpy : self._handle_payload_loadpy }
113 113 self._previous_prompt_obj = None
114 self._keep_kernel_on_exit = None
114 115
115 116 # Initialize widget styling.
116 117 if self.style_sheet:
@@ -424,6 +425,7 b' class IPythonWidget(FrontendWidget):'
424 425 self._edit(item['filename'], item['line_number'])
425 426
426 427 def _handle_payload_exit(self, item):
428 self._keep_kernel_on_exit = item['keepkernel']
427 429 self.exit_requested.emit()
428 430
429 431 def _handle_payload_loadpy(self, item):
@@ -58,52 +58,71 b' class MainWindow(QtGui.QMainWindow):'
58 58 #---------------------------------------------------------------------------
59 59
60 60 def closeEvent(self, event):
61 """ Reimplemented to prompt the user and close the kernel cleanly.
61 """ Close the window and the kernel (if necessary).
62
63 This will prompt the user if they are finished with the kernel, and if
64 so, closes the kernel cleanly. Alternatively, if the exit magic is used,
65 it closes without prompt.
62 66 """
67 keepkernel = None #Use the prompt by default
68 if hasattr(self._frontend,'_keep_kernel_on_exit'): #set by exit magic
69 keepkernel = self._frontend._keep_kernel_on_exit
70
63 71 kernel_manager = self._frontend.kernel_manager
64 if kernel_manager and kernel_manager.channels_running:
65 title = self.window().windowTitle()
66 cancel = QtGui.QMessageBox.Cancel
67 okay = QtGui.QMessageBox.Ok
68 if self._may_close:
69 msg = "You are closing this Console window."
70 info = "Would you like to quit the Kernel and all attached Consoles as well?"
71 justthis = QtGui.QPushButton("&No, just this Console", self)
72 justthis.setShortcut('N')
73 closeall = QtGui.QPushButton("&Yes, quit everything", self)
74 closeall.setShortcut('Y')
75 box = QtGui.QMessageBox(QtGui.QMessageBox.Question, title, msg)
76 box.setInformativeText(info)
77 box.addButton(cancel)
78 box.addButton(justthis, QtGui.QMessageBox.NoRole)
79 box.addButton(closeall, QtGui.QMessageBox.YesRole)
80 box.setDefaultButton(closeall)
81 box.setEscapeButton(cancel)
82 reply = box.exec_()
83 if reply == 1: # close All
84 kernel_manager.shutdown_kernel()
85 #kernel_manager.stop_channels()
86 event.accept()
87 elif reply == 0: # close Console
88 if not self._existing:
89 # I have the kernel: don't quit, just close the window
90 self._app.setQuitOnLastWindowClosed(False)
91 self.deleteLater()
92 event.accept()
93 else:
94 event.ignore()
95 else:
96 reply = QtGui.QMessageBox.question(self, title,
97 "Are you sure you want to close this Console?"+
98 "\nThe Kernel and other Consoles will remain active.",
99 okay|cancel,
100 defaultButton=okay
101 )
102 if reply == okay:
103 event.accept()
72
73 if keepkernel is None: #show prompt
74 if kernel_manager and kernel_manager.channels_running:
75 title = self.window().windowTitle()
76 cancel = QtGui.QMessageBox.Cancel
77 okay = QtGui.QMessageBox.Ok
78 if self._may_close:
79 msg = "You are closing this Console window."
80 info = "Would you like to quit the Kernel and all attached Consoles as well?"
81 justthis = QtGui.QPushButton("&No, just this Console", self)
82 justthis.setShortcut('N')
83 closeall = QtGui.QPushButton("&Yes, quit everything", self)
84 closeall.setShortcut('Y')
85 box = QtGui.QMessageBox(QtGui.QMessageBox.Question, title, msg)
86 box.setInformativeText(info)
87 box.addButton(cancel)
88 box.addButton(justthis, QtGui.QMessageBox.NoRole)
89 box.addButton(closeall, QtGui.QMessageBox.YesRole)
90 box.setDefaultButton(closeall)
91 box.setEscapeButton(cancel)
92 reply = box.exec_()
93 if reply == 1: # close All
94 kernel_manager.shutdown_kernel()
95 #kernel_manager.stop_channels()
96 event.accept()
97 elif reply == 0: # close Console
98 if not self._existing:
99 # Have kernel: don't quit, just close the window
100 self._app.setQuitOnLastWindowClosed(False)
101 self.deleteLater()
102 event.accept()
103 else:
104 event.ignore()
104 105 else:
105 event.ignore()
106
106 reply = QtGui.QMessageBox.question(self, title,
107 "Are you sure you want to close this Console?"+
108 "\nThe Kernel and other Consoles will remain active.",
109 okay|cancel,
110 defaultButton=okay
111 )
112 if reply == okay:
113 event.accept()
114 else:
115 event.ignore()
116 elif keepkernel: #close console but leave kernel running (no prompt)
117 if kernel_manager and kernel_manager.channels_running:
118 if not self._existing:
119 # I have the kernel: don't quit, just close the window
120 self._app.setQuitOnLastWindowClosed(False)
121 event.accept()
122 else: #close console and kernel (no prompt)
123 if kernel_manager and kernel_manager.channels_running:
124 kernel_manager.shutdown_kernel()
125 event.accept()
107 126
108 127 #-----------------------------------------------------------------------------
109 128 # Main entry point
@@ -78,6 +78,7 b' class ZMQInteractiveShell(InteractiveShell):'
78 78 """A subclass of InteractiveShell for ZMQ."""
79 79
80 80 displayhook_class = Type(ZMQDisplayHook)
81 keepkernel_on_exit = None
81 82
82 83 def init_environment(self):
83 84 """Configure the user's environment.
@@ -111,6 +112,7 b' class ZMQInteractiveShell(InteractiveShell):'
111 112 payload = dict(
112 113 source='IPython.zmq.zmqshell.ZMQInteractiveShell.ask_exit',
113 114 exit=True,
115 keepkernel=self.keepkernel_on_exit,
114 116 )
115 117 self.payload_manager.write_payload(payload)
116 118
@@ -563,5 +565,16 b' class ZMQInteractiveShell(InteractiveShell):'
563 565 text=content
564 566 )
565 567 self.payload_manager.write_payload(payload)
568
569 def magic_Exit(self, parameter_s=''):
570 """Exit IPython. If the -k option is provided, the kernel will be left
571 running. Otherwise, it will shutdown without prompting.
572 """
573 opts,args = self.parse_options(parameter_s,'k')
574 self.shell.keepkernel_on_exit = opts.has_key('k')
575 self.shell.ask_exit()
576
577 # Add aliases as magics so all common forms work: exit, quit, Exit, Quit.
578 magic_exit = magic_quit = magic_Quit = magic_Exit
566 579
567 580 InteractiveShellABC.register(ZMQInteractiveShell)
General Comments 0
You need to be logged in to leave comments. Login now