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