##// END OF EJS Templates
documentation update
Paul Ivanov -
Show More
@@ -1,402 +1,405 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-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
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, ConfigFileNotFound
34 34 )
35 35 from IPython.config.application import boolean_flag, catch_config_error
36 36 from IPython.core import release
37 37 from IPython.core import usage
38 38 from IPython.core.completer import IPCompleter
39 39 from IPython.core.crashhandler import CrashHandler
40 40 from IPython.core.formatters import PlainTextFormatter
41 41 from IPython.core.prompts import PromptManager
42 42 from IPython.core.application import (
43 43 ProfileDir, BaseIPythonApplication, base_flags, base_aliases
44 44 )
45 45 from IPython.core.shellapp import (
46 46 InteractiveShellApp, shell_flags, shell_aliases
47 47 )
48 48 from IPython.frontend.terminal.interactiveshell import TerminalInteractiveShell
49 49 from IPython.lib import inputhook
50 50 from IPython.utils import warn
51 51 from IPython.utils.path import get_ipython_dir, check_for_old_config
52 52 from IPython.utils.traitlets import (
53 53 Bool, List, Dict, CaselessStrEnum
54 54 )
55 55
56 56 #-----------------------------------------------------------------------------
57 57 # Globals, utilities and helpers
58 58 #-----------------------------------------------------------------------------
59 59
60 60 #: The default config file name for this application.
61 61 default_config_file_name = u'ipython_config.py'
62 62
63 63 _examples = """
64 64 ipython --pylab # start in pylab mode
65 65 ipython --pylab=qt # start in pylab mode with the qt4 backend
66 66 ipython --log-level=DEBUG # set logging to DEBUG
67 67 ipython --profile=foo # start with profile foo
68 68
69 69 ipython qtconsole # start the qtconsole GUI application
70 70 ipython qtconsole -h # show the help string for the qtconsole subcmd
71 71
72 ipython console # start the terminal-based console application
73 ipython console -h # show the help string for the console subcmd
74
72 75 ipython profile create foo # create profile foo w/ default config files
73 76 ipython profile -h # show the help string for the profile subcmd
74 77 """
75 78
76 79 #-----------------------------------------------------------------------------
77 80 # Crash handler for this application
78 81 #-----------------------------------------------------------------------------
79 82
80 83 class IPAppCrashHandler(CrashHandler):
81 84 """sys.excepthook for IPython itself, leaves a detailed report on disk."""
82 85
83 86 def __init__(self, app):
84 87 contact_name = release.authors['Fernando'][0]
85 88 contact_email = release.author_email
86 89 bug_tracker = 'https://github.com/ipython/ipython/issues'
87 90 super(IPAppCrashHandler,self).__init__(
88 91 app, contact_name, contact_email, bug_tracker
89 92 )
90 93
91 94 def make_report(self,traceback):
92 95 """Return a string containing a crash report."""
93 96
94 97 sec_sep = self.section_sep
95 98 # Start with parent report
96 99 report = [super(IPAppCrashHandler, self).make_report(traceback)]
97 100 # Add interactive-specific info we may have
98 101 rpt_add = report.append
99 102 try:
100 103 rpt_add(sec_sep+"History of session input:")
101 104 for line in self.app.shell.user_ns['_ih']:
102 105 rpt_add(line)
103 106 rpt_add('\n*** Last line of input (may not be in above history):\n')
104 107 rpt_add(self.app.shell._last_input_line+'\n')
105 108 except:
106 109 pass
107 110
108 111 return ''.join(report)
109 112
110 113 #-----------------------------------------------------------------------------
111 114 # Aliases and Flags
112 115 #-----------------------------------------------------------------------------
113 116 flags = dict(base_flags)
114 117 flags.update(shell_flags)
115 118 addflag = lambda *args: flags.update(boolean_flag(*args))
116 119 addflag('autoedit-syntax', 'TerminalInteractiveShell.autoedit_syntax',
117 120 'Turn on auto editing of files with syntax errors.',
118 121 'Turn off auto editing of files with syntax errors.'
119 122 )
120 123 addflag('banner', 'TerminalIPythonApp.display_banner',
121 124 "Display a banner upon starting IPython.",
122 125 "Don't display a banner upon starting IPython."
123 126 )
124 127 addflag('confirm-exit', 'TerminalInteractiveShell.confirm_exit',
125 128 """Set to confirm when you try to exit IPython with an EOF (Control-D
126 129 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
127 130 you can force a direct exit without any confirmation.""",
128 131 "Don't prompt the user when exiting."
129 132 )
130 133 addflag('term-title', 'TerminalInteractiveShell.term_title',
131 134 "Enable auto setting the terminal title.",
132 135 "Disable auto setting the terminal title."
133 136 )
134 137 classic_config = Config()
135 138 classic_config.InteractiveShell.cache_size = 0
136 139 classic_config.PlainTextFormatter.pprint = False
137 140 classic_config.PromptManager.in_template = '>>> '
138 141 classic_config.PromptManager.in2_template = '... '
139 142 classic_config.PromptManager.out_template = ''
140 143 classic_config.InteractiveShell.separate_in = ''
141 144 classic_config.InteractiveShell.separate_out = ''
142 145 classic_config.InteractiveShell.separate_out2 = ''
143 146 classic_config.InteractiveShell.colors = 'NoColor'
144 147 classic_config.InteractiveShell.xmode = 'Plain'
145 148
146 149 flags['classic']=(
147 150 classic_config,
148 151 "Gives IPython a similar feel to the classic Python prompt."
149 152 )
150 153 # # log doesn't make so much sense this way anymore
151 154 # paa('--log','-l',
152 155 # action='store_true', dest='InteractiveShell.logstart',
153 156 # help="Start logging to the default log file (./ipython_log.py).")
154 157 #
155 158 # # quick is harder to implement
156 159 flags['quick']=(
157 160 {'TerminalIPythonApp' : {'quick' : True}},
158 161 "Enable quick startup with no config files."
159 162 )
160 163
161 164 flags['i'] = (
162 165 {'TerminalIPythonApp' : {'force_interact' : True}},
163 166 """If running code from the command line, become interactive afterwards.
164 167 Note: can also be given simply as '-i.'"""
165 168 )
166 169 flags['pylab'] = (
167 170 {'TerminalIPythonApp' : {'pylab' : 'auto'}},
168 171 """Pre-load matplotlib and numpy for interactive use with
169 172 the default matplotlib backend."""
170 173 )
171 174
172 175 aliases = dict(base_aliases)
173 176 aliases.update(shell_aliases)
174 177
175 178 # it's possible we don't want short aliases for *all* of these:
176 179 aliases.update(dict(
177 180 gui='TerminalIPythonApp.gui',
178 181 pylab='TerminalIPythonApp.pylab',
179 182 ))
180 183
181 184 #-----------------------------------------------------------------------------
182 185 # Main classes and functions
183 186 #-----------------------------------------------------------------------------
184 187
185 188 class TerminalIPythonApp(BaseIPythonApplication, InteractiveShellApp):
186 189 name = u'ipython'
187 190 description = usage.cl_usage
188 191 default_config_file_name = default_config_file_name
189 192 crash_handler_class = IPAppCrashHandler
190 193 examples = _examples
191 194
192 195 flags = Dict(flags)
193 196 aliases = Dict(aliases)
194 197 classes = List()
195 198 def _classes_default(self):
196 199 """This has to be in a method, for TerminalIPythonApp to be available."""
197 200 return [
198 201 InteractiveShellApp, # ShellApp comes before TerminalApp, because
199 202 self.__class__, # it will also affect subclasses (e.g. QtConsole)
200 203 TerminalInteractiveShell,
201 204 PromptManager,
202 205 ProfileDir,
203 206 PlainTextFormatter,
204 207 IPCompleter,
205 208 ]
206 209
207 210 subcommands = Dict(dict(
208 211 qtconsole=('IPython.frontend.qt.console.qtconsoleapp.IPythonQtConsoleApp',
209 212 """Launch the IPython Qt Console."""
210 213 ),
211 214 notebook=('IPython.frontend.html.notebook.notebookapp.NotebookApp',
212 """Launch the IPython HTML Notebook Server"""
215 """Launch the IPython HTML Notebook Server."""
213 216 ),
214 217 profile = ("IPython.core.profileapp.ProfileApp",
215 218 "Create and manage IPython profiles."
216 219 ),
217 220 kernel = ("IPython.zmq.ipkernel.IPKernelApp",
218 221 "Start a kernel without an attached frontend."
219 222 ),
220 zmq=('IPython.frontend.zmqterminal.app.ZMQTerminalIPythonApp',
221 """Launch two-process Terminal session with 0MQ."""
223 console=('IPython.frontend.zmqterminal.app.ZMQTerminalIPythonApp',
224 """Launch the IPython terminal-based Console."""
222 225 ),
223 226 ))
224 227
225 228 # *do* autocreate requested profile, but don't create the config file.
226 229 auto_create=Bool(True)
227 230 # configurables
228 231 ignore_old_config=Bool(False, config=True,
229 232 help="Suppress warning messages about legacy config files"
230 233 )
231 234 quick = Bool(False, config=True,
232 235 help="""Start IPython quickly by skipping the loading of config files."""
233 236 )
234 237 def _quick_changed(self, name, old, new):
235 238 if new:
236 239 self.load_config_file = lambda *a, **kw: None
237 240 self.ignore_old_config=True
238 241
239 242 gui = CaselessStrEnum(('qt', 'wx', 'gtk', 'glut', 'pyglet'), config=True,
240 243 help="Enable GUI event loop integration ('qt', 'wx', 'gtk', 'glut', 'pyglet')."
241 244 )
242 245 pylab = CaselessStrEnum(['tk', 'qt', 'wx', 'gtk', 'osx', 'auto'],
243 246 config=True,
244 247 help="""Pre-load matplotlib and numpy for interactive use,
245 248 selecting a particular matplotlib backend and loop integration.
246 249 """
247 250 )
248 251 display_banner = Bool(True, config=True,
249 252 help="Whether to display a banner upon starting IPython."
250 253 )
251 254
252 255 # if there is code of files to run from the cmd line, don't interact
253 256 # unless the --i flag (App.force_interact) is true.
254 257 force_interact = Bool(False, config=True,
255 258 help="""If a command or file is given via the command-line,
256 259 e.g. 'ipython foo.py"""
257 260 )
258 261 def _force_interact_changed(self, name, old, new):
259 262 if new:
260 263 self.interact = True
261 264
262 265 def _file_to_run_changed(self, name, old, new):
263 266 if new and not self.force_interact:
264 267 self.interact = False
265 268 _code_to_run_changed = _file_to_run_changed
266 269
267 270 # internal, not-configurable
268 271 interact=Bool(True)
269 272
270 273
271 274 def parse_command_line(self, argv=None):
272 275 """override to allow old '-pylab' flag with deprecation warning"""
273 276
274 277 argv = sys.argv[1:] if argv is None else argv
275 278
276 279 if '-pylab' in argv:
277 280 # deprecated `-pylab` given,
278 281 # warn and transform into current syntax
279 282 argv = argv[:] # copy, don't clobber
280 283 idx = argv.index('-pylab')
281 284 warn.warn("`-pylab` flag has been deprecated.\n"
282 285 " Use `--pylab` instead, or `--pylab=foo` to specify a backend.")
283 286 sub = '--pylab'
284 287 if len(argv) > idx+1:
285 288 # check for gui arg, as in '-pylab qt'
286 289 gui = argv[idx+1]
287 290 if gui in ('wx', 'qt', 'qt4', 'gtk', 'auto'):
288 291 sub = '--pylab='+gui
289 292 argv.pop(idx+1)
290 293 argv[idx] = sub
291 294
292 295 return super(TerminalIPythonApp, self).parse_command_line(argv)
293 296
294 297 @catch_config_error
295 298 def initialize(self, argv=None):
296 299 """Do actions after construct, but before starting the app."""
297 300 super(TerminalIPythonApp, self).initialize(argv)
298 301 if self.subapp is not None:
299 302 # don't bother initializing further, starting subapp
300 303 return
301 304 if not self.ignore_old_config:
302 305 check_for_old_config(self.ipython_dir)
303 306 # print self.extra_args
304 307 if self.extra_args:
305 308 self.file_to_run = self.extra_args[0]
306 309 # create the shell
307 310 self.init_shell()
308 311 # and draw the banner
309 312 self.init_banner()
310 313 # Now a variety of things that happen after the banner is printed.
311 314 self.init_gui_pylab()
312 315 self.init_extensions()
313 316 self.init_code()
314 317
315 318 def init_shell(self):
316 319 """initialize the InteractiveShell instance"""
317 320 # I am a little hesitant to put these into InteractiveShell itself.
318 321 # But that might be the place for them
319 322 sys.path.insert(0, '')
320 323
321 324 # Create an InteractiveShell instance.
322 325 # shell.display_banner should always be False for the terminal
323 326 # based app, because we call shell.show_banner() by hand below
324 327 # so the banner shows *before* all extension loading stuff.
325 328 self.shell = TerminalInteractiveShell.instance(config=self.config,
326 329 display_banner=False, profile_dir=self.profile_dir,
327 330 ipython_dir=self.ipython_dir)
328 331 self.shell.configurables.append(self)
329 332
330 333 def init_banner(self):
331 334 """optionally display the banner"""
332 335 if self.display_banner and self.interact:
333 336 self.shell.show_banner()
334 337 # Make sure there is a space below the banner.
335 338 if self.log_level <= logging.INFO: print
336 339
337 340
338 341 def init_gui_pylab(self):
339 342 """Enable GUI event loop integration, taking pylab into account."""
340 343 gui = self.gui
341 344
342 345 # Using `pylab` will also require gui activation, though which toolkit
343 346 # to use may be chosen automatically based on mpl configuration.
344 347 if self.pylab:
345 348 activate = self.shell.enable_pylab
346 349 if self.pylab == 'auto':
347 350 gui = None
348 351 else:
349 352 gui = self.pylab
350 353 else:
351 354 # Enable only GUI integration, no pylab
352 355 activate = inputhook.enable_gui
353 356
354 357 if gui or self.pylab:
355 358 try:
356 359 self.log.info("Enabling GUI event loop integration, "
357 360 "toolkit=%s, pylab=%s" % (gui, self.pylab) )
358 361 if self.pylab:
359 362 activate(gui, import_all=self.pylab_import_all)
360 363 else:
361 364 activate(gui)
362 365 except:
363 366 self.log.warn("Error in enabling GUI event loop integration:")
364 367 self.shell.showtraceback()
365 368
366 369 def start(self):
367 370 if self.subapp is not None:
368 371 return self.subapp.start()
369 372 # perform any prexec steps:
370 373 if self.interact:
371 374 self.log.debug("Starting IPython's mainloop...")
372 375 self.shell.mainloop()
373 376 else:
374 377 self.log.debug("IPython not interactive...")
375 378
376 379
377 380 def load_default_config(ipython_dir=None):
378 381 """Load the default config file from the default ipython_dir.
379 382
380 383 This is useful for embedded shells.
381 384 """
382 385 if ipython_dir is None:
383 386 ipython_dir = get_ipython_dir()
384 387 profile_dir = os.path.join(ipython_dir, 'profile_default')
385 388 cl = PyFileConfigLoader(default_config_file_name, profile_dir)
386 389 try:
387 390 config = cl.load_config()
388 391 except ConfigFileNotFound:
389 392 # no config found
390 393 config = Config()
391 394 return config
392 395
393 396
394 397 def launch_new_instance():
395 398 """Create and run a full blown IPython instance"""
396 399 app = TerminalIPythonApp.instance()
397 400 app.initialize()
398 401 app.start()
399 402
400 403
401 404 if __name__ == '__main__':
402 405 launch_new_instance()
@@ -1,101 +1,120 b''
1 1 """ A minimal application using the ZMQ-based terminal IPython frontend.
2 2
3 3 This is not a complete console app, as subprocess will not be able to receive
4 4 input, there is no real readline support, among other limitations.
5 5
6 6 Authors:
7 7
8 8 * Min RK
9 9 * Paul Ivanov
10 10
11 11 """
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16 import signal
17 17 import sys
18 18 import time
19 19
20 20 from IPython.frontend.terminal.ipapp import TerminalIPythonApp
21 21
22 22 from IPython.utils.traitlets import (
23 23 Dict, List, Unicode, Int, CaselessStrEnum, CBool, Any
24 24 )
25 25 from IPython.zmq.ipkernel import IPKernelApp
26 26 from IPython.zmq.session import Session, default_secure
27 27 from IPython.zmq.zmqshell import ZMQInteractiveShell
28 28 from IPython.frontend.kernelmixinapp import (
29 29 IPythonMixinConsoleApp, app_aliases, app_flags
30 30 )
31 31
32 32 from IPython.frontend.zmqterminal.interactiveshell import ZMQTerminalInteractiveShell
33 33
34 34 #-----------------------------------------------------------------------------
35 35 # Globals
36 36 #-----------------------------------------------------------------------------
37 37
38 38 _examples = """
39 39 ipython console # start the ZMQ-based console
40 ipython console --pylab # start with pylab plotting mode
40 ipython console --existing # connect to an existing ipython session
41 41 """
42 42
43 43 #-----------------------------------------------------------------------------
44 44 # Flags and Aliases
45 45 #-----------------------------------------------------------------------------
46 46
47 47 # XXX: the app_flags should really be flags from the mixin
48 48 flags = dict(app_flags)
49 49 frontend_flags = { }
50 50 flags.update(frontend_flags)
51 51
52 52 frontend_flags = frontend_flags.keys()
53 53
54 54 aliases = dict(app_aliases)
55 55
56 56 frontend_aliases = dict()
57 57
58 58 aliases.update(frontend_aliases)
59 59
60 60 #-----------------------------------------------------------------------------
61 61 # Classes
62 62 #-----------------------------------------------------------------------------
63 63
64 64
65 65 class ZMQTerminalIPythonApp(TerminalIPythonApp, IPythonMixinConsoleApp):
66 name = "ipython console"
66 67 """Start a terminal frontend to the IPython zmq kernel."""
67
68
69 description = """
70 The IPython terminal-based Console.
71
72 This launches a Console application inside a terminal.
73
74 The Console supports various extra features beyond the traditional
75 single-process Terminal IPython shell, such as connecting to an
76 existing ipython session, via:
77
78 ipython console --existing
79
80 where the previous session could have been created by another ipython
81 console, an ipython qtconsole, or by opening an ipython notebook.
82
83 """
84 examples = _examples
85
68 86 classes = List([IPKernelApp, ZMQTerminalInteractiveShell])
69 87 flags = Dict(flags)
70 88 aliases = Dict(aliases)
89 subcommands = Dict()
71 90 def parse_command_line(self, argv=None):
72 91 super(ZMQTerminalIPythonApp, self).parse_command_line(argv)
73 92 IPythonMixinConsoleApp.parse_command_line(self,argv)
74 93 self.swallow_args(frontend_aliases,frontend_flags,argv=argv)
75 94
76 95 def init_shell(self):
77 96 IPythonMixinConsoleApp.initialize(self)
78 97 # relay sigint to kernel
79 98 signal.signal(signal.SIGINT, self.handle_sigint)
80 99 self.shell = ZMQTerminalInteractiveShell.instance(config=self.config,
81 100 display_banner=False, profile_dir=self.profile_dir,
82 101 ipython_dir=self.ipython_dir, kernel_manager=self.kernel_manager)
83 102
84 103 def handle_sigint(self, *args):
85 104 self.shell.write('KeyboardInterrupt\n')
86 105 self.kernel_manager.interrupt_kernel()
87 106
88 107 def init_code(self):
89 108 # no-op in the frontend, code gets run in the backend
90 109 pass
91 110
92 111 def launch_new_instance():
93 112 """Create and run a full blown IPython instance"""
94 113 app = ZMQTerminalIPythonApp.instance()
95 114 app.initialize()
96 115 app.start()
97 116
98 117
99 118 if __name__ == '__main__':
100 119 launch_new_instance()
101 120
General Comments 0
You need to be logged in to leave comments. Login now