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