##// END OF EJS Templates
add config file inheritance to kernelapp...
MinRK -
Show More
@@ -1,421 +1,422 b''
1 1 """ A minimal application using the Qt console-style IPython frontend.
2 2
3 3 This is not a complete console app, as subprocess will not be able to receive
4 4 input, there is no real readline support, among other limitations.
5 5
6 6 Authors:
7 7
8 8 * Evan Patterson
9 9 * Min RK
10 10 * Erik Tollerud
11 11 * Fernando Perez
12 12
13 13 """
14 14
15 15 #-----------------------------------------------------------------------------
16 16 # Imports
17 17 #-----------------------------------------------------------------------------
18 18
19 19 # stdlib imports
20 20 import os
21 21 import signal
22 22 import sys
23 23
24 24 # System library imports
25 25 from IPython.external.qt import QtGui
26 26 from pygments.styles import get_all_styles
27 27
28 28 # Local imports
29 29 from IPython.config.application import boolean_flag
30 30 from IPython.core.application import BaseIPythonApplication
31 31 from IPython.core.profiledir import ProfileDir
32 32 from IPython.frontend.qt.console.frontend_widget import FrontendWidget
33 33 from IPython.frontend.qt.console.ipython_widget import IPythonWidget
34 34 from IPython.frontend.qt.console.rich_ipython_widget import RichIPythonWidget
35 35 from IPython.frontend.qt.console import styles
36 36 from IPython.frontend.qt.kernelmanager import QtKernelManager
37 37 from IPython.utils.traitlets import (
38 38 Dict, List, Unicode, Int, CaselessStrEnum, CBool, Any
39 39 )
40 40 from IPython.zmq.ipkernel import (
41 41 flags as ipkernel_flags,
42 42 aliases as ipkernel_aliases,
43 43 IPKernelApp
44 44 )
45 45 from IPython.zmq.session import Session
46 46 from IPython.zmq.zmqshell import ZMQInteractiveShell
47 47
48 48
49 49 #-----------------------------------------------------------------------------
50 50 # Network Constants
51 51 #-----------------------------------------------------------------------------
52 52
53 53 from IPython.utils.localinterfaces import LOCALHOST, LOCAL_IPS
54 54
55 55 #-----------------------------------------------------------------------------
56 56 # Classes
57 57 #-----------------------------------------------------------------------------
58 58
59 59 class MainWindow(QtGui.QMainWindow):
60 60
61 61 #---------------------------------------------------------------------------
62 62 # 'object' interface
63 63 #---------------------------------------------------------------------------
64 64
65 65 def __init__(self, app, frontend, existing=False, may_close=True,
66 66 confirm_exit=True):
67 67 """ Create a MainWindow for the specified FrontendWidget.
68 68
69 69 The app is passed as an argument to allow for different
70 70 closing behavior depending on whether we are the Kernel's parent.
71 71
72 72 If existing is True, then this Console does not own the Kernel.
73 73
74 74 If may_close is True, then this Console is permitted to close the kernel
75 75 """
76 76 super(MainWindow, self).__init__()
77 77 self._app = app
78 78 self._frontend = frontend
79 79 self._existing = existing
80 80 if existing:
81 81 self._may_close = may_close
82 82 else:
83 83 self._may_close = True
84 84 self._frontend.exit_requested.connect(self.close)
85 85 self._confirm_exit = confirm_exit
86 86 self.setCentralWidget(frontend)
87 87
88 88 #---------------------------------------------------------------------------
89 89 # QWidget interface
90 90 #---------------------------------------------------------------------------
91 91
92 92 def closeEvent(self, event):
93 93 """ Close the window and the kernel (if necessary).
94 94
95 95 This will prompt the user if they are finished with the kernel, and if
96 96 so, closes the kernel cleanly. Alternatively, if the exit magic is used,
97 97 it closes without prompt.
98 98 """
99 99 keepkernel = None #Use the prompt by default
100 100 if hasattr(self._frontend,'_keep_kernel_on_exit'): #set by exit magic
101 101 keepkernel = self._frontend._keep_kernel_on_exit
102 102
103 103 kernel_manager = self._frontend.kernel_manager
104 104
105 105 if keepkernel is None and not self._confirm_exit:
106 106 # don't prompt, just terminate the kernel if we own it
107 107 # or leave it alone if we don't
108 108 keepkernel = not self._existing
109 109
110 110 if keepkernel is None: #show prompt
111 111 if kernel_manager and kernel_manager.channels_running:
112 112 title = self.window().windowTitle()
113 113 cancel = QtGui.QMessageBox.Cancel
114 114 okay = QtGui.QMessageBox.Ok
115 115 if self._may_close:
116 116 msg = "You are closing this Console window."
117 117 info = "Would you like to quit the Kernel and all attached Consoles as well?"
118 118 justthis = QtGui.QPushButton("&No, just this Console", self)
119 119 justthis.setShortcut('N')
120 120 closeall = QtGui.QPushButton("&Yes, quit everything", self)
121 121 closeall.setShortcut('Y')
122 122 box = QtGui.QMessageBox(QtGui.QMessageBox.Question,
123 123 title, msg)
124 124 box.setInformativeText(info)
125 125 box.addButton(cancel)
126 126 box.addButton(justthis, QtGui.QMessageBox.NoRole)
127 127 box.addButton(closeall, QtGui.QMessageBox.YesRole)
128 128 box.setDefaultButton(closeall)
129 129 box.setEscapeButton(cancel)
130 130 reply = box.exec_()
131 131 if reply == 1: # close All
132 132 kernel_manager.shutdown_kernel()
133 133 #kernel_manager.stop_channels()
134 134 event.accept()
135 135 elif reply == 0: # close Console
136 136 if not self._existing:
137 137 # Have kernel: don't quit, just close the window
138 138 self._app.setQuitOnLastWindowClosed(False)
139 139 self.deleteLater()
140 140 event.accept()
141 141 else:
142 142 event.ignore()
143 143 else:
144 144 reply = QtGui.QMessageBox.question(self, title,
145 145 "Are you sure you want to close this Console?"+
146 146 "\nThe Kernel and other Consoles will remain active.",
147 147 okay|cancel,
148 148 defaultButton=okay
149 149 )
150 150 if reply == okay:
151 151 event.accept()
152 152 else:
153 153 event.ignore()
154 154 elif keepkernel: #close console but leave kernel running (no prompt)
155 155 if kernel_manager and kernel_manager.channels_running:
156 156 if not self._existing:
157 157 # I have the kernel: don't quit, just close the window
158 158 self._app.setQuitOnLastWindowClosed(False)
159 159 event.accept()
160 160 else: #close console and kernel (no prompt)
161 161 if kernel_manager and kernel_manager.channels_running:
162 162 kernel_manager.shutdown_kernel()
163 163 event.accept()
164 164
165 165 #-----------------------------------------------------------------------------
166 166 # Aliases and Flags
167 167 #-----------------------------------------------------------------------------
168 168
169 169 flags = dict(ipkernel_flags)
170 170
171 171 flags.update({
172 172 'existing' : ({'IPythonQtConsoleApp' : {'existing' : True}},
173 173 "Connect to an existing kernel."),
174 174 'pure' : ({'IPythonQtConsoleApp' : {'pure' : True}},
175 175 "Use a pure Python kernel instead of an IPython kernel."),
176 176 'plain' : ({'ConsoleWidget' : {'kind' : 'plain'}},
177 177 "Disable rich text support."),
178 178 })
179 179 flags.update(boolean_flag(
180 180 'gui-completion', 'ConsoleWidget.gui_completion',
181 181 "use a GUI widget for tab completion",
182 182 "use plaintext output for completion"
183 183 ))
184 184 flags.update(boolean_flag(
185 185 'confirm-exit', 'IPythonQtConsoleApp.confirm_exit',
186 186 """Set to display confirmation dialog on exit. You can always use 'exit' or 'quit',
187 187 to force a direct exit without any confirmation.
188 188 """,
189 189 """Don't prompt the user when exiting. This will terminate the kernel
190 190 if it is owned by the frontend, and leave it alive if it is external.
191 191 """
192 192 ))
193 193 # the flags that are specific to the frontend
194 194 # these must be scrubbed before being passed to the kernel,
195 195 # or it will raise an error on unrecognized flags
196 196 qt_flags = ['existing', 'pure', 'plain', 'gui-completion', 'no-gui-completion',
197 197 'confirm-exit', 'no-confirm-exit']
198 198
199 199 aliases = dict(ipkernel_aliases)
200 200
201 201 aliases.update(dict(
202 202 hb = 'IPythonQtConsoleApp.hb_port',
203 203 shell = 'IPythonQtConsoleApp.shell_port',
204 204 iopub = 'IPythonQtConsoleApp.iopub_port',
205 205 stdin = 'IPythonQtConsoleApp.stdin_port',
206 206 ip = 'IPythonQtConsoleApp.ip',
207 207
208 208 plain = 'IPythonQtConsoleApp.plain',
209 209 pure = 'IPythonQtConsoleApp.pure',
210 210 gui_completion = 'ConsoleWidget.gui_completion',
211 211 style = 'IPythonWidget.syntax_style',
212 212 stylesheet = 'IPythonQtConsoleApp.stylesheet',
213 213 colors = 'ZMQInteractiveShell.colors',
214 214
215 215 editor = 'IPythonWidget.editor',
216 216 ))
217 217
218 218 #-----------------------------------------------------------------------------
219 219 # IPythonQtConsole
220 220 #-----------------------------------------------------------------------------
221 221 class IPythonQtConsoleApp(BaseIPythonApplication):
222 222 name = 'ipython-qtconsole'
223 223 default_config_file_name='ipython_config.py'
224 224
225 225 description = """
226 226 The IPython QtConsole.
227 227
228 228 This launches a Console-style application using Qt. It is not a full
229 229 console, in that launched terminal subprocesses will not.
230 230
231 231 The QtConsole supports various extra features beyond the
232 232
233 233 """
234 234
235 235 classes = [IPKernelApp, IPythonWidget, ZMQInteractiveShell, ProfileDir, Session]
236 236 flags = Dict(flags)
237 237 aliases = Dict(aliases)
238 238
239 239 kernel_argv = List(Unicode)
240 240
241 241 # connection info:
242 242 ip = Unicode(LOCALHOST, config=True,
243 243 help="""Set the kernel\'s IP address [default localhost].
244 244 If the IP address is something other than localhost, then
245 245 Consoles on other machines will be able to connect
246 246 to the Kernel, so be careful!"""
247 247 )
248 248 hb_port = Int(0, config=True,
249 249 help="set the heartbeat port [default: random]")
250 250 shell_port = Int(0, config=True,
251 251 help="set the shell (XREP) port [default: random]")
252 252 iopub_port = Int(0, config=True,
253 253 help="set the iopub (PUB) port [default: random]")
254 254 stdin_port = Int(0, config=True,
255 255 help="set the stdin (XREQ) port [default: random]")
256 256
257 257 existing = CBool(False, config=True,
258 258 help="Whether to connect to an already running Kernel.")
259 259
260 260 stylesheet = Unicode('', config=True,
261 261 help="path to a custom CSS stylesheet")
262 262
263 263 pure = CBool(False, config=True,
264 264 help="Use a pure Python kernel instead of an IPython kernel.")
265 265 plain = CBool(False, config=True,
266 266 help="Use a plaintext widget instead of rich text (plain can't print/save).")
267 267
268 268 def _pure_changed(self, name, old, new):
269 269 kind = 'plain' if self.plain else 'rich'
270 270 self.config.ConsoleWidget.kind = kind
271 271 if self.pure:
272 272 self.widget_factory = FrontendWidget
273 273 elif self.plain:
274 274 self.widget_factory = IPythonWidget
275 275 else:
276 276 self.widget_factory = RichIPythonWidget
277 277
278 278 _plain_changed = _pure_changed
279 279
280 280 confirm_exit = CBool(True, config=True,
281 281 help="""
282 282 Set to display confirmation dialog on exit. You can always use 'exit' or 'quit',
283 283 to force a direct exit without any confirmation.""",
284 284 )
285 285
286 286 # the factory for creating a widget
287 287 widget_factory = Any(RichIPythonWidget)
288 288
289 289 def parse_command_line(self, argv=None):
290 290 super(IPythonQtConsoleApp, self).parse_command_line(argv)
291 291 if argv is None:
292 292 argv = sys.argv[1:]
293 293
294 294 self.kernel_argv = list(argv) # copy
295
295 # kernel should inherit default config file from frontend
296 self.kernel_argv.append("KernelApp.parent_appname='%s'"%self.name)
296 297 # scrub frontend-specific flags
297 298 for a in argv:
298 299 if a.startswith('--') and a[2:] in qt_flags:
299 300 self.kernel_argv.remove(a)
300 301
301 302 def init_kernel_manager(self):
302 303 # Don't let Qt or ZMQ swallow KeyboardInterupts.
303 304 signal.signal(signal.SIGINT, signal.SIG_DFL)
304 305
305 306 # Create a KernelManager and start a kernel.
306 307 self.kernel_manager = QtKernelManager(
307 308 shell_address=(self.ip, self.shell_port),
308 309 sub_address=(self.ip, self.iopub_port),
309 310 stdin_address=(self.ip, self.stdin_port),
310 311 hb_address=(self.ip, self.hb_port),
311 312 config=self.config
312 313 )
313 314 # start the kernel
314 315 if not self.existing:
315 316 kwargs = dict(ip=self.ip, ipython=not self.pure)
316 317 kwargs['extra_arguments'] = self.kernel_argv
317 318 self.kernel_manager.start_kernel(**kwargs)
318 319 self.kernel_manager.start_channels()
319 320
320 321
321 322 def init_qt_elements(self):
322 323 # Create the widget.
323 324 self.app = QtGui.QApplication([])
324 325 local_kernel = (not self.existing) or self.ip in LOCAL_IPS
325 326 self.widget = self.widget_factory(config=self.config,
326 327 local_kernel=local_kernel)
327 328 self.widget.kernel_manager = self.kernel_manager
328 329 self.window = MainWindow(self.app, self.widget, self.existing,
329 330 may_close=local_kernel,
330 331 confirm_exit=self.confirm_exit)
331 332 self.window.setWindowTitle('Python' if self.pure else 'IPython')
332 333
333 334 def init_colors(self):
334 335 """Configure the coloring of the widget"""
335 336 # Note: This will be dramatically simplified when colors
336 337 # are removed from the backend.
337 338
338 339 if self.pure:
339 340 # only IPythonWidget supports styling
340 341 return
341 342
342 343 # parse the colors arg down to current known labels
343 344 try:
344 345 colors = self.config.ZMQInteractiveShell.colors
345 346 except AttributeError:
346 347 colors = None
347 348 try:
348 349 style = self.config.IPythonWidget.colors
349 350 except AttributeError:
350 351 style = None
351 352
352 353 # find the value for colors:
353 354 if colors:
354 355 colors=colors.lower()
355 356 if colors in ('lightbg', 'light'):
356 357 colors='lightbg'
357 358 elif colors in ('dark', 'linux'):
358 359 colors='linux'
359 360 else:
360 361 colors='nocolor'
361 362 elif style:
362 363 if style=='bw':
363 364 colors='nocolor'
364 365 elif styles.dark_style(style):
365 366 colors='linux'
366 367 else:
367 368 colors='lightbg'
368 369 else:
369 370 colors=None
370 371
371 372 # Configure the style.
372 373 widget = self.widget
373 374 if style:
374 375 widget.style_sheet = styles.sheet_from_template(style, colors)
375 376 widget.syntax_style = style
376 377 widget._syntax_style_changed()
377 378 widget._style_sheet_changed()
378 379 elif colors:
379 380 # use a default style
380 381 widget.set_default_style(colors=colors)
381 382 else:
382 383 # this is redundant for now, but allows the widget's
383 384 # defaults to change
384 385 widget.set_default_style()
385 386
386 387 if self.stylesheet:
387 388 # we got an expicit stylesheet
388 389 if os.path.isfile(self.stylesheet):
389 390 with open(self.stylesheet) as f:
390 391 sheet = f.read()
391 392 widget.style_sheet = sheet
392 393 widget._style_sheet_changed()
393 394 else:
394 395 raise IOError("Stylesheet %r not found."%self.stylesheet)
395 396
396 397 def initialize(self, argv=None):
397 398 super(IPythonQtConsoleApp, self).initialize(argv)
398 399 self.init_kernel_manager()
399 400 self.init_qt_elements()
400 401 self.init_colors()
401 402
402 403 def start(self):
403 404
404 405 # draw the window
405 406 self.window.show()
406 407
407 408 # Start the application main loop.
408 409 self.app.exec_()
409 410
410 411 #-----------------------------------------------------------------------------
411 412 # Main entry point
412 413 #-----------------------------------------------------------------------------
413 414
414 415 def main():
415 416 app = IPythonQtConsoleApp()
416 417 app.initialize()
417 418 app.start()
418 419
419 420
420 421 if __name__ == '__main__':
421 422 main()
@@ -1,216 +1,226 b''
1 1 #!/usr/bin/env python
2 2 """An Application for launching a kernel
3 3
4 4 Authors
5 5 -------
6 6 * MinRK
7 7 """
8 8 #-----------------------------------------------------------------------------
9 9 # Copyright (C) 2011 The IPython Development Team
10 10 #
11 11 # Distributed under the terms of the BSD License. The full license is in
12 12 # the file COPYING.txt, distributed as part of this software.
13 13 #-----------------------------------------------------------------------------
14 14
15 15 #-----------------------------------------------------------------------------
16 16 # Imports
17 17 #-----------------------------------------------------------------------------
18 18
19 19 # Standard library imports.
20 20 import os
21 21 import sys
22 22
23 23 # System library imports.
24 24 import zmq
25 25
26 26 # IPython imports.
27 27 from IPython.core.ultratb import FormattedTB
28 28 from IPython.core.application import (
29 29 BaseIPythonApplication, base_flags, base_aliases
30 30 )
31 31 from IPython.utils import io
32 32 from IPython.utils.localinterfaces import LOCALHOST
33 33 from IPython.utils.traitlets import (Any, Instance, Dict, Unicode, Int, Bool,
34 34 DottedObjectName)
35 35 from IPython.utils.importstring import import_item
36 36 # local imports
37 37 from IPython.zmq.heartbeat import Heartbeat
38 38 from IPython.zmq.parentpoller import ParentPollerUnix, ParentPollerWindows
39 39 from IPython.zmq.session import Session
40 40
41 41
42 42 #-----------------------------------------------------------------------------
43 43 # Flags and Aliases
44 44 #-----------------------------------------------------------------------------
45 45
46 46 kernel_aliases = dict(base_aliases)
47 47 kernel_aliases.update({
48 48 'ip' : 'KernelApp.ip',
49 49 'hb' : 'KernelApp.hb_port',
50 50 'shell' : 'KernelApp.shell_port',
51 51 'iopub' : 'KernelApp.iopub_port',
52 52 'stdin' : 'KernelApp.stdin_port',
53 53 'parent': 'KernelApp.parent',
54 54 })
55 55 if sys.platform.startswith('win'):
56 56 kernel_aliases['interrupt'] = 'KernelApp.interrupt'
57 57
58 58 kernel_flags = dict(base_flags)
59 59 kernel_flags.update({
60 60 'no-stdout' : (
61 61 {'KernelApp' : {'no_stdout' : True}},
62 62 "redirect stdout to the null device"),
63 63 'no-stderr' : (
64 64 {'KernelApp' : {'no_stderr' : True}},
65 65 "redirect stderr to the null device"),
66 66 })
67 67
68 68
69 69 #-----------------------------------------------------------------------------
70 70 # Application class for starting a Kernel
71 71 #-----------------------------------------------------------------------------
72 72
73 73 class KernelApp(BaseIPythonApplication):
74 74 name='pykernel'
75 75 aliases = Dict(kernel_aliases)
76 76 flags = Dict(kernel_flags)
77 77 classes = [Session]
78 78 # the kernel class, as an importstring
79 79 kernel_class = DottedObjectName('IPython.zmq.pykernel.Kernel')
80 80 kernel = Any()
81 81 poller = Any() # don't restrict this even though current pollers are all Threads
82 82 heartbeat = Instance(Heartbeat)
83 83 session = Instance('IPython.zmq.session.Session')
84 84 ports = Dict()
85 85
86 # inherit config file name from parent:
87 parent_appname = Unicode(config=True)
88 def _parent_appname_changed(self, name, old, new):
89 if self.config_file_specified:
90 # it was manually specified, ignore
91 return
92 self.config_file_name = new.replace('-','_') + u'_config.py'
93 # don't let this count as specifying the config file
94 self.config_file_specified = False
95
86 96 # connection info:
87 97 ip = Unicode(LOCALHOST, config=True,
88 98 help="Set the IP or interface on which the kernel will listen.")
89 99 hb_port = Int(0, config=True, help="set the heartbeat port [default: random]")
90 100 shell_port = Int(0, config=True, help="set the shell (XREP) port [default: random]")
91 101 iopub_port = Int(0, config=True, help="set the iopub (PUB) port [default: random]")
92 102 stdin_port = Int(0, config=True, help="set the stdin (XREQ) port [default: random]")
93 103
94 104 # streams, etc.
95 105 no_stdout = Bool(False, config=True, help="redirect stdout to the null device")
96 106 no_stderr = Bool(False, config=True, help="redirect stderr to the null device")
97 107 outstream_class = DottedObjectName('IPython.zmq.iostream.OutStream',
98 108 config=True, help="The importstring for the OutStream factory")
99 109 displayhook_class = DottedObjectName('IPython.zmq.displayhook.ZMQDisplayHook',
100 110 config=True, help="The importstring for the DisplayHook factory")
101 111
102 112 # polling
103 113 parent = Int(0, config=True,
104 114 help="""kill this process if its parent dies. On Windows, the argument
105 115 specifies the HANDLE of the parent process, otherwise it is simply boolean.
106 116 """)
107 117 interrupt = Int(0, config=True,
108 118 help="""ONLY USED ON WINDOWS
109 119 Interrupt this process when the parent is signalled.
110 120 """)
111 121
112 122 def init_crash_handler(self):
113 123 # Install minimal exception handling
114 124 sys.excepthook = FormattedTB(mode='Verbose', color_scheme='NoColor',
115 125 ostream=sys.__stdout__)
116 126
117 127 def init_poller(self):
118 128 if sys.platform == 'win32':
119 129 if self.interrupt or self.parent:
120 130 self.poller = ParentPollerWindows(self.interrupt, self.parent)
121 131 elif self.parent:
122 132 self.poller = ParentPollerUnix()
123 133
124 134 def _bind_socket(self, s, port):
125 135 iface = 'tcp://%s' % self.ip
126 136 if port <= 0:
127 137 port = s.bind_to_random_port(iface)
128 138 else:
129 139 s.bind(iface + ':%i'%port)
130 140 return port
131 141
132 142 def init_sockets(self):
133 143 # Create a context, a session, and the kernel sockets.
134 144 io.raw_print("Starting the kernel at pid:", os.getpid())
135 145 context = zmq.Context.instance()
136 146 # Uncomment this to try closing the context.
137 147 # atexit.register(context.term)
138 148
139 149 self.shell_socket = context.socket(zmq.XREP)
140 150 self.shell_port = self._bind_socket(self.shell_socket, self.shell_port)
141 151 self.log.debug("shell XREP Channel on port: %i"%self.shell_port)
142 152
143 153 self.iopub_socket = context.socket(zmq.PUB)
144 154 self.iopub_port = self._bind_socket(self.iopub_socket, self.iopub_port)
145 155 self.log.debug("iopub PUB Channel on port: %i"%self.iopub_port)
146 156
147 157 self.stdin_socket = context.socket(zmq.XREQ)
148 158 self.stdin_port = self._bind_socket(self.stdin_socket, self.stdin_port)
149 159 self.log.debug("stdin XREQ Channel on port: %i"%self.stdin_port)
150 160
151 161 self.heartbeat = Heartbeat(context, (self.ip, self.hb_port))
152 162 self.hb_port = self.heartbeat.port
153 163 self.log.debug("Heartbeat REP Channel on port: %i"%self.hb_port)
154 164
155 165 # Helper to make it easier to connect to an existing kernel, until we have
156 166 # single-port connection negotiation fully implemented.
157 167 self.log.info("To connect another client to this kernel, use:")
158 168 self.log.info("--external shell={0} iopub={1} stdin={2} hb={3}".format(
159 169 self.shell_port, self.iopub_port, self.stdin_port, self.hb_port))
160 170
161 171
162 172 self.ports = dict(shell=self.shell_port, iopub=self.iopub_port,
163 173 stdin=self.stdin_port, hb=self.hb_port)
164 174
165 175 def init_session(self):
166 176 """create our session object"""
167 177 self.session = Session(config=self.config, username=u'kernel')
168 178
169 179 def init_blackhole(self):
170 180 """redirects stdout/stderr to devnull if necessary"""
171 181 if self.no_stdout or self.no_stderr:
172 182 blackhole = file(os.devnull, 'w')
173 183 if self.no_stdout:
174 184 sys.stdout = sys.__stdout__ = blackhole
175 185 if self.no_stderr:
176 186 sys.stderr = sys.__stderr__ = blackhole
177 187
178 188 def init_io(self):
179 189 """Redirect input streams and set a display hook."""
180 190 if self.outstream_class:
181 191 outstream_factory = import_item(str(self.outstream_class))
182 192 sys.stdout = outstream_factory(self.session, self.iopub_socket, u'stdout')
183 193 sys.stderr = outstream_factory(self.session, self.iopub_socket, u'stderr')
184 194 if self.displayhook_class:
185 195 displayhook_factory = import_item(str(self.displayhook_class))
186 196 sys.displayhook = displayhook_factory(self.session, self.iopub_socket)
187 197
188 198 def init_kernel(self):
189 199 """Create the Kernel object itself"""
190 200 kernel_factory = import_item(str(self.kernel_class))
191 201 self.kernel = kernel_factory(config=self.config, session=self.session,
192 202 shell_socket=self.shell_socket,
193 203 iopub_socket=self.iopub_socket,
194 204 stdin_socket=self.stdin_socket,
195 205 log=self.log
196 206 )
197 207 self.kernel.record_ports(self.ports)
198 208
199 209 def initialize(self, argv=None):
200 210 super(KernelApp, self).initialize(argv)
201 211 self.init_blackhole()
202 212 self.init_session()
203 213 self.init_poller()
204 214 self.init_sockets()
205 215 self.init_io()
206 216 self.init_kernel()
207 217
208 218 def start(self):
209 219 self.heartbeat.start()
210 220 if self.poller is not None:
211 221 self.poller.start()
212 222 try:
213 223 self.kernel.start()
214 224 except KeyboardInterrupt:
215 225 pass
216 226
General Comments 0
You need to be logged in to leave comments. Login now