##// END OF EJS Templates
Add kernel_info method to InProcessShellChannel
Christophe Pradal -
Show More
@@ -1,195 +1,201 b''
1 1 """ A kernel client for in-process kernels. """
2 2
3 3 #-----------------------------------------------------------------------------
4 4 # Copyright (C) 2012 The IPython Development Team
5 5 #
6 6 # Distributed under the terms of the BSD License. The full license is in
7 7 # the file COPYING, distributed as part of this software.
8 8 #-----------------------------------------------------------------------------
9 9
10 10 #-----------------------------------------------------------------------------
11 11 # Imports
12 12 #-----------------------------------------------------------------------------
13 13
14 14 # IPython imports
15 15 from IPython.kernel.channelsabc import (
16 16 ShellChannelABC, IOPubChannelABC,
17 17 HBChannelABC, StdInChannelABC,
18 18 )
19 19
20 20 # Local imports
21 21 from .socket import DummySocket
22 22
23 23 #-----------------------------------------------------------------------------
24 24 # Channel classes
25 25 #-----------------------------------------------------------------------------
26 26
27 27 class InProcessChannel(object):
28 28 """Base class for in-process channels."""
29 29 proxy_methods = []
30 30
31 31 def __init__(self, client):
32 32 super(InProcessChannel, self).__init__()
33 33 self.client = client
34 34 self._is_alive = False
35 35
36 36 #--------------------------------------------------------------------------
37 37 # Channel interface
38 38 #--------------------------------------------------------------------------
39 39
40 40 def is_alive(self):
41 41 return self._is_alive
42 42
43 43 def start(self):
44 44 self._is_alive = True
45 45
46 46 def stop(self):
47 47 self._is_alive = False
48 48
49 49 def call_handlers(self, msg):
50 50 """ This method is called in the main thread when a message arrives.
51 51
52 52 Subclasses should override this method to handle incoming messages.
53 53 """
54 54 raise NotImplementedError('call_handlers must be defined in a subclass.')
55 55
56 56 #--------------------------------------------------------------------------
57 57 # InProcessChannel interface
58 58 #--------------------------------------------------------------------------
59 59
60 60 def call_handlers_later(self, *args, **kwds):
61 61 """ Call the message handlers later.
62 62
63 63 The default implementation just calls the handlers immediately, but this
64 64 method exists so that GUI toolkits can defer calling the handlers until
65 65 after the event loop has run, as expected by GUI frontends.
66 66 """
67 67 self.call_handlers(*args, **kwds)
68 68
69 69 def process_events(self):
70 70 """ Process any pending GUI events.
71 71
72 72 This method will be never be called from a frontend without an event
73 73 loop (e.g., a terminal frontend).
74 74 """
75 75 raise NotImplementedError
76 76
77 77
78 78 class InProcessShellChannel(InProcessChannel):
79 79 """See `IPython.kernel.channels.ShellChannel` for docstrings."""
80 80
81 81 # flag for whether execute requests should be allowed to call raw_input
82 82 allow_stdin = True
83 83 proxy_methods = [
84 84 'execute',
85 85 'complete',
86 86 'object_info',
87 87 'history',
88 88 'shutdown',
89 89 'kernel_info',
90 90 ]
91 91
92 92 #--------------------------------------------------------------------------
93 93 # ShellChannel interface
94 94 #--------------------------------------------------------------------------
95 95
96 96 def execute(self, code, silent=False, store_history=True,
97 97 user_variables=[], user_expressions={}, allow_stdin=None):
98 98 if allow_stdin is None:
99 99 allow_stdin = self.allow_stdin
100 100 content = dict(code=code, silent=silent, store_history=store_history,
101 101 user_variables=user_variables,
102 102 user_expressions=user_expressions,
103 103 allow_stdin=allow_stdin)
104 104 msg = self.client.session.msg('execute_request', content)
105 105 self._dispatch_to_kernel(msg)
106 106 return msg['header']['msg_id']
107 107
108 108 def complete(self, text, line, cursor_pos, block=None):
109 109 content = dict(text=text, line=line, block=block, cursor_pos=cursor_pos)
110 110 msg = self.client.session.msg('complete_request', content)
111 111 self._dispatch_to_kernel(msg)
112 112 return msg['header']['msg_id']
113 113
114 114 def object_info(self, oname, detail_level=0):
115 115 content = dict(oname=oname, detail_level=detail_level)
116 116 msg = self.client.session.msg('object_info_request', content)
117 117 self._dispatch_to_kernel(msg)
118 118 return msg['header']['msg_id']
119 119
120 120 def history(self, raw=True, output=False, hist_access_type='range', **kwds):
121 121 content = dict(raw=raw, output=output,
122 122 hist_access_type=hist_access_type, **kwds)
123 123 msg = self.client.session.msg('history_request', content)
124 124 self._dispatch_to_kernel(msg)
125 125 return msg['header']['msg_id']
126 126
127 127 def shutdown(self, restart=False):
128 128 # FIXME: What to do here?
129 129 raise NotImplementedError('Cannot shutdown in-process kernel')
130 130
131 def kernel_info(self):
132 """Request kernel info."""
133 msg = self.client.session.msg('kernel_info_request')
134 self._dispatch_to_kernel(msg)
135 return msg['header']['msg_id']
136
131 137 #--------------------------------------------------------------------------
132 138 # Protected interface
133 139 #--------------------------------------------------------------------------
134 140
135 141 def _dispatch_to_kernel(self, msg):
136 142 """ Send a message to the kernel and handle a reply.
137 143 """
138 144 kernel = self.client.kernel
139 145 if kernel is None:
140 146 raise RuntimeError('Cannot send request. No kernel exists.')
141 147
142 148 stream = DummySocket()
143 149 self.client.session.send(stream, msg)
144 150 msg_parts = stream.recv_multipart()
145 151 kernel.dispatch_shell(stream, msg_parts)
146 152
147 153 idents, reply_msg = self.client.session.recv(stream, copy=False)
148 154 self.call_handlers_later(reply_msg)
149 155
150 156
151 157 class InProcessIOPubChannel(InProcessChannel):
152 158 """See `IPython.kernel.channels.IOPubChannel` for docstrings."""
153 159
154 160 def flush(self, timeout=1.0):
155 161 pass
156 162
157 163
158 164 class InProcessStdInChannel(InProcessChannel):
159 165 """See `IPython.kernel.channels.StdInChannel` for docstrings."""
160 166
161 167 proxy_methods = ['input']
162 168
163 169 def input(self, string):
164 170 kernel = self.client.kernel
165 171 if kernel is None:
166 172 raise RuntimeError('Cannot send input reply. No kernel exists.')
167 173 kernel.raw_input_str = string
168 174
169 175
170 176 class InProcessHBChannel(InProcessChannel):
171 177 """See `IPython.kernel.channels.HBChannel` for docstrings."""
172 178
173 179 time_to_dead = 3.0
174 180
175 181 def __init__(self, *args, **kwds):
176 182 super(InProcessHBChannel, self).__init__(*args, **kwds)
177 183 self._pause = True
178 184
179 185 def pause(self):
180 186 self._pause = True
181 187
182 188 def unpause(self):
183 189 self._pause = False
184 190
185 191 def is_beating(self):
186 192 return not self._pause
187 193
188 194 #-----------------------------------------------------------------------------
189 195 # ABC Registration
190 196 #-----------------------------------------------------------------------------
191 197
192 198 ShellChannelABC.register(InProcessShellChannel)
193 199 IOPubChannelABC.register(InProcessIOPubChannel)
194 200 HBChannelABC.register(InProcessHBChannel)
195 201 StdInChannelABC.register(InProcessStdInChannel)
General Comments 0
You need to be logged in to leave comments. Login now