##// END OF EJS Templates
typo
MinRK -
Show More
@@ -1,395 +1,395
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-2011 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 from __future__ import print_function
28 28
29 29 import logging
30 30 import os
31 31 import sys
32 32
33 33 from IPython.config.loader import (
34 34 Config, PyFileConfigLoader, ConfigFileNotFound
35 35 )
36 36 from IPython.config.application import boolean_flag, catch_config_error, Application
37 37 from IPython.core import release
38 38 from IPython.core import usage
39 39 from IPython.core.completer import IPCompleter
40 40 from IPython.core.crashhandler import CrashHandler
41 41 from IPython.core.formatters import PlainTextFormatter
42 42 from IPython.core.history import HistoryManager
43 43 from IPython.core.prompts import PromptManager
44 44 from IPython.core.application import (
45 45 ProfileDir, BaseIPythonApplication, base_flags, base_aliases
46 46 )
47 47 from IPython.core.magics import ScriptMagics
48 48 from IPython.core.shellapp import (
49 49 InteractiveShellApp, shell_flags, shell_aliases
50 50 )
51 51 from IPython.extensions.storemagic import StoreMagics
52 52 from IPython.terminal.interactiveshell import TerminalInteractiveShell
53 53 from IPython.utils import warn
54 54 from IPython.utils.path import get_ipython_dir, check_for_old_config
55 55 from IPython.utils.traitlets import (
56 56 Bool, List, Dict,
57 57 )
58 58
59 59 #-----------------------------------------------------------------------------
60 60 # Globals, utilities and helpers
61 61 #-----------------------------------------------------------------------------
62 62
63 63 _examples = """
64 64 ipython --matplotlib # enable matplotlib integration
65 65 ipython --matplotlib=qt # enable matplotlib integration with qt4 backend
66 66
67 67 ipython --log-level=DEBUG # set logging to DEBUG
68 68 ipython --profile=foo # start with profile foo
69 69
70 70 ipython qtconsole # start the qtconsole GUI application
71 71 ipython help qtconsole # show the help for the qtconsole subcmd
72 72
73 73 ipython console # start the terminal-based console application
74 74 ipython help console # show the help for the console subcmd
75 75
76 76 ipython notebook # start the IPython notebook
77 77 ipython help notebook # show the help for the notebook subcmd
78 78
79 79 ipython profile create foo # create profile foo w/ default config files
80 80 ipython help profile # show the help for the profile subcmd
81 81
82 82 ipython locate # print the path to the IPython directory
83 83 ipython locate profile foo # print the path to the directory for profile `foo`
84 84
85 85 ipython nbconvert # convert notebooks to/from other formats
86 86 """
87 87
88 88 #-----------------------------------------------------------------------------
89 89 # Crash handler for this application
90 90 #-----------------------------------------------------------------------------
91 91
92 92 class IPAppCrashHandler(CrashHandler):
93 93 """sys.excepthook for IPython itself, leaves a detailed report on disk."""
94 94
95 95 def __init__(self, app):
96 96 contact_name = release.author
97 97 contact_email = release.author_email
98 98 bug_tracker = 'https://github.com/ipython/ipython/issues'
99 99 super(IPAppCrashHandler,self).__init__(
100 100 app, contact_name, contact_email, bug_tracker
101 101 )
102 102
103 103 def make_report(self,traceback):
104 104 """Return a string containing a crash report."""
105 105
106 106 sec_sep = self.section_sep
107 107 # Start with parent report
108 108 report = [super(IPAppCrashHandler, self).make_report(traceback)]
109 109 # Add interactive-specific info we may have
110 110 rpt_add = report.append
111 111 try:
112 112 rpt_add(sec_sep+"History of session input:")
113 113 for line in self.app.shell.user_ns['_ih']:
114 114 rpt_add(line)
115 115 rpt_add('\n*** Last line of input (may not be in above history):\n')
116 116 rpt_add(self.app.shell._last_input_line+'\n')
117 117 except:
118 118 pass
119 119
120 120 return ''.join(report)
121 121
122 122 #-----------------------------------------------------------------------------
123 123 # Aliases and Flags
124 124 #-----------------------------------------------------------------------------
125 125 flags = dict(base_flags)
126 126 flags.update(shell_flags)
127 127 frontend_flags = {}
128 128 addflag = lambda *args: frontend_flags.update(boolean_flag(*args))
129 129 addflag('autoedit-syntax', 'TerminalInteractiveShell.autoedit_syntax',
130 130 'Turn on auto editing of files with syntax errors.',
131 131 'Turn off auto editing of files with syntax errors.'
132 132 )
133 133 addflag('banner', 'TerminalIPythonApp.display_banner',
134 134 "Display a banner upon starting IPython.",
135 135 "Don't display a banner upon starting IPython."
136 136 )
137 137 addflag('confirm-exit', 'TerminalInteractiveShell.confirm_exit',
138 138 """Set to confirm when you try to exit IPython with an EOF (Control-D
139 139 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
140 140 you can force a direct exit without any confirmation.""",
141 141 "Don't prompt the user when exiting."
142 142 )
143 143 addflag('term-title', 'TerminalInteractiveShell.term_title',
144 144 "Enable auto setting the terminal title.",
145 145 "Disable auto setting the terminal title."
146 146 )
147 147 classic_config = Config()
148 148 classic_config.InteractiveShell.cache_size = 0
149 149 classic_config.PlainTextFormatter.pprint = False
150 150 classic_config.PromptManager.in_template = '>>> '
151 151 classic_config.PromptManager.in2_template = '... '
152 152 classic_config.PromptManager.out_template = ''
153 153 classic_config.InteractiveShell.separate_in = ''
154 154 classic_config.InteractiveShell.separate_out = ''
155 155 classic_config.InteractiveShell.separate_out2 = ''
156 156 classic_config.InteractiveShell.colors = 'NoColor'
157 157 classic_config.InteractiveShell.xmode = 'Plain'
158 158
159 159 frontend_flags['classic']=(
160 160 classic_config,
161 161 "Gives IPython a similar feel to the classic Python prompt."
162 162 )
163 163 # # log doesn't make so much sense this way anymore
164 164 # paa('--log','-l',
165 165 # action='store_true', dest='InteractiveShell.logstart',
166 166 # help="Start logging to the default log file (./ipython_log.py).")
167 167 #
168 168 # # quick is harder to implement
169 169 frontend_flags['quick']=(
170 170 {'TerminalIPythonApp' : {'quick' : True}},
171 171 "Enable quick startup with no config files."
172 172 )
173 173
174 174 frontend_flags['i'] = (
175 175 {'TerminalIPythonApp' : {'force_interact' : True}},
176 176 """If running code from the command line, become interactive afterwards.
177 177 Note: can also be given simply as '-i'."""
178 178 )
179 179 flags.update(frontend_flags)
180 180
181 181 aliases = dict(base_aliases)
182 182 aliases.update(shell_aliases)
183 183
184 184 #-----------------------------------------------------------------------------
185 185 # Main classes and functions
186 186 #-----------------------------------------------------------------------------
187 187
188 188
189 189 class LocateIPythonApp(BaseIPythonApplication):
190 190 description = """print the path to the IPython dir"""
191 191 subcommands = Dict(dict(
192 192 profile=('IPython.core.profileapp.ProfileLocate',
193 193 "print the path to an IPython profile directory",
194 194 ),
195 195 ))
196 196 def start(self):
197 197 if self.subapp is not None:
198 198 return self.subapp.start()
199 199 else:
200 200 print(self.ipython_dir)
201 201
202 202
203 203 class TerminalIPythonApp(BaseIPythonApplication, InteractiveShellApp):
204 204 name = u'ipython'
205 205 description = usage.cl_usage
206 206 crash_handler_class = IPAppCrashHandler
207 207 examples = _examples
208 208
209 209 flags = Dict(flags)
210 210 aliases = Dict(aliases)
211 211 classes = List()
212 212 def _classes_default(self):
213 213 """This has to be in a method, for TerminalIPythonApp to be available."""
214 214 return [
215 215 InteractiveShellApp, # ShellApp comes before TerminalApp, because
216 216 self.__class__, # it will also affect subclasses (e.g. QtConsole)
217 217 TerminalInteractiveShell,
218 218 PromptManager,
219 219 HistoryManager,
220 220 ProfileDir,
221 221 PlainTextFormatter,
222 222 IPCompleter,
223 223 ScriptMagics,
224 224 StoreMagics,
225 225 ]
226 226
227 227 subcommands = dict(
228 228 qtconsole=('IPython.qt.console.qtconsoleapp.IPythonQtConsoleApp',
229 229 """Launch the IPython Qt Console."""
230 230 ),
231 231 notebook=('IPython.html.notebookapp.NotebookApp',
232 232 """Launch the IPython HTML Notebook Server."""
233 233 ),
234 234 profile = ("IPython.core.profileapp.ProfileApp",
235 235 "Create and manage IPython profiles."
236 236 ),
237 237 kernel = ("IPython.kernel.zmq.kernelapp.IPKernelApp",
238 238 "Start a kernel without an attached frontend."
239 239 ),
240 240 console=('IPython.terminal.console.app.ZMQTerminalIPythonApp',
241 241 """Launch the IPython terminal-based Console."""
242 242 ),
243 243 locate=('IPython.terminal.ipapp.LocateIPythonApp',
244 244 LocateIPythonApp.description
245 245 ),
246 246 history=('IPython.core.historyapp.HistoryApp',
247 247 "Manage the IPython history database."
248 248 ),
249 249 nbconvert=('IPython.nbconvert.nbconvertapp.NbConvertApp',
250 250 "Convert notebooks to/from other formats."
251 251 ),
252 252 trust=('IPython.nbformat.sign.TrustNotebookApp',
253 253 "Sign notebooks to trust their potentially unsafe contents at load."
254 254 ),
255 ))
255 )
256 256 subcommands['install-nbextension'] = (
257 257 "IPython.html.nbextensions.NBExtensionApp",
258 258 "Install IPython notebook extension files"
259 259 )
260 260
261 261 # *do* autocreate requested profile, but don't create the config file.
262 262 auto_create=Bool(True)
263 263 # configurables
264 264 ignore_old_config=Bool(False, config=True,
265 265 help="Suppress warning messages about legacy config files"
266 266 )
267 267 quick = Bool(False, config=True,
268 268 help="""Start IPython quickly by skipping the loading of config files."""
269 269 )
270 270 def _quick_changed(self, name, old, new):
271 271 if new:
272 272 self.load_config_file = lambda *a, **kw: None
273 273 self.ignore_old_config=True
274 274
275 275 display_banner = Bool(True, config=True,
276 276 help="Whether to display a banner upon starting IPython."
277 277 )
278 278
279 279 # if there is code of files to run from the cmd line, don't interact
280 280 # unless the --i flag (App.force_interact) is true.
281 281 force_interact = Bool(False, config=True,
282 282 help="""If a command or file is given via the command-line,
283 283 e.g. 'ipython foo.py', start an interactive shell after executing the
284 284 file or command."""
285 285 )
286 286 def _force_interact_changed(self, name, old, new):
287 287 if new:
288 288 self.interact = True
289 289
290 290 def _file_to_run_changed(self, name, old, new):
291 291 if new:
292 292 self.something_to_run = True
293 293 if new and not self.force_interact:
294 294 self.interact = False
295 295 _code_to_run_changed = _file_to_run_changed
296 296 _module_to_run_changed = _file_to_run_changed
297 297
298 298 # internal, not-configurable
299 299 interact=Bool(True)
300 300 something_to_run=Bool(False)
301 301
302 302 def parse_command_line(self, argv=None):
303 303 """override to allow old '-pylab' flag with deprecation warning"""
304 304
305 305 argv = sys.argv[1:] if argv is None else argv
306 306
307 307 if '-pylab' in argv:
308 308 # deprecated `-pylab` given,
309 309 # warn and transform into current syntax
310 310 argv = argv[:] # copy, don't clobber
311 311 idx = argv.index('-pylab')
312 312 warn.warn("`-pylab` flag has been deprecated.\n"
313 313 " Use `--matplotlib <backend>` and import pylab manually.")
314 314 argv[idx] = '--pylab'
315 315
316 316 return super(TerminalIPythonApp, self).parse_command_line(argv)
317 317
318 318 @catch_config_error
319 319 def initialize(self, argv=None):
320 320 """Do actions after construct, but before starting the app."""
321 321 super(TerminalIPythonApp, self).initialize(argv)
322 322 if self.subapp is not None:
323 323 # don't bother initializing further, starting subapp
324 324 return
325 325 if not self.ignore_old_config:
326 326 check_for_old_config(self.ipython_dir)
327 327 # print self.extra_args
328 328 if self.extra_args and not self.something_to_run:
329 329 self.file_to_run = self.extra_args[0]
330 330 self.init_path()
331 331 # create the shell
332 332 self.init_shell()
333 333 # and draw the banner
334 334 self.init_banner()
335 335 # Now a variety of things that happen after the banner is printed.
336 336 self.init_gui_pylab()
337 337 self.init_extensions()
338 338 self.init_code()
339 339
340 340 def init_shell(self):
341 341 """initialize the InteractiveShell instance"""
342 342 # Create an InteractiveShell instance.
343 343 # shell.display_banner should always be False for the terminal
344 344 # based app, because we call shell.show_banner() by hand below
345 345 # so the banner shows *before* all extension loading stuff.
346 346 self.shell = TerminalInteractiveShell.instance(parent=self,
347 347 display_banner=False, profile_dir=self.profile_dir,
348 348 ipython_dir=self.ipython_dir, user_ns=self.user_ns)
349 349 self.shell.configurables.append(self)
350 350
351 351 def init_banner(self):
352 352 """optionally display the banner"""
353 353 if self.display_banner and self.interact:
354 354 self.shell.show_banner()
355 355 # Make sure there is a space below the banner.
356 356 if self.log_level <= logging.INFO: print()
357 357
358 358 def _pylab_changed(self, name, old, new):
359 359 """Replace --pylab='inline' with --pylab='auto'"""
360 360 if new == 'inline':
361 361 warn.warn("'inline' not available as pylab backend, "
362 362 "using 'auto' instead.")
363 363 self.pylab = 'auto'
364 364
365 365 def start(self):
366 366 if self.subapp is not None:
367 367 return self.subapp.start()
368 368 # perform any prexec steps:
369 369 if self.interact:
370 370 self.log.debug("Starting IPython's mainloop...")
371 371 self.shell.mainloop()
372 372 else:
373 373 self.log.debug("IPython not interactive...")
374 374
375 375 def load_default_config(ipython_dir=None):
376 376 """Load the default config file from the default ipython_dir.
377 377
378 378 This is useful for embedded shells.
379 379 """
380 380 if ipython_dir is None:
381 381 ipython_dir = get_ipython_dir()
382 382
383 383 profile_dir = os.path.join(ipython_dir, 'profile_default')
384 384
385 385 config = Config()
386 386 for cf in Application._load_config_files("ipython_config", path=profile_dir):
387 387 config.update(cf)
388 388
389 389 return config
390 390
391 391 launch_new_instance = TerminalIPythonApp.launch_instance
392 392
393 393
394 394 if __name__ == '__main__':
395 395 launch_new_instance()
General Comments 0
You need to be logged in to leave comments. Login now