##// 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 import __builtin__
21 import __builtin__
22
22
23 from IPython.config.configurable import Configurable
23 from IPython.config.configurable import Configurable
24 from IPython.core.quitter import Quitter
25
24
26 from IPython.utils.traitlets import Instance
25 from IPython.utils.traitlets import Instance
27
26
@@ -32,6 +31,9 b' from IPython.utils.traitlets import Instance'
32 class __BuiltinUndefined(object): pass
31 class __BuiltinUndefined(object): pass
33 BuiltinUndefined = __BuiltinUndefined()
32 BuiltinUndefined = __BuiltinUndefined()
34
33
34 class __HideBuiltin(object): pass
35 HideBuiltin = __HideBuiltin()
36
35
37
36 class BuiltinTrap(Configurable):
38 class BuiltinTrap(Configurable):
37
39
@@ -44,9 +46,10 b' class BuiltinTrap(Configurable):'
44 # Only turn off the trap when the outermost call to __exit__ is made.
46 # Only turn off the trap when the outermost call to __exit__ is made.
45 self._nested_level = 0
47 self._nested_level = 0
46 self.shell = shell
48 self.shell = shell
47 # builtins we always add
49 # builtins we always add - if set to HideBuiltin, they will just
48 self.auto_builtins = {'exit': Quitter(self.shell, 'exit'),
50 # be removed instead of being replaced by something else
49 'quit': Quitter(self.shell, 'quit'),
51 self.auto_builtins = {'exit': HideBuiltin,
52 'quit': HideBuiltin,
50 'get_ipython': self.shell.get_ipython,
53 'get_ipython': self.shell.get_ipython,
51 }
54 }
52 # Recursive reload function
55 # Recursive reload function
@@ -77,8 +80,13 b' class BuiltinTrap(Configurable):'
77 """Add a builtin and save the original."""
80 """Add a builtin and save the original."""
78 bdict = __builtin__.__dict__
81 bdict = __builtin__.__dict__
79 orig = bdict.get(key, BuiltinUndefined)
82 orig = bdict.get(key, BuiltinUndefined)
80 self._orig_builtins[key] = orig
83 if value is HideBuiltin:
81 bdict[key] = value
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 def remove_builtin(self, key):
91 def remove_builtin(self, key):
84 """Remove an added builtin and re-set the original."""
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
NO CONTENT: file renamed from IPython/core/quitter.py to IPython/deathrow/quitter.py
@@ -546,8 +546,16 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):'
546 """ Process a reply for an execution request that resulted in an error.
546 """ Process a reply for an execution request that resulted in an error.
547 """
547 """
548 content = msg['content']
548 content = msg['content']
549 traceback = ''.join(content['traceback'])
549 # If a SystemExit is passed along, this means exit() was called - also
550 self._append_plain_text(traceback)
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 def _process_execute_ok(self, msg):
560 def _process_execute_ok(self, msg):
553 """ Process a reply for a successful execution equest.
561 """ Process a reply for a successful execution equest.
@@ -111,6 +111,7 b' class IPythonWidget(FrontendWidget):'
111 self._payload_source_page : self._handle_payload_page,
111 self._payload_source_page : self._handle_payload_page,
112 self._payload_source_loadpy : self._handle_payload_loadpy }
112 self._payload_source_loadpy : self._handle_payload_loadpy }
113 self._previous_prompt_obj = None
113 self._previous_prompt_obj = None
114 self._keep_kernel_on_exit = None
114
115
115 # Initialize widget styling.
116 # Initialize widget styling.
116 if self.style_sheet:
117 if self.style_sheet:
@@ -424,6 +425,7 b' class IPythonWidget(FrontendWidget):'
424 self._edit(item['filename'], item['line_number'])
425 self._edit(item['filename'], item['line_number'])
425
426
426 def _handle_payload_exit(self, item):
427 def _handle_payload_exit(self, item):
428 self._keep_kernel_on_exit = item['keepkernel']
427 self.exit_requested.emit()
429 self.exit_requested.emit()
428
430
429 def _handle_payload_loadpy(self, item):
431 def _handle_payload_loadpy(self, item):
@@ -58,52 +58,71 b' class MainWindow(QtGui.QMainWindow):'
58 #---------------------------------------------------------------------------
58 #---------------------------------------------------------------------------
59
59
60 def closeEvent(self, event):
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 kernel_manager = self._frontend.kernel_manager
71 kernel_manager = self._frontend.kernel_manager
64 if kernel_manager and kernel_manager.channels_running:
72
65 title = self.window().windowTitle()
73 if keepkernel is None: #show prompt
66 cancel = QtGui.QMessageBox.Cancel
74 if kernel_manager and kernel_manager.channels_running:
67 okay = QtGui.QMessageBox.Ok
75 title = self.window().windowTitle()
68 if self._may_close:
76 cancel = QtGui.QMessageBox.Cancel
69 msg = "You are closing this Console window."
77 okay = QtGui.QMessageBox.Ok
70 info = "Would you like to quit the Kernel and all attached Consoles as well?"
78 if self._may_close:
71 justthis = QtGui.QPushButton("&No, just this Console", self)
79 msg = "You are closing this Console window."
72 justthis.setShortcut('N')
80 info = "Would you like to quit the Kernel and all attached Consoles as well?"
73 closeall = QtGui.QPushButton("&Yes, quit everything", self)
81 justthis = QtGui.QPushButton("&No, just this Console", self)
74 closeall.setShortcut('Y')
82 justthis.setShortcut('N')
75 box = QtGui.QMessageBox(QtGui.QMessageBox.Question, title, msg)
83 closeall = QtGui.QPushButton("&Yes, quit everything", self)
76 box.setInformativeText(info)
84 closeall.setShortcut('Y')
77 box.addButton(cancel)
85 box = QtGui.QMessageBox(QtGui.QMessageBox.Question, title, msg)
78 box.addButton(justthis, QtGui.QMessageBox.NoRole)
86 box.setInformativeText(info)
79 box.addButton(closeall, QtGui.QMessageBox.YesRole)
87 box.addButton(cancel)
80 box.setDefaultButton(closeall)
88 box.addButton(justthis, QtGui.QMessageBox.NoRole)
81 box.setEscapeButton(cancel)
89 box.addButton(closeall, QtGui.QMessageBox.YesRole)
82 reply = box.exec_()
90 box.setDefaultButton(closeall)
83 if reply == 1: # close All
91 box.setEscapeButton(cancel)
84 kernel_manager.shutdown_kernel()
92 reply = box.exec_()
85 #kernel_manager.stop_channels()
93 if reply == 1: # close All
86 event.accept()
94 kernel_manager.shutdown_kernel()
87 elif reply == 0: # close Console
95 #kernel_manager.stop_channels()
88 if not self._existing:
96 event.accept()
89 # I have the kernel: don't quit, just close the window
97 elif reply == 0: # close Console
90 self._app.setQuitOnLastWindowClosed(False)
98 if not self._existing:
91 self.deleteLater()
99 # Have kernel: don't quit, just close the window
92 event.accept()
100 self._app.setQuitOnLastWindowClosed(False)
93 else:
101 self.deleteLater()
94 event.ignore()
102 event.accept()
95 else:
103 else:
96 reply = QtGui.QMessageBox.question(self, title,
104 event.ignore()
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()
104 else:
105 else:
105 event.ignore()
106 reply = QtGui.QMessageBox.question(self, title,
106
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 # Main entry point
128 # Main entry point
@@ -78,6 +78,7 b' class ZMQInteractiveShell(InteractiveShell):'
78 """A subclass of InteractiveShell for ZMQ."""
78 """A subclass of InteractiveShell for ZMQ."""
79
79
80 displayhook_class = Type(ZMQDisplayHook)
80 displayhook_class = Type(ZMQDisplayHook)
81 keepkernel_on_exit = None
81
82
82 def init_environment(self):
83 def init_environment(self):
83 """Configure the user's environment.
84 """Configure the user's environment.
@@ -111,6 +112,7 b' class ZMQInteractiveShell(InteractiveShell):'
111 payload = dict(
112 payload = dict(
112 source='IPython.zmq.zmqshell.ZMQInteractiveShell.ask_exit',
113 source='IPython.zmq.zmqshell.ZMQInteractiveShell.ask_exit',
113 exit=True,
114 exit=True,
115 keepkernel=self.keepkernel_on_exit,
114 )
116 )
115 self.payload_manager.write_payload(payload)
117 self.payload_manager.write_payload(payload)
116
118
@@ -563,5 +565,16 b' class ZMQInteractiveShell(InteractiveShell):'
563 text=content
565 text=content
564 )
566 )
565 self.payload_manager.write_payload(payload)
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 InteractiveShellABC.register(ZMQInteractiveShell)
580 InteractiveShellABC.register(ZMQInteractiveShell)
General Comments 0
You need to be logged in to leave comments. Login now