##// END OF EJS Templates
Collapse Qt in-process channel classes together
Thomas Kluyver -
Show More
@@ -43,6 +43,9 b' class InProcessChannel(object):'
43 """
43 """
44 raise NotImplementedError('call_handlers must be defined in a subclass.')
44 raise NotImplementedError('call_handlers must be defined in a subclass.')
45
45
46 def flush(self, timeout=1.0):
47 pass
48
46 #--------------------------------------------------------------------------
49 #--------------------------------------------------------------------------
47 # InProcessChannel interface
50 # InProcessChannel interface
48 #--------------------------------------------------------------------------
51 #--------------------------------------------------------------------------
@@ -70,102 +73,14 b' class InProcessShellChannel(InProcessChannel):'
70
73
71 # flag for whether execute requests should be allowed to call raw_input
74 # flag for whether execute requests should be allowed to call raw_input
72 allow_stdin = True
75 allow_stdin = True
73 proxy_methods = [
74 'execute',
75 'complete',
76 'inspect',
77 'history',
78 'shutdown',
79 'kernel_info',
80 ]
81
82 #--------------------------------------------------------------------------
83 # ShellChannel interface
84 #--------------------------------------------------------------------------
85
86 def execute(self, code, silent=False, store_history=True,
87 user_expressions={}, allow_stdin=None):
88 if allow_stdin is None:
89 allow_stdin = self.allow_stdin
90 content = dict(code=code, silent=silent, store_history=store_history,
91 user_expressions=user_expressions,
92 allow_stdin=allow_stdin)
93 msg = self.client.session.msg('execute_request', content)
94 self._dispatch_to_kernel(msg)
95 return msg['header']['msg_id']
96
97 def complete(self, code, cursor_pos=None):
98 if cursor_pos is None:
99 cursor_pos = len(code)
100 content = dict(code=code, cursor_pos=cursor_pos)
101 msg = self.client.session.msg('complete_request', content)
102 self._dispatch_to_kernel(msg)
103 return msg['header']['msg_id']
104
105 def inspect(self, code, cursor_pos=None, detail_level=0):
106 if cursor_pos is None:
107 cursor_pos = len(code)
108 content = dict(code=code, cursor_pos=cursor_pos,
109 detail_level=detail_level,
110 )
111 msg = self.client.session.msg('inspect_request', content)
112 self._dispatch_to_kernel(msg)
113 return msg['header']['msg_id']
114
115 def history(self, raw=True, output=False, hist_access_type='range', **kwds):
116 content = dict(raw=raw, output=output,
117 hist_access_type=hist_access_type, **kwds)
118 msg = self.client.session.msg('history_request', content)
119 self._dispatch_to_kernel(msg)
120 return msg['header']['msg_id']
121
122 def shutdown(self, restart=False):
123 # FIXME: What to do here?
124 raise NotImplementedError('Cannot shutdown in-process kernel')
125
126 def kernel_info(self):
127 """Request kernel info."""
128 msg = self.client.session.msg('kernel_info_request')
129 self._dispatch_to_kernel(msg)
130 return msg['header']['msg_id']
131
132 #--------------------------------------------------------------------------
133 # Protected interface
134 #--------------------------------------------------------------------------
135
136 def _dispatch_to_kernel(self, msg):
137 """ Send a message to the kernel and handle a reply.
138 """
139 kernel = self.client.kernel
140 if kernel is None:
141 raise RuntimeError('Cannot send request. No kernel exists.')
142
143 stream = DummySocket()
144 self.client.session.send(stream, msg)
145 msg_parts = stream.recv_multipart()
146 kernel.dispatch_shell(stream, msg_parts)
147
148 idents, reply_msg = self.client.session.recv(stream, copy=False)
149 self.call_handlers_later(reply_msg)
150
151
76
152 class InProcessIOPubChannel(InProcessChannel):
77 class InProcessIOPubChannel(InProcessChannel):
153 """See `IPython.kernel.channels.IOPubChannel` for docstrings."""
78 """See `IPython.kernel.channels.IOPubChannel` for docstrings."""
154
79
155 def flush(self, timeout=1.0):
156 pass
157
158
80
159 class InProcessStdInChannel(InProcessChannel):
81 class InProcessStdInChannel(InProcessChannel):
160 """See `IPython.kernel.channels.StdInChannel` for docstrings."""
82 """See `IPython.kernel.channels.StdInChannel` for docstrings."""
161
83
162 proxy_methods = ['input']
163
164 def input(self, string):
165 kernel = self.client.kernel
166 if kernel is None:
167 raise RuntimeError('Cannot send input reply. No kernel exists.')
168 kernel.raw_input_str = string
169
84
170
85
171 class InProcessHBChannel(InProcessChannel):
86 class InProcessHBChannel(InProcessChannel):
@@ -12,6 +12,7 b''
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13
13
14 # IPython imports
14 # IPython imports
15 from IPython.kernel.inprocess.socket import DummySocket
15 from IPython.utils.traitlets import Type, Instance
16 from IPython.utils.traitlets import Type, Instance
16 from IPython.kernel.clientabc import KernelClientABC
17 from IPython.kernel.clientabc import KernelClientABC
17 from IPython.kernel.client import KernelClient
18 from IPython.kernel.client import KernelClient
@@ -79,6 +80,76 b' class InProcessKernelClient(KernelClient):'
79 self._hb_channel = self.hb_channel_class(self)
80 self._hb_channel = self.hb_channel_class(self)
80 return self._hb_channel
81 return self._hb_channel
81
82
83 # Methods for sending specific messages
84 # -------------------------------------
85
86 def execute(self, code, silent=False, store_history=True,
87 user_expressions={}, allow_stdin=None):
88 if allow_stdin is None:
89 allow_stdin = self.allow_stdin
90 content = dict(code=code, silent=silent, store_history=store_history,
91 user_expressions=user_expressions,
92 allow_stdin=allow_stdin)
93 msg = self.session.msg('execute_request', content)
94 self._dispatch_to_kernel(msg)
95 return msg['header']['msg_id']
96
97 def complete(self, code, cursor_pos=None):
98 if cursor_pos is None:
99 cursor_pos = len(code)
100 content = dict(code=code, cursor_pos=cursor_pos)
101 msg = self.session.msg('complete_request', content)
102 self._dispatch_to_kernel(msg)
103 return msg['header']['msg_id']
104
105 def inspect(self, code, cursor_pos=None, detail_level=0):
106 if cursor_pos is None:
107 cursor_pos = len(code)
108 content = dict(code=code, cursor_pos=cursor_pos,
109 detail_level=detail_level,
110 )
111 msg = self.session.msg('inspect_request', content)
112 self._dispatch_to_kernel(msg)
113 return msg['header']['msg_id']
114
115 def history(self, raw=True, output=False, hist_access_type='range', **kwds):
116 content = dict(raw=raw, output=output,
117 hist_access_type=hist_access_type, **kwds)
118 msg = self.session.msg('history_request', content)
119 self._dispatch_to_kernel(msg)
120 return msg['header']['msg_id']
121
122 def shutdown(self, restart=False):
123 # FIXME: What to do here?
124 raise NotImplementedError('Cannot shutdown in-process kernel')
125
126 def kernel_info(self):
127 """Request kernel info."""
128 msg = self.session.msg('kernel_info_request')
129 self._dispatch_to_kernel(msg)
130 return msg['header']['msg_id']
131
132 def input(self, string):
133 if self.kernel is None:
134 raise RuntimeError('Cannot send input reply. No kernel exists.')
135 self.kernel.raw_input_str = string
136
137
138 def _dispatch_to_kernel(self, msg):
139 """ Send a message to the kernel and handle a reply.
140 """
141 kernel = self.kernel
142 if kernel is None:
143 raise RuntimeError('Cannot send request. No kernel exists.')
144
145 stream = DummySocket()
146 self.session.send(stream, msg)
147 msg_parts = stream.recv_multipart()
148 kernel.dispatch_shell(stream, msg_parts)
149
150 idents, reply_msg = self.session.recv(stream, copy=False)
151 self.shell_channel.call_handlers_later(reply_msg)
152
82
153
83 #-----------------------------------------------------------------------------
154 #-----------------------------------------------------------------------------
84 # ABC Registration
155 # ABC Registration
@@ -4,9 +4,9 b''
4 # Local imports.
4 # Local imports.
5 from IPython.external.qt import QtCore
5 from IPython.external.qt import QtCore
6 from IPython.kernel.inprocess import (
6 from IPython.kernel.inprocess import (
7 InProcessShellChannel, InProcessIOPubChannel, InProcessStdInChannel,
8 InProcessHBChannel, InProcessKernelClient, InProcessKernelManager,
7 InProcessHBChannel, InProcessKernelClient, InProcessKernelManager,
9 )
8 )
9 from IPython.kernel.inprocess.channels import InProcessChannel
10
10
11 from IPython.utils.traitlets import Type
11 from IPython.utils.traitlets import Type
12 from .kernel_mixins import ( ChannelQObject,
12 from .kernel_mixins import ( ChannelQObject,
@@ -14,90 +14,8 b' from .kernel_mixins import ( ChannelQObject,'
14 QtKernelManagerMixin,
14 QtKernelManagerMixin,
15 )
15 )
16
16
17
17 class QtInProcessChannel(ChannelQObject, InProcessChannel):
18 class QtInProcessShellChannel(ChannelQObject, InProcessShellChannel):
18 pass
19 # Emitted when a reply has been received for the corresponding request type.
20 execute_reply = QtCore.Signal(object)
21 complete_reply = QtCore.Signal(object)
22 inspect_reply = QtCore.Signal(object)
23 history_reply = QtCore.Signal(object)
24 kernel_info_reply = QtCore.Signal(object)
25
26 def call_handlers(self, msg):
27 """ Reimplemented to emit signals instead of making callbacks.
28 """
29 # Emit the generic signal.
30 self.message_received.emit(msg)
31
32 # Emit signals for specialized message types.
33 msg_type = msg['header']['msg_type']
34 if msg_type == 'kernel_info_reply':
35 self._handle_kernel_info_reply(msg)
36
37 signal = getattr(self, msg_type, None)
38 if signal:
39 signal.emit(msg)
40
41 class QtInProcessIOPubChannel(ChannelQObject, InProcessIOPubChannel):
42 # Emitted when a message of type 'stream' is received.
43 stream_received = QtCore.Signal(object)
44
45 # Emitted when a message of type 'execute_input' is received.
46 execute_input_received = QtCore.Signal(object)
47
48 # Emitted when a message of type 'execute_result' is received.
49 execute_result_received = QtCore.Signal(object)
50
51 # Emitted when a message of type 'error' is received.
52 error_received = QtCore.Signal(object)
53
54 # Emitted when a message of type 'display_data' is received
55 display_data_received = QtCore.Signal(object)
56
57 # Emitted when a crash report message is received from the kernel's
58 # last-resort sys.excepthook.
59 crash_received = QtCore.Signal(object)
60
61 # Emitted when a shutdown is noticed.
62 shutdown_reply_received = QtCore.Signal(object)
63
64 #---------------------------------------------------------------------------
65 # 'IOPubChannel' interface
66 #---------------------------------------------------------------------------
67
68 def call_handlers(self, msg):
69 """ Reimplemented to emit signals instead of making callbacks.
70 """
71 # Emit the generic signal.
72 self.message_received.emit(msg)
73 # Emit signals for specialized message types.
74 msg_type = msg['header']['msg_type']
75 signal = getattr(self, msg_type + '_received', None)
76 if signal:
77 signal.emit(msg)
78 elif msg_type in ('stdout', 'stderr'):
79 self.stream_received.emit(msg)
80
81 def flush(self):
82 """ Reimplemented to ensure that signals are dispatched immediately.
83 """
84 super(QtInProcessIOPubChannel, self).flush()
85 QtCore.QCoreApplication.instance().processEvents()
86
87 class QtInProcessStdInChannel(ChannelQObject, InProcessStdInChannel):
88 # Emitted when an input request is received.
89 input_requested = QtCore.Signal(object)
90
91 def call_handlers(self, msg):
92 """ Reimplemented to emit signals instead of making callbacks.
93 """
94 # Emit the generic signal.
95 self.message_received.emit(msg)
96
97 # Emit signals for specialized message types.
98 msg_type = msg['header']['msg_type']
99 if msg_type == 'input_request':
100 self.input_requested.emit(msg)
101
19
102 class QtInProcessHBChannel(QtHBChannelMixin, InProcessHBChannel):
20 class QtInProcessHBChannel(QtHBChannelMixin, InProcessHBChannel):
103 pass
21 pass
@@ -106,9 +24,9 b' class QtInProcessKernelClient(QtKernelClientMixin, InProcessKernelClient):'
106 """ An in-process KernelManager with signals and slots.
24 """ An in-process KernelManager with signals and slots.
107 """
25 """
108
26
109 iopub_channel_class = Type(QtInProcessIOPubChannel)
27 iopub_channel_class = Type(QtInProcessChannel)
110 shell_channel_class = Type(QtInProcessShellChannel)
28 shell_channel_class = Type(QtInProcessChannel)
111 stdin_channel_class = Type(QtInProcessStdInChannel)
29 stdin_channel_class = Type(QtInProcessChannel)
112 hb_channel_class = Type(QtInProcessHBChannel)
30 hb_channel_class = Type(QtInProcessHBChannel)
113
31
114 class QtInProcessKernelManager(QtKernelManagerMixin, InProcessKernelManager):
32 class QtInProcessKernelManager(QtKernelManagerMixin, InProcessKernelManager):
@@ -20,10 +20,6 b' class ChannelQObject(SuperQObject):'
20 # Emitted when any message is received.
20 # Emitted when any message is received.
21 message_received = QtCore.Signal(object)
21 message_received = QtCore.Signal(object)
22
22
23 #---------------------------------------------------------------------------
24 # Channel interface
25 #---------------------------------------------------------------------------
26
27 def start(self):
23 def start(self):
28 """ Reimplemented to emit signal.
24 """ Reimplemented to emit signal.
29 """
25 """
@@ -36,21 +32,26 b' class ChannelQObject(SuperQObject):'
36 super(ChannelQObject, self).stop()
32 super(ChannelQObject, self).stop()
37 self.stopped.emit()
33 self.stopped.emit()
38
34
39 #---------------------------------------------------------------------------
40 # InProcessChannel interface
41 #---------------------------------------------------------------------------
42
43 def call_handlers_later(self, *args, **kwds):
35 def call_handlers_later(self, *args, **kwds):
44 """ Call the message handlers later.
36 """ Call the message handlers later.
45 """
37 """
46 do_later = lambda: self.call_handlers(*args, **kwds)
38 do_later = lambda: self.call_handlers(*args, **kwds)
47 QtCore.QTimer.singleShot(0, do_later)
39 QtCore.QTimer.singleShot(0, do_later)
48
40
41 def call_handlers(self, msg):
42 self.message_received.emit(msg)
43
49 def process_events(self):
44 def process_events(self):
50 """ Process any pending GUI events.
45 """ Process any pending GUI events.
51 """
46 """
52 QtCore.QCoreApplication.instance().processEvents()
47 QtCore.QCoreApplication.instance().processEvents()
53
48
49 def flush(self):
50 """ Reimplemented to ensure that signals are dispatched immediately.
51 """
52 super(ChannelQObject, self).flush()
53 self.process_events()
54
54
55
55 class QtHBChannelMixin(ChannelQObject):
56 class QtHBChannelMixin(ChannelQObject):
56
57
General Comments 0
You need to be logged in to leave comments. Login now