##// END OF EJS Templates
move interact trait up one level to InteractiveShellApp
Min RK -
Show More
@@ -1,435 +1,437
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 # whether interact-loop should start
202 interact = Bool(True)
201 203
202 204 user_ns = Instance(dict, args=None, allow_none=True)
203 205 def _user_ns_changed(self, name, old, new):
204 206 if self.shell is not None:
205 207 self.shell.user_ns = new
206 208 self.shell.init_user_ns()
207 209
208 210 def init_path(self):
209 211 """Add current working directory, '', to sys.path"""
210 212 if sys.path[0] != '':
211 213 sys.path.insert(0, '')
212 214
213 215 def init_shell(self):
214 216 raise NotImplementedError("Override in subclasses")
215 217
216 218 def init_gui_pylab(self):
217 219 """Enable GUI event loop integration, taking pylab into account."""
218 220 enable = False
219 221 shell = self.shell
220 222 if self.pylab:
221 223 enable = lambda key: shell.enable_pylab(key, import_all=self.pylab_import_all)
222 224 key = self.pylab
223 225 elif self.matplotlib:
224 226 enable = shell.enable_matplotlib
225 227 key = self.matplotlib
226 228 elif self.gui:
227 229 enable = shell.enable_gui
228 230 key = self.gui
229 231
230 232 if not enable:
231 233 return
232 234
233 235 try:
234 236 r = enable(key)
235 237 except ImportError:
236 238 self.log.warning("Eventloop or matplotlib integration failed. Is matplotlib installed?")
237 239 self.shell.showtraceback()
238 240 return
239 241 except Exception:
240 242 self.log.warning("GUI event loop or pylab initialization failed")
241 243 self.shell.showtraceback()
242 244 return
243 245
244 246 if isinstance(r, tuple):
245 247 gui, backend = r[:2]
246 248 self.log.info("Enabling GUI event loop integration, "
247 249 "eventloop=%s, matplotlib=%s", gui, backend)
248 250 if key == "auto":
249 251 print("Using matplotlib backend: %s" % backend)
250 252 else:
251 253 gui = r
252 254 self.log.info("Enabling GUI event loop integration, "
253 255 "eventloop=%s", gui)
254 256
255 257 def init_extensions(self):
256 258 """Load all IPython extensions in IPythonApp.extensions.
257 259
258 260 This uses the :meth:`ExtensionManager.load_extensions` to load all
259 261 the extensions listed in ``self.extensions``.
260 262 """
261 263 try:
262 264 self.log.debug("Loading IPython extensions...")
263 265 extensions = self.default_extensions + self.extensions
264 266 if self.extra_extension:
265 267 extensions.append(self.extra_extension)
266 268 for ext in extensions:
267 269 try:
268 270 self.log.info("Loading IPython extension: %s" % ext)
269 271 self.shell.extension_manager.load_extension(ext)
270 272 except:
271 273 if self.reraise_ipython_extension_failures:
272 274 raise
273 275 msg = ("Error in loading extension: {ext}\n"
274 276 "Check your config files in {location}".format(
275 277 ext=ext,
276 278 location=self.profile_dir.location
277 279 ))
278 280 self.log.warning(msg, exc_info=True)
279 281 except:
280 282 if self.reraise_ipython_extension_failures:
281 283 raise
282 284 self.log.warning("Unknown error in loading extensions:", exc_info=True)
283 285
284 286 def init_code(self):
285 287 """run the pre-flight code, specified via exec_lines"""
286 288 self._run_startup_files()
287 289 self._run_exec_lines()
288 290 self._run_exec_files()
289 291
290 292 # Hide variables defined here from %who etc.
291 293 if self.hide_initial_ns:
292 294 self.shell.user_ns_hidden.update(self.shell.user_ns)
293 295
294 296 # command-line execution (ipython -i script.py, ipython -m module)
295 297 # should *not* be excluded from %whos
296 298 self._run_cmd_line_code()
297 299 self._run_module()
298 300
299 301 # flush output, so itwon't be attached to the first cell
300 302 sys.stdout.flush()
301 303 sys.stderr.flush()
302 304
303 305 def _run_exec_lines(self):
304 306 """Run lines of code in IPythonApp.exec_lines in the user's namespace."""
305 307 if not self.exec_lines:
306 308 return
307 309 try:
308 310 self.log.debug("Running code from IPythonApp.exec_lines...")
309 311 for line in self.exec_lines:
310 312 try:
311 313 self.log.info("Running code in user namespace: %s" %
312 314 line)
313 315 self.shell.run_cell(line, store_history=False)
314 316 except:
315 317 self.log.warning("Error in executing line in user "
316 318 "namespace: %s" % line)
317 319 self.shell.showtraceback()
318 320 except:
319 321 self.log.warning("Unknown error in handling IPythonApp.exec_lines:")
320 322 self.shell.showtraceback()
321 323
322 324 def _exec_file(self, fname, shell_futures=False):
323 325 try:
324 326 full_filename = filefind(fname, [u'.', self.ipython_dir])
325 327 except IOError as e:
326 328 self.log.warning("File not found: %r"%fname)
327 329 return
328 330 # Make sure that the running script gets a proper sys.argv as if it
329 331 # were run from a system shell.
330 332 save_argv = sys.argv
331 333 sys.argv = [full_filename] + self.extra_args[1:]
332 334 # protect sys.argv from potential unicode strings on Python 2:
333 335 if not py3compat.PY3:
334 336 sys.argv = [ py3compat.cast_bytes(a) for a in sys.argv ]
335 337 try:
336 338 if os.path.isfile(full_filename):
337 339 self.log.info("Running file in user namespace: %s" %
338 340 full_filename)
339 341 # Ensure that __file__ is always defined to match Python
340 342 # behavior.
341 343 with preserve_keys(self.shell.user_ns, '__file__'):
342 344 self.shell.user_ns['__file__'] = fname
343 345 if full_filename.endswith('.ipy'):
344 346 self.shell.safe_execfile_ipy(full_filename,
345 347 shell_futures=shell_futures)
346 348 else:
347 349 # default to python, even without extension
348 350 self.shell.safe_execfile(full_filename,
349 351 self.shell.user_ns,
350 352 shell_futures=shell_futures,
351 353 raise_exceptions=True)
352 354 finally:
353 355 sys.argv = save_argv
354 356
355 357 def _run_startup_files(self):
356 358 """Run files from profile startup directory"""
357 359 startup_dir = self.profile_dir.startup_dir
358 360 startup_files = []
359 361
360 362 if self.exec_PYTHONSTARTUP and os.environ.get('PYTHONSTARTUP', False) and \
361 363 not (self.file_to_run or self.code_to_run or self.module_to_run):
362 364 python_startup = os.environ['PYTHONSTARTUP']
363 365 self.log.debug("Running PYTHONSTARTUP file %s...", python_startup)
364 366 try:
365 367 self._exec_file(python_startup)
366 368 except:
367 369 self.log.warning("Unknown error in handling PYTHONSTARTUP file %s:", python_startup)
368 370 self.shell.showtraceback()
369 371 finally:
370 372 # Many PYTHONSTARTUP files set up the readline completions,
371 373 # but this is often at odds with IPython's own completions.
372 374 # Do not allow PYTHONSTARTUP to set up readline.
373 375 if self.shell.has_readline:
374 376 self.shell.set_readline_completer()
375 377
376 378 startup_files += glob.glob(os.path.join(startup_dir, '*.py'))
377 379 startup_files += glob.glob(os.path.join(startup_dir, '*.ipy'))
378 380 if not startup_files:
379 381 return
380 382
381 383 self.log.debug("Running startup files from %s...", startup_dir)
382 384 try:
383 385 for fname in sorted(startup_files):
384 386 self._exec_file(fname)
385 387 except:
386 388 self.log.warning("Unknown error in handling startup files:")
387 389 self.shell.showtraceback()
388 390
389 391 def _run_exec_files(self):
390 392 """Run files from IPythonApp.exec_files"""
391 393 if not self.exec_files:
392 394 return
393 395
394 396 self.log.debug("Running files in IPythonApp.exec_files...")
395 397 try:
396 398 for fname in self.exec_files:
397 399 self._exec_file(fname)
398 400 except:
399 401 self.log.warning("Unknown error in handling IPythonApp.exec_files:")
400 402 self.shell.showtraceback()
401 403
402 404 def _run_cmd_line_code(self):
403 405 """Run code or file specified at the command-line"""
404 406 if self.code_to_run:
405 407 line = self.code_to_run
406 408 try:
407 409 self.log.info("Running code given at command line (c=): %s" %
408 410 line)
409 411 self.shell.run_cell(line, store_history=False)
410 412 except:
411 413 self.log.warning("Error in executing line in user namespace: %s" %
412 414 line)
413 415 self.shell.showtraceback()
414 416
415 417 # Like Python itself, ignore the second if the first of these is present
416 418 elif self.file_to_run:
417 419 fname = self.file_to_run
418 420 try:
419 421 self._exec_file(fname, shell_futures=True)
420 422 except:
421 423 self.shell.showtraceback(tb_offset=4)
422 424 self.exit(1)
423 425
424 426 def _run_module(self):
425 427 """Run module specified at the command-line."""
426 428 if self.module_to_run:
427 429 # Make sure that the module gets a proper sys.argv as if it were
428 430 # run using `python -m`.
429 431 save_argv = sys.argv
430 432 sys.argv = [sys.executable] + self.extra_args
431 433 try:
432 434 self.shell.safe_run_module(self.module_to_run,
433 435 self.shell.user_ns)
434 436 finally:
435 437 sys.argv = save_argv
@@ -1,369 +1,368
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
8 8 # Copyright (c) IPython Development Team.
9 9 # Distributed under the terms of the Modified BSD License.
10 10
11 11 from __future__ import absolute_import
12 12 from __future__ import print_function
13 13
14 14 import logging
15 15 import os
16 16 import sys
17 17
18 18 from traitlets.config.loader import Config
19 19 from traitlets.config.application import boolean_flag, catch_config_error, Application
20 20 from IPython.core import release
21 21 from IPython.core import usage
22 22 from IPython.core.completer import IPCompleter
23 23 from IPython.core.crashhandler import CrashHandler
24 24 from IPython.core.formatters import PlainTextFormatter
25 25 from IPython.core.history import HistoryManager
26 26 from IPython.core.prompts import PromptManager
27 27 from IPython.core.application import (
28 28 ProfileDir, BaseIPythonApplication, base_flags, base_aliases
29 29 )
30 30 from IPython.core.magics import ScriptMagics
31 31 from IPython.core.shellapp import (
32 32 InteractiveShellApp, shell_flags, shell_aliases
33 33 )
34 34 from IPython.extensions.storemagic import StoreMagics
35 35 from IPython.terminal.interactiveshell import TerminalInteractiveShell
36 36 from IPython.utils import warn
37 37 from IPython.paths import get_ipython_dir
38 38 from traitlets import (
39 39 Bool, List, Dict,
40 40 )
41 41
42 42 #-----------------------------------------------------------------------------
43 43 # Globals, utilities and helpers
44 44 #-----------------------------------------------------------------------------
45 45
46 46 _examples = """
47 47 ipython --matplotlib # enable matplotlib integration
48 48 ipython --matplotlib=qt # enable matplotlib integration with qt4 backend
49 49
50 50 ipython --log-level=DEBUG # set logging to DEBUG
51 51 ipython --profile=foo # start with profile foo
52 52
53 53 ipython profile create foo # create profile foo w/ default config files
54 54 ipython help profile # show the help for the profile subcmd
55 55
56 56 ipython locate # print the path to the IPython directory
57 57 ipython locate profile foo # print the path to the directory for profile `foo`
58 58 """
59 59
60 60 #-----------------------------------------------------------------------------
61 61 # Crash handler for this application
62 62 #-----------------------------------------------------------------------------
63 63
64 64 class IPAppCrashHandler(CrashHandler):
65 65 """sys.excepthook for IPython itself, leaves a detailed report on disk."""
66 66
67 67 def __init__(self, app):
68 68 contact_name = release.author
69 69 contact_email = release.author_email
70 70 bug_tracker = 'https://github.com/ipython/ipython/issues'
71 71 super(IPAppCrashHandler,self).__init__(
72 72 app, contact_name, contact_email, bug_tracker
73 73 )
74 74
75 75 def make_report(self,traceback):
76 76 """Return a string containing a crash report."""
77 77
78 78 sec_sep = self.section_sep
79 79 # Start with parent report
80 80 report = [super(IPAppCrashHandler, self).make_report(traceback)]
81 81 # Add interactive-specific info we may have
82 82 rpt_add = report.append
83 83 try:
84 84 rpt_add(sec_sep+"History of session input:")
85 85 for line in self.app.shell.user_ns['_ih']:
86 86 rpt_add(line)
87 87 rpt_add('\n*** Last line of input (may not be in above history):\n')
88 88 rpt_add(self.app.shell._last_input_line+'\n')
89 89 except:
90 90 pass
91 91
92 92 return ''.join(report)
93 93
94 94 #-----------------------------------------------------------------------------
95 95 # Aliases and Flags
96 96 #-----------------------------------------------------------------------------
97 97 flags = dict(base_flags)
98 98 flags.update(shell_flags)
99 99 frontend_flags = {}
100 100 addflag = lambda *args: frontend_flags.update(boolean_flag(*args))
101 101 addflag('autoedit-syntax', 'TerminalInteractiveShell.autoedit_syntax',
102 102 'Turn on auto editing of files with syntax errors.',
103 103 'Turn off auto editing of files with syntax errors.'
104 104 )
105 105 addflag('banner', 'TerminalIPythonApp.display_banner',
106 106 "Display a banner upon starting IPython.",
107 107 "Don't display a banner upon starting IPython."
108 108 )
109 109 addflag('confirm-exit', 'TerminalInteractiveShell.confirm_exit',
110 110 """Set to confirm when you try to exit IPython with an EOF (Control-D
111 111 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
112 112 you can force a direct exit without any confirmation.""",
113 113 "Don't prompt the user when exiting."
114 114 )
115 115 addflag('term-title', 'TerminalInteractiveShell.term_title',
116 116 "Enable auto setting the terminal title.",
117 117 "Disable auto setting the terminal title."
118 118 )
119 119 classic_config = Config()
120 120 classic_config.InteractiveShell.cache_size = 0
121 121 classic_config.PlainTextFormatter.pprint = False
122 122 classic_config.PromptManager.in_template = '>>> '
123 123 classic_config.PromptManager.in2_template = '... '
124 124 classic_config.PromptManager.out_template = ''
125 125 classic_config.InteractiveShell.separate_in = ''
126 126 classic_config.InteractiveShell.separate_out = ''
127 127 classic_config.InteractiveShell.separate_out2 = ''
128 128 classic_config.InteractiveShell.colors = 'NoColor'
129 129 classic_config.InteractiveShell.xmode = 'Plain'
130 130
131 131 frontend_flags['classic']=(
132 132 classic_config,
133 133 "Gives IPython a similar feel to the classic Python prompt."
134 134 )
135 135 # # log doesn't make so much sense this way anymore
136 136 # paa('--log','-l',
137 137 # action='store_true', dest='InteractiveShell.logstart',
138 138 # help="Start logging to the default log file (./ipython_log.py).")
139 139 #
140 140 # # quick is harder to implement
141 141 frontend_flags['quick']=(
142 142 {'TerminalIPythonApp' : {'quick' : True}},
143 143 "Enable quick startup with no config files."
144 144 )
145 145
146 146 frontend_flags['i'] = (
147 147 {'TerminalIPythonApp' : {'force_interact' : True}},
148 148 """If running code from the command line, become interactive afterwards.
149 149 It is often useful to follow this with `--` to treat remaining flags as
150 150 script arguments.
151 151 """
152 152 )
153 153 flags.update(frontend_flags)
154 154
155 155 aliases = dict(base_aliases)
156 156 aliases.update(shell_aliases)
157 157
158 158 #-----------------------------------------------------------------------------
159 159 # Main classes and functions
160 160 #-----------------------------------------------------------------------------
161 161
162 162
163 163 class LocateIPythonApp(BaseIPythonApplication):
164 164 description = """print the path to the IPython dir"""
165 165 subcommands = Dict(dict(
166 166 profile=('IPython.core.profileapp.ProfileLocate',
167 167 "print the path to an IPython profile directory",
168 168 ),
169 169 ))
170 170 def start(self):
171 171 if self.subapp is not None:
172 172 return self.subapp.start()
173 173 else:
174 174 print(self.ipython_dir)
175 175
176 176
177 177 class TerminalIPythonApp(BaseIPythonApplication, InteractiveShellApp):
178 178 name = u'ipython'
179 179 description = usage.cl_usage
180 180 crash_handler_class = IPAppCrashHandler
181 181 examples = _examples
182 182
183 183 flags = Dict(flags)
184 184 aliases = Dict(aliases)
185 185 classes = List()
186 186 def _classes_default(self):
187 187 """This has to be in a method, for TerminalIPythonApp to be available."""
188 188 return [
189 189 InteractiveShellApp, # ShellApp comes before TerminalApp, because
190 190 self.__class__, # it will also affect subclasses (e.g. QtConsole)
191 191 TerminalInteractiveShell,
192 192 PromptManager,
193 193 HistoryManager,
194 194 ProfileDir,
195 195 PlainTextFormatter,
196 196 IPCompleter,
197 197 ScriptMagics,
198 198 StoreMagics,
199 199 ]
200 200
201 201 deprecated_subcommands = dict(
202 202 qtconsole=('qtconsole.qtconsoleapp.JupyterQtConsoleApp',
203 203 """DEPRECATED, Will be removed in IPython 6.0 : Launch the Jupyter Qt Console."""
204 204 ),
205 205 notebook=('notebook.notebookapp.NotebookApp',
206 206 """DEPRECATED, Will be removed in IPython 6.0 : Launch the Jupyter HTML Notebook Server."""
207 207 ),
208 208 console=('jupyter_console.app.ZMQTerminalIPythonApp',
209 209 """DEPRECATED, Will be removed in IPython 6.0 : Launch the Jupyter terminal-based Console."""
210 210 ),
211 211 nbconvert=('nbconvert.nbconvertapp.NbConvertApp',
212 212 "DEPRECATED, Will be removed in IPython 6.0 : Convert notebooks to/from other formats."
213 213 ),
214 214 trust=('nbformat.sign.TrustNotebookApp',
215 215 "DEPRECATED, Will be removed in IPython 6.0 : Sign notebooks to trust their potentially unsafe contents at load."
216 216 ),
217 217 kernelspec=('jupyter_client.kernelspecapp.KernelSpecApp',
218 218 "DEPRECATED, Will be removed in IPython 6.0 : Manage Jupyter kernel specifications."
219 219 ),
220 220 )
221 221 subcommands = dict(
222 222 profile = ("IPython.core.profileapp.ProfileApp",
223 223 "Create and manage IPython profiles."
224 224 ),
225 225 kernel = ("ipykernel.kernelapp.IPKernelApp",
226 226 "Start a kernel without an attached frontend."
227 227 ),
228 228 locate=('IPython.terminal.ipapp.LocateIPythonApp',
229 229 LocateIPythonApp.description
230 230 ),
231 231 history=('IPython.core.historyapp.HistoryApp',
232 232 "Manage the IPython history database."
233 233 ),
234 234 )
235 235 deprecated_subcommands['install-nbextension'] = (
236 236 "notebook.nbextensions.InstallNBExtensionApp",
237 237 "DEPRECATED, Will be removed in IPython 6.0 : Install Jupyter notebook extension files"
238 238 )
239 239 subcommands.update(deprecated_subcommands)
240 240
241 241 # *do* autocreate requested profile, but don't create the config file.
242 242 auto_create=Bool(True)
243 243 # configurables
244 244 quick = Bool(False, config=True,
245 245 help="""Start IPython quickly by skipping the loading of config files."""
246 246 )
247 247 def _quick_changed(self, name, old, new):
248 248 if new:
249 249 self.load_config_file = lambda *a, **kw: None
250 250
251 251 display_banner = Bool(True, config=True,
252 252 help="Whether to display a banner upon starting IPython."
253 253 )
254 254
255 255 # if there is code of files to run from the cmd line, don't interact
256 256 # unless the --i flag (App.force_interact) is true.
257 257 force_interact = Bool(False, config=True,
258 258 help="""If a command or file is given via the command-line,
259 259 e.g. 'ipython foo.py', start an interactive shell after executing the
260 260 file or command."""
261 261 )
262 262 def _force_interact_changed(self, name, old, new):
263 263 if new:
264 264 self.interact = True
265 265
266 266 def _file_to_run_changed(self, name, old, new):
267 267 if new:
268 268 self.something_to_run = True
269 269 if new and not self.force_interact:
270 270 self.interact = False
271 271 _code_to_run_changed = _file_to_run_changed
272 272 _module_to_run_changed = _file_to_run_changed
273 273
274 274 # internal, not-configurable
275 interact=Bool(True)
276 275 something_to_run=Bool(False)
277 276
278 277 def parse_command_line(self, argv=None):
279 278 """override to allow old '-pylab' flag with deprecation warning"""
280 279
281 280 argv = sys.argv[1:] if argv is None else argv
282 281
283 282 if '-pylab' in argv:
284 283 # deprecated `-pylab` given,
285 284 # warn and transform into current syntax
286 285 argv = argv[:] # copy, don't clobber
287 286 idx = argv.index('-pylab')
288 287 warn.warn("`-pylab` flag has been deprecated.\n"
289 288 " Use `--matplotlib <backend>` and import pylab manually.")
290 289 argv[idx] = '--pylab'
291 290
292 291 return super(TerminalIPythonApp, self).parse_command_line(argv)
293 292
294 293 @catch_config_error
295 294 def initialize(self, argv=None):
296 295 """Do actions after construct, but before starting the app."""
297 296 super(TerminalIPythonApp, self).initialize(argv)
298 297 if self.subapp is not None:
299 298 # don't bother initializing further, starting subapp
300 299 return
301 300 # print self.extra_args
302 301 if self.extra_args and not self.something_to_run:
303 302 self.file_to_run = self.extra_args[0]
304 303 self.init_path()
305 304 # create the shell
306 305 self.init_shell()
307 306 # and draw the banner
308 307 self.init_banner()
309 308 # Now a variety of things that happen after the banner is printed.
310 309 self.init_gui_pylab()
311 310 self.init_extensions()
312 311 self.init_code()
313 312
314 313 def init_shell(self):
315 314 """initialize the InteractiveShell instance"""
316 315 # Create an InteractiveShell instance.
317 316 # shell.display_banner should always be False for the terminal
318 317 # based app, because we call shell.show_banner() by hand below
319 318 # so the banner shows *before* all extension loading stuff.
320 319 self.shell = TerminalInteractiveShell.instance(parent=self,
321 320 display_banner=False, profile_dir=self.profile_dir,
322 321 ipython_dir=self.ipython_dir, user_ns=self.user_ns)
323 322 self.shell.configurables.append(self)
324 323
325 324 def init_banner(self):
326 325 """optionally display the banner"""
327 326 if self.display_banner and self.interact:
328 327 self.shell.show_banner()
329 328 # Make sure there is a space below the banner.
330 329 if self.log_level <= logging.INFO: print()
331 330
332 331 def _pylab_changed(self, name, old, new):
333 332 """Replace --pylab='inline' with --pylab='auto'"""
334 333 if new == 'inline':
335 334 warn.warn("'inline' not available as pylab backend, "
336 335 "using 'auto' instead.")
337 336 self.pylab = 'auto'
338 337
339 338 def start(self):
340 339 if self.subapp is not None:
341 340 return self.subapp.start()
342 341 # perform any prexec steps:
343 342 if self.interact:
344 343 self.log.debug("Starting IPython's mainloop...")
345 344 self.shell.mainloop()
346 345 else:
347 346 self.log.debug("IPython not interactive...")
348 347
349 348 def load_default_config(ipython_dir=None):
350 349 """Load the default config file from the default ipython_dir.
351 350
352 351 This is useful for embedded shells.
353 352 """
354 353 if ipython_dir is None:
355 354 ipython_dir = get_ipython_dir()
356 355
357 356 profile_dir = os.path.join(ipython_dir, 'profile_default')
358 357
359 358 config = Config()
360 359 for cf in Application._load_config_files("ipython_config", path=profile_dir):
361 360 config.update(cf)
362 361
363 362 return config
364 363
365 364 launch_new_instance = TerminalIPythonApp.launch_instance
366 365
367 366
368 367 if __name__ == '__main__':
369 368 launch_new_instance()
General Comments 0
You need to be logged in to leave comments. Login now