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(QtInProcess |
|
27 | iopub_channel_class = Type(QtInProcessChannel) | |
110 |
shell_channel_class = Type(QtInProcess |
|
28 | shell_channel_class = Type(QtInProcessChannel) | |
111 |
stdin_channel_class = Type(QtInProcess |
|
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