##// END OF EJS Templates
Fix for using Type traitlet
Thomas Kluyver -
Show More
@@ -1,402 +1,402 b''
1 """An Application for launching a kernel"""
1 """An Application for launching a kernel"""
2
2
3 # Copyright (c) IPython Development Team.
3 # Copyright (c) IPython Development Team.
4 # Distributed under the terms of the Modified BSD License.
4 # Distributed under the terms of the Modified BSD License.
5
5
6 from __future__ import print_function
6 from __future__ import print_function
7
7
8 import atexit
8 import atexit
9 import os
9 import os
10 import sys
10 import sys
11 import signal
11 import signal
12
12
13 import zmq
13 import zmq
14 from zmq.eventloop import ioloop
14 from zmq.eventloop import ioloop
15 from zmq.eventloop.zmqstream import ZMQStream
15 from zmq.eventloop.zmqstream import ZMQStream
16
16
17 from IPython.core.ultratb import FormattedTB
17 from IPython.core.ultratb import FormattedTB
18 from IPython.core.application import (
18 from IPython.core.application import (
19 BaseIPythonApplication, base_flags, base_aliases, catch_config_error
19 BaseIPythonApplication, base_flags, base_aliases, catch_config_error
20 )
20 )
21 from IPython.core.profiledir import ProfileDir
21 from IPython.core.profiledir import ProfileDir
22 from IPython.core.shellapp import (
22 from IPython.core.shellapp import (
23 InteractiveShellApp, shell_flags, shell_aliases
23 InteractiveShellApp, shell_flags, shell_aliases
24 )
24 )
25 from IPython.utils import io
25 from IPython.utils import io
26 from IPython.utils.path import filefind
26 from IPython.utils.path import filefind
27 from IPython.utils.traitlets import (
27 from IPython.utils.traitlets import (
28 Any, Instance, Dict, Unicode, Integer, Bool, DottedObjectName, Type,
28 Any, Instance, Dict, Unicode, Integer, Bool, DottedObjectName, Type,
29 )
29 )
30 from IPython.utils.importstring import import_item
30 from IPython.utils.importstring import import_item
31 from IPython.kernel import write_connection_file
31 from IPython.kernel import write_connection_file
32 from IPython.kernel.connect import ConnectionFileMixin
32 from IPython.kernel.connect import ConnectionFileMixin
33
33
34 # local imports
34 # local imports
35 from .heartbeat import Heartbeat
35 from .heartbeat import Heartbeat
36 from .ipkernel import Kernel
36 from .ipkernel import Kernel
37 from .parentpoller import ParentPollerUnix, ParentPollerWindows
37 from .parentpoller import ParentPollerUnix, ParentPollerWindows
38 from .session import (
38 from .session import (
39 Session, session_flags, session_aliases, default_secure,
39 Session, session_flags, session_aliases, default_secure,
40 )
40 )
41 from .zmqshell import ZMQInteractiveShell
41 from .zmqshell import ZMQInteractiveShell
42
42
43 #-----------------------------------------------------------------------------
43 #-----------------------------------------------------------------------------
44 # Flags and Aliases
44 # Flags and Aliases
45 #-----------------------------------------------------------------------------
45 #-----------------------------------------------------------------------------
46
46
47 kernel_aliases = dict(base_aliases)
47 kernel_aliases = dict(base_aliases)
48 kernel_aliases.update({
48 kernel_aliases.update({
49 'ip' : 'IPKernelApp.ip',
49 'ip' : 'IPKernelApp.ip',
50 'hb' : 'IPKernelApp.hb_port',
50 'hb' : 'IPKernelApp.hb_port',
51 'shell' : 'IPKernelApp.shell_port',
51 'shell' : 'IPKernelApp.shell_port',
52 'iopub' : 'IPKernelApp.iopub_port',
52 'iopub' : 'IPKernelApp.iopub_port',
53 'stdin' : 'IPKernelApp.stdin_port',
53 'stdin' : 'IPKernelApp.stdin_port',
54 'control' : 'IPKernelApp.control_port',
54 'control' : 'IPKernelApp.control_port',
55 'f' : 'IPKernelApp.connection_file',
55 'f' : 'IPKernelApp.connection_file',
56 'parent': 'IPKernelApp.parent_handle',
56 'parent': 'IPKernelApp.parent_handle',
57 'transport': 'IPKernelApp.transport',
57 'transport': 'IPKernelApp.transport',
58 })
58 })
59 if sys.platform.startswith('win'):
59 if sys.platform.startswith('win'):
60 kernel_aliases['interrupt'] = 'IPKernelApp.interrupt'
60 kernel_aliases['interrupt'] = 'IPKernelApp.interrupt'
61
61
62 kernel_flags = dict(base_flags)
62 kernel_flags = dict(base_flags)
63 kernel_flags.update({
63 kernel_flags.update({
64 'no-stdout' : (
64 'no-stdout' : (
65 {'IPKernelApp' : {'no_stdout' : True}},
65 {'IPKernelApp' : {'no_stdout' : True}},
66 "redirect stdout to the null device"),
66 "redirect stdout to the null device"),
67 'no-stderr' : (
67 'no-stderr' : (
68 {'IPKernelApp' : {'no_stderr' : True}},
68 {'IPKernelApp' : {'no_stderr' : True}},
69 "redirect stderr to the null device"),
69 "redirect stderr to the null device"),
70 'pylab' : (
70 'pylab' : (
71 {'IPKernelApp' : {'pylab' : 'auto'}},
71 {'IPKernelApp' : {'pylab' : 'auto'}},
72 """Pre-load matplotlib and numpy for interactive use with
72 """Pre-load matplotlib and numpy for interactive use with
73 the default matplotlib backend."""),
73 the default matplotlib backend."""),
74 })
74 })
75
75
76 # inherit flags&aliases for any IPython shell apps
76 # inherit flags&aliases for any IPython shell apps
77 kernel_aliases.update(shell_aliases)
77 kernel_aliases.update(shell_aliases)
78 kernel_flags.update(shell_flags)
78 kernel_flags.update(shell_flags)
79
79
80 # inherit flags&aliases for Sessions
80 # inherit flags&aliases for Sessions
81 kernel_aliases.update(session_aliases)
81 kernel_aliases.update(session_aliases)
82 kernel_flags.update(session_flags)
82 kernel_flags.update(session_flags)
83
83
84 _ctrl_c_message = """\
84 _ctrl_c_message = """\
85 NOTE: When using the `ipython kernel` entry point, Ctrl-C will not work.
85 NOTE: When using the `ipython kernel` entry point, Ctrl-C will not work.
86
86
87 To exit, you will have to explicitly quit this process, by either sending
87 To exit, you will have to explicitly quit this process, by either sending
88 "quit" from a client, or using Ctrl-\\ in UNIX-like environments.
88 "quit" from a client, or using Ctrl-\\ in UNIX-like environments.
89
89
90 To read more about this, see https://github.com/ipython/ipython/issues/2049
90 To read more about this, see https://github.com/ipython/ipython/issues/2049
91
91
92 """
92 """
93
93
94 #-----------------------------------------------------------------------------
94 #-----------------------------------------------------------------------------
95 # Application class for starting an IPython Kernel
95 # Application class for starting an IPython Kernel
96 #-----------------------------------------------------------------------------
96 #-----------------------------------------------------------------------------
97
97
98 class IPKernelApp(BaseIPythonApplication, InteractiveShellApp,
98 class IPKernelApp(BaseIPythonApplication, InteractiveShellApp,
99 ConnectionFileMixin):
99 ConnectionFileMixin):
100 name='ipkernel'
100 name='ipkernel'
101 aliases = Dict(kernel_aliases)
101 aliases = Dict(kernel_aliases)
102 flags = Dict(kernel_flags)
102 flags = Dict(kernel_flags)
103 classes = [Kernel, ZMQInteractiveShell, ProfileDir, Session]
103 classes = [Kernel, ZMQInteractiveShell, ProfileDir, Session]
104 # the kernel class, as an importstring
104 # the kernel class, as an importstring
105 kernel_class = Type('IPython.kernel.zmq.ipkernel.Kernel', config=True,
105 kernel_class = Type('IPython.kernel.zmq.ipkernel.Kernel', config=True,
106 help="""The Kernel subclass to be used.
106 help="""The Kernel subclass to be used.
107
107
108 This should allow easy re-use of the IPKernelApp entry point
108 This should allow easy re-use of the IPKernelApp entry point
109 to configure and launch kernels other than IPython's own.
109 to configure and launch kernels other than IPython's own.
110 """)
110 """)
111 kernel = Any()
111 kernel = Any()
112 poller = Any() # don't restrict this even though current pollers are all Threads
112 poller = Any() # don't restrict this even though current pollers are all Threads
113 heartbeat = Instance(Heartbeat)
113 heartbeat = Instance(Heartbeat)
114 ports = Dict()
114 ports = Dict()
115
115
116 # ipkernel doesn't get its own config file
116 # ipkernel doesn't get its own config file
117 def _config_file_name_default(self):
117 def _config_file_name_default(self):
118 return 'ipython_config.py'
118 return 'ipython_config.py'
119
119
120 # inherit config file name from parent:
120 # inherit config file name from parent:
121 parent_appname = Unicode(config=True)
121 parent_appname = Unicode(config=True)
122 def _parent_appname_changed(self, name, old, new):
122 def _parent_appname_changed(self, name, old, new):
123 if self.config_file_specified:
123 if self.config_file_specified:
124 # it was manually specified, ignore
124 # it was manually specified, ignore
125 return
125 return
126 self.config_file_name = new.replace('-','_') + u'_config.py'
126 self.config_file_name = new.replace('-','_') + u'_config.py'
127 # don't let this count as specifying the config file
127 # don't let this count as specifying the config file
128 self.config_file_specified.remove(self.config_file_name)
128 self.config_file_specified.remove(self.config_file_name)
129
129
130 # connection info:
130 # connection info:
131
131
132 @property
132 @property
133 def abs_connection_file(self):
133 def abs_connection_file(self):
134 if os.path.basename(self.connection_file) == self.connection_file:
134 if os.path.basename(self.connection_file) == self.connection_file:
135 return os.path.join(self.profile_dir.security_dir, self.connection_file)
135 return os.path.join(self.profile_dir.security_dir, self.connection_file)
136 else:
136 else:
137 return self.connection_file
137 return self.connection_file
138
138
139
139
140 # streams, etc.
140 # streams, etc.
141 no_stdout = Bool(False, config=True, help="redirect stdout to the null device")
141 no_stdout = Bool(False, config=True, help="redirect stdout to the null device")
142 no_stderr = Bool(False, config=True, help="redirect stderr to the null device")
142 no_stderr = Bool(False, config=True, help="redirect stderr to the null device")
143 outstream_class = DottedObjectName('IPython.kernel.zmq.iostream.OutStream',
143 outstream_class = DottedObjectName('IPython.kernel.zmq.iostream.OutStream',
144 config=True, help="The importstring for the OutStream factory")
144 config=True, help="The importstring for the OutStream factory")
145 displayhook_class = DottedObjectName('IPython.kernel.zmq.displayhook.ZMQDisplayHook',
145 displayhook_class = DottedObjectName('IPython.kernel.zmq.displayhook.ZMQDisplayHook',
146 config=True, help="The importstring for the DisplayHook factory")
146 config=True, help="The importstring for the DisplayHook factory")
147
147
148 # polling
148 # polling
149 parent_handle = Integer(0, config=True,
149 parent_handle = Integer(0, config=True,
150 help="""kill this process if its parent dies. On Windows, the argument
150 help="""kill this process if its parent dies. On Windows, the argument
151 specifies the HANDLE of the parent process, otherwise it is simply boolean.
151 specifies the HANDLE of the parent process, otherwise it is simply boolean.
152 """)
152 """)
153 interrupt = Integer(0, config=True,
153 interrupt = Integer(0, config=True,
154 help="""ONLY USED ON WINDOWS
154 help="""ONLY USED ON WINDOWS
155 Interrupt this process when the parent is signaled.
155 Interrupt this process when the parent is signaled.
156 """)
156 """)
157
157
158 def init_crash_handler(self):
158 def init_crash_handler(self):
159 # Install minimal exception handling
159 # Install minimal exception handling
160 sys.excepthook = FormattedTB(mode='Verbose', color_scheme='NoColor',
160 sys.excepthook = FormattedTB(mode='Verbose', color_scheme='NoColor',
161 ostream=sys.__stdout__)
161 ostream=sys.__stdout__)
162
162
163 def init_poller(self):
163 def init_poller(self):
164 if sys.platform == 'win32':
164 if sys.platform == 'win32':
165 if self.interrupt or self.parent_handle:
165 if self.interrupt or self.parent_handle:
166 self.poller = ParentPollerWindows(self.interrupt, self.parent_handle)
166 self.poller = ParentPollerWindows(self.interrupt, self.parent_handle)
167 elif self.parent_handle:
167 elif self.parent_handle:
168 self.poller = ParentPollerUnix()
168 self.poller = ParentPollerUnix()
169
169
170 def _bind_socket(self, s, port):
170 def _bind_socket(self, s, port):
171 iface = '%s://%s' % (self.transport, self.ip)
171 iface = '%s://%s' % (self.transport, self.ip)
172 if self.transport == 'tcp':
172 if self.transport == 'tcp':
173 if port <= 0:
173 if port <= 0:
174 port = s.bind_to_random_port(iface)
174 port = s.bind_to_random_port(iface)
175 else:
175 else:
176 s.bind("tcp://%s:%i" % (self.ip, port))
176 s.bind("tcp://%s:%i" % (self.ip, port))
177 elif self.transport == 'ipc':
177 elif self.transport == 'ipc':
178 if port <= 0:
178 if port <= 0:
179 port = 1
179 port = 1
180 path = "%s-%i" % (self.ip, port)
180 path = "%s-%i" % (self.ip, port)
181 while os.path.exists(path):
181 while os.path.exists(path):
182 port = port + 1
182 port = port + 1
183 path = "%s-%i" % (self.ip, port)
183 path = "%s-%i" % (self.ip, port)
184 else:
184 else:
185 path = "%s-%i" % (self.ip, port)
185 path = "%s-%i" % (self.ip, port)
186 s.bind("ipc://%s" % path)
186 s.bind("ipc://%s" % path)
187 return port
187 return port
188
188
189 def write_connection_file(self):
189 def write_connection_file(self):
190 """write connection info to JSON file"""
190 """write connection info to JSON file"""
191 cf = self.abs_connection_file
191 cf = self.abs_connection_file
192 self.log.debug("Writing connection file: %s", cf)
192 self.log.debug("Writing connection file: %s", cf)
193 write_connection_file(cf, ip=self.ip, key=self.session.key, transport=self.transport,
193 write_connection_file(cf, ip=self.ip, key=self.session.key, transport=self.transport,
194 shell_port=self.shell_port, stdin_port=self.stdin_port, hb_port=self.hb_port,
194 shell_port=self.shell_port, stdin_port=self.stdin_port, hb_port=self.hb_port,
195 iopub_port=self.iopub_port, control_port=self.control_port)
195 iopub_port=self.iopub_port, control_port=self.control_port)
196
196
197 def cleanup_connection_file(self):
197 def cleanup_connection_file(self):
198 cf = self.abs_connection_file
198 cf = self.abs_connection_file
199 self.log.debug("Cleaning up connection file: %s", cf)
199 self.log.debug("Cleaning up connection file: %s", cf)
200 try:
200 try:
201 os.remove(cf)
201 os.remove(cf)
202 except (IOError, OSError):
202 except (IOError, OSError):
203 pass
203 pass
204
204
205 self.cleanup_ipc_files()
205 self.cleanup_ipc_files()
206
206
207 def init_connection_file(self):
207 def init_connection_file(self):
208 if not self.connection_file:
208 if not self.connection_file:
209 self.connection_file = "kernel-%s.json"%os.getpid()
209 self.connection_file = "kernel-%s.json"%os.getpid()
210 try:
210 try:
211 self.connection_file = filefind(self.connection_file, ['.', self.profile_dir.security_dir])
211 self.connection_file = filefind(self.connection_file, ['.', self.profile_dir.security_dir])
212 except IOError:
212 except IOError:
213 self.log.debug("Connection file not found: %s", self.connection_file)
213 self.log.debug("Connection file not found: %s", self.connection_file)
214 # This means I own it, so I will clean it up:
214 # This means I own it, so I will clean it up:
215 atexit.register(self.cleanup_connection_file)
215 atexit.register(self.cleanup_connection_file)
216 return
216 return
217 try:
217 try:
218 self.load_connection_file()
218 self.load_connection_file()
219 except Exception:
219 except Exception:
220 self.log.error("Failed to load connection file: %r", self.connection_file, exc_info=True)
220 self.log.error("Failed to load connection file: %r", self.connection_file, exc_info=True)
221 self.exit(1)
221 self.exit(1)
222
222
223 def init_sockets(self):
223 def init_sockets(self):
224 # Create a context, a session, and the kernel sockets.
224 # Create a context, a session, and the kernel sockets.
225 self.log.info("Starting the kernel at pid: %i", os.getpid())
225 self.log.info("Starting the kernel at pid: %i", os.getpid())
226 context = zmq.Context.instance()
226 context = zmq.Context.instance()
227 # Uncomment this to try closing the context.
227 # Uncomment this to try closing the context.
228 # atexit.register(context.term)
228 # atexit.register(context.term)
229
229
230 self.shell_socket = context.socket(zmq.ROUTER)
230 self.shell_socket = context.socket(zmq.ROUTER)
231 self.shell_socket.linger = 1000
231 self.shell_socket.linger = 1000
232 self.shell_port = self._bind_socket(self.shell_socket, self.shell_port)
232 self.shell_port = self._bind_socket(self.shell_socket, self.shell_port)
233 self.log.debug("shell ROUTER Channel on port: %i" % self.shell_port)
233 self.log.debug("shell ROUTER Channel on port: %i" % self.shell_port)
234
234
235 self.iopub_socket = context.socket(zmq.PUB)
235 self.iopub_socket = context.socket(zmq.PUB)
236 self.iopub_socket.linger = 1000
236 self.iopub_socket.linger = 1000
237 self.iopub_port = self._bind_socket(self.iopub_socket, self.iopub_port)
237 self.iopub_port = self._bind_socket(self.iopub_socket, self.iopub_port)
238 self.log.debug("iopub PUB Channel on port: %i" % self.iopub_port)
238 self.log.debug("iopub PUB Channel on port: %i" % self.iopub_port)
239
239
240 self.stdin_socket = context.socket(zmq.ROUTER)
240 self.stdin_socket = context.socket(zmq.ROUTER)
241 self.stdin_socket.linger = 1000
241 self.stdin_socket.linger = 1000
242 self.stdin_port = self._bind_socket(self.stdin_socket, self.stdin_port)
242 self.stdin_port = self._bind_socket(self.stdin_socket, self.stdin_port)
243 self.log.debug("stdin ROUTER Channel on port: %i" % self.stdin_port)
243 self.log.debug("stdin ROUTER Channel on port: %i" % self.stdin_port)
244
244
245 self.control_socket = context.socket(zmq.ROUTER)
245 self.control_socket = context.socket(zmq.ROUTER)
246 self.control_socket.linger = 1000
246 self.control_socket.linger = 1000
247 self.control_port = self._bind_socket(self.control_socket, self.control_port)
247 self.control_port = self._bind_socket(self.control_socket, self.control_port)
248 self.log.debug("control ROUTER Channel on port: %i" % self.control_port)
248 self.log.debug("control ROUTER Channel on port: %i" % self.control_port)
249
249
250 def init_heartbeat(self):
250 def init_heartbeat(self):
251 """start the heart beating"""
251 """start the heart beating"""
252 # heartbeat doesn't share context, because it mustn't be blocked
252 # heartbeat doesn't share context, because it mustn't be blocked
253 # by the GIL, which is accessed by libzmq when freeing zero-copy messages
253 # by the GIL, which is accessed by libzmq when freeing zero-copy messages
254 hb_ctx = zmq.Context()
254 hb_ctx = zmq.Context()
255 self.heartbeat = Heartbeat(hb_ctx, (self.transport, self.ip, self.hb_port))
255 self.heartbeat = Heartbeat(hb_ctx, (self.transport, self.ip, self.hb_port))
256 self.hb_port = self.heartbeat.port
256 self.hb_port = self.heartbeat.port
257 self.log.debug("Heartbeat REP Channel on port: %i" % self.hb_port)
257 self.log.debug("Heartbeat REP Channel on port: %i" % self.hb_port)
258 self.heartbeat.start()
258 self.heartbeat.start()
259
259
260 def log_connection_info(self):
260 def log_connection_info(self):
261 """display connection info, and store ports"""
261 """display connection info, and store ports"""
262 basename = os.path.basename(self.connection_file)
262 basename = os.path.basename(self.connection_file)
263 if basename == self.connection_file or \
263 if basename == self.connection_file or \
264 os.path.dirname(self.connection_file) == self.profile_dir.security_dir:
264 os.path.dirname(self.connection_file) == self.profile_dir.security_dir:
265 # use shortname
265 # use shortname
266 tail = basename
266 tail = basename
267 if self.profile != 'default':
267 if self.profile != 'default':
268 tail += " --profile %s" % self.profile
268 tail += " --profile %s" % self.profile
269 else:
269 else:
270 tail = self.connection_file
270 tail = self.connection_file
271 lines = [
271 lines = [
272 "To connect another client to this kernel, use:",
272 "To connect another client to this kernel, use:",
273 " --existing %s" % tail,
273 " --existing %s" % tail,
274 ]
274 ]
275 # log connection info
275 # log connection info
276 # info-level, so often not shown.
276 # info-level, so often not shown.
277 # frontends should use the %connect_info magic
277 # frontends should use the %connect_info magic
278 # to see the connection info
278 # to see the connection info
279 for line in lines:
279 for line in lines:
280 self.log.info(line)
280 self.log.info(line)
281 # also raw print to the terminal if no parent_handle (`ipython kernel`)
281 # also raw print to the terminal if no parent_handle (`ipython kernel`)
282 if not self.parent_handle:
282 if not self.parent_handle:
283 io.rprint(_ctrl_c_message)
283 io.rprint(_ctrl_c_message)
284 for line in lines:
284 for line in lines:
285 io.rprint(line)
285 io.rprint(line)
286
286
287 self.ports = dict(shell=self.shell_port, iopub=self.iopub_port,
287 self.ports = dict(shell=self.shell_port, iopub=self.iopub_port,
288 stdin=self.stdin_port, hb=self.hb_port,
288 stdin=self.stdin_port, hb=self.hb_port,
289 control=self.control_port)
289 control=self.control_port)
290
290
291 def init_blackhole(self):
291 def init_blackhole(self):
292 """redirects stdout/stderr to devnull if necessary"""
292 """redirects stdout/stderr to devnull if necessary"""
293 if self.no_stdout or self.no_stderr:
293 if self.no_stdout or self.no_stderr:
294 blackhole = open(os.devnull, 'w')
294 blackhole = open(os.devnull, 'w')
295 if self.no_stdout:
295 if self.no_stdout:
296 sys.stdout = sys.__stdout__ = blackhole
296 sys.stdout = sys.__stdout__ = blackhole
297 if self.no_stderr:
297 if self.no_stderr:
298 sys.stderr = sys.__stderr__ = blackhole
298 sys.stderr = sys.__stderr__ = blackhole
299
299
300 def init_io(self):
300 def init_io(self):
301 """Redirect input streams and set a display hook."""
301 """Redirect input streams and set a display hook."""
302 if self.outstream_class:
302 if self.outstream_class:
303 outstream_factory = import_item(str(self.outstream_class))
303 outstream_factory = import_item(str(self.outstream_class))
304 sys.stdout = outstream_factory(self.session, self.iopub_socket, u'stdout')
304 sys.stdout = outstream_factory(self.session, self.iopub_socket, u'stdout')
305 sys.stderr = outstream_factory(self.session, self.iopub_socket, u'stderr')
305 sys.stderr = outstream_factory(self.session, self.iopub_socket, u'stderr')
306 if self.displayhook_class:
306 if self.displayhook_class:
307 displayhook_factory = import_item(str(self.displayhook_class))
307 displayhook_factory = import_item(str(self.displayhook_class))
308 sys.displayhook = displayhook_factory(self.session, self.iopub_socket)
308 sys.displayhook = displayhook_factory(self.session, self.iopub_socket)
309
309
310 def init_signal(self):
310 def init_signal(self):
311 signal.signal(signal.SIGINT, signal.SIG_IGN)
311 signal.signal(signal.SIGINT, signal.SIG_IGN)
312
312
313 def init_kernel(self):
313 def init_kernel(self):
314 """Create the Kernel object itself"""
314 """Create the Kernel object itself"""
315 shell_stream = ZMQStream(self.shell_socket)
315 shell_stream = ZMQStream(self.shell_socket)
316 control_stream = ZMQStream(self.control_socket)
316 control_stream = ZMQStream(self.control_socket)
317
317
318 kernel_factory = import_item(str(self.kernel_class))
318 kernel_factory = self.kernel_class
319
319
320 kernel = kernel_factory(parent=self, session=self.session,
320 kernel = kernel_factory(parent=self, session=self.session,
321 shell_streams=[shell_stream, control_stream],
321 shell_streams=[shell_stream, control_stream],
322 iopub_socket=self.iopub_socket,
322 iopub_socket=self.iopub_socket,
323 stdin_socket=self.stdin_socket,
323 stdin_socket=self.stdin_socket,
324 log=self.log,
324 log=self.log,
325 profile_dir=self.profile_dir,
325 profile_dir=self.profile_dir,
326 user_ns=self.user_ns,
326 user_ns=self.user_ns,
327 )
327 )
328 kernel.record_ports(self.ports)
328 kernel.record_ports(self.ports)
329 self.kernel = kernel
329 self.kernel = kernel
330
330
331 def init_gui_pylab(self):
331 def init_gui_pylab(self):
332 """Enable GUI event loop integration, taking pylab into account."""
332 """Enable GUI event loop integration, taking pylab into account."""
333
333
334 # Provide a wrapper for :meth:`InteractiveShellApp.init_gui_pylab`
334 # Provide a wrapper for :meth:`InteractiveShellApp.init_gui_pylab`
335 # to ensure that any exception is printed straight to stderr.
335 # to ensure that any exception is printed straight to stderr.
336 # Normally _showtraceback associates the reply with an execution,
336 # Normally _showtraceback associates the reply with an execution,
337 # which means frontends will never draw it, as this exception
337 # which means frontends will never draw it, as this exception
338 # is not associated with any execute request.
338 # is not associated with any execute request.
339
339
340 shell = self.shell
340 shell = self.shell
341 _showtraceback = shell._showtraceback
341 _showtraceback = shell._showtraceback
342 try:
342 try:
343 # replace error-sending traceback with stderr
343 # replace error-sending traceback with stderr
344 def print_tb(etype, evalue, stb):
344 def print_tb(etype, evalue, stb):
345 print ("GUI event loop or pylab initialization failed",
345 print ("GUI event loop or pylab initialization failed",
346 file=io.stderr)
346 file=io.stderr)
347 print (shell.InteractiveTB.stb2text(stb), file=io.stderr)
347 print (shell.InteractiveTB.stb2text(stb), file=io.stderr)
348 shell._showtraceback = print_tb
348 shell._showtraceback = print_tb
349 InteractiveShellApp.init_gui_pylab(self)
349 InteractiveShellApp.init_gui_pylab(self)
350 finally:
350 finally:
351 shell._showtraceback = _showtraceback
351 shell._showtraceback = _showtraceback
352
352
353 def init_shell(self):
353 def init_shell(self):
354 self.shell = self.kernel.shell
354 self.shell = self.kernel.shell
355 self.shell.configurables.append(self)
355 self.shell.configurables.append(self)
356
356
357 @catch_config_error
357 @catch_config_error
358 def initialize(self, argv=None):
358 def initialize(self, argv=None):
359 super(IPKernelApp, self).initialize(argv)
359 super(IPKernelApp, self).initialize(argv)
360 default_secure(self.config)
360 default_secure(self.config)
361 self.init_blackhole()
361 self.init_blackhole()
362 self.init_connection_file()
362 self.init_connection_file()
363 self.init_poller()
363 self.init_poller()
364 self.init_sockets()
364 self.init_sockets()
365 self.init_heartbeat()
365 self.init_heartbeat()
366 # writing/displaying connection info must be *after* init_sockets/heartbeat
366 # writing/displaying connection info must be *after* init_sockets/heartbeat
367 self.log_connection_info()
367 self.log_connection_info()
368 self.write_connection_file()
368 self.write_connection_file()
369 self.init_io()
369 self.init_io()
370 self.init_signal()
370 self.init_signal()
371 self.init_kernel()
371 self.init_kernel()
372 # shell init steps
372 # shell init steps
373 self.init_path()
373 self.init_path()
374 self.init_shell()
374 self.init_shell()
375 self.init_gui_pylab()
375 self.init_gui_pylab()
376 self.init_extensions()
376 self.init_extensions()
377 self.init_code()
377 self.init_code()
378 # flush stdout/stderr, so that anything written to these streams during
378 # flush stdout/stderr, so that anything written to these streams during
379 # initialization do not get associated with the first execution request
379 # initialization do not get associated with the first execution request
380 sys.stdout.flush()
380 sys.stdout.flush()
381 sys.stderr.flush()
381 sys.stderr.flush()
382
382
383 def start(self):
383 def start(self):
384 if self.poller is not None:
384 if self.poller is not None:
385 self.poller.start()
385 self.poller.start()
386 self.kernel.start()
386 self.kernel.start()
387 try:
387 try:
388 ioloop.IOLoop.instance().start()
388 ioloop.IOLoop.instance().start()
389 except KeyboardInterrupt:
389 except KeyboardInterrupt:
390 pass
390 pass
391
391
392 launch_new_instance = IPKernelApp.launch_instance
392 launch_new_instance = IPKernelApp.launch_instance
393
393
394 def main():
394 def main():
395 """Run an IPKernel as an application"""
395 """Run an IPKernel as an application"""
396 app = IPKernelApp.instance()
396 app = IPKernelApp.instance()
397 app.initialize()
397 app.initialize()
398 app.start()
398 app.start()
399
399
400
400
401 if __name__ == '__main__':
401 if __name__ == '__main__':
402 main()
402 main()
General Comments 0
You need to be logged in to leave comments. Login now