Show More
@@ -13,55 +13,53 b' class BaseFrontendMixin(object):' | |||
|
13 | 13 | # 'BaseFrontendMixin' concrete interface |
|
14 | 14 | #--------------------------------------------------------------------------- |
|
15 | 15 | |
|
16 |
def _get_kernel_ |
|
|
17 |
""" |
|
|
16 | def _get_kernel_client(self): | |
|
17 | """Returns the current kernel client. | |
|
18 | 18 | """ |
|
19 |
return self._kernel_ |
|
|
19 | return self._kernel_client | |
|
20 | 20 | |
|
21 |
def _set_kernel_ |
|
|
22 |
""" |
|
|
23 |
kernel |
|
|
21 | def _set_kernel_client(self, kernel_client): | |
|
22 | """Disconnect from the current kernel client (if any) and set a new | |
|
23 | kernel client. | |
|
24 | 24 | """ |
|
25 |
# Disconnect the old kernel |
|
|
26 |
old_ |
|
|
27 |
if old_ |
|
|
28 |
old_ |
|
|
29 |
old_ |
|
|
30 | old_manager.stopped_channels.disconnect(self._stopped_channels) | |
|
31 | ||
|
32 | # Disconnect the old kernel manager's channels. | |
|
33 |
old_ |
|
|
34 |
old_ |
|
|
35 |
old_ |
|
|
36 | old_manager.hb_channel.kernel_died.disconnect( | |
|
25 | # Disconnect the old kernel client, if necessary. | |
|
26 | old_client = self._kernel_client | |
|
27 | if old_client is not None: | |
|
28 | old_client.started_channels.disconnect(self._started_channels) | |
|
29 | old_client.stopped_channels.disconnect(self._stopped_channels) | |
|
30 | ||
|
31 | # Disconnect the old kernel client's channels. | |
|
32 | old_client.iopub_channel.message_received.disconnect(self._dispatch) | |
|
33 | old_client.shell_channel.message_received.disconnect(self._dispatch) | |
|
34 | old_client.stdin_channel.message_received.disconnect(self._dispatch) | |
|
35 | old_client.hb_channel.kernel_died.disconnect( | |
|
37 | 36 | self._handle_kernel_died) |
|
38 | 37 | |
|
39 |
# Handle the case where the old kernel |
|
|
40 |
if old_ |
|
|
38 | # Handle the case where the old kernel client is still listening. | |
|
39 | if old_client.channels_running: | |
|
41 | 40 | self._stopped_channels() |
|
42 | 41 | |
|
43 |
# Set the new kernel |
|
|
44 |
self._kernel_ |
|
|
45 |
if kernel_ |
|
|
42 | # Set the new kernel client. | |
|
43 | self._kernel_client = kernel_client | |
|
44 | if kernel_client is None: | |
|
46 | 45 | return |
|
47 | 46 | |
|
48 |
# Connect the new kernel |
|
|
49 |
kernel_ |
|
|
50 |
kernel_ |
|
|
51 | kernel_manager.stopped_channels.connect(self._stopped_channels) | |
|
47 | # Connect the new kernel client. | |
|
48 | kernel_client.started_channels.connect(self._started_channels) | |
|
49 | kernel_client.stopped_channels.connect(self._stopped_channels) | |
|
52 | 50 | |
|
53 |
# Connect the new kernel |
|
|
54 |
kernel_ |
|
|
55 |
kernel_ |
|
|
56 |
kernel_ |
|
|
57 |
kernel_ |
|
|
51 | # Connect the new kernel client's channels. | |
|
52 | kernel_client.iopub_channel.message_received.connect(self._dispatch) | |
|
53 | kernel_client.shell_channel.message_received.connect(self._dispatch) | |
|
54 | kernel_client.stdin_channel.message_received.connect(self._dispatch) | |
|
55 | kernel_client.hb_channel.kernel_died.connect(self._handle_kernel_died) | |
|
58 | 56 | |
|
59 |
# Handle the case where the kernel |
|
|
57 | # Handle the case where the kernel client started channels before | |
|
60 | 58 | # we connected. |
|
61 |
if kernel_ |
|
|
59 | if kernel_client.channels_running: | |
|
62 | 60 | self._started_channels() |
|
63 | 61 | |
|
64 |
kernel_ |
|
|
62 | kernel_client = property(_get_kernel_client, _set_kernel_client) | |
|
65 | 63 | |
|
66 | 64 | #--------------------------------------------------------------------------- |
|
67 | 65 | # 'BaseFrontendMixin' abstract interface |
@@ -112,7 +110,7 b' class BaseFrontendMixin(object):' | |||
|
112 | 110 | """ Returns whether a reply from the kernel originated from a request |
|
113 | 111 | from this frontend. |
|
114 | 112 | """ |
|
115 |
session = self._kernel_ |
|
|
113 | session = self._kernel_client.session.session | |
|
116 | 114 | parent = msg['parent_header'] |
|
117 | 115 | if not parent: |
|
118 | 116 | # if the message has no parent, assume it is meant for all frontends |
@@ -1,13 +1,18 b'' | |||
|
1 |
""" Defines a Kernel |
|
|
1 | """ Defines a KernelClient that provides signals and slots. | |
|
2 | 2 | """ |
|
3 | 3 | |
|
4 |
# Local imports |
|
|
4 | # Local imports | |
|
5 | 5 | from IPython.utils.traitlets import Type |
|
6 | from IPython.kernel.kernelmanager import ShellChannel, IOPubChannel, \ | |
|
7 | StdInChannel, HBChannel, KernelManager | |
|
8 | from base_kernelmanager import QtShellChannelMixin, QtIOPubChannelMixin, \ | |
|
9 | QtStdInChannelMixin, QtHBChannelMixin, QtKernelManagerMixin | |
|
6 | from IPython.kernel.channels import ( | |
|
7 | ShellChannel, IOPubChannel, StdInChannel, HBChannel | |
|
8 | ) | |
|
9 | from IPython.kernel import KernelClient | |
|
10 | 10 | |
|
11 | from .kernel_mixins import ( | |
|
12 | QtShellChannelMixin, QtIOPubChannelMixin, | |
|
13 | QtStdInChannelMixin, QtHBChannelMixin, | |
|
14 | QtKernelClientMixin | |
|
15 | ) | |
|
11 | 16 | |
|
12 | 17 | class QtShellChannel(QtShellChannelMixin, ShellChannel): |
|
13 | 18 | pass |
@@ -22,8 +27,8 b' class QtHBChannel(QtHBChannelMixin, HBChannel):' | |||
|
22 | 27 | pass |
|
23 | 28 | |
|
24 | 29 | |
|
25 |
class QtKernel |
|
|
26 |
""" A Kernel |
|
|
30 | class QtKernelClient(QtKernelClientMixin, KernelClient): | |
|
31 | """ A KernelClient that provides signals and slots. | |
|
27 | 32 | """ |
|
28 | 33 | |
|
29 | 34 | iopub_channel_class = Type(QtIOPubChannel) |
@@ -148,6 +148,7 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):' | |||
|
148 | 148 | self._highlighter = FrontendHighlighter(self) |
|
149 | 149 | self._input_splitter = self._input_splitter_class() |
|
150 | 150 | self._kernel_manager = None |
|
151 | self._kernel_client = None | |
|
151 | 152 | self._request_info = {} |
|
152 | 153 | self._request_info['execute'] = {}; |
|
153 | 154 | self._callback_dict = {} |
@@ -215,7 +216,7 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):' | |||
|
215 | 216 | |
|
216 | 217 | See parent class :meth:`execute` docstring for full details. |
|
217 | 218 | """ |
|
218 |
msg_id = self.kernel_ |
|
|
219 | msg_id = self.kernel_client.shell_channel.execute(source, hidden) | |
|
219 | 220 | self._request_info['execute'][msg_id] = self._ExecutionRequest(msg_id, 'user') |
|
220 | 221 | self._hidden = hidden |
|
221 | 222 | if not hidden: |
@@ -357,7 +358,7 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):' | |||
|
357 | 358 | # generate uuid, which would be used as an indication of whether or |
|
358 | 359 | # not the unique request originated from here (can use msg id ?) |
|
359 | 360 | local_uuid = str(uuid.uuid1()) |
|
360 |
msg_id = self.kernel_ |
|
|
361 | msg_id = self.kernel_client.shell_channel.execute('', | |
|
361 | 362 | silent=True, user_expressions={ local_uuid:expr }) |
|
362 | 363 | self._callback_dict[local_uuid] = callback |
|
363 | 364 | self._request_info['execute'][msg_id] = self._ExecutionRequest(msg_id, 'silent_exec_callback') |
@@ -400,7 +401,7 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):' | |||
|
400 | 401 | if info and info.kind == 'user' and not self._hidden: |
|
401 | 402 | # Make sure that all output from the SUB channel has been processed |
|
402 | 403 | # before writing a new prompt. |
|
403 |
self.kernel_ |
|
|
404 | self.kernel_client.iopub_channel.flush() | |
|
404 | 405 | |
|
405 | 406 | # Reset the ANSI style information to prevent bad text in stdout |
|
406 | 407 | # from messing up our colors. We're not a true terminal so we're |
@@ -435,10 +436,10 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):' | |||
|
435 | 436 | |
|
436 | 437 | # Make sure that all output from the SUB channel has been processed |
|
437 | 438 | # before entering readline mode. |
|
438 |
self.kernel_ |
|
|
439 | self.kernel_client.iopub_channel.flush() | |
|
439 | 440 | |
|
440 | 441 | def callback(line): |
|
441 |
self.kernel_ |
|
|
442 | self.kernel_client.stdin_channel.input(line) | |
|
442 | 443 | if self._reading: |
|
443 | 444 | self.log.debug("Got second input request, assuming first was interrupted.") |
|
444 | 445 | self._reading = False |
@@ -568,7 +569,7 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):' | |||
|
568 | 569 | if self.custom_interrupt: |
|
569 | 570 | self._reading = False |
|
570 | 571 | self.custom_interrupt_requested.emit() |
|
571 |
elif self.kernel_manager |
|
|
572 | elif self.kernel_manager: | |
|
572 | 573 | self._reading = False |
|
573 | 574 | self.kernel_manager.interrupt_kernel() |
|
574 | 575 | else: |
@@ -615,9 +616,9 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):' | |||
|
615 | 616 | if self.custom_restart: |
|
616 | 617 | self.custom_restart_requested.emit() |
|
617 | 618 | |
|
618 |
elif self.kernel_manager |
|
|
619 | elif self.kernel_manager: | |
|
619 | 620 | # Pause the heart beat channel to prevent further warnings. |
|
620 |
self.kernel_ |
|
|
621 | self.kernel_client.hb_channel.pause() | |
|
621 | 622 | |
|
622 | 623 | # Prompt the user to restart the kernel. Un-pause the heartbeat if |
|
623 | 624 | # they decline. (If they accept, the heartbeat will be un-paused |
@@ -642,7 +643,7 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):' | |||
|
642 | 643 | else: |
|
643 | 644 | self.reset() |
|
644 | 645 | else: |
|
645 |
self.kernel_ |
|
|
646 | self.kernel_client.hb_channel.unpause() | |
|
646 | 647 | |
|
647 | 648 | else: |
|
648 | 649 | self._append_plain_text('Kernel process is either remote or ' |
@@ -670,7 +671,7 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):' | |||
|
670 | 671 | |
|
671 | 672 | # Send the metadata request to the kernel |
|
672 | 673 | name = '.'.join(context) |
|
673 |
msg_id = self.kernel_ |
|
|
674 | msg_id = self.kernel_client.shell_channel.object_info(name) | |
|
674 | 675 | pos = self._get_cursor().position() |
|
675 | 676 | self._request_info['call_tip'] = self._CallTipRequest(msg_id, pos) |
|
676 | 677 | return True |
@@ -681,7 +682,7 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):' | |||
|
681 | 682 | context = self._get_context() |
|
682 | 683 | if context: |
|
683 | 684 | # Send the completion request to the kernel |
|
684 |
msg_id = self.kernel_ |
|
|
685 | msg_id = self.kernel_client.shell_channel.complete( | |
|
685 | 686 | '.'.join(context), # text |
|
686 | 687 | self._get_input_buffer_cursor_line(), # line |
|
687 | 688 | self._get_input_buffer_cursor_column(), # cursor_pos |
@@ -224,7 +224,7 b' class HistoryConsoleWidget(ConsoleWidget):' | |||
|
224 | 224 | return self._history[-n:] |
|
225 | 225 | |
|
226 | 226 | def _request_update_session_history_length(self): |
|
227 |
msg_id = self.kernel_ |
|
|
227 | msg_id = self.kernel_client.shell_channel.execute('', | |
|
228 | 228 | silent=True, |
|
229 | 229 | user_expressions={ |
|
230 | 230 | 'hlen':'len(get_ipython().history_manager.input_hist_raw)', |
@@ -194,7 +194,7 b' class IPythonWidget(FrontendWidget):' | |||
|
194 | 194 | self._retrying_history_request = True |
|
195 | 195 | # wait out the kernel's queue flush, which is currently timed at 0.1s |
|
196 | 196 | time.sleep(0.25) |
|
197 |
self.kernel_ |
|
|
197 | self.kernel_client.shell_channel.history(hist_access_type='tail',n=1000) | |
|
198 | 198 | else: |
|
199 | 199 | self._retrying_history_request = False |
|
200 | 200 | return |
@@ -261,7 +261,7 b' class IPythonWidget(FrontendWidget):' | |||
|
261 | 261 | """Reimplemented to make a history request and load %guiref.""" |
|
262 | 262 | super(IPythonWidget, self)._started_channels() |
|
263 | 263 | self._load_guiref_magic() |
|
264 |
self.kernel_ |
|
|
264 | self.kernel_client.shell_channel.history(hist_access_type='tail', | |
|
265 | 265 | n=1000) |
|
266 | 266 | |
|
267 | 267 | def _started_kernel(self): |
@@ -269,12 +269,12 b' class IPythonWidget(FrontendWidget):' | |||
|
269 | 269 | |
|
270 | 270 | Principally triggered by kernel restart. |
|
271 | 271 | """ |
|
272 |
if self.kernel_ |
|
|
272 | if self.kernel_client.shell_channel is not None: | |
|
273 | 273 | self._load_guiref_magic() |
|
274 | 274 | |
|
275 | 275 | def _load_guiref_magic(self): |
|
276 | 276 | """Load %guiref magic.""" |
|
277 |
self.kernel_ |
|
|
277 | self.kernel_client.shell_channel.execute('\n'.join([ | |
|
278 | 278 | "try:", |
|
279 | 279 | " _usage", |
|
280 | 280 | "except:", |
@@ -330,7 +330,7 b' class IPythonWidget(FrontendWidget):' | |||
|
330 | 330 | text = '' |
|
331 | 331 | |
|
332 | 332 | # Send the completion request to the kernel |
|
333 |
msg_id = self.kernel_ |
|
|
333 | msg_id = self.kernel_client.shell_channel.complete( | |
|
334 | 334 | text, # text |
|
335 | 335 | self._get_input_buffer_cursor_line(), # line |
|
336 | 336 | self._get_input_buffer_cursor_column(), # cursor_pos |
@@ -376,7 +376,7 b' class IPythonWidget(FrontendWidget):' | |||
|
376 | 376 | """ |
|
377 | 377 | # If a number was not specified, make a prompt number request. |
|
378 | 378 | if number is None: |
|
379 |
msg_id = self.kernel_ |
|
|
379 | msg_id = self.kernel_client.shell_channel.execute('', silent=True) | |
|
380 | 380 | info = self._ExecutionRequest(msg_id, 'prompt') |
|
381 | 381 | self._request_info['execute'][msg_id] = info |
|
382 | 382 | return |
@@ -176,14 +176,14 b' class MainWindow(QtGui.QMainWindow):' | |||
|
176 | 176 | self.update_tab_bar_visibility() |
|
177 | 177 | return |
|
178 | 178 | |
|
179 |
kernel_ |
|
|
179 | kernel_client = closing_widget.kernel_client | |
|
180 | 180 | |
|
181 | 181 | if keepkernel is None and not closing_widget._confirm_exit: |
|
182 | 182 | # don't prompt, just terminate the kernel if we own it |
|
183 | 183 | # or leave it alone if we don't |
|
184 | 184 | keepkernel = closing_widget._existing |
|
185 | 185 | if keepkernel is None: #show prompt |
|
186 |
if kernel_ |
|
|
186 | if kernel_client and kernel_client.channels_running: | |
|
187 | 187 | title = self.window().windowTitle() |
|
188 | 188 | cancel = QtGui.QMessageBox.Cancel |
|
189 | 189 | okay = QtGui.QMessageBox.Ok |
@@ -209,17 +209,17 b' class MainWindow(QtGui.QMainWindow):' | |||
|
209 | 209 | reply = box.exec_() |
|
210 | 210 | if reply == 1: # close All |
|
211 | 211 | for slave in slave_tabs: |
|
212 |
background(slave.kernel_ |
|
|
212 | background(slave.kernel_client.stop_channels) | |
|
213 | 213 | self.tab_widget.removeTab(self.tab_widget.indexOf(slave)) |
|
214 | 214 | closing_widget.execute("exit") |
|
215 | 215 | self.tab_widget.removeTab(current_tab) |
|
216 |
background(kernel_ |
|
|
216 | background(kernel_client.stop_channels) | |
|
217 | 217 | elif reply == 0: # close Console |
|
218 | 218 | if not closing_widget._existing: |
|
219 | 219 | # Have kernel: don't quit, just close the tab |
|
220 | 220 | closing_widget.execute("exit True") |
|
221 | 221 | self.tab_widget.removeTab(current_tab) |
|
222 |
background(kernel_ |
|
|
222 | background(kernel_client.stop_channels) | |
|
223 | 223 | else: |
|
224 | 224 | reply = QtGui.QMessageBox.question(self, title, |
|
225 | 225 | "Are you sure you want to close this Console?"+ |
@@ -231,15 +231,15 b' class MainWindow(QtGui.QMainWindow):' | |||
|
231 | 231 | self.tab_widget.removeTab(current_tab) |
|
232 | 232 | elif keepkernel: #close console but leave kernel running (no prompt) |
|
233 | 233 | self.tab_widget.removeTab(current_tab) |
|
234 |
background(kernel_ |
|
|
234 | background(kernel_client.stop_channels) | |
|
235 | 235 | else: #close console and kernel (no prompt) |
|
236 | 236 | self.tab_widget.removeTab(current_tab) |
|
237 |
if kernel_ |
|
|
237 | if kernel_client and kernel_client.channels_running: | |
|
238 | 238 | for slave in slave_tabs: |
|
239 |
background(slave.kernel_ |
|
|
239 | background(slave.kernel_client.stop_channels) | |
|
240 | 240 | self.tab_widget.removeTab(self.tab_widget.indexOf(slave)) |
|
241 | 241 | kernel_manager.shutdown_kernel() |
|
242 |
background(kernel_ |
|
|
242 | background(kernel_client.stop_channels) | |
|
243 | 243 | |
|
244 | 244 | self.update_tab_bar_visibility() |
|
245 | 245 | |
@@ -284,7 +284,7 b' class MainWindow(QtGui.QMainWindow):' | |||
|
284 | 284 | #convert from/to int/richIpythonWidget if needed |
|
285 | 285 | if isinstance(tab, int): |
|
286 | 286 | tab = self.tab_widget.widget(tab) |
|
287 |
km=tab.kernel_ |
|
|
287 | km=tab.kernel_client | |
|
288 | 288 | |
|
289 | 289 | #build list of all widgets |
|
290 | 290 | widget_list = [self.tab_widget.widget(i) for i in range(self.tab_widget.count())] |
@@ -292,7 +292,7 b' class MainWindow(QtGui.QMainWindow):' | |||
|
292 | 292 | # widget that are candidate to be the owner of the kernel does have all the same port of the curent widget |
|
293 | 293 | # And should have a _may_close attribute |
|
294 | 294 | filtered_widget_list = [ widget for widget in widget_list if |
|
295 |
widget.kernel_ |
|
|
295 | widget.kernel_client.connection_file == km.connection_file and | |
|
296 | 296 | hasattr(widget,'_may_close') ] |
|
297 | 297 | # the master widget is the one that may close the kernel |
|
298 | 298 | master_widget= [ widget for widget in filtered_widget_list if widget._may_close] |
@@ -315,14 +315,14 b' class MainWindow(QtGui.QMainWindow):' | |||
|
315 | 315 | #convert from/to int/richIpythonWidget if needed |
|
316 | 316 | if isinstance(tab, int): |
|
317 | 317 | tab = self.tab_widget.widget(tab) |
|
318 |
km=tab.kernel_ |
|
|
318 | km=tab.kernel_client | |
|
319 | 319 | |
|
320 | 320 | #build list of all widgets |
|
321 | 321 | widget_list = [self.tab_widget.widget(i) for i in range(self.tab_widget.count())] |
|
322 | 322 | |
|
323 | 323 | # widget that are candidate not to be the owner of the kernel does have all the same port of the curent widget |
|
324 | 324 | filtered_widget_list = ( widget for widget in widget_list if |
|
325 |
widget.kernel_ |
|
|
325 | widget.kernel_client.connection_file == km.connection_file) | |
|
326 | 326 | # Get a list of all widget owning the same kernel and removed it from |
|
327 | 327 | # the previous cadidate. (better using sets ?) |
|
328 | 328 | master_widget_list = self.find_master_tab(tab, as_list=True) |
@@ -64,7 +64,7 b' from IPython.frontend.qt.console.ipython_widget import IPythonWidget' | |||
|
64 | 64 | from IPython.frontend.qt.console.rich_ipython_widget import RichIPythonWidget |
|
65 | 65 | from IPython.frontend.qt.console import styles |
|
66 | 66 | from IPython.frontend.qt.console.mainwindow import MainWindow |
|
67 |
from IPython.frontend.qt. |
|
|
67 | from IPython.frontend.qt.client import QtKernelClient | |
|
68 | 68 | from IPython.kernel import tunnel_to_kernel, find_connection_file |
|
69 | 69 | from IPython.utils.path import filefind |
|
70 | 70 | from IPython.utils.py3compat import str_to_bytes |
@@ -166,7 +166,7 b' class IPythonQtConsoleApp(BaseIPythonApplication, IPythonConsoleApp):' | |||
|
166 | 166 | aliases = Dict(aliases) |
|
167 | 167 | frontend_flags = Any(qt_flags) |
|
168 | 168 | frontend_aliases = Any(qt_aliases) |
|
169 |
kernel_ |
|
|
169 | kernel_client_class = QtKernelClient | |
|
170 | 170 | |
|
171 | 171 | stylesheet = Unicode('', config=True, |
|
172 | 172 | help="path to a custom CSS stylesheet") |
@@ -201,7 +201,7 b' class IPythonQtConsoleApp(BaseIPythonApplication, IPythonConsoleApp):' | |||
|
201 | 201 | kwargs = dict() |
|
202 | 202 | kwargs['extra_arguments'] = self.kernel_argv |
|
203 | 203 | kernel_manager.start_kernel(**kwargs) |
|
204 |
kernel_ |
|
|
204 | kernel_client.start_channels() | |
|
205 | 205 | widget = self.widget_factory(config=self.config, |
|
206 | 206 | local_kernel=True) |
|
207 | 207 | self.init_colors(widget) |
@@ -219,19 +219,19 b' class IPythonQtConsoleApp(BaseIPythonApplication, IPythonConsoleApp):' | |||
|
219 | 219 | current_widget : IPythonWidget |
|
220 | 220 | The IPythonWidget whose kernel this frontend is to share |
|
221 | 221 | """ |
|
222 |
kernel_ |
|
|
223 |
connection_file=current_widget.kernel_ |
|
|
222 | kernel_client = self.kernel_client_class( | |
|
223 | connection_file=current_widget.kernel_client.connection_file, | |
|
224 | 224 | config = self.config, |
|
225 | 225 | ) |
|
226 |
kernel_ |
|
|
227 |
kernel_ |
|
|
226 | kernel_client.load_connection_file() | |
|
227 | kernel_client.start_channels() | |
|
228 | 228 | widget = self.widget_factory(config=self.config, |
|
229 | 229 | local_kernel=False) |
|
230 | 230 | self.init_colors(widget) |
|
231 | 231 | widget._existing = True |
|
232 | 232 | widget._may_close = False |
|
233 | 233 | widget._confirm_exit = False |
|
234 |
widget.kernel_ |
|
|
234 | widget.kernel_client = kernel_client | |
|
235 | 235 | return widget |
|
236 | 236 | |
|
237 | 237 | def init_qt_elements(self): |
@@ -256,6 +256,7 b' class IPythonQtConsoleApp(BaseIPythonApplication, IPythonConsoleApp):' | |||
|
256 | 256 | self.widget._confirm_exit = self.confirm_exit |
|
257 | 257 | |
|
258 | 258 | self.widget.kernel_manager = self.kernel_manager |
|
259 | self.widget.kernel_client = self.kernel_client | |
|
259 | 260 | self.window = MainWindow(self.app, |
|
260 | 261 | confirm_exit=self.confirm_exit, |
|
261 | 262 | new_frontend_factory=self.new_frontend_master, |
@@ -54,20 +54,12 b' class QtShellChannelMixin(ChannelQObject):' | |||
|
54 | 54 | # Emitted when any message is received. |
|
55 | 55 | message_received = QtCore.Signal(object) |
|
56 | 56 | |
|
57 | # Emitted when a reply has been received for the corresponding request | |
|
58 | # type. | |
|
57 | # Emitted when a reply has been received for the corresponding request type. | |
|
59 | 58 | execute_reply = QtCore.Signal(object) |
|
60 | 59 | complete_reply = QtCore.Signal(object) |
|
61 | 60 | object_info_reply = QtCore.Signal(object) |
|
62 | 61 | history_reply = QtCore.Signal(object) |
|
63 | 62 | |
|
64 | # Emitted when the first reply comes back. | |
|
65 | first_reply = QtCore.Signal() | |
|
66 | ||
|
67 | # Used by the first_reply signal logic to determine if a reply is the | |
|
68 | # first. | |
|
69 | _handlers_called = False | |
|
70 | ||
|
71 | 63 | #--------------------------------------------------------------------------- |
|
72 | 64 | # 'ShellChannel' interface |
|
73 | 65 | #--------------------------------------------------------------------------- |
@@ -84,19 +76,6 b' class QtShellChannelMixin(ChannelQObject):' | |||
|
84 | 76 | if signal: |
|
85 | 77 | signal.emit(msg) |
|
86 | 78 | |
|
87 | if not self._handlers_called: | |
|
88 | self.first_reply.emit() | |
|
89 | self._handlers_called = True | |
|
90 | ||
|
91 | #--------------------------------------------------------------------------- | |
|
92 | # 'QtShellChannelMixin' interface | |
|
93 | #--------------------------------------------------------------------------- | |
|
94 | ||
|
95 | def reset_first_reply(self): | |
|
96 | """ Reset the first_reply signal to fire again on the next reply. | |
|
97 | """ | |
|
98 | self._handlers_called = False | |
|
99 | ||
|
100 | 79 | |
|
101 | 80 | class QtIOPubChannelMixin(ChannelQObject): |
|
102 | 81 | |
@@ -189,19 +168,16 b' class QtHBChannelMixin(ChannelQObject):' | |||
|
189 | 168 | self.kernel_died.emit(since_last_heartbeat) |
|
190 | 169 | |
|
191 | 170 | |
|
192 |
class QtKernel |
|
|
193 |
""" A Kernel |
|
|
171 | class QtKernelClientMixin(HasTraits, SuperQObject): | |
|
172 | """ A KernelClient that provides signals and slots. | |
|
194 | 173 | """ |
|
195 | 174 | |
|
196 | 175 | __metaclass__ = MetaQObjectHasTraits |
|
197 | 176 | |
|
198 |
# Emitted when the kernel |
|
|
199 | started_kernel = QtCore.Signal() | |
|
200 | ||
|
201 | # Emitted when the kernel manager has started listening. | |
|
177 | # Emitted when the kernel client has started listening. | |
|
202 | 178 | started_channels = QtCore.Signal() |
|
203 | 179 | |
|
204 |
# Emitted when the kernel |
|
|
180 | # Emitted when the kernel client has stopped listening. | |
|
205 | 181 | stopped_channels = QtCore.Signal() |
|
206 | 182 | |
|
207 | 183 | # Use Qt-specific channel classes that emit signals. |
@@ -211,50 +187,19 b' class QtKernelManagerMixin(HasTraits, SuperQObject):' | |||
|
211 | 187 | hb_channel_class = Type(QtHBChannelMixin) |
|
212 | 188 | |
|
213 | 189 | #--------------------------------------------------------------------------- |
|
214 |
# 'Kernel |
|
|
190 | # 'KernelClient' interface | |
|
215 | 191 | #--------------------------------------------------------------------------- |
|
216 | 192 | |
|
217 | #------ Kernel process management ------------------------------------------ | |
|
218 | ||
|
219 | def start_kernel(self, *args, **kw): | |
|
220 | """ Reimplemented for proper heartbeat management. | |
|
221 | """ | |
|
222 | if self._shell_channel is not None: | |
|
223 | self._shell_channel.reset_first_reply() | |
|
224 | super(QtKernelManagerMixin, self).start_kernel(*args, **kw) | |
|
225 | self.started_kernel.emit() | |
|
226 | ||
|
227 | 193 | #------ Channel management ------------------------------------------------- |
|
228 | 194 | |
|
229 | 195 | def start_channels(self, *args, **kw): |
|
230 | 196 | """ Reimplemented to emit signal. |
|
231 | 197 | """ |
|
232 |
super(QtKernel |
|
|
198 | super(QtKernelClientMixin, self).start_channels(*args, **kw) | |
|
233 | 199 | self.started_channels.emit() |
|
234 | 200 | |
|
235 | 201 | def stop_channels(self): |
|
236 | 202 | """ Reimplemented to emit signal. |
|
237 | 203 | """ |
|
238 |
super(QtKernel |
|
|
204 | super(QtKernelClientMixin, self).stop_channels() | |
|
239 | 205 | self.stopped_channels.emit() |
|
240 | ||
|
241 | @property | |
|
242 | def shell_channel(self): | |
|
243 | """ Reimplemented for proper heartbeat management. | |
|
244 | """ | |
|
245 | if self._shell_channel is None: | |
|
246 | self._shell_channel = super(QtKernelManagerMixin,self).shell_channel | |
|
247 | self._shell_channel.first_reply.connect(self._first_reply) | |
|
248 | return self._shell_channel | |
|
249 | ||
|
250 | #--------------------------------------------------------------------------- | |
|
251 | # Protected interface | |
|
252 | #--------------------------------------------------------------------------- | |
|
253 | ||
|
254 | def _first_reply(self): | |
|
255 | """ Unpauses the heartbeat channel when the first reply is received on | |
|
256 | the execute channel. Note that this will *not* start the heartbeat | |
|
257 | channel if it is not already running! | |
|
258 | """ | |
|
259 | if self._hb_channel is not None: | |
|
260 | self._hb_channel.unpause() |
General Comments 0
You need to be logged in to leave comments.
Login now