##// END OF EJS Templates
Added the command line option
Nicolas Rougier -
Show More
@@ -1,393 +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 gui = CaselessStrEnum(('qt','wx','gtk', 'pyglet'), config=True,
233 help="Enable GUI event loop integration ('qt', 'wx', 'gtk', 'pyglet')."
232 gui = CaselessStrEnum(('qt', 'wx', 'gtk', 'glut', 'pyglet'), config=True,
233 help="Enable GUI event loop integration ('qt', 'wx', 'gtk', 'glut', 'pyglet')."
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 349 if self.pylab:
350 350 activate(gui, import_all=self.pylab_import_all)
351 351 else:
352 352 activate(gui)
353 353 except:
354 354 self.log.warn("Error in enabling GUI event loop integration:")
355 355 self.shell.showtraceback()
356 356
357 357 def start(self):
358 358 if self.subapp is not None:
359 359 return self.subapp.start()
360 360 # perform any prexec steps:
361 361 if self.interact:
362 362 self.log.debug("Starting IPython's mainloop...")
363 363 self.shell.mainloop()
364 364 else:
365 365 self.log.debug("IPython not interactive...")
366 366
367 367
368 368 def load_default_config(ipython_dir=None):
369 369 """Load the default config file from the default ipython_dir.
370 370
371 371 This is useful for embedded shells.
372 372 """
373 373 if ipython_dir is None:
374 374 ipython_dir = get_ipython_dir()
375 375 profile_dir = os.path.join(ipython_dir, 'profile_default')
376 376 cl = PyFileConfigLoader(default_config_file_name, profile_dir)
377 377 try:
378 378 config = cl.load_config()
379 379 except IOError:
380 380 # no config found
381 381 config = Config()
382 382 return config
383 383
384 384
385 385 def launch_new_instance():
386 386 """Create and run a full blown IPython instance"""
387 387 app = TerminalIPythonApp.instance()
388 388 app.initialize()
389 389 app.start()
390 390
391 391
392 392 if __name__ == '__main__':
393 393 launch_new_instance()
General Comments 0
You need to be logged in to leave comments. Login now