##// END OF EJS Templates
Make import_all configurable in InteractiveShellApp
Jens Hedegaard Nielsen -
Show More
@@ -1,252 +1,256 b''
1 1 # encoding: utf-8
2 2 """
3 3 A mixin for :class:`~IPython.core.application.Application` classes that
4 4 launch InteractiveShell instances, load extensions, etc.
5 5
6 6 Authors
7 7 -------
8 8
9 9 * Min Ragan-Kelley
10 10 """
11 11
12 12 #-----------------------------------------------------------------------------
13 13 # Copyright (C) 2008-2011 The IPython Development Team
14 14 #
15 15 # Distributed under the terms of the BSD License. The full license is in
16 16 # the file COPYING, distributed as part of this software.
17 17 #-----------------------------------------------------------------------------
18 18
19 19 #-----------------------------------------------------------------------------
20 20 # Imports
21 21 #-----------------------------------------------------------------------------
22 22
23 23 from __future__ import absolute_import
24 24
25 25 import os
26 26 import sys
27 27
28 28 from IPython.config.application import boolean_flag
29 29 from IPython.config.configurable import Configurable
30 30 from IPython.config.loader import Config
31 31 from IPython.utils.path import filefind
32 from IPython.utils.traitlets import Unicode, Instance, List
32 from IPython.utils.traitlets import Unicode, Instance, List, Bool
33 33
34 34 #-----------------------------------------------------------------------------
35 35 # Aliases and Flags
36 36 #-----------------------------------------------------------------------------
37 37
38 38 shell_flags = {}
39 39
40 40 addflag = lambda *args: shell_flags.update(boolean_flag(*args))
41 41 addflag('autoindent', 'InteractiveShell.autoindent',
42 42 'Turn on autoindenting.', 'Turn off autoindenting.'
43 43 )
44 44 addflag('automagic', 'InteractiveShell.automagic',
45 45 """Turn on the auto calling of magic commands. Type %%magic at the
46 46 IPython prompt for more information.""",
47 47 'Turn off the auto calling of magic commands.'
48 48 )
49 49 addflag('pdb', 'InteractiveShell.pdb',
50 50 "Enable auto calling the pdb debugger after every exception.",
51 51 "Disable auto calling the pdb debugger after every exception."
52 52 )
53 53 addflag('pprint', 'PlainTextFormatter.pprint',
54 54 "Enable auto pretty printing of results.",
55 55 "Disable auto auto pretty printing of results."
56 56 )
57 57 addflag('color-info', 'InteractiveShell.color_info',
58 58 """IPython can display information about objects via a set of func-
59 59 tions, and optionally can use colors for this, syntax highlighting
60 60 source code and various other elements. However, because this
61 61 information is passed through a pager (like 'less') and many pagers get
62 62 confused with color codes, this option is off by default. You can test
63 63 it and turn it on permanently in your ipython_config.py file if it
64 64 works for you. Test it and turn it on permanently if it works with
65 65 your system. The magic function %%color_info allows you to toggle this
66 66 interactively for testing.""",
67 67 "Disable using colors for info related things."
68 68 )
69 69 addflag('deep-reload', 'InteractiveShell.deep_reload',
70 70 """Enable deep (recursive) reloading by default. IPython can use the
71 71 deep_reload module which reloads changes in modules recursively (it
72 72 replaces the reload() function, so you don't need to change anything to
73 73 use it). deep_reload() forces a full reload of modules whose code may
74 74 have changed, which the default reload() function does not. When
75 75 deep_reload is off, IPython will use the normal reload(), but
76 76 deep_reload will still be available as dreload(). This feature is off
77 77 by default [which means that you have both normal reload() and
78 78 dreload()].""",
79 79 "Disable deep (recursive) reloading by default."
80 80 )
81 81 nosep_config = Config()
82 82 nosep_config.InteractiveShell.separate_in = ''
83 83 nosep_config.InteractiveShell.separate_out = ''
84 84 nosep_config.InteractiveShell.separate_out2 = ''
85 85
86 86 shell_flags['nosep']=(nosep_config, "Eliminate all spacing between prompts.")
87 87
88 88
89 89 # it's possible we don't want short aliases for *all* of these:
90 90 shell_aliases = dict(
91 91 autocall='InteractiveShell.autocall',
92 92 colors='InteractiveShell.colors',
93 93 logfile='InteractiveShell.logfile',
94 94 logappend='InteractiveShell.logappend',
95 95 c='InteractiveShellApp.code_to_run',
96 96 ext='InteractiveShellApp.extra_extension',
97 97 )
98 98 shell_aliases['cache-size'] = 'InteractiveShell.cache_size'
99 99
100 100 #-----------------------------------------------------------------------------
101 101 # Main classes and functions
102 102 #-----------------------------------------------------------------------------
103 103
104 104 class InteractiveShellApp(Configurable):
105 105 """A Mixin for applications that start InteractiveShell instances.
106 106
107 107 Provides configurables for loading extensions and executing files
108 108 as part of configuring a Shell environment.
109 109
110 110 Provides init_extensions() and init_code() methods, to be called
111 111 after init_shell(), which must be implemented by subclasses.
112 112 """
113 113 extensions = List(Unicode, config=True,
114 114 help="A list of dotted module names of IPython extensions to load."
115 115 )
116 116 extra_extension = Unicode('', config=True,
117 117 help="dotted module name of an IPython extension to load."
118 118 )
119 119 def _extra_extension_changed(self, name, old, new):
120 120 if new:
121 121 # add to self.extensions
122 122 self.extensions.append(new)
123 123
124 124 exec_files = List(Unicode, config=True,
125 125 help="""List of files to run at IPython startup."""
126 126 )
127 127 file_to_run = Unicode('', config=True,
128 128 help="""A file to be run""")
129 129
130 130 exec_lines = List(Unicode, config=True,
131 131 help="""lines of code to run at IPython startup."""
132 132 )
133 133 code_to_run = Unicode('', config=True,
134 134 help="Execute the given command string."
135 135 )
136 pylab_import_all = Bool(True, config=True,
137 help="""If true, an 'import *' is done from numpy and pylab,
138 when using pylab"""
139 )
136 140 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
137 141
138 142 def init_shell(self):
139 143 raise NotImplementedError("Override in subclasses")
140 144
141 145 def init_extensions(self):
142 146 """Load all IPython extensions in IPythonApp.extensions.
143 147
144 148 This uses the :meth:`ExtensionManager.load_extensions` to load all
145 149 the extensions listed in ``self.extensions``.
146 150 """
147 151 if not self.extensions:
148 152 return
149 153 try:
150 154 self.log.debug("Loading IPython extensions...")
151 155 extensions = self.extensions
152 156 for ext in extensions:
153 157 try:
154 158 self.log.info("Loading IPython extension: %s" % ext)
155 159 self.shell.extension_manager.load_extension(ext)
156 160 except:
157 161 self.log.warn("Error in loading extension: %s" % ext)
158 162 self.shell.showtraceback()
159 163 except:
160 164 self.log.warn("Unknown error in loading extensions:")
161 165 self.shell.showtraceback()
162 166
163 167 def init_code(self):
164 168 """run the pre-flight code, specified via exec_lines"""
165 169 self._run_exec_lines()
166 170 self._run_exec_files()
167 171 self._run_cmd_line_code()
168 172
169 173 def _run_exec_lines(self):
170 174 """Run lines of code in IPythonApp.exec_lines in the user's namespace."""
171 175 if not self.exec_lines:
172 176 return
173 177 try:
174 178 self.log.debug("Running code from IPythonApp.exec_lines...")
175 179 for line in self.exec_lines:
176 180 try:
177 181 self.log.info("Running code in user namespace: %s" %
178 182 line)
179 183 self.shell.run_cell(line, store_history=False)
180 184 except:
181 185 self.log.warn("Error in executing line in user "
182 186 "namespace: %s" % line)
183 187 self.shell.showtraceback()
184 188 except:
185 189 self.log.warn("Unknown error in handling IPythonApp.exec_lines:")
186 190 self.shell.showtraceback()
187 191
188 192 def _exec_file(self, fname):
189 193 try:
190 194 full_filename = filefind(fname, [u'.', self.ipython_dir])
191 195 except IOError as e:
192 196 self.log.warn("File not found: %r"%fname)
193 197 return
194 198 # Make sure that the running script gets a proper sys.argv as if it
195 199 # were run from a system shell.
196 200 save_argv = sys.argv
197 201 sys.argv = [full_filename] + self.extra_args[1:]
198 202 try:
199 203 if os.path.isfile(full_filename):
200 204 if full_filename.endswith('.ipy'):
201 205 self.log.info("Running file in user namespace: %s" %
202 206 full_filename)
203 207 self.shell.safe_execfile_ipy(full_filename)
204 208 else:
205 209 # default to python, even without extension
206 210 self.log.info("Running file in user namespace: %s" %
207 211 full_filename)
208 212 # Ensure that __file__ is always defined to match Python behavior
209 213 self.shell.user_ns['__file__'] = fname
210 214 try:
211 215 self.shell.safe_execfile(full_filename, self.shell.user_ns)
212 216 finally:
213 217 del self.shell.user_ns['__file__']
214 218 finally:
215 219 sys.argv = save_argv
216 220
217 221 def _run_exec_files(self):
218 222 """Run files from IPythonApp.exec_files"""
219 223 if not self.exec_files:
220 224 return
221 225
222 226 self.log.debug("Running files in IPythonApp.exec_files...")
223 227 try:
224 228 for fname in self.exec_files:
225 229 self._exec_file(fname)
226 230 except:
227 231 self.log.warn("Unknown error in handling IPythonApp.exec_files:")
228 232 self.shell.showtraceback()
229 233
230 234 def _run_cmd_line_code(self):
231 235 """Run code or file specified at the command-line"""
232 236 if self.code_to_run:
233 237 line = self.code_to_run
234 238 try:
235 239 self.log.info("Running code given at command line (c=): %s" %
236 240 line)
237 241 self.shell.run_cell(line, store_history=False)
238 242 except:
239 243 self.log.warn("Error in executing line in user namespace: %s" %
240 244 line)
241 245 self.shell.showtraceback()
242 246
243 247 # Like Python itself, ignore the second if the first of these is present
244 248 elif self.file_to_run:
245 249 fname = self.file_to_run
246 250 try:
247 251 self._exec_file(fname)
248 252 except:
249 253 self.log.warn("Error in executing file in user namespace: %s" %
250 254 fname)
251 255 self.shell.showtraceback()
252 256
@@ -1,390 +1,393 b''
1 1 #!/usr/bin/env python
2 2 # encoding: utf-8
3 3 """
4 4 The :class:`~IPython.core.application.Application` object for the command
5 5 line :command:`ipython` program.
6 6
7 7 Authors
8 8 -------
9 9
10 10 * Brian Granger
11 11 * Fernando Perez
12 12 * Min Ragan-Kelley
13 13 """
14 14
15 15 #-----------------------------------------------------------------------------
16 16 # Copyright (C) 2008-2010 The IPython Development Team
17 17 #
18 18 # Distributed under the terms of the BSD License. The full license is in
19 19 # the file COPYING, distributed as part of this software.
20 20 #-----------------------------------------------------------------------------
21 21
22 22 #-----------------------------------------------------------------------------
23 23 # Imports
24 24 #-----------------------------------------------------------------------------
25 25
26 26 from __future__ import absolute_import
27 27
28 28 import logging
29 29 import os
30 30 import sys
31 31
32 32 from IPython.config.loader import (
33 33 Config, PyFileConfigLoader
34 34 )
35 35 from IPython.config.application import boolean_flag
36 36 from IPython.core import release
37 37 from IPython.core import usage
38 38 from IPython.core.crashhandler import CrashHandler
39 39 from IPython.core.formatters import PlainTextFormatter
40 40 from IPython.core.application import (
41 41 ProfileDir, BaseIPythonApplication, base_flags, base_aliases
42 42 )
43 43 from IPython.core.shellapp import (
44 44 InteractiveShellApp, shell_flags, shell_aliases
45 45 )
46 46 from IPython.frontend.terminal.interactiveshell import TerminalInteractiveShell
47 47 from IPython.lib import inputhook
48 48 from IPython.utils import warn
49 49 from IPython.utils.path import get_ipython_dir, check_for_old_config
50 50 from IPython.utils.traitlets import (
51 51 Bool, List, Dict, CaselessStrEnum
52 52 )
53 53
54 54 #-----------------------------------------------------------------------------
55 55 # Globals, utilities and helpers
56 56 #-----------------------------------------------------------------------------
57 57
58 58 #: The default config file name for this application.
59 59 default_config_file_name = u'ipython_config.py'
60 60
61 61 _examples = """
62 62 ipython --pylab # start in pylab mode
63 63 ipython --pylab=qt # start in pylab mode with the qt4 backend
64 64 ipython --log-level=DEBUG # set logging to DEBUG
65 65 ipython --profile=foo # start with profile foo
66 66
67 67 ipython qtconsole # start the qtconsole GUI application
68 68 ipython qtconsole -h # show the help string for the qtconsole subcmd
69 69
70 70 ipython profile create foo # create profile foo w/ default config files
71 71 ipython profile -h # show the help string for the profile subcmd
72 72 """
73 73
74 74 #-----------------------------------------------------------------------------
75 75 # Crash handler for this application
76 76 #-----------------------------------------------------------------------------
77 77
78 78 class IPAppCrashHandler(CrashHandler):
79 79 """sys.excepthook for IPython itself, leaves a detailed report on disk."""
80 80
81 81 def __init__(self, app):
82 82 contact_name = release.authors['Fernando'][0]
83 83 contact_email = release.authors['Fernando'][1]
84 84 bug_tracker = 'http://github.com/ipython/ipython/issues'
85 85 super(IPAppCrashHandler,self).__init__(
86 86 app, contact_name, contact_email, bug_tracker
87 87 )
88 88
89 89 def make_report(self,traceback):
90 90 """Return a string containing a crash report."""
91 91
92 92 sec_sep = self.section_sep
93 93 # Start with parent report
94 94 report = [super(IPAppCrashHandler, self).make_report(traceback)]
95 95 # Add interactive-specific info we may have
96 96 rpt_add = report.append
97 97 try:
98 98 rpt_add(sec_sep+"History of session input:")
99 99 for line in self.app.shell.user_ns['_ih']:
100 100 rpt_add(line)
101 101 rpt_add('\n*** Last line of input (may not be in above history):\n')
102 102 rpt_add(self.app.shell._last_input_line+'\n')
103 103 except:
104 104 pass
105 105
106 106 return ''.join(report)
107 107
108 108 #-----------------------------------------------------------------------------
109 109 # Aliases and Flags
110 110 #-----------------------------------------------------------------------------
111 111 flags = dict(base_flags)
112 112 flags.update(shell_flags)
113 113 addflag = lambda *args: flags.update(boolean_flag(*args))
114 114 addflag('autoedit-syntax', 'TerminalInteractiveShell.autoedit_syntax',
115 115 'Turn on auto editing of files with syntax errors.',
116 116 'Turn off auto editing of files with syntax errors.'
117 117 )
118 118 addflag('banner', 'TerminalIPythonApp.display_banner',
119 119 "Display a banner upon starting IPython.",
120 120 "Don't display a banner upon starting IPython."
121 121 )
122 122 addflag('confirm-exit', 'TerminalInteractiveShell.confirm_exit',
123 123 """Set to confirm when you try to exit IPython with an EOF (Control-D
124 124 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
125 125 you can force a direct exit without any confirmation.""",
126 126 "Don't prompt the user when exiting."
127 127 )
128 128 addflag('term-title', 'TerminalInteractiveShell.term_title',
129 129 "Enable auto setting the terminal title.",
130 130 "Disable auto setting the terminal title."
131 131 )
132 132 classic_config = Config()
133 133 classic_config.InteractiveShell.cache_size = 0
134 134 classic_config.PlainTextFormatter.pprint = False
135 135 classic_config.InteractiveShell.prompt_in1 = '>>> '
136 136 classic_config.InteractiveShell.prompt_in2 = '... '
137 137 classic_config.InteractiveShell.prompt_out = ''
138 138 classic_config.InteractiveShell.separate_in = ''
139 139 classic_config.InteractiveShell.separate_out = ''
140 140 classic_config.InteractiveShell.separate_out2 = ''
141 141 classic_config.InteractiveShell.colors = 'NoColor'
142 142 classic_config.InteractiveShell.xmode = 'Plain'
143 143
144 144 flags['classic']=(
145 145 classic_config,
146 146 "Gives IPython a similar feel to the classic Python prompt."
147 147 )
148 148 # # log doesn't make so much sense this way anymore
149 149 # paa('--log','-l',
150 150 # action='store_true', dest='InteractiveShell.logstart',
151 151 # help="Start logging to the default log file (./ipython_log.py).")
152 152 #
153 153 # # quick is harder to implement
154 154 flags['quick']=(
155 155 {'TerminalIPythonApp' : {'quick' : True}},
156 156 "Enable quick startup with no config files."
157 157 )
158 158
159 159 flags['i'] = (
160 160 {'TerminalIPythonApp' : {'force_interact' : True}},
161 161 """If running code from the command line, become interactive afterwards.
162 162 Note: can also be given simply as '-i.'"""
163 163 )
164 164 flags['pylab'] = (
165 165 {'TerminalIPythonApp' : {'pylab' : 'auto'}},
166 166 """Pre-load matplotlib and numpy for interactive use with
167 167 the default matplotlib backend."""
168 168 )
169 169
170 170 aliases = dict(base_aliases)
171 171 aliases.update(shell_aliases)
172 172
173 173 # it's possible we don't want short aliases for *all* of these:
174 174 aliases.update(dict(
175 175 gui='TerminalIPythonApp.gui',
176 176 pylab='TerminalIPythonApp.pylab',
177 177 ))
178 178
179 179 #-----------------------------------------------------------------------------
180 180 # Main classes and functions
181 181 #-----------------------------------------------------------------------------
182 182
183 183 class TerminalIPythonApp(BaseIPythonApplication, InteractiveShellApp):
184 184 name = u'ipython'
185 185 description = usage.cl_usage
186 186 default_config_file_name = default_config_file_name
187 187 crash_handler_class = IPAppCrashHandler
188 188 examples = _examples
189 189
190 190 flags = Dict(flags)
191 191 aliases = Dict(aliases)
192 192 classes = List()
193 193 def _classes_default(self):
194 194 """This has to be in a method, for TerminalIPythonApp to be available."""
195 195 return [
196 196 InteractiveShellApp, # ShellApp comes before TerminalApp, because
197 197 self.__class__, # it will also affect subclasses (e.g. QtConsole)
198 198 TerminalInteractiveShell,
199 199 ProfileDir,
200 200 PlainTextFormatter,
201 201 ]
202 202
203 203 subcommands = Dict(dict(
204 204 qtconsole=('IPython.frontend.qt.console.qtconsoleapp.IPythonQtConsoleApp',
205 205 """Launch the IPython Qt Console."""
206 206 ),
207 207 notebook=('IPython.frontend.html.notebook.notebookapp.IPythonNotebookApp',
208 208 """Launch the IPython HTML Notebook Server"""
209 209 ),
210 210 profile = ("IPython.core.profileapp.ProfileApp",
211 211 "Create and manage IPython profiles."
212 212 ),
213 213 kernel = ("IPython.zmq.ipkernel.IPKernelApp",
214 214 "Start a kernel without an attached frontend."
215 215 ),
216 216 ))
217 217
218 218 # *do* autocreate requested profile, but don't create the config file.
219 219 auto_create=Bool(True)
220 220 # configurables
221 221 ignore_old_config=Bool(False, config=True,
222 222 help="Suppress warning messages about legacy config files"
223 223 )
224 224 quick = Bool(False, config=True,
225 225 help="""Start IPython quickly by skipping the loading of config files."""
226 226 )
227 227 def _quick_changed(self, name, old, new):
228 228 if new:
229 229 self.load_config_file = lambda *a, **kw: None
230 230 self.ignore_old_config=True
231 231
232 232 gui = CaselessStrEnum(('qt','wx','gtk'), config=True,
233 233 help="Enable GUI event loop integration ('qt', 'wx', 'gtk')."
234 234 )
235 235 pylab = CaselessStrEnum(['tk', 'qt', 'wx', 'gtk', 'osx', 'auto'],
236 236 config=True,
237 237 help="""Pre-load matplotlib and numpy for interactive use,
238 238 selecting a particular matplotlib backend and loop integration.
239 239 """
240 240 )
241 241 display_banner = Bool(True, config=True,
242 242 help="Whether to display a banner upon starting IPython."
243 243 )
244 244
245 245 # if there is code of files to run from the cmd line, don't interact
246 246 # unless the --i flag (App.force_interact) is true.
247 247 force_interact = Bool(False, config=True,
248 248 help="""If a command or file is given via the command-line,
249 249 e.g. 'ipython foo.py"""
250 250 )
251 251 def _force_interact_changed(self, name, old, new):
252 252 if new:
253 253 self.interact = True
254 254
255 255 def _file_to_run_changed(self, name, old, new):
256 256 if new and not self.force_interact:
257 257 self.interact = False
258 258 _code_to_run_changed = _file_to_run_changed
259 259
260 260 # internal, not-configurable
261 261 interact=Bool(True)
262 262
263 263
264 264 def parse_command_line(self, argv=None):
265 265 """override to allow old '-pylab' flag with deprecation warning"""
266 266
267 267 argv = sys.argv[1:] if argv is None else argv
268 268
269 269 if '-pylab' in argv:
270 270 # deprecated `-pylab` given,
271 271 # warn and transform into current syntax
272 272 argv = argv[:] # copy, don't clobber
273 273 idx = argv.index('-pylab')
274 274 warn.warn("`-pylab` flag has been deprecated.\n"
275 275 " Use `--pylab` instead, or `--pylab=foo` to specify a backend.")
276 276 sub = '--pylab'
277 277 if len(argv) > idx+1:
278 278 # check for gui arg, as in '-pylab qt'
279 279 gui = argv[idx+1]
280 280 if gui in ('wx', 'qt', 'qt4', 'gtk', 'auto'):
281 281 sub = '--pylab='+gui
282 282 argv.pop(idx+1)
283 283 argv[idx] = sub
284 284
285 285 return super(TerminalIPythonApp, self).parse_command_line(argv)
286 286
287 287 def initialize(self, argv=None):
288 288 """Do actions after construct, but before starting the app."""
289 289 super(TerminalIPythonApp, self).initialize(argv)
290 290 if self.subapp is not None:
291 291 # don't bother initializing further, starting subapp
292 292 return
293 293 if not self.ignore_old_config:
294 294 check_for_old_config(self.ipython_dir)
295 295 # print self.extra_args
296 296 if self.extra_args:
297 297 self.file_to_run = self.extra_args[0]
298 298 # create the shell
299 299 self.init_shell()
300 300 # and draw the banner
301 301 self.init_banner()
302 302 # Now a variety of things that happen after the banner is printed.
303 303 self.init_gui_pylab()
304 304 self.init_extensions()
305 305 self.init_code()
306 306
307 307 def init_shell(self):
308 308 """initialize the InteractiveShell instance"""
309 309 # I am a little hesitant to put these into InteractiveShell itself.
310 310 # But that might be the place for them
311 311 sys.path.insert(0, '')
312 312
313 313 # Create an InteractiveShell instance.
314 314 # shell.display_banner should always be False for the terminal
315 315 # based app, because we call shell.show_banner() by hand below
316 316 # so the banner shows *before* all extension loading stuff.
317 317 self.shell = TerminalInteractiveShell.instance(config=self.config,
318 318 display_banner=False, profile_dir=self.profile_dir,
319 319 ipython_dir=self.ipython_dir)
320 320
321 321 def init_banner(self):
322 322 """optionally display the banner"""
323 323 if self.display_banner and self.interact:
324 324 self.shell.show_banner()
325 325 # Make sure there is a space below the banner.
326 326 if self.log_level <= logging.INFO: print
327 327
328 328
329 329 def init_gui_pylab(self):
330 330 """Enable GUI event loop integration, taking pylab into account."""
331 331 gui = self.gui
332 332
333 333 # Using `pylab` will also require gui activation, though which toolkit
334 334 # to use may be chosen automatically based on mpl configuration.
335 335 if self.pylab:
336 336 activate = self.shell.enable_pylab
337 337 if self.pylab == 'auto':
338 338 gui = None
339 339 else:
340 340 gui = self.pylab
341 341 else:
342 342 # Enable only GUI integration, no pylab
343 343 activate = inputhook.enable_gui
344 344
345 345 if gui or self.pylab:
346 346 try:
347 347 self.log.info("Enabling GUI event loop integration, "
348 348 "toolkit=%s, pylab=%s" % (gui, self.pylab) )
349 activate(gui)
349 if self.pylab:
350 activate(gui, import_all=self.pylab_import_all)
351 else:
352 activate(gui)
350 353 except:
351 354 self.log.warn("Error in enabling GUI event loop integration:")
352 355 self.shell.showtraceback()
353 356
354 357 def start(self):
355 358 if self.subapp is not None:
356 359 return self.subapp.start()
357 360 # perform any prexec steps:
358 361 if self.interact:
359 362 self.log.debug("Starting IPython's mainloop...")
360 363 self.shell.mainloop()
361 364 else:
362 365 self.log.debug("IPython not interactive...")
363 366
364 367
365 368 def load_default_config(ipython_dir=None):
366 369 """Load the default config file from the default ipython_dir.
367 370
368 371 This is useful for embedded shells.
369 372 """
370 373 if ipython_dir is None:
371 374 ipython_dir = get_ipython_dir()
372 375 profile_dir = os.path.join(ipython_dir, 'profile_default')
373 376 cl = PyFileConfigLoader(default_config_file_name, profile_dir)
374 377 try:
375 378 config = cl.load_config()
376 379 except IOError:
377 380 # no config found
378 381 config = Config()
379 382 return config
380 383
381 384
382 385 def launch_new_instance():
383 386 """Create and run a full blown IPython instance"""
384 387 app = TerminalIPythonApp.instance()
385 388 app.initialize()
386 389 app.start()
387 390
388 391
389 392 if __name__ == '__main__':
390 393 launch_new_instance()
@@ -1,703 +1,699 b''
1 1 #!/usr/bin/env python
2 2 """A simple interactive kernel that talks to a frontend over 0MQ.
3 3
4 4 Things to do:
5 5
6 6 * Implement `set_parent` logic. Right before doing exec, the Kernel should
7 7 call set_parent on all the PUB objects with the message about to be executed.
8 8 * Implement random port and security key logic.
9 9 * Implement control messages.
10 10 * Implement event loop and poll version.
11 11 """
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16 from __future__ import print_function
17 17
18 18 # Standard library imports.
19 19 import __builtin__
20 20 import atexit
21 21 import sys
22 22 import time
23 23 import traceback
24 24 import logging
25 25 # System library imports.
26 26 import zmq
27 27
28 28 # Local imports.
29 29 from IPython.config.configurable import Configurable
30 30 from IPython.config.application import boolean_flag
31 31 from IPython.core.application import ProfileDir
32 32 from IPython.core.shellapp import (
33 33 InteractiveShellApp, shell_flags, shell_aliases
34 34 )
35 35 from IPython.utils import io
36 36 from IPython.utils import py3compat
37 37 from IPython.utils.jsonutil import json_clean
38 38 from IPython.lib import pylabtools
39 39 from IPython.utils.traitlets import (
40 40 List, Instance, Float, Dict, Bool, Int, Unicode, CaselessStrEnum
41 41 )
42 42
43 43 from entry_point import base_launch_kernel
44 44 from kernelapp import KernelApp, kernel_flags, kernel_aliases
45 45 from iostream import OutStream
46 46 from session import Session, Message
47 47 from zmqshell import ZMQInteractiveShell
48 48
49 49
50 50 #-----------------------------------------------------------------------------
51 51 # Main kernel class
52 52 #-----------------------------------------------------------------------------
53 53
54 54 class Kernel(Configurable):
55 55
56 56 #---------------------------------------------------------------------------
57 57 # Kernel interface
58 58 #---------------------------------------------------------------------------
59 59
60 60 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
61 61 session = Instance(Session)
62 62 shell_socket = Instance('zmq.Socket')
63 63 iopub_socket = Instance('zmq.Socket')
64 64 stdin_socket = Instance('zmq.Socket')
65 65 log = Instance(logging.Logger)
66 66
67 67 # Private interface
68 68
69 69 # Time to sleep after flushing the stdout/err buffers in each execute
70 70 # cycle. While this introduces a hard limit on the minimal latency of the
71 71 # execute cycle, it helps prevent output synchronization problems for
72 72 # clients.
73 73 # Units are in seconds. The minimum zmq latency on local host is probably
74 74 # ~150 microseconds, set this to 500us for now. We may need to increase it
75 75 # a little if it's not enough after more interactive testing.
76 76 _execute_sleep = Float(0.0005, config=True)
77 77
78 78 # Frequency of the kernel's event loop.
79 79 # Units are in seconds, kernel subclasses for GUI toolkits may need to
80 80 # adapt to milliseconds.
81 81 _poll_interval = Float(0.05, config=True)
82 82
83 83 # If the shutdown was requested over the network, we leave here the
84 84 # necessary reply message so it can be sent by our registered atexit
85 85 # handler. This ensures that the reply is only sent to clients truly at
86 86 # the end of our shutdown process (which happens after the underlying
87 87 # IPython shell's own shutdown).
88 88 _shutdown_message = None
89 89
90 90 # This is a dict of port number that the kernel is listening on. It is set
91 91 # by record_ports and used by connect_request.
92 92 _recorded_ports = Dict()
93 93
94 94
95 95
96 96 def __init__(self, **kwargs):
97 97 super(Kernel, self).__init__(**kwargs)
98 98
99 99 # Before we even start up the shell, register *first* our exit handlers
100 100 # so they come before the shell's
101 101 atexit.register(self._at_shutdown)
102 102
103 103 # Initialize the InteractiveShell subclass
104 104 self.shell = ZMQInteractiveShell.instance(config=self.config)
105 105 self.shell.displayhook.session = self.session
106 106 self.shell.displayhook.pub_socket = self.iopub_socket
107 107 self.shell.display_pub.session = self.session
108 108 self.shell.display_pub.pub_socket = self.iopub_socket
109 109
110 110 # TMP - hack while developing
111 111 self.shell._reply_content = None
112 112
113 113 # Build dict of handlers for message types
114 114 msg_types = [ 'execute_request', 'complete_request',
115 115 'object_info_request', 'history_request',
116 116 'connect_request', 'shutdown_request']
117 117 self.handlers = {}
118 118 for msg_type in msg_types:
119 119 self.handlers[msg_type] = getattr(self, msg_type)
120 120
121 121 def do_one_iteration(self):
122 122 """Do one iteration of the kernel's evaluation loop.
123 123 """
124 124 try:
125 125 ident,msg = self.session.recv(self.shell_socket, zmq.NOBLOCK)
126 126 except Exception:
127 127 self.log.warn("Invalid Message:", exc_info=True)
128 128 return
129 129 if msg is None:
130 130 return
131 131
132 132 msg_type = msg['header']['msg_type']
133 133
134 134 # This assert will raise in versions of zeromq 2.0.7 and lesser.
135 135 # We now require 2.0.8 or above, so we can uncomment for safety.
136 136 # print(ident,msg, file=sys.__stdout__)
137 137 assert ident is not None, "Missing message part."
138 138
139 139 # Print some info about this message and leave a '--->' marker, so it's
140 140 # easier to trace visually the message chain when debugging. Each
141 141 # handler prints its message at the end.
142 142 self.log.debug('\n*** MESSAGE TYPE:'+str(msg_type)+'***')
143 143 self.log.debug(' Content: '+str(msg['content'])+'\n --->\n ')
144 144
145 145 # Find and call actual handler for message
146 146 handler = self.handlers.get(msg_type, None)
147 147 if handler is None:
148 148 self.log.error("UNKNOWN MESSAGE TYPE:" +str(msg))
149 149 else:
150 150 handler(ident, msg)
151 151
152 152 # Check whether we should exit, in case the incoming message set the
153 153 # exit flag on
154 154 if self.shell.exit_now:
155 155 self.log.debug('\nExiting IPython kernel...')
156 156 # We do a normal, clean exit, which allows any actions registered
157 157 # via atexit (such as history saving) to take place.
158 158 sys.exit(0)
159 159
160 160
161 161 def start(self):
162 162 """ Start the kernel main loop.
163 163 """
164 164 poller = zmq.Poller()
165 165 poller.register(self.shell_socket, zmq.POLLIN)
166 166 while True:
167 167 try:
168 168 # scale by extra factor of 10, because there is no
169 169 # reason for this to be anything less than ~ 0.1s
170 170 # since it is a real poller and will respond
171 171 # to events immediately
172 172
173 173 # double nested try/except, to properly catch KeyboardInterrupt
174 174 # due to pyzmq Issue #130
175 175 try:
176 176 poller.poll(10*1000*self._poll_interval)
177 177 self.do_one_iteration()
178 178 except:
179 179 raise
180 180 except KeyboardInterrupt:
181 181 # Ctrl-C shouldn't crash the kernel
182 182 io.raw_print("KeyboardInterrupt caught in kernel")
183 183
184 184 def record_ports(self, ports):
185 185 """Record the ports that this kernel is using.
186 186
187 187 The creator of the Kernel instance must call this methods if they
188 188 want the :meth:`connect_request` method to return the port numbers.
189 189 """
190 190 self._recorded_ports = ports
191 191
192 192 #---------------------------------------------------------------------------
193 193 # Kernel request handlers
194 194 #---------------------------------------------------------------------------
195 195
196 196 def _publish_pyin(self, code, parent):
197 197 """Publish the code request on the pyin stream."""
198 198
199 199 pyin_msg = self.session.send(self.iopub_socket, u'pyin',{u'code':code}, parent=parent)
200 200
201 201 def execute_request(self, ident, parent):
202 202
203 203 status_msg = self.session.send(self.iopub_socket,
204 204 u'status',
205 205 {u'execution_state':u'busy'},
206 206 parent=parent
207 207 )
208 208
209 209 try:
210 210 content = parent[u'content']
211 211 code = content[u'code']
212 212 silent = content[u'silent']
213 213 except:
214 214 self.log.error("Got bad msg: ")
215 215 self.log.error(str(Message(parent)))
216 216 return
217 217
218 218 shell = self.shell # we'll need this a lot here
219 219
220 220 # Replace raw_input. Note that is not sufficient to replace
221 221 # raw_input in the user namespace.
222 222 raw_input = lambda prompt='': self._raw_input(prompt, ident, parent)
223 223 if py3compat.PY3:
224 224 __builtin__.input = raw_input
225 225 else:
226 226 __builtin__.raw_input = raw_input
227 227
228 228 # Set the parent message of the display hook and out streams.
229 229 shell.displayhook.set_parent(parent)
230 230 shell.display_pub.set_parent(parent)
231 231 sys.stdout.set_parent(parent)
232 232 sys.stderr.set_parent(parent)
233 233
234 234 # Re-broadcast our input for the benefit of listening clients, and
235 235 # start computing output
236 236 if not silent:
237 237 self._publish_pyin(code, parent)
238 238
239 239 reply_content = {}
240 240 try:
241 241 if silent:
242 242 # run_code uses 'exec' mode, so no displayhook will fire, and it
243 243 # doesn't call logging or history manipulations. Print
244 244 # statements in that code will obviously still execute.
245 245 shell.run_code(code)
246 246 else:
247 247 # FIXME: the shell calls the exception handler itself.
248 248 shell.run_cell(code)
249 249 except:
250 250 status = u'error'
251 251 # FIXME: this code right now isn't being used yet by default,
252 252 # because the run_cell() call above directly fires off exception
253 253 # reporting. This code, therefore, is only active in the scenario
254 254 # where runlines itself has an unhandled exception. We need to
255 255 # uniformize this, for all exception construction to come from a
256 256 # single location in the codbase.
257 257 etype, evalue, tb = sys.exc_info()
258 258 tb_list = traceback.format_exception(etype, evalue, tb)
259 259 reply_content.update(shell._showtraceback(etype, evalue, tb_list))
260 260 else:
261 261 status = u'ok'
262 262
263 263 reply_content[u'status'] = status
264 264
265 265 # Return the execution counter so clients can display prompts
266 266 reply_content['execution_count'] = shell.execution_count -1
267 267
268 268 # FIXME - fish exception info out of shell, possibly left there by
269 269 # runlines. We'll need to clean up this logic later.
270 270 if shell._reply_content is not None:
271 271 reply_content.update(shell._reply_content)
272 272 # reset after use
273 273 shell._reply_content = None
274 274
275 275 # At this point, we can tell whether the main code execution succeeded
276 276 # or not. If it did, we proceed to evaluate user_variables/expressions
277 277 if reply_content['status'] == 'ok':
278 278 reply_content[u'user_variables'] = \
279 279 shell.user_variables(content[u'user_variables'])
280 280 reply_content[u'user_expressions'] = \
281 281 shell.user_expressions(content[u'user_expressions'])
282 282 else:
283 283 # If there was an error, don't even try to compute variables or
284 284 # expressions
285 285 reply_content[u'user_variables'] = {}
286 286 reply_content[u'user_expressions'] = {}
287 287
288 288 # Payloads should be retrieved regardless of outcome, so we can both
289 289 # recover partial output (that could have been generated early in a
290 290 # block, before an error) and clear the payload system always.
291 291 reply_content[u'payload'] = shell.payload_manager.read_payload()
292 292 # Be agressive about clearing the payload because we don't want
293 293 # it to sit in memory until the next execute_request comes in.
294 294 shell.payload_manager.clear_payload()
295 295
296 296 # Flush output before sending the reply.
297 297 sys.stdout.flush()
298 298 sys.stderr.flush()
299 299 # FIXME: on rare occasions, the flush doesn't seem to make it to the
300 300 # clients... This seems to mitigate the problem, but we definitely need
301 301 # to better understand what's going on.
302 302 if self._execute_sleep:
303 303 time.sleep(self._execute_sleep)
304 304
305 305 # Send the reply.
306 306 reply_msg = self.session.send(self.shell_socket, u'execute_reply',
307 307 reply_content, parent, ident=ident)
308 308 self.log.debug(str(reply_msg))
309 309
310 310 if reply_msg['content']['status'] == u'error':
311 311 self._abort_queue()
312 312
313 313 status_msg = self.session.send(self.iopub_socket,
314 314 u'status',
315 315 {u'execution_state':u'idle'},
316 316 parent=parent
317 317 )
318 318
319 319 def complete_request(self, ident, parent):
320 320 txt, matches = self._complete(parent)
321 321 matches = {'matches' : matches,
322 322 'matched_text' : txt,
323 323 'status' : 'ok'}
324 324 completion_msg = self.session.send(self.shell_socket, 'complete_reply',
325 325 matches, parent, ident)
326 326 self.log.debug(str(completion_msg))
327 327
328 328 def object_info_request(self, ident, parent):
329 329 object_info = self.shell.object_inspect(parent['content']['oname'])
330 330 # Before we send this object over, we scrub it for JSON usage
331 331 oinfo = json_clean(object_info)
332 332 msg = self.session.send(self.shell_socket, 'object_info_reply',
333 333 oinfo, parent, ident)
334 334 self.log.debug(msg)
335 335
336 336 def history_request(self, ident, parent):
337 337 # We need to pull these out, as passing **kwargs doesn't work with
338 338 # unicode keys before Python 2.6.5.
339 339 hist_access_type = parent['content']['hist_access_type']
340 340 raw = parent['content']['raw']
341 341 output = parent['content']['output']
342 342 if hist_access_type == 'tail':
343 343 n = parent['content']['n']
344 344 hist = self.shell.history_manager.get_tail(n, raw=raw, output=output,
345 345 include_latest=True)
346 346
347 347 elif hist_access_type == 'range':
348 348 session = parent['content']['session']
349 349 start = parent['content']['start']
350 350 stop = parent['content']['stop']
351 351 hist = self.shell.history_manager.get_range(session, start, stop,
352 352 raw=raw, output=output)
353 353
354 354 elif hist_access_type == 'search':
355 355 pattern = parent['content']['pattern']
356 356 hist = self.shell.history_manager.search(pattern, raw=raw, output=output)
357 357
358 358 else:
359 359 hist = []
360 360 content = {'history' : list(hist)}
361 361 msg = self.session.send(self.shell_socket, 'history_reply',
362 362 content, parent, ident)
363 363 self.log.debug(str(msg))
364 364
365 365 def connect_request(self, ident, parent):
366 366 if self._recorded_ports is not None:
367 367 content = self._recorded_ports.copy()
368 368 else:
369 369 content = {}
370 370 msg = self.session.send(self.shell_socket, 'connect_reply',
371 371 content, parent, ident)
372 372 self.log.debug(msg)
373 373
374 374 def shutdown_request(self, ident, parent):
375 375 self.shell.exit_now = True
376 376 self._shutdown_message = self.session.msg(u'shutdown_reply', parent['content'], parent)
377 377 sys.exit(0)
378 378
379 379 #---------------------------------------------------------------------------
380 380 # Protected interface
381 381 #---------------------------------------------------------------------------
382 382
383 383 def _abort_queue(self):
384 384 while True:
385 385 try:
386 386 ident,msg = self.session.recv(self.shell_socket, zmq.NOBLOCK)
387 387 except Exception:
388 388 self.log.warn("Invalid Message:", exc_info=True)
389 389 continue
390 390 if msg is None:
391 391 break
392 392 else:
393 393 assert ident is not None, \
394 394 "Unexpected missing message part."
395 395
396 396 self.log.debug("Aborting:\n"+str(Message(msg)))
397 397 msg_type = msg['header']['msg_type']
398 398 reply_type = msg_type.split('_')[0] + '_reply'
399 399 reply_msg = self.session.send(self.shell_socket, reply_type,
400 400 {'status' : 'aborted'}, msg, ident=ident)
401 401 self.log.debug(reply_msg)
402 402 # We need to wait a bit for requests to come in. This can probably
403 403 # be set shorter for true asynchronous clients.
404 404 time.sleep(0.1)
405 405
406 406 def _raw_input(self, prompt, ident, parent):
407 407 # Flush output before making the request.
408 408 sys.stderr.flush()
409 409 sys.stdout.flush()
410 410
411 411 # Send the input request.
412 412 content = dict(prompt=prompt)
413 413 msg = self.session.send(self.stdin_socket, u'input_request', content, parent)
414 414
415 415 # Await a response.
416 416 while True:
417 417 try:
418 418 ident, reply = self.session.recv(self.stdin_socket, 0)
419 419 except Exception:
420 420 self.log.warn("Invalid Message:", exc_info=True)
421 421 else:
422 422 break
423 423 try:
424 424 value = reply['content']['value']
425 425 except:
426 426 self.log.error("Got bad raw_input reply: ")
427 427 self.log.error(str(Message(parent)))
428 428 value = ''
429 429 return value
430 430
431 431 def _complete(self, msg):
432 432 c = msg['content']
433 433 try:
434 434 cpos = int(c['cursor_pos'])
435 435 except:
436 436 # If we don't get something that we can convert to an integer, at
437 437 # least attempt the completion guessing the cursor is at the end of
438 438 # the text, if there's any, and otherwise of the line
439 439 cpos = len(c['text'])
440 440 if cpos==0:
441 441 cpos = len(c['line'])
442 442 return self.shell.complete(c['text'], c['line'], cpos)
443 443
444 444 def _object_info(self, context):
445 445 symbol, leftover = self._symbol_from_context(context)
446 446 if symbol is not None and not leftover:
447 447 doc = getattr(symbol, '__doc__', '')
448 448 else:
449 449 doc = ''
450 450 object_info = dict(docstring = doc)
451 451 return object_info
452 452
453 453 def _symbol_from_context(self, context):
454 454 if not context:
455 455 return None, context
456 456
457 457 base_symbol_string = context[0]
458 458 symbol = self.shell.user_ns.get(base_symbol_string, None)
459 459 if symbol is None:
460 460 symbol = __builtin__.__dict__.get(base_symbol_string, None)
461 461 if symbol is None:
462 462 return None, context
463 463
464 464 context = context[1:]
465 465 for i, name in enumerate(context):
466 466 new_symbol = getattr(symbol, name, None)
467 467 if new_symbol is None:
468 468 return symbol, context[i:]
469 469 else:
470 470 symbol = new_symbol
471 471
472 472 return symbol, []
473 473
474 474 def _at_shutdown(self):
475 475 """Actions taken at shutdown by the kernel, called by python's atexit.
476 476 """
477 477 # io.rprint("Kernel at_shutdown") # dbg
478 478 if self._shutdown_message is not None:
479 479 self.session.send(self.shell_socket, self._shutdown_message)
480 480 self.session.send(self.iopub_socket, self._shutdown_message)
481 481 self.log.debug(str(self._shutdown_message))
482 482 # A very short sleep to give zmq time to flush its message buffers
483 483 # before Python truly shuts down.
484 484 time.sleep(0.01)
485 485
486 486
487 487 class QtKernel(Kernel):
488 488 """A Kernel subclass with Qt support."""
489 489
490 490 def start(self):
491 491 """Start a kernel with QtPy4 event loop integration."""
492 492
493 493 from IPython.external.qt_for_kernel import QtCore
494 494 from IPython.lib.guisupport import get_app_qt4, start_event_loop_qt4
495 495
496 496 self.app = get_app_qt4([" "])
497 497 self.app.setQuitOnLastWindowClosed(False)
498 498 self.timer = QtCore.QTimer()
499 499 self.timer.timeout.connect(self.do_one_iteration)
500 500 # Units for the timer are in milliseconds
501 501 self.timer.start(1000*self._poll_interval)
502 502 start_event_loop_qt4(self.app)
503 503
504 504
505 505 class WxKernel(Kernel):
506 506 """A Kernel subclass with Wx support."""
507 507
508 508 def start(self):
509 509 """Start a kernel with wx event loop support."""
510 510
511 511 import wx
512 512 from IPython.lib.guisupport import start_event_loop_wx
513 513
514 514 doi = self.do_one_iteration
515 515 # Wx uses milliseconds
516 516 poll_interval = int(1000*self._poll_interval)
517 517
518 518 # We have to put the wx.Timer in a wx.Frame for it to fire properly.
519 519 # We make the Frame hidden when we create it in the main app below.
520 520 class TimerFrame(wx.Frame):
521 521 def __init__(self, func):
522 522 wx.Frame.__init__(self, None, -1)
523 523 self.timer = wx.Timer(self)
524 524 # Units for the timer are in milliseconds
525 525 self.timer.Start(poll_interval)
526 526 self.Bind(wx.EVT_TIMER, self.on_timer)
527 527 self.func = func
528 528
529 529 def on_timer(self, event):
530 530 self.func()
531 531
532 532 # We need a custom wx.App to create our Frame subclass that has the
533 533 # wx.Timer to drive the ZMQ event loop.
534 534 class IPWxApp(wx.App):
535 535 def OnInit(self):
536 536 self.frame = TimerFrame(doi)
537 537 self.frame.Show(False)
538 538 return True
539 539
540 540 # The redirect=False here makes sure that wx doesn't replace
541 541 # sys.stdout/stderr with its own classes.
542 542 self.app = IPWxApp(redirect=False)
543 543 start_event_loop_wx(self.app)
544 544
545 545
546 546 class TkKernel(Kernel):
547 547 """A Kernel subclass with Tk support."""
548 548
549 549 def start(self):
550 550 """Start a Tk enabled event loop."""
551 551
552 552 import Tkinter
553 553 doi = self.do_one_iteration
554 554 # Tk uses milliseconds
555 555 poll_interval = int(1000*self._poll_interval)
556 556 # For Tkinter, we create a Tk object and call its withdraw method.
557 557 class Timer(object):
558 558 def __init__(self, func):
559 559 self.app = Tkinter.Tk()
560 560 self.app.withdraw()
561 561 self.func = func
562 562
563 563 def on_timer(self):
564 564 self.func()
565 565 self.app.after(poll_interval, self.on_timer)
566 566
567 567 def start(self):
568 568 self.on_timer() # Call it once to get things going.
569 569 self.app.mainloop()
570 570
571 571 self.timer = Timer(doi)
572 572 self.timer.start()
573 573
574 574
575 575 class GTKKernel(Kernel):
576 576 """A Kernel subclass with GTK support."""
577 577
578 578 def start(self):
579 579 """Start the kernel, coordinating with the GTK event loop"""
580 580 from .gui.gtkembed import GTKEmbed
581 581
582 582 gtk_kernel = GTKEmbed(self)
583 583 gtk_kernel.start()
584 584
585 585
586 586 #-----------------------------------------------------------------------------
587 587 # Aliases and Flags for the IPKernelApp
588 588 #-----------------------------------------------------------------------------
589 589
590 590 flags = dict(kernel_flags)
591 591 flags.update(shell_flags)
592 592
593 593 addflag = lambda *args: flags.update(boolean_flag(*args))
594 594
595 595 flags['pylab'] = (
596 596 {'IPKernelApp' : {'pylab' : 'auto'}},
597 597 """Pre-load matplotlib and numpy for interactive use with
598 598 the default matplotlib backend."""
599 599 )
600 600
601 601 aliases = dict(kernel_aliases)
602 602 aliases.update(shell_aliases)
603 603
604 604 # it's possible we don't want short aliases for *all* of these:
605 605 aliases.update(dict(
606 606 pylab='IPKernelApp.pylab',
607 607 ))
608 608
609 609 #-----------------------------------------------------------------------------
610 610 # The IPKernelApp class
611 611 #-----------------------------------------------------------------------------
612 612
613 613 class IPKernelApp(KernelApp, InteractiveShellApp):
614 614 name = 'ipkernel'
615 615
616 616 aliases = Dict(aliases)
617 617 flags = Dict(flags)
618 618 classes = [Kernel, ZMQInteractiveShell, ProfileDir, Session]
619 619 # configurables
620 620 pylab = CaselessStrEnum(['tk', 'qt', 'wx', 'gtk', 'osx', 'inline', 'auto'],
621 621 config=True,
622 622 help="""Pre-load matplotlib and numpy for interactive use,
623 623 selecting a particular matplotlib backend and loop integration.
624 624 """
625 625 )
626 pylab_import_all = Bool(True, config=True,
627 help="""If true, an 'import *' is done from numpy and pylab,
628 when using pylab"""
629 )
630 626 def initialize(self, argv=None):
631 627 super(IPKernelApp, self).initialize(argv)
632 628 self.init_shell()
633 629 self.init_extensions()
634 630 self.init_code()
635 631
636 632 def init_kernel(self):
637 633 kernel_factory = Kernel
638 634
639 635 kernel_map = {
640 636 'qt' : QtKernel,
641 637 'qt4': QtKernel,
642 638 'inline': Kernel,
643 639 'osx': TkKernel,
644 640 'wx' : WxKernel,
645 641 'tk' : TkKernel,
646 642 'gtk': GTKKernel,
647 643 }
648 644
649 645 if self.pylab:
650 646 key = None if self.pylab == 'auto' else self.pylab
651 647 gui, backend = pylabtools.find_gui_and_backend(key)
652 648 kernel_factory = kernel_map.get(gui)
653 649 if kernel_factory is None:
654 650 raise ValueError('GUI is not supported: %r' % gui)
655 651 pylabtools.activate_matplotlib(backend)
656 652
657 653 kernel = kernel_factory(config=self.config, session=self.session,
658 654 shell_socket=self.shell_socket,
659 655 iopub_socket=self.iopub_socket,
660 656 stdin_socket=self.stdin_socket,
661 657 log=self.log
662 658 )
663 659 self.kernel = kernel
664 660 kernel.record_ports(self.ports)
665 661
666 662 if self.pylab:
667 663 import_all = self.pylab_import_all
668 664 pylabtools.import_pylab(kernel.shell.user_ns, backend, import_all,
669 665 shell=kernel.shell)
670 666
671 667 def init_shell(self):
672 668 self.shell = self.kernel.shell
673 669
674 670
675 671 #-----------------------------------------------------------------------------
676 672 # Kernel main and launch functions
677 673 #-----------------------------------------------------------------------------
678 674
679 675 def launch_kernel(*args, **kwargs):
680 676 """Launches a localhost IPython kernel, binding to the specified ports.
681 677
682 678 This function simply calls entry_point.base_launch_kernel with the right first
683 679 command to start an ipkernel. See base_launch_kernel for arguments.
684 680
685 681 Returns
686 682 -------
687 683 A tuple of form:
688 684 (kernel_process, shell_port, iopub_port, stdin_port, hb_port)
689 685 where kernel_process is a Popen object and the ports are integers.
690 686 """
691 687 return base_launch_kernel('from IPython.zmq.ipkernel import main; main()',
692 688 *args, **kwargs)
693 689
694 690
695 691 def main():
696 692 """Run an IPKernel as an application"""
697 693 app = IPKernelApp.instance()
698 694 app.initialize()
699 695 app.start()
700 696
701 697
702 698 if __name__ == '__main__':
703 699 main()
General Comments 0
You need to be logged in to leave comments. Login now