##// END OF EJS Templates
use IOLoop in ipkernel...
MinRK -
Show More
@@ -164,7 +164,10 b' def loop_cocoa(kernel):'
164 # but still need a Poller for when there are no active windows,
164 # but still need a Poller for when there are no active windows,
165 # during which time mainloop() returns immediately
165 # during which time mainloop() returns immediately
166 poller = zmq.Poller()
166 poller = zmq.Poller()
167 poller.register(kernel.shell_socket, zmq.POLLIN)
167 if kernel.control_stream:
168 poller.register(kernel.control_stream.socket, zmq.POLLIN)
169 for stream in kernel.shell_streams:
170 poller.register(stream.socket, zmq.POLLIN)
168
171
169 while True:
172 while True:
170 try:
173 try:
@@ -26,11 +26,13 b' import uuid'
26
26
27 from datetime import datetime
27 from datetime import datetime
28 from signal import (
28 from signal import (
29 signal, default_int_handler, SIGINT, SIG_IGN
29 signal, getsignal, default_int_handler, SIGINT, SIG_IGN
30 )
30 )
31
31
32 # System library imports
32 # System library imports
33 import zmq
33 import zmq
34 from zmq.eventloop import ioloop
35 from zmq.eventloop.zmqstream import ZMQStream
34
36
35 # Local imports
37 # Local imports
36 from IPython.core import pylabtools
38 from IPython.core import pylabtools
@@ -68,13 +70,18 b' class Kernel(Configurable):'
68
70
69 # attribute to override with a GUI
71 # attribute to override with a GUI
70 eventloop = Any(None)
72 eventloop = Any(None)
73 def _eventloop_changed(self, name, old, new):
74 """schedule call to eventloop from IOLoop"""
75 loop = ioloop.IOLoop.instance()
76 loop.add_timeout(time.time()+0.1, self.enter_eventloop)
71
77
72 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
78 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
73 session = Instance(Session)
79 session = Instance(Session)
74 profile_dir = Instance('IPython.core.profiledir.ProfileDir')
80 profile_dir = Instance('IPython.core.profiledir.ProfileDir')
75 shell_sockets = List()
81 shell_streams = List()
76 control_socket = Instance('zmq.Socket')
82 control_stream = Instance(ZMQStream)
77 iopub_socket = Instance('zmq.Socket')
83 iopub_stream = Instance(ZMQStream)
84 stdin_socket = Instance(zmq.Socket)
78 log = Instance(logging.Logger)
85 log = Instance(logging.Logger)
79
86
80 user_module = Instance('types.ModuleType')
87 user_module = Instance('types.ModuleType')
@@ -127,14 +134,9 b' class Kernel(Configurable):'
127 aborted = Set()
134 aborted = Set()
128
135
129
136
130
131 def __init__(self, **kwargs):
137 def __init__(self, **kwargs):
132 super(Kernel, self).__init__(**kwargs)
138 super(Kernel, self).__init__(**kwargs)
133
139
134 # Before we even start up the shell, register *first* our exit handlers
135 # so they come before the shell's
136 atexit.register(self._at_shutdown)
137
138 # Initialize the InteractiveShell subclass
140 # Initialize the InteractiveShell subclass
139 self.shell = ZMQInteractiveShell.instance(config=self.config,
141 self.shell = ZMQInteractiveShell.instance(config=self.config,
140 profile_dir = self.profile_dir,
142 profile_dir = self.profile_dir,
@@ -142,9 +144,9 b' class Kernel(Configurable):'
142 user_ns = self.user_ns,
144 user_ns = self.user_ns,
143 )
145 )
144 self.shell.displayhook.session = self.session
146 self.shell.displayhook.session = self.session
145 self.shell.displayhook.pub_socket = self.iopub_socket
147 self.shell.displayhook.pub_socket = self.iopub_stream.socket
146 self.shell.display_pub.session = self.session
148 self.shell.display_pub.session = self.session
147 self.shell.display_pub.pub_socket = self.iopub_socket
149 self.shell.display_pub.pub_socket = self.iopub_stream.socket
148
150
149 # TMP - hack while developing
151 # TMP - hack while developing
150 self.shell._reply_content = None
152 self.shell._reply_content = None
@@ -155,135 +157,111 b' class Kernel(Configurable):'
155 'connect_request', 'shutdown_request',
157 'connect_request', 'shutdown_request',
156 'apply_request',
158 'apply_request',
157 ]
159 ]
158 self.handlers = {}
160 self.shell_handlers = {}
159 for msg_type in msg_types:
161 for msg_type in msg_types:
160 self.handlers[msg_type] = getattr(self, msg_type)
162 self.shell_handlers[msg_type] = getattr(self, msg_type)
161
163
162 control_msg_types = [ 'clear_request', 'abort_request' ]
164 control_msg_types = [ 'clear_request', 'abort_request' ]
163 self.control_handlers = {}
165 self.control_handlers = {}
164 for msg_type in control_msg_types:
166 for msg_type in control_msg_types:
165 self.control_handlers[msg_type] = getattr(self, msg_type)
167 self.control_handlers[msg_type] = getattr(self, msg_type)
166
168
167 def do_one_iteration(self):
169 def dispatch_control(self, msg):
168 """Do one iteration of the kernel's evaluation loop.
170 """dispatch control requests"""
169 """
171 idents,msg = self.session.feed_identities(msg, copy=False)
170
172 try:
171 # always flush control socket first
173 msg = self.session.unserialize(msg, content=True, copy=False)
172 while True:
174 except:
173 if self.control_socket is None:
175 self.log.error("Invalid Control Message", exc_info=True)
174 break
176 return
175 try:
176 idents,msg = self.session.recv(self.control_socket, zmq.NOBLOCK)
177 except Exception:
178 self.log.warn("Invalid Control Message:", exc_info=True)
179 continue
180 if msg is None:
181 break
182 self.dispatch_message(self.control_socket, idents, msg, self.control_handlers)
183
184 for socket in self.shell_sockets:
185 try:
186 idents,msg = self.session.recv(socket, zmq.NOBLOCK, copy=False)
187 except Exception:
188 self.log.warn("Invalid Message:", exc_info=True)
189 continue
190
191 if msg is None:
192 continue
193
194 self.dispatch_message(socket, idents, msg, self.handlers)
195
177
196 def dispatch_message(self, socket, idents, msg, handlers):
178 self.log.debug("Control received: %s", msg)
197 msg_type = msg['header']['msg_type']
198 msg_id = msg['header']['msg_id']
199
179
200 # This assert will raise in versions of zeromq 2.0.7 and lesser.
180 header = msg['header']
201 # We now require 2.0.8 or above, so we can uncomment for safety.
181 msg_id = header['msg_id']
202 # print(ident,msg, file=sys.__stdout__)
182 msg_type = header['msg_type']
203 assert idents is not None, "Missing message part."
204
183
184 handler = self.control_handlers.get(msg_type, None)
185 if handler is None:
186 self.log.error("UNKNOWN CONTROL MESSAGE TYPE: %r", msg_type)
187 else:
188 handler(self.control_stream, idents, msg)
189
190 def dispatch_shell(self, stream, msg):
191 """dispatch shell requests"""
192 # flush control requests first
193 if self.control_stream:
194 self.control_stream.flush()
195
196 idents,msg = self.session.feed_identities(msg, copy=False)
197 try:
198 msg = self.session.unserialize(msg, content=True, copy=False)
199 except:
200 self.log.error("Invalid Message", exc_info=True)
201 return
202
203 header = msg['header']
204 msg_id = header['msg_id']
205 msg_type = msg['header']['msg_type']
206
205 # Print some info about this message and leave a '--->' marker, so it's
207 # Print some info about this message and leave a '--->' marker, so it's
206 # easier to trace visually the message chain when debugging. Each
208 # easier to trace visually the message chain when debugging. Each
207 # handler prints its message at the end.
209 # handler prints its message at the end.
208 self.log.debug('\n*** MESSAGE TYPE:%s***', msg_type)
210 self.log.debug('\n*** MESSAGE TYPE:%s***', msg_type)
209 self.log.debug(' Content: %s\n --->\n ', msg['content'])
211 self.log.debug(' Content: %s\n --->\n ', msg['content'])
210
212
211 # check if request has been aborted
212 if msg_id in self.aborted:
213 if msg_id in self.aborted:
213 self.aborted.remove(msg_id)
214 self.aborted.remove(msg_id)
214 # is it safe to assume a msg_id will not be resubmitted?
215 # is it safe to assume a msg_id will not be resubmitted?
215 reply_type = msg_type.split('_')[0] + '_reply'
216 reply_type = msg_type.split('_')[0] + '_reply'
216 status = {'status' : 'aborted'}
217 status = {'status' : 'aborted'}
217 reply_msg = self.session.send(socket, reply_type, subheader=status,
218 reply_msg = self.session.send(stream, reply_type, subheader=status,
218 content=status, parent=msg, ident=idents)
219 content=status, parent=msg, ident=idents)
219 return
220 return
220
221
221
222 handler = self.shell_handlers.get(msg_type, None)
222 # Find and call actual handler for message
223 handler = handlers.get(msg_type, None)
224 if handler is None:
223 if handler is None:
225 self.log.error("UNKNOWN MESSAGE TYPE: %s", msg)
224 self.log.error("UNKNOWN MESSAGE TYPE: %r", msg_type)
226 else:
225 else:
227 handler(socket, idents, msg)
226 # ensure default_int_handler during handler call
227 sig = signal(SIGINT, default_int_handler)
228 try:
229 handler(stream, idents, msg)
230 finally:
231 signal(SIGINT, sig)
232
233 def enter_eventloop(self):
234 """enter eventloop"""
235 self.log.critical("entering eventloop")
236 # restore default_int_handler
237 signal(SIGINT, default_int_handler)
238 self.eventloop(self)
239 self.log.critical("exiting eventloop")
240 # if eventloop exits, IOLoop should stop
241 ioloop.IOLoop.instance().stop()
228
242
229 # Check whether we should exit, in case the incoming message set the
243 def start(self):
230 # exit flag on
244 """register dispatchers for streams"""
231 if self.shell.exit_now:
245 if self.control_stream:
232 self.log.debug('\nExiting IPython kernel...')
246 self.control_stream.on_recv(self.dispatch_control, copy=False)
233 # We do a normal, clean exit, which allows any actions registered
234 # via atexit (such as history saving) to take place.
235 sys.exit(0)
236
247
248 def make_dispatcher(stream):
249 def dispatcher(msg):
250 return self.dispatch_shell(stream, msg)
251 return dispatcher
237
252
238 def start(self):
253 for s in self.shell_streams:
239 """ Start the kernel main loop.
254 s.on_recv(make_dispatcher(s), copy=False)
240 """
255
241 # a KeyboardInterrupt (SIGINT) can occur on any python statement, so
256 def do_one_iteration(self):
242 # let's ignore (SIG_IGN) them until we're in a place to handle them properly
257 """step eventloop just once"""
243 signal(SIGINT,SIG_IGN)
258 if self.control_stream:
244 poller = zmq.Poller()
259 self.control_stream.flush()
245 for socket in self.shell_sockets:
260 for stream in self.shell_streams:
246 poller.register(socket, zmq.POLLIN)
261 # handle at most one request per iteration
247 if self.control_socket:
262 stream.flush(zmq.POLLIN, 1)
248 poller.register(self.control_socket, zmq.POLLIN)
263 stream.flush(zmq.POLLOUT)
249
264 self.iopub_stream.flush()
250 # loop while self.eventloop has not been overridden
251 while self.eventloop is None:
252 try:
253 # scale by extra factor of 10, because there is no
254 # reason for this to be anything less than ~ 0.1s
255 # since it is a real poller and will respond
256 # to events immediately
257
258 # double nested try/except, to properly catch KeyboardInterrupt
259 # due to pyzmq Issue #130
260 try:
261 poller.poll(10*1000*self._poll_interval)
262 # restore raising of KeyboardInterrupt
263 signal(SIGINT, default_int_handler)
264 self.do_one_iteration()
265 except:
266 raise
267 finally:
268 # prevent raising of KeyboardInterrupt
269 signal(SIGINT,SIG_IGN)
270 except KeyboardInterrupt:
271 # Ctrl-C shouldn't crash the kernel
272 io.raw_print("KeyboardInterrupt caught in kernel")
273 # stop ignoring sigint, now that we are out of our own loop,
274 # we don't want to prevent future code from handling it
275 signal(SIGINT, default_int_handler)
276 while self.eventloop is not None:
277 try:
278 self.eventloop(self)
279 except KeyboardInterrupt:
280 # Ctrl-C shouldn't crash the kernel
281 io.raw_print("KeyboardInterrupt caught in kernel")
282 continue
283 else:
284 # eventloop exited cleanly, this means we should stop (right?)
285 self.eventloop = None
286 break
287
265
288
266
289 def record_ports(self, ports):
267 def record_ports(self, ports):
@@ -301,12 +279,12 b' class Kernel(Configurable):'
301 def _publish_pyin(self, code, parent, execution_count):
279 def _publish_pyin(self, code, parent, execution_count):
302 """Publish the code request on the pyin stream."""
280 """Publish the code request on the pyin stream."""
303
281
304 self.session.send(self.iopub_socket, u'pyin', {u'code':code,
282 self.session.send(self.iopub_stream, u'pyin', {u'code':code,
305 u'execution_count': execution_count}, parent=parent)
283 u'execution_count': execution_count}, parent=parent)
306
284
307 def execute_request(self, socket, ident, parent):
285 def execute_request(self, stream, ident, parent):
308
286
309 self.session.send(self.iopub_socket,
287 self.session.send(self.iopub_stream,
310 u'status',
288 u'status',
311 {u'execution_state':u'busy'},
289 {u'execution_state':u'busy'},
312 parent=parent )
290 parent=parent )
@@ -413,40 +391,40 b' class Kernel(Configurable):'
413
391
414 # Send the reply.
392 # Send the reply.
415 reply_content = json_clean(reply_content)
393 reply_content = json_clean(reply_content)
416 reply_msg = self.session.send(socket, u'execute_reply',
394 reply_msg = self.session.send(stream, u'execute_reply',
417 reply_content, parent, ident=ident)
395 reply_content, parent, ident=ident)
418 self.log.debug("%s", reply_msg)
396 self.log.debug("%s", reply_msg)
419
397
420 if reply_msg['content']['status'] == u'error':
398 if reply_msg['content']['status'] == u'error':
421 self._abort_queues()
399 self._abort_queues()
422
400
423 self.session.send(self.iopub_socket,
401 self.session.send(self.iopub_stream,
424 u'status',
402 u'status',
425 {u'execution_state':u'idle'},
403 {u'execution_state':u'idle'},
426 parent=parent )
404 parent=parent )
427
405
428 def complete_request(self, socket, ident, parent):
406 def complete_request(self, stream, ident, parent):
429 txt, matches = self._complete(parent)
407 txt, matches = self._complete(parent)
430 matches = {'matches' : matches,
408 matches = {'matches' : matches,
431 'matched_text' : txt,
409 'matched_text' : txt,
432 'status' : 'ok'}
410 'status' : 'ok'}
433 matches = json_clean(matches)
411 matches = json_clean(matches)
434 completion_msg = self.session.send(socket, 'complete_reply',
412 completion_msg = self.session.send(stream, 'complete_reply',
435 matches, parent, ident)
413 matches, parent, ident)
436 self.log.debug("%s", completion_msg)
414 self.log.debug("%s", completion_msg)
437
415
438 def object_info_request(self, socket, ident, parent):
416 def object_info_request(self, stream, ident, parent):
439 content = parent['content']
417 content = parent['content']
440 object_info = self.shell.object_inspect(content['oname'],
418 object_info = self.shell.object_inspect(content['oname'],
441 detail_level = content.get('detail_level', 0)
419 detail_level = content.get('detail_level', 0)
442 )
420 )
443 # Before we send this object over, we scrub it for JSON usage
421 # Before we send this object over, we scrub it for JSON usage
444 oinfo = json_clean(object_info)
422 oinfo = json_clean(object_info)
445 msg = self.session.send(socket, 'object_info_reply',
423 msg = self.session.send(stream, 'object_info_reply',
446 oinfo, parent, ident)
424 oinfo, parent, ident)
447 self.log.debug("%s", msg)
425 self.log.debug("%s", msg)
448
426
449 def history_request(self, socket, ident, parent):
427 def history_request(self, stream, ident, parent):
450 # We need to pull these out, as passing **kwargs doesn't work with
428 # We need to pull these out, as passing **kwargs doesn't work with
451 # unicode keys before Python 2.6.5.
429 # unicode keys before Python 2.6.5.
452 hist_access_type = parent['content']['hist_access_type']
430 hist_access_type = parent['content']['hist_access_type']
@@ -474,30 +452,35 b' class Kernel(Configurable):'
474 hist = list(hist)
452 hist = list(hist)
475 content = {'history' : hist}
453 content = {'history' : hist}
476 content = json_clean(content)
454 content = json_clean(content)
477 msg = self.session.send(socket, 'history_reply',
455 msg = self.session.send(stream, 'history_reply',
478 content, parent, ident)
456 content, parent, ident)
479 self.log.debug("Sending history reply with %i entries", len(hist))
457 self.log.debug("Sending history reply with %i entries", len(hist))
480
458
481 def connect_request(self, socket, ident, parent):
459 def connect_request(self, stream, ident, parent):
482 if self._recorded_ports is not None:
460 if self._recorded_ports is not None:
483 content = self._recorded_ports.copy()
461 content = self._recorded_ports.copy()
484 else:
462 else:
485 content = {}
463 content = {}
486 msg = self.session.send(socket, 'connect_reply',
464 msg = self.session.send(stream, 'connect_reply',
487 content, parent, ident)
465 content, parent, ident)
488 self.log.debug("%s", msg)
466 self.log.debug("%s", msg)
489
467
490 def shutdown_request(self, ident, parent):
468 def shutdown_request(self, stream, ident, parent):
491 self.shell.exit_now = True
469 self.shell.exit_now = True
492 self._shutdown_message = self.session.msg(u'shutdown_reply',
470 self._shutdown_message = self.session.msg(u'shutdown_reply',
493 parent['content'], parent)
471 parent['content'], parent
494 sys.exit(0)
472 )
473 # self.session.send(stream, self._shutdown_message, ident=ident)
474
475 self._at_shutdown()
476 # call sys.exit after a short delay
477 ioloop.IOLoop.instance().add_timeout(time.time()+0.05, lambda : sys.exit(0))
495
478
496 #---------------------------------------------------------------------------
479 #---------------------------------------------------------------------------
497 # Engine methods
480 # Engine methods
498 #---------------------------------------------------------------------------
481 #---------------------------------------------------------------------------
499
482
500 def apply_request(self, socket, ident, parent):
483 def apply_request(self, stream, ident, parent):
501 try:
484 try:
502 content = parent[u'content']
485 content = parent[u'content']
503 bufs = parent[u'buffers']
486 bufs = parent[u'buffers']
@@ -552,7 +535,7 b' class Kernel(Configurable):'
552 except:
535 except:
553 exc_content = self._wrap_exception('apply')
536 exc_content = self._wrap_exception('apply')
554 # exc_msg = self.session.msg(u'pyerr', exc_content, parent)
537 # exc_msg = self.session.msg(u'pyerr', exc_content, parent)
555 self.session.send(self.iopub_socket, u'pyerr', exc_content, parent=parent,
538 self.session.send(self.iopub_stream, u'pyerr', exc_content, parent=parent,
556 ident=py3compat.str_to_bytes('%s.pyerr'%self.prefix))
539 ident=py3compat.str_to_bytes('%s.pyerr'%self.prefix))
557 reply_content = exc_content
540 reply_content = exc_content
558 result_buf = []
541 result_buf = []
@@ -569,14 +552,14 b' class Kernel(Configurable):'
569 sys.stdout.flush()
552 sys.stdout.flush()
570 sys.stderr.flush()
553 sys.stderr.flush()
571
554
572 reply_msg = self.session.send(socket, u'apply_reply', reply_content,
555 reply_msg = self.session.send(stream, u'apply_reply', reply_content,
573 parent=parent, ident=ident,buffers=result_buf, subheader=sub)
556 parent=parent, ident=ident,buffers=result_buf, subheader=sub)
574
557
575 #---------------------------------------------------------------------------
558 #---------------------------------------------------------------------------
576 # Control messages
559 # Control messages
577 #---------------------------------------------------------------------------
560 #---------------------------------------------------------------------------
578
561
579 def abort_request(self, socket, ident, parent):
562 def abort_request(self, stream, ident, parent):
580 """abort a specifig msg by id"""
563 """abort a specifig msg by id"""
581 msg_ids = parent['content'].get('msg_ids', None)
564 msg_ids = parent['content'].get('msg_ids', None)
582 if isinstance(msg_ids, basestring):
565 if isinstance(msg_ids, basestring):
@@ -587,14 +570,14 b' class Kernel(Configurable):'
587 self.aborted.add(str(mid))
570 self.aborted.add(str(mid))
588
571
589 content = dict(status='ok')
572 content = dict(status='ok')
590 reply_msg = self.session.send(socket, 'abort_reply', content=content,
573 reply_msg = self.session.send(stream, 'abort_reply', content=content,
591 parent=parent, ident=ident)
574 parent=parent, ident=ident)
592 self.log.debug("%s", reply_msg)
575 self.log.debug("%s", reply_msg)
593
576
594 def clear_request(self, socket, idents, parent):
577 def clear_request(self, stream, idents, parent):
595 """Clear our namespace."""
578 """Clear our namespace."""
596 self.user_ns = {}
579 self.user_ns = {}
597 msg = self.session.send(socket, 'clear_reply', ident=idents, parent=parent,
580 msg = self.session.send(stream, 'clear_reply', ident=idents, parent=parent,
598 content = dict(status='ok'))
581 content = dict(status='ok'))
599 self._initial_exec_lines()
582 self._initial_exec_lines()
600
583
@@ -604,13 +587,13 b' class Kernel(Configurable):'
604 #---------------------------------------------------------------------------
587 #---------------------------------------------------------------------------
605
588
606 def _abort_queues(self):
589 def _abort_queues(self):
607 for socket in self.shell_sockets:
590 for stream in self.shell_streams:
608 if socket:
591 if stream:
609 self._abort_queue(socket)
592 self._abort_queue(stream)
610
593
611 def _abort_queue(self, socket):
594 def _abort_queue(self, stream):
612 while True:
595 while True:
613 idents,msg = self.session.recv(socket, zmq.NOBLOCK, content=True)
596 idents,msg = self.session.recv(stream, zmq.NOBLOCK, content=True)
614 if msg is None:
597 if msg is None:
615 return
598 return
616
599
@@ -619,9 +602,9 b' class Kernel(Configurable):'
619 msg_type = msg['header']['msg_type']
602 msg_type = msg['header']['msg_type']
620 reply_type = msg_type.split('_')[0] + '_reply'
603 reply_type = msg_type.split('_')[0] + '_reply'
621 # reply_msg = self.session.msg(reply_type, {'status' : 'aborted'}, msg)
604 # reply_msg = self.session.msg(reply_type, {'status' : 'aborted'}, msg)
622 # self.reply_socket.send(ident,zmq.SNDMORE)
605 # self.reply_stream.send(ident,zmq.SNDMORE)
623 # self.reply_socket.send_json(reply_msg)
606 # self.reply_stream.send_json(reply_msg)
624 reply_msg = self.session.send(socket, reply_type,
607 reply_msg = self.session.send(stream, reply_type,
625 content={'status' : 'aborted'}, parent=msg, ident=idents)
608 content={'status' : 'aborted'}, parent=msg, ident=idents)
626 self.log.debug("%s", reply_msg)
609 self.log.debug("%s", reply_msg)
627 # We need to wait a bit for requests to come in. This can probably
610 # We need to wait a bit for requests to come in. This can probably
@@ -712,12 +695,9 b' class Kernel(Configurable):'
712 """
695 """
713 # io.rprint("Kernel at_shutdown") # dbg
696 # io.rprint("Kernel at_shutdown") # dbg
714 if self._shutdown_message is not None:
697 if self._shutdown_message is not None:
715 self.session.send(self.shell_socket, self._shutdown_message)
698 self.session.send(self.iopub_stream, self._shutdown_message)
716 self.session.send(self.iopub_socket, self._shutdown_message)
717 self.log.debug("%s", self._shutdown_message)
699 self.log.debug("%s", self._shutdown_message)
718 # A very short sleep to give zmq time to flush its message buffers
700 [ s.flush(zmq.POLLOUT) for s in self.shell_streams + [self.iopub_stream] ]
719 # before Python truly shuts down.
720 time.sleep(0.01)
721
701
722 #-----------------------------------------------------------------------------
702 #-----------------------------------------------------------------------------
723 # Aliases and Flags for the IPKernelApp
703 # Aliases and Flags for the IPKernelApp
@@ -770,10 +750,13 b' class IPKernelApp(KernelApp, InteractiveShellApp):'
770 self.init_code()
750 self.init_code()
771
751
772 def init_kernel(self):
752 def init_kernel(self):
753
754 shell_stream = ZMQStream(self.shell_socket)
755 iopub_stream = ZMQStream(self.iopub_socket)
773
756
774 kernel = Kernel(config=self.config, session=self.session,
757 kernel = Kernel(config=self.config, session=self.session,
775 shell_sockets=[self.shell_socket],
758 shell_streams=[shell_stream],
776 iopub_socket=self.iopub_socket,
759 iopub_stream=iopub_stream,
777 stdin_socket=self.stdin_socket,
760 stdin_socket=self.stdin_socket,
778 log=self.log,
761 log=self.log,
779 profile_dir=self.profile_dir,
762 profile_dir=self.profile_dir,
@@ -15,15 +15,17 b' Authors'
15 # Imports
15 # Imports
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17
17
18 # Standard library imports.
18 # Standard library imports
19 import json
19 import json
20 import os
20 import os
21 import sys
21 import sys
22 import signal
22
23
23 # System library imports.
24 # System library imports
24 import zmq
25 import zmq
26 from zmq.eventloop import ioloop
25
27
26 # IPython imports.
28 # IPython imports
27 from IPython.core.ultratb import FormattedTB
29 from IPython.core.ultratb import FormattedTB
28 from IPython.core.application import (
30 from IPython.core.application import (
29 BaseIPythonApplication, base_flags, base_aliases, catch_config_error
31 BaseIPythonApplication, base_flags, base_aliases, catch_config_error
@@ -267,6 +269,9 b' class KernelApp(BaseIPythonApplication):'
267 displayhook_factory = import_item(str(self.displayhook_class))
269 displayhook_factory = import_item(str(self.displayhook_class))
268 sys.displayhook = displayhook_factory(self.session, self.iopub_socket)
270 sys.displayhook = displayhook_factory(self.session, self.iopub_socket)
269
271
272 def init_signal(self):
273 signal.signal(signal.SIGINT, signal.SIG_IGN)
274
270 def init_kernel(self):
275 def init_kernel(self):
271 """Create the Kernel object itself"""
276 """Create the Kernel object itself"""
272 kernel_factory = import_item(str(self.kernel_class))
277 kernel_factory = import_item(str(self.kernel_class))
@@ -289,6 +294,7 b' class KernelApp(BaseIPythonApplication):'
289 # writing connection file must be *after* init_sockets
294 # writing connection file must be *after* init_sockets
290 self.write_connection_file()
295 self.write_connection_file()
291 self.init_io()
296 self.init_io()
297 self.init_signal()
292 self.init_kernel()
298 self.init_kernel()
293 # flush stdout/stderr, so that anything written to these streams during
299 # flush stdout/stderr, so that anything written to these streams during
294 # initialization do not get associated with the first execution request
300 # initialization do not get associated with the first execution request
@@ -299,8 +305,9 b' class KernelApp(BaseIPythonApplication):'
299 self.heartbeat.start()
305 self.heartbeat.start()
300 if self.poller is not None:
306 if self.poller is not None:
301 self.poller.start()
307 self.poller.start()
308 self.kernel.start()
302 try:
309 try:
303 self.kernel.start()
310 ioloop.IOLoop.instance().start()
304 except KeyboardInterrupt:
311 except KeyboardInterrupt:
305 pass
312 pass
306
313
General Comments 0
You need to be logged in to leave comments. Login now