##// END OF EJS Templates
Update shellapp.py...
Tony Fast -
Show More
@@ -1,408 +1,408 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
7 7 # Copyright (c) IPython Development Team.
8 8 # Distributed under the terms of the Modified BSD License.
9 9
10 10 import glob
11 11 from itertools import chain
12 12 import os
13 13 import sys
14 14
15 15 from traitlets.config.application import boolean_flag
16 16 from traitlets.config.configurable import Configurable
17 17 from traitlets.config.loader import Config
18 18 from IPython.core.application import SYSTEM_CONFIG_DIRS, ENV_CONFIG_DIRS
19 19 from IPython.core import pylabtools
20 20 from IPython.utils.contexts import preserve_keys
21 21 from IPython.utils.path import filefind
22 22 from traitlets import (
23 23 Unicode, Instance, List, Bool, CaselessStrEnum, observe,
24 24 )
25 25 from IPython.terminal import pt_inputhooks
26 26
27 27 #-----------------------------------------------------------------------------
28 28 # Aliases and Flags
29 29 #-----------------------------------------------------------------------------
30 30
31 31 gui_keys = tuple(sorted(pt_inputhooks.backends) + sorted(pt_inputhooks.aliases))
32 32
33 33 backend_keys = sorted(pylabtools.backends.keys())
34 34 backend_keys.insert(0, 'auto')
35 35
36 36 shell_flags = {}
37 37
38 38 addflag = lambda *args: shell_flags.update(boolean_flag(*args))
39 39 addflag('autoindent', 'InteractiveShell.autoindent',
40 40 'Turn on autoindenting.', 'Turn off autoindenting.'
41 41 )
42 42 addflag('automagic', 'InteractiveShell.automagic',
43 43 """Turn on the auto calling of magic commands. Type %%magic at the
44 44 IPython prompt for more information.""",
45 45 'Turn off the auto calling of magic commands.'
46 46 )
47 47 addflag('pdb', 'InteractiveShell.pdb',
48 48 "Enable auto calling the pdb debugger after every exception.",
49 49 "Disable auto calling the pdb debugger after every exception."
50 50 )
51 51 addflag('pprint', 'PlainTextFormatter.pprint',
52 52 "Enable auto pretty printing of results.",
53 53 "Disable auto pretty printing of results."
54 54 )
55 55 addflag('color-info', 'InteractiveShell.color_info',
56 56 """IPython can display information about objects via a set of functions,
57 57 and optionally can use colors for this, syntax highlighting
58 58 source code and various other elements. This is on by default, but can cause
59 59 problems with some pagers. If you see such problems, you can disable the
60 60 colours.""",
61 61 "Disable using colors for info related things."
62 62 )
63 63 nosep_config = Config()
64 64 nosep_config.InteractiveShell.separate_in = ''
65 65 nosep_config.InteractiveShell.separate_out = ''
66 66 nosep_config.InteractiveShell.separate_out2 = ''
67 67
68 68 shell_flags['nosep']=(nosep_config, "Eliminate all spacing between prompts.")
69 69 shell_flags['pylab'] = (
70 70 {'InteractiveShellApp' : {'pylab' : 'auto'}},
71 71 """Pre-load matplotlib and numpy for interactive use with
72 72 the default matplotlib backend."""
73 73 )
74 74 shell_flags['matplotlib'] = (
75 75 {'InteractiveShellApp' : {'matplotlib' : 'auto'}},
76 76 """Configure matplotlib for interactive use with
77 77 the default matplotlib backend."""
78 78 )
79 79
80 80 # it's possible we don't want short aliases for *all* of these:
81 81 shell_aliases = dict(
82 82 autocall='InteractiveShell.autocall',
83 83 colors='InteractiveShell.colors',
84 84 logfile='InteractiveShell.logfile',
85 85 logappend='InteractiveShell.logappend',
86 86 c='InteractiveShellApp.code_to_run',
87 87 m='InteractiveShellApp.module_to_run',
88 88 ext='InteractiveShellApp.extra_extension',
89 89 gui='InteractiveShellApp.gui',
90 90 pylab='InteractiveShellApp.pylab',
91 91 matplotlib='InteractiveShellApp.matplotlib',
92 92 )
93 93 shell_aliases['cache-size'] = 'InteractiveShell.cache_size'
94 94
95 95 #-----------------------------------------------------------------------------
96 96 # Main classes and functions
97 97 #-----------------------------------------------------------------------------
98 98
99 99 class InteractiveShellApp(Configurable):
100 100 """A Mixin for applications that start InteractiveShell instances.
101 101
102 102 Provides configurables for loading extensions and executing files
103 103 as part of configuring a Shell environment.
104 104
105 105 The following methods should be called by the :meth:`initialize` method
106 106 of the subclass:
107 107
108 108 - :meth:`init_path`
109 109 - :meth:`init_shell` (to be implemented by the subclass)
110 110 - :meth:`init_gui_pylab`
111 111 - :meth:`init_extensions`
112 112 - :meth:`init_code`
113 113 """
114 114 extensions = List(Unicode(),
115 115 help="A list of dotted module names of IPython extensions to load."
116 116 ).tag(config=True)
117 117 extra_extension = Unicode('',
118 118 help="dotted module name of an IPython extension to load."
119 119 ).tag(config=True)
120 120
121 121 reraise_ipython_extension_failures = Bool(False,
122 122 help="Reraise exceptions encountered loading IPython extensions?",
123 123 ).tag(config=True)
124 124
125 125 # Extensions that are always loaded (not configurable)
126 126 default_extensions = List(Unicode(), [u'storemagic']).tag(config=False)
127 127
128 128 hide_initial_ns = Bool(True,
129 129 help="""Should variables loaded at startup (by startup files, exec_lines, etc.)
130 130 be hidden from tools like %who?"""
131 131 ).tag(config=True)
132 132
133 133 exec_files = List(Unicode(),
134 134 help="""List of files to run at IPython startup."""
135 135 ).tag(config=True)
136 136 exec_PYTHONSTARTUP = Bool(True,
137 137 help="""Run the file referenced by the PYTHONSTARTUP environment
138 138 variable at IPython startup."""
139 139 ).tag(config=True)
140 140 file_to_run = Unicode('',
141 141 help="""A file to be run""").tag(config=True)
142 142
143 143 exec_lines = List(Unicode(),
144 144 help="""lines of code to run at IPython startup."""
145 145 ).tag(config=True)
146 146 code_to_run = Unicode('',
147 147 help="Execute the given command string."
148 148 ).tag(config=True)
149 149 module_to_run = Unicode('',
150 150 help="Run the module as a script."
151 151 ).tag(config=True)
152 152 gui = CaselessStrEnum(gui_keys, allow_none=True,
153 153 help="Enable GUI event loop integration with any of {0}.".format(gui_keys)
154 154 ).tag(config=True)
155 155 matplotlib = CaselessStrEnum(backend_keys, allow_none=True,
156 156 help="""Configure matplotlib for interactive use with
157 157 the default matplotlib backend."""
158 158 ).tag(config=True)
159 159 pylab = CaselessStrEnum(backend_keys, allow_none=True,
160 160 help="""Pre-load matplotlib and numpy for interactive use,
161 161 selecting a particular matplotlib backend and loop integration.
162 162 """
163 163 ).tag(config=True)
164 164 pylab_import_all = Bool(True,
165 165 help="""If true, IPython will populate the user namespace with numpy, pylab, etc.
166 166 and an ``import *`` is done from numpy and pylab, when using pylab mode.
167 167
168 168 When False, pylab mode should not import any names into the user namespace.
169 169 """
170 170 ).tag(config=True)
171 171 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC',
172 172 allow_none=True)
173 173 # whether interact-loop should start
174 174 interact = Bool(True)
175 175
176 176 user_ns = Instance(dict, args=None, allow_none=True)
177 177 @observe('user_ns')
178 178 def _user_ns_changed(self, change):
179 179 if self.shell is not None:
180 180 self.shell.user_ns = change['new']
181 181 self.shell.init_user_ns()
182 182
183 183 def init_path(self):
184 184 """Add current working directory, '', to sys.path"""
185 185 if sys.path[0] != '':
186 186 sys.path.insert(0, '')
187 187
188 188 def init_shell(self):
189 189 raise NotImplementedError("Override in subclasses")
190 190
191 191 def init_gui_pylab(self):
192 192 """Enable GUI event loop integration, taking pylab into account."""
193 193 enable = False
194 194 shell = self.shell
195 195 if self.pylab:
196 196 enable = lambda key: shell.enable_pylab(key, import_all=self.pylab_import_all)
197 197 key = self.pylab
198 198 elif self.matplotlib:
199 199 enable = shell.enable_matplotlib
200 200 key = self.matplotlib
201 201 elif self.gui:
202 202 enable = shell.enable_gui
203 203 key = self.gui
204 204
205 205 if not enable:
206 206 return
207 207
208 208 try:
209 209 r = enable(key)
210 210 except ImportError:
211 211 self.log.warning("Eventloop or matplotlib integration failed. Is matplotlib installed?")
212 212 self.shell.showtraceback()
213 213 return
214 214 except Exception:
215 215 self.log.warning("GUI event loop or pylab initialization failed")
216 216 self.shell.showtraceback()
217 217 return
218 218
219 219 if isinstance(r, tuple):
220 220 gui, backend = r[:2]
221 221 self.log.info("Enabling GUI event loop integration, "
222 222 "eventloop=%s, matplotlib=%s", gui, backend)
223 223 if key == "auto":
224 224 print("Using matplotlib backend: %s" % backend)
225 225 else:
226 226 gui = r
227 227 self.log.info("Enabling GUI event loop integration, "
228 228 "eventloop=%s", gui)
229 229
230 230 def init_extensions(self):
231 231 """Load all IPython extensions in IPythonApp.extensions.
232 232
233 233 This uses the :meth:`ExtensionManager.load_extensions` to load all
234 234 the extensions listed in ``self.extensions``.
235 235 """
236 236 try:
237 237 self.log.debug("Loading IPython extensions...")
238 238 extensions = self.default_extensions + self.extensions
239 239 if self.extra_extension:
240 240 extensions.append(self.extra_extension)
241 241 for ext in extensions:
242 242 try:
243 243 self.log.info("Loading IPython extension: %s" % ext)
244 244 self.shell.extension_manager.load_extension(ext)
245 245 except:
246 246 if self.reraise_ipython_extension_failures:
247 247 raise
248 248 msg = ("Error in loading extension: {ext}\n"
249 249 "Check your config files in {location}".format(
250 250 ext=ext,
251 251 location=self.profile_dir.location
252 252 ))
253 253 self.log.warning(msg, exc_info=True)
254 254 except:
255 255 if self.reraise_ipython_extension_failures:
256 256 raise
257 257 self.log.warning("Unknown error in loading extensions:", exc_info=True)
258 258
259 259 def init_code(self):
260 260 """run the pre-flight code, specified via exec_lines"""
261 261 self._run_startup_files()
262 262 self._run_exec_lines()
263 263 self._run_exec_files()
264 264
265 265 # Hide variables defined here from %who etc.
266 266 if self.hide_initial_ns:
267 267 self.shell.user_ns_hidden.update(self.shell.user_ns)
268 268
269 269 # command-line execution (ipython -i script.py, ipython -m module)
270 270 # should *not* be excluded from %whos
271 271 self._run_cmd_line_code()
272 272 self._run_module()
273 273
274 274 # flush output, so itwon't be attached to the first cell
275 275 sys.stdout.flush()
276 276 sys.stderr.flush()
277 277
278 278 def _run_exec_lines(self):
279 279 """Run lines of code in IPythonApp.exec_lines in the user's namespace."""
280 280 if not self.exec_lines:
281 281 return
282 282 try:
283 283 self.log.debug("Running code from IPythonApp.exec_lines...")
284 284 for line in self.exec_lines:
285 285 try:
286 286 self.log.info("Running code in user namespace: %s" %
287 287 line)
288 288 self.shell.run_cell(line, store_history=False)
289 289 except:
290 290 self.log.warning("Error in executing line in user "
291 291 "namespace: %s" % line)
292 292 self.shell.showtraceback()
293 293 except:
294 294 self.log.warning("Unknown error in handling IPythonApp.exec_lines:")
295 295 self.shell.showtraceback()
296 296
297 297 def _exec_file(self, fname, shell_futures=False):
298 298 try:
299 299 full_filename = filefind(fname, [u'.', self.ipython_dir])
300 300 except IOError:
301 301 self.log.warning("File not found: %r"%fname)
302 302 return
303 303 # Make sure that the running script gets a proper sys.argv as if it
304 304 # were run from a system shell.
305 305 save_argv = sys.argv
306 306 sys.argv = [full_filename] + self.extra_args[1:]
307 307 try:
308 308 if os.path.isfile(full_filename):
309 309 self.log.info("Running file in user namespace: %s" %
310 310 full_filename)
311 311 # Ensure that __file__ is always defined to match Python
312 312 # behavior.
313 313 with preserve_keys(self.shell.user_ns, '__file__'):
314 314 self.shell.user_ns['__file__'] = fname
315 if full_filename.endswith('.ipy'):
315 if full_filename.endswith('.ipy') or full_filename.endswith('.ipynb'):
316 316 self.shell.safe_execfile_ipy(full_filename,
317 317 shell_futures=shell_futures)
318 318 else:
319 319 # default to python, even without extension
320 320 self.shell.safe_execfile(full_filename,
321 321 self.shell.user_ns,
322 322 shell_futures=shell_futures,
323 323 raise_exceptions=True)
324 324 finally:
325 325 sys.argv = save_argv
326 326
327 327 def _run_startup_files(self):
328 328 """Run files from profile startup directory"""
329 329 startup_dirs = [self.profile_dir.startup_dir] + [
330 330 os.path.join(p, 'startup') for p in chain(ENV_CONFIG_DIRS, SYSTEM_CONFIG_DIRS)
331 331 ]
332 332 startup_files = []
333 333
334 334 if self.exec_PYTHONSTARTUP and os.environ.get('PYTHONSTARTUP', False) and \
335 335 not (self.file_to_run or self.code_to_run or self.module_to_run):
336 336 python_startup = os.environ['PYTHONSTARTUP']
337 337 self.log.debug("Running PYTHONSTARTUP file %s...", python_startup)
338 338 try:
339 339 self._exec_file(python_startup)
340 340 except:
341 341 self.log.warning("Unknown error in handling PYTHONSTARTUP file %s:", python_startup)
342 342 self.shell.showtraceback()
343 343 for startup_dir in startup_dirs[::-1]:
344 344 startup_files += glob.glob(os.path.join(startup_dir, '*.py'))
345 345 startup_files += glob.glob(os.path.join(startup_dir, '*.ipy'))
346 346 if not startup_files:
347 347 return
348 348
349 349 self.log.debug("Running startup files from %s...", startup_dir)
350 350 try:
351 351 for fname in sorted(startup_files):
352 352 self._exec_file(fname)
353 353 except:
354 354 self.log.warning("Unknown error in handling startup files:")
355 355 self.shell.showtraceback()
356 356
357 357 def _run_exec_files(self):
358 358 """Run files from IPythonApp.exec_files"""
359 359 if not self.exec_files:
360 360 return
361 361
362 362 self.log.debug("Running files in IPythonApp.exec_files...")
363 363 try:
364 364 for fname in self.exec_files:
365 365 self._exec_file(fname)
366 366 except:
367 367 self.log.warning("Unknown error in handling IPythonApp.exec_files:")
368 368 self.shell.showtraceback()
369 369
370 370 def _run_cmd_line_code(self):
371 371 """Run code or file specified at the command-line"""
372 372 if self.code_to_run:
373 373 line = self.code_to_run
374 374 try:
375 375 self.log.info("Running code given at command line (c=): %s" %
376 376 line)
377 377 self.shell.run_cell(line, store_history=False)
378 378 except:
379 379 self.log.warning("Error in executing line in user namespace: %s" %
380 380 line)
381 381 self.shell.showtraceback()
382 382 if not self.interact:
383 383 self.exit(1)
384 384
385 385 # Like Python itself, ignore the second if the first of these is present
386 386 elif self.file_to_run:
387 387 fname = self.file_to_run
388 388 if os.path.isdir(fname):
389 389 fname = os.path.join(fname, "__main__.py")
390 390 try:
391 391 self._exec_file(fname, shell_futures=True)
392 392 except:
393 393 self.shell.showtraceback(tb_offset=4)
394 394 if not self.interact:
395 395 self.exit(1)
396 396
397 397 def _run_module(self):
398 398 """Run module specified at the command-line."""
399 399 if self.module_to_run:
400 400 # Make sure that the module gets a proper sys.argv as if it were
401 401 # run using `python -m`.
402 402 save_argv = sys.argv
403 403 sys.argv = [sys.executable] + self.extra_args
404 404 try:
405 405 self.shell.safe_run_module(self.module_to_run,
406 406 self.shell.user_ns)
407 407 finally:
408 408 sys.argv = save_argv
General Comments 0
You need to be logged in to leave comments. Login now