Show More
@@ -43,6 +43,9 b' class InProcessChannel(object):' | |||
|
43 | 43 | """ |
|
44 | 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 | 50 | # InProcessChannel interface |
|
48 | 51 | #-------------------------------------------------------------------------- |
@@ -70,102 +73,14 b' class InProcessShellChannel(InProcessChannel):' | |||
|
70 | 73 | |
|
71 | 74 | # flag for whether execute requests should be allowed to call raw_input |
|
72 | 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 | 77 | class InProcessIOPubChannel(InProcessChannel): |
|
153 | 78 | """See `IPython.kernel.channels.IOPubChannel` for docstrings.""" |
|
154 | 79 | |
|
155 | def flush(self, timeout=1.0): | |
|
156 | pass | |
|
157 | ||
|
158 | 80 | |
|
159 | 81 | class InProcessStdInChannel(InProcessChannel): |
|
160 | 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 | 86 | class InProcessHBChannel(InProcessChannel): |
@@ -12,6 +12,7 b'' | |||
|
12 | 12 | #----------------------------------------------------------------------------- |
|
13 | 13 | |
|
14 | 14 | # IPython imports |
|
15 | from IPython.kernel.inprocess.socket import DummySocket | |
|
15 | 16 | from IPython.utils.traitlets import Type, Instance |
|
16 | 17 | from IPython.kernel.clientabc import KernelClientABC |
|
17 | 18 | from IPython.kernel.client import KernelClient |
@@ -79,6 +80,76 b' class InProcessKernelClient(KernelClient):' | |||
|
79 | 80 | self._hb_channel = self.hb_channel_class(self) |
|
80 | 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 | 155 | # ABC Registration |
@@ -4,9 +4,9 b'' | |||
|
4 | 4 | # Local imports. |
|
5 | 5 | from IPython.external.qt import QtCore |
|
6 | 6 | from IPython.kernel.inprocess import ( |
|
7 | InProcessShellChannel, InProcessIOPubChannel, InProcessStdInChannel, | |
|
8 | 7 | InProcessHBChannel, InProcessKernelClient, InProcessKernelManager, |
|
9 | 8 | ) |
|
9 | from IPython.kernel.inprocess.channels import InProcessChannel | |
|
10 | 10 | |
|
11 | 11 | from IPython.utils.traitlets import Type |
|
12 | 12 | from .kernel_mixins import ( ChannelQObject, |
@@ -14,90 +14,8 b' from .kernel_mixins import ( ChannelQObject,' | |||
|
14 | 14 | QtKernelManagerMixin, |
|
15 | 15 | ) |
|
16 | 16 | |
|
17 | ||
|
18 | class QtInProcessShellChannel(ChannelQObject, InProcessShellChannel): | |
|
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) | |
|
17 | class QtInProcessChannel(ChannelQObject, InProcessChannel): | |
|
18 | pass | |
|
101 | 19 | |
|
102 | 20 | class QtInProcessHBChannel(QtHBChannelMixin, InProcessHBChannel): |
|
103 | 21 | pass |
@@ -106,9 +24,9 b' class QtInProcessKernelClient(QtKernelClientMixin, InProcessKernelClient):' | |||
|
106 | 24 | """ An in-process KernelManager with signals and slots. |
|
107 | 25 | """ |
|
108 | 26 | |
|
109 |
iopub_channel_class = Type(QtInProcess |
|
|
110 |
shell_channel_class = Type(QtInProcess |
|
|
111 |
stdin_channel_class = Type(QtInProcess |
|
|
27 | iopub_channel_class = Type(QtInProcessChannel) | |
|
28 | shell_channel_class = Type(QtInProcessChannel) | |
|
29 | stdin_channel_class = Type(QtInProcessChannel) | |
|
112 | 30 | hb_channel_class = Type(QtInProcessHBChannel) |
|
113 | 31 | |
|
114 | 32 | class QtInProcessKernelManager(QtKernelManagerMixin, InProcessKernelManager): |
@@ -20,10 +20,6 b' class ChannelQObject(SuperQObject):' | |||
|
20 | 20 | # Emitted when any message is received. |
|
21 | 21 | message_received = QtCore.Signal(object) |
|
22 | 22 | |
|
23 | #--------------------------------------------------------------------------- | |
|
24 | # Channel interface | |
|
25 | #--------------------------------------------------------------------------- | |
|
26 | ||
|
27 | 23 | def start(self): |
|
28 | 24 | """ Reimplemented to emit signal. |
|
29 | 25 | """ |
@@ -36,21 +32,26 b' class ChannelQObject(SuperQObject):' | |||
|
36 | 32 | super(ChannelQObject, self).stop() |
|
37 | 33 | self.stopped.emit() |
|
38 | 34 | |
|
39 | #--------------------------------------------------------------------------- | |
|
40 | # InProcessChannel interface | |
|
41 | #--------------------------------------------------------------------------- | |
|
42 | ||
|
43 | 35 | def call_handlers_later(self, *args, **kwds): |
|
44 | 36 | """ Call the message handlers later. |
|
45 | 37 | """ |
|
46 | 38 | do_later = lambda: self.call_handlers(*args, **kwds) |
|
47 | 39 | QtCore.QTimer.singleShot(0, do_later) |
|
48 | 40 | |
|
41 | def call_handlers(self, msg): | |
|
42 | self.message_received.emit(msg) | |
|
43 | ||
|
49 | 44 | def process_events(self): |
|
50 | 45 | """ Process any pending GUI events. |
|
51 | 46 | """ |
|
52 | 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 | 56 | class QtHBChannelMixin(ChannelQObject): |
|
56 | 57 |
General Comments 0
You need to be logged in to leave comments.
Login now