##// END OF EJS Templates
Remove dead code accidentally left over in prior refactor.
Fernando Perez -
Show More
@@ -1,431 +1,404 b''
1 1 #!/usr/bin/env python
2 2 # encoding: utf-8
3 3 """
4 4 An application for IPython.
5 5
6 6 All top-level applications should use the classes in this module for
7 7 handling configuration and creating componenets.
8 8
9 9 The job of an :class:`Application` is to create the master configuration
10 10 object and then create the components, passing the config to them.
11 11
12 12 Authors:
13 13
14 14 * Brian Granger
15 15 * Fernando Perez
16 16
17 17 Notes
18 18 -----
19 19 """
20 20
21 21 #-----------------------------------------------------------------------------
22 22 # Copyright (C) 2008-2009 The IPython Development Team
23 23 #
24 24 # Distributed under the terms of the BSD License. The full license is in
25 25 # the file COPYING, distributed as part of this software.
26 26 #-----------------------------------------------------------------------------
27 27
28 28 #-----------------------------------------------------------------------------
29 29 # Imports
30 30 #-----------------------------------------------------------------------------
31 31
32 32 import logging
33 33 import os
34 34 import sys
35 35
36 36 from IPython.core import release, crashhandler
37 37 from IPython.utils.genutils import get_ipython_dir, get_ipython_package_dir
38 38 from IPython.config.loader import (
39 39 PyFileConfigLoader,
40 40 ArgParseConfigLoader,
41 41 Config,
42 42 NoConfigDefault
43 43 )
44 44
45 45 #-----------------------------------------------------------------------------
46 46 # Classes and functions
47 47 #-----------------------------------------------------------------------------
48 48
49
50 class BaseAppArgParseConfigLoader(ArgParseConfigLoader):
51 """Default command line options for IPython based applications."""
52
53 def _add_other_arguments(self):
54 self.parser.add_argument('--ipython-dir',
55 dest='Global.ipython_dir',type=unicode,
56 help='Set to override default location of Global.ipython_dir.',
57 default=NoConfigDefault,
58 metavar='Global.ipython_dir')
59 self.parser.add_argument('-p', '--profile',
60 dest='Global.profile',type=unicode,
61 help='The string name of the ipython profile to be used.',
62 default=NoConfigDefault,
63 metavar='Global.profile')
64 self.parser.add_argument('--log-level',
65 dest="Global.log_level",type=int,
66 help='Set the log level (0,10,20,30,40,50). Default is 30.',
67 default=NoConfigDefault,
68 metavar='Global.log_level')
69 self.parser.add_argument('--config-file',
70 dest='Global.config_file',type=unicode,
71 help='Set the config file name to override default.',
72 default=NoConfigDefault,
73 metavar='Global.config_file')
74
75
76 49 class ApplicationError(Exception):
77 50 pass
78 51
79 52
80 53 app_cl_args = (
81 54 (('--ipython-dir', ), dict(
82 55 dest='Global.ipython_dir',type=unicode,
83 56 help='Set to override default location of Global.ipython_dir.',
84 57 default=NoConfigDefault,
85 58 metavar='Global.ipython_dir') ),
86 59 (('-p', '--profile',), dict(
87 60 dest='Global.profile',type=unicode,
88 61 help='The string name of the ipython profile to be used.',
89 62 default=NoConfigDefault,
90 63 metavar='Global.profile') ),
91 64 (('--log-level',), dict(
92 65 dest="Global.log_level",type=int,
93 66 help='Set the log level (0,10,20,30,40,50). Default is 30.',
94 67 default=NoConfigDefault,
95 68 metavar='Global.log_level')),
96 69 (('--config-file',), dict(
97 70 dest='Global.config_file',type=unicode,
98 71 help='Set the config file name to override default.',
99 72 default=NoConfigDefault,
100 73 metavar='Global.config_file')),
101 74 )
102 75
103 76 class Application(object):
104 77 """Load a config, construct components and set them running."""
105 78
106 79 name = u'ipython'
107 80 description = 'IPython: an enhanced interactive Python shell.'
108 81
109 82 config_file_name = u'ipython_config.py'
110 83 # Track the default and actual separately because some messages are
111 84 # only printed if we aren't using the default.
112 85 default_config_file_name = config_file_name
113 86 default_log_level = logging.WARN
114 87 # Set by --profile option
115 88 profile_name = None
116 89 #: User's ipython directory, typically ~/.ipython/
117 90 ipython_dir = None
118 91 #: A reference to the argv to be used (typically ends up being sys.argv[1:])
119 92 argv = None
120 93 #: Default command line arguments. Subclasses should create a new tuple
121 94 #: that *includes* these.
122 95 cl_arguments = app_cl_args
123 96
124 97 # Private attributes
125 98 _exiting = False
126 99 _initialized = False
127 100
128 101 # Class choices for things that will be instantiated at runtime.
129 102 _CrashHandler = crashhandler.CrashHandler
130 103
131 104 def __init__(self, argv=None):
132 105 self.argv = sys.argv[1:] if argv is None else argv
133 106 self.init_logger()
134 107
135 108 def init_logger(self):
136 109 self.log = logging.getLogger(self.__class__.__name__)
137 110 # This is used as the default until the command line arguments are read.
138 111 self.log.setLevel(self.default_log_level)
139 112 self._log_handler = logging.StreamHandler()
140 113 self._log_formatter = logging.Formatter("[%(name)s] %(message)s")
141 114 self._log_handler.setFormatter(self._log_formatter)
142 115 self.log.addHandler(self._log_handler)
143 116
144 117 def _set_log_level(self, level):
145 118 self.log.setLevel(level)
146 119
147 120 def _get_log_level(self):
148 121 return self.log.level
149 122
150 123 log_level = property(_get_log_level, _set_log_level)
151 124
152 125 def initialize(self):
153 126 """Start the application."""
154 127
155 128 if self._initialized:
156 129 return
157 130
158 131 # The first part is protected with an 'attempt' wrapper, that will log
159 132 # failures with the basic system traceback machinery. Once our crash
160 133 # handler is in place, we can let any subsequent exception propagate,
161 134 # as our handler will log it with much better detail than the default.
162 135 self.attempt(self.create_crash_handler)
163 136 self.create_default_config()
164 137 self.log_default_config()
165 138 self.set_default_config_log_level()
166 139 self.pre_load_command_line_config()
167 140 self.load_command_line_config()
168 141 self.set_command_line_config_log_level()
169 142 self.post_load_command_line_config()
170 143 self.log_command_line_config()
171 144 self.find_ipython_dir()
172 145 self.find_resources()
173 146 self.find_config_file_name()
174 147 self.find_config_file_paths()
175 148 self.pre_load_file_config()
176 149 self.load_file_config()
177 150 self.set_file_config_log_level()
178 151 self.post_load_file_config()
179 152 self.log_file_config()
180 153 self.merge_configs()
181 154 self.log_master_config()
182 155 self.pre_construct()
183 156 self.construct()
184 157 self.post_construct()
185 158 self._initialized = True
186 159
187 160 def start(self):
188 161 self.initialize()
189 162 self.start_app()
190 163
191 164 #-------------------------------------------------------------------------
192 165 # Various stages of Application creation
193 166 #-------------------------------------------------------------------------
194 167
195 168 def create_crash_handler(self):
196 169 """Create a crash handler, typically setting sys.excepthook to it."""
197 170 self.crash_handler = self._CrashHandler(self, self.name)
198 171 sys.excepthook = self.crash_handler
199 172
200 173 def create_default_config(self):
201 174 """Create defaults that can't be set elsewhere.
202 175
203 176 For the most part, we try to set default in the class attributes
204 177 of Components. But, defaults the top-level Application (which is
205 178 not a HasTraitlets or Component) are not set in this way. Instead
206 179 we set them here. The Global section is for variables like this that
207 180 don't belong to a particular component.
208 181 """
209 182 c = Config()
210 183 c.Global.ipython_dir = get_ipython_dir()
211 184 c.Global.log_level = self.log_level
212 185 self.default_config = c
213 186
214 187 def log_default_config(self):
215 188 self.log.debug('Default config loaded:')
216 189 self.log.debug(repr(self.default_config))
217 190
218 191 def set_default_config_log_level(self):
219 192 try:
220 193 self.log_level = self.default_config.Global.log_level
221 194 except AttributeError:
222 195 # Fallback to the default_log_level class attribute
223 196 pass
224 197
225 198 def create_command_line_config(self):
226 199 """Create and return a command line config loader."""
227 200 return ArgParseConfigLoader(self.argv, self.cl_arguments,
228 201 description=self.description,
229 202 version=release.version)
230 203
231 204 def pre_load_command_line_config(self):
232 205 """Do actions just before loading the command line config."""
233 206 pass
234 207
235 208 def load_command_line_config(self):
236 209 """Load the command line config."""
237 210 loader = self.create_command_line_config()
238 211 self.command_line_config = loader.load_config()
239 212 self.extra_args = loader.get_extra_args()
240 213
241 214 def set_command_line_config_log_level(self):
242 215 try:
243 216 self.log_level = self.command_line_config.Global.log_level
244 217 except AttributeError:
245 218 pass
246 219
247 220 def post_load_command_line_config(self):
248 221 """Do actions just after loading the command line config."""
249 222 pass
250 223
251 224 def log_command_line_config(self):
252 225 self.log.debug("Command line config loaded:")
253 226 self.log.debug(repr(self.command_line_config))
254 227
255 228 def find_ipython_dir(self):
256 229 """Set the IPython directory.
257 230
258 231 This sets ``self.ipython_dir``, but the actual value that is passed to
259 232 the application is kept in either ``self.default_config`` or
260 233 ``self.command_line_config``. This also adds ``self.ipython_dir`` to
261 234 ``sys.path`` so config files there can be referenced by other config
262 235 files.
263 236 """
264 237
265 238 try:
266 239 self.ipython_dir = self.command_line_config.Global.ipython_dir
267 240 except AttributeError:
268 241 self.ipython_dir = self.default_config.Global.ipython_dir
269 242 sys.path.append(os.path.abspath(self.ipython_dir))
270 243 if not os.path.isdir(self.ipython_dir):
271 244 os.makedirs(self.ipython_dir, mode=0777)
272 245 self.log.debug("IPYTHON_DIR set to: %s" % self.ipython_dir)
273 246
274 247 def find_resources(self):
275 248 """Find other resources that need to be in place.
276 249
277 250 Things like cluster directories need to be in place to find the
278 251 config file. These happen right after the IPython directory has
279 252 been set.
280 253 """
281 254 pass
282 255
283 256 def find_config_file_name(self):
284 257 """Find the config file name for this application.
285 258
286 259 This must set ``self.config_file_name`` to the filename of the
287 260 config file to use (just the filename). The search paths for the
288 261 config file are set in :meth:`find_config_file_paths` and then passed
289 262 to the config file loader where they are resolved to an absolute path.
290 263
291 264 If a profile has been set at the command line, this will resolve it.
292 265 """
293 266
294 267 try:
295 268 self.config_file_name = self.command_line_config.Global.config_file
296 269 except AttributeError:
297 270 pass
298 271
299 272 try:
300 273 self.profile_name = self.command_line_config.Global.profile
301 274 except AttributeError:
302 275 pass
303 276 else:
304 277 name_parts = self.config_file_name.split('.')
305 278 name_parts.insert(1, u'_' + self.profile_name + u'.')
306 279 self.config_file_name = ''.join(name_parts)
307 280
308 281 def find_config_file_paths(self):
309 282 """Set the search paths for resolving the config file.
310 283
311 284 This must set ``self.config_file_paths`` to a sequence of search
312 285 paths to pass to the config file loader.
313 286 """
314 287 # Include our own profiles directory last, so that users can still find
315 288 # our shipped copies of builtin profiles even if they don't have them
316 289 # in their local ipython directory.
317 290 prof_dir = os.path.join(get_ipython_package_dir(), 'config', 'profile')
318 291 self.config_file_paths = (os.getcwd(), self.ipython_dir, prof_dir)
319 292
320 293 def pre_load_file_config(self):
321 294 """Do actions before the config file is loaded."""
322 295 pass
323 296
324 297 def load_file_config(self):
325 298 """Load the config file.
326 299
327 300 This tries to load the config file from disk. If successful, the
328 301 ``CONFIG_FILE`` config variable is set to the resolved config file
329 302 location. If not successful, an empty config is used.
330 303 """
331 304 self.log.debug("Attempting to load config file: %s" %
332 305 self.config_file_name)
333 306 loader = PyFileConfigLoader(self.config_file_name,
334 307 path=self.config_file_paths)
335 308 try:
336 309 self.file_config = loader.load_config()
337 310 self.file_config.Global.config_file = loader.full_filename
338 311 except IOError:
339 312 # Only warn if the default config file was NOT being used.
340 313 if not self.config_file_name==self.default_config_file_name:
341 314 self.log.warn("Config file not found, skipping: %s" %
342 315 self.config_file_name, exc_info=True)
343 316 self.file_config = Config()
344 317 except:
345 318 self.log.warn("Error loading config file: %s" %
346 319 self.config_file_name, exc_info=True)
347 320 self.file_config = Config()
348 321
349 322 def set_file_config_log_level(self):
350 323 # We need to keeep self.log_level updated. But we only use the value
351 324 # of the file_config if a value was not specified at the command
352 325 # line, because the command line overrides everything.
353 326 if not hasattr(self.command_line_config.Global, 'log_level'):
354 327 try:
355 328 self.log_level = self.file_config.Global.log_level
356 329 except AttributeError:
357 330 pass # Use existing value
358 331
359 332 def post_load_file_config(self):
360 333 """Do actions after the config file is loaded."""
361 334 pass
362 335
363 336 def log_file_config(self):
364 337 if hasattr(self.file_config.Global, 'config_file'):
365 338 self.log.debug("Config file loaded: %s" %
366 339 self.file_config.Global.config_file)
367 340 self.log.debug(repr(self.file_config))
368 341
369 342 def merge_configs(self):
370 343 """Merge the default, command line and file config objects."""
371 344 config = Config()
372 345 config._merge(self.default_config)
373 346 config._merge(self.file_config)
374 347 config._merge(self.command_line_config)
375 348 self.master_config = config
376 349
377 350 def log_master_config(self):
378 351 self.log.debug("Master config created:")
379 352 self.log.debug(repr(self.master_config))
380 353
381 354 def pre_construct(self):
382 355 """Do actions after the config has been built, but before construct."""
383 356 pass
384 357
385 358 def construct(self):
386 359 """Construct the main components that make up this app."""
387 360 self.log.debug("Constructing components for application")
388 361
389 362 def post_construct(self):
390 363 """Do actions after construct, but before starting the app."""
391 364 pass
392 365
393 366 def start_app(self):
394 367 """Actually start the app."""
395 368 self.log.debug("Starting application")
396 369
397 370 #-------------------------------------------------------------------------
398 371 # Utility methods
399 372 #-------------------------------------------------------------------------
400 373
401 374 def abort(self):
402 375 """Abort the starting of the application."""
403 376 if self._exiting:
404 377 pass
405 378 else:
406 379 self.log.critical("Aborting application: %s" % self.name, exc_info=True)
407 380 self._exiting = True
408 381 sys.exit(1)
409 382
410 383 def exit(self, exit_status=0):
411 384 if self._exiting:
412 385 pass
413 386 else:
414 387 self.log.debug("Exiting application: %s" % self.name)
415 388 self._exiting = True
416 389 sys.exit(exit_status)
417 390
418 391 def attempt(self, func, action='abort'):
419 392 try:
420 393 func()
421 394 except SystemExit:
422 395 raise
423 396 except:
424 397 if action == 'abort':
425 398 self.log.critical("Aborting application: %s" % self.name,
426 399 exc_info=True)
427 400 self.abort()
428 401 raise
429 402 elif action == 'exit':
430 403 self.exit(0)
431 404
@@ -1,576 +1,576 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 * Brian Granger
10 10 * Fernando Perez
11 11
12 12 Notes
13 13 -----
14 14 """
15 15
16 16 #-----------------------------------------------------------------------------
17 17 # Copyright (C) 2008-2009 The IPython Development Team
18 18 #
19 19 # Distributed under the terms of the BSD License. The full license is in
20 20 # the file COPYING, distributed as part of this software.
21 21 #-----------------------------------------------------------------------------
22 22
23 23 #-----------------------------------------------------------------------------
24 24 # Imports
25 25 #-----------------------------------------------------------------------------
26 26
27 27 import logging
28 28 import os
29 29 import sys
30 30
31 31 from IPython.core import crashhandler
32 32 from IPython.core import release
33 from IPython.core.application import Application, BaseAppArgParseConfigLoader
33 from IPython.core.application import Application
34 34 from IPython.core.error import UsageError
35 35 from IPython.core.iplib import InteractiveShell
36 36 from IPython.core.pylabtools import pylab_activate
37 37 from IPython.config.loader import (
38 38 NoConfigDefault,
39 39 Config,
40 40 PyFileConfigLoader
41 41 )
42 42 from IPython.lib import inputhook
43 43 from IPython.utils.genutils import filefind, get_ipython_dir
44 44
45 45 #-----------------------------------------------------------------------------
46 46 # Utilities and helpers
47 47 #-----------------------------------------------------------------------------
48 48
49 49 ipython_desc = """
50 50 A Python shell with automatic history (input and output), dynamic object
51 51 introspection, easier configuration, command completion, access to the system
52 52 shell and more.
53 53 """
54 54
55 55 #-----------------------------------------------------------------------------
56 56 # Main classes and functions
57 57 #-----------------------------------------------------------------------------
58 58
59 59 cl_args = (
60 60 (('--autocall',), dict(
61 61 type=int, dest='InteractiveShell.autocall', default=NoConfigDefault,
62 62 help='Set the autocall value (0,1,2).',
63 63 metavar='InteractiveShell.autocall')
64 64 ),
65 65 (('--autoindent',), dict(
66 66 action='store_true', dest='InteractiveShell.autoindent', default=NoConfigDefault,
67 67 help='Turn on autoindenting.')
68 68 ),
69 69 (('--no-autoindent',), dict(
70 70 action='store_false', dest='InteractiveShell.autoindent', default=NoConfigDefault,
71 71 help='Turn off autoindenting.')
72 72 ),
73 73 (('--automagic',), dict(
74 74 action='store_true', dest='InteractiveShell.automagic', default=NoConfigDefault,
75 75 help='Turn on the auto calling of magic commands.')
76 76 ),
77 77 (('--no-automagic',), dict(
78 78 action='store_false', dest='InteractiveShell.automagic', default=NoConfigDefault,
79 79 help='Turn off the auto calling of magic commands.')
80 80 ),
81 81 (('--autoedit-syntax',), dict(
82 82 action='store_true', dest='InteractiveShell.autoedit_syntax', default=NoConfigDefault,
83 83 help='Turn on auto editing of files with syntax errors.')
84 84 ),
85 85 (('--no-autoedit-syntax',), dict(
86 86 action='store_false', dest='InteractiveShell.autoedit_syntax', default=NoConfigDefault,
87 87 help='Turn off auto editing of files with syntax errors.')
88 88 ),
89 89 (('--banner',), dict(
90 90 action='store_true', dest='Global.display_banner', default=NoConfigDefault,
91 91 help='Display a banner upon starting IPython.')
92 92 ),
93 93 (('--no-banner',), dict(
94 94 action='store_false', dest='Global.display_banner', default=NoConfigDefault,
95 95 help="Don't display a banner upon starting IPython.")
96 96 ),
97 97 (('--cache-size',), dict(
98 98 type=int, dest='InteractiveShell.cache_size', default=NoConfigDefault,
99 99 help="Set the size of the output cache.",
100 100 metavar='InteractiveShell.cache_size')
101 101 ),
102 102 (('--classic',), dict(
103 103 action='store_true', dest='Global.classic', default=NoConfigDefault,
104 104 help="Gives IPython a similar feel to the classic Python prompt.")
105 105 ),
106 106 (('--colors',), dict(
107 107 type=str, dest='InteractiveShell.colors', default=NoConfigDefault,
108 108 help="Set the color scheme (NoColor, Linux, and LightBG).",
109 109 metavar='InteractiveShell.colors')
110 110 ),
111 111 (('--color-info',), dict(
112 112 action='store_true', dest='InteractiveShell.color_info', default=NoConfigDefault,
113 113 help="Enable using colors for info related things.")
114 114 ),
115 115 (('--no-color-info',), dict(
116 116 action='store_false', dest='InteractiveShell.color_info', default=NoConfigDefault,
117 117 help="Disable using colors for info related things.")
118 118 ),
119 119 (('--confirm-exit',), dict(
120 120 action='store_true', dest='InteractiveShell.confirm_exit', default=NoConfigDefault,
121 121 help="Prompt the user when existing.")
122 122 ),
123 123 (('--no-confirm-exit',), dict(
124 124 action='store_false', dest='InteractiveShell.confirm_exit', default=NoConfigDefault,
125 125 help="Don't prompt the user when existing.")
126 126 ),
127 127 (('--deep-reload',), dict(
128 128 action='store_true', dest='InteractiveShell.deep_reload', default=NoConfigDefault,
129 129 help="Enable deep (recursive) reloading by default.")
130 130 ),
131 131 (('--no-deep-reload',), dict(
132 132 action='store_false', dest='InteractiveShell.deep_reload', default=NoConfigDefault,
133 133 help="Disable deep (recursive) reloading by default.")
134 134 ),
135 135 (('--editor',), dict(
136 136 type=str, dest='InteractiveShell.editor', default=NoConfigDefault,
137 137 help="Set the editor used by IPython (default to $EDITOR/vi/notepad).",
138 138 metavar='InteractiveShell.editor')
139 139 ),
140 140 (('--log','-l'), dict(
141 141 action='store_true', dest='InteractiveShell.logstart', default=NoConfigDefault,
142 142 help="Start logging to the default file (./ipython_log.py).")
143 143 ),
144 144 (('--logfile','-lf'), dict(
145 145 type=unicode, dest='InteractiveShell.logfile', default=NoConfigDefault,
146 146 help="Start logging to logfile.",
147 147 metavar='InteractiveShell.logfile')
148 148 ),
149 149 (('--log-append','-la'), dict(
150 150 type=unicode, dest='InteractiveShell.logappend', default=NoConfigDefault,
151 151 help="Start logging to the give file in append mode.",
152 152 metavar='InteractiveShell.logfile')
153 153 ),
154 154 (('--pdb',), dict(
155 155 action='store_true', dest='InteractiveShell.pdb', default=NoConfigDefault,
156 156 help="Enable auto calling the pdb debugger after every exception.")
157 157 ),
158 158 (('--no-pdb',), dict(
159 159 action='store_false', dest='InteractiveShell.pdb', default=NoConfigDefault,
160 160 help="Disable auto calling the pdb debugger after every exception.")
161 161 ),
162 162 (('--pprint',), dict(
163 163 action='store_true', dest='InteractiveShell.pprint', default=NoConfigDefault,
164 164 help="Enable auto pretty printing of results.")
165 165 ),
166 166 (('--no-pprint',), dict(
167 167 action='store_false', dest='InteractiveShell.pprint', default=NoConfigDefault,
168 168 help="Disable auto auto pretty printing of results.")
169 169 ),
170 170 (('--prompt-in1','-pi1'), dict(
171 171 type=str, dest='InteractiveShell.prompt_in1', default=NoConfigDefault,
172 172 help="Set the main input prompt ('In [\#]: ')",
173 173 metavar='InteractiveShell.prompt_in1')
174 174 ),
175 175 (('--prompt-in2','-pi2'), dict(
176 176 type=str, dest='InteractiveShell.prompt_in2', default=NoConfigDefault,
177 177 help="Set the secondary input prompt (' .\D.: ')",
178 178 metavar='InteractiveShell.prompt_in2')
179 179 ),
180 180 (('--prompt-out','-po'), dict(
181 181 type=str, dest='InteractiveShell.prompt_out', default=NoConfigDefault,
182 182 help="Set the output prompt ('Out[\#]:')",
183 183 metavar='InteractiveShell.prompt_out')
184 184 ),
185 185 (('--quick',), dict(
186 186 action='store_true', dest='Global.quick', default=NoConfigDefault,
187 187 help="Enable quick startup with no config files.")
188 188 ),
189 189 (('--readline',), dict(
190 190 action='store_true', dest='InteractiveShell.readline_use', default=NoConfigDefault,
191 191 help="Enable readline for command line usage.")
192 192 ),
193 193 (('--no-readline',), dict(
194 194 action='store_false', dest='InteractiveShell.readline_use', default=NoConfigDefault,
195 195 help="Disable readline for command line usage.")
196 196 ),
197 197 (('--screen-length','-sl'), dict(
198 198 type=int, dest='InteractiveShell.screen_length', default=NoConfigDefault,
199 199 help='Number of lines on screen, used to control printing of long strings.',
200 200 metavar='InteractiveShell.screen_length')
201 201 ),
202 202 (('--separate-in','-si'), dict(
203 203 type=str, dest='InteractiveShell.separate_in', default=NoConfigDefault,
204 204 help="Separator before input prompts. Default '\n'.",
205 205 metavar='InteractiveShell.separate_in')
206 206 ),
207 207 (('--separate-out','-so'), dict(
208 208 type=str, dest='InteractiveShell.separate_out', default=NoConfigDefault,
209 209 help="Separator before output prompts. Default 0 (nothing).",
210 210 metavar='InteractiveShell.separate_out')
211 211 ),
212 212 (('--separate-out2','-so2'), dict(
213 213 type=str, dest='InteractiveShell.separate_out2', default=NoConfigDefault,
214 214 help="Separator after output prompts. Default 0 (nonight).",
215 215 metavar='InteractiveShell.separate_out2')
216 216 ),
217 217 (('-no-sep',), dict(
218 218 action='store_true', dest='Global.nosep', default=NoConfigDefault,
219 219 help="Eliminate all spacing between prompts.")
220 220 ),
221 221 (('--term-title',), dict(
222 222 action='store_true', dest='InteractiveShell.term_title', default=NoConfigDefault,
223 223 help="Enable auto setting the terminal title.")
224 224 ),
225 225 (('--no-term-title',), dict(
226 226 action='store_false', dest='InteractiveShell.term_title', default=NoConfigDefault,
227 227 help="Disable auto setting the terminal title.")
228 228 ),
229 229 (('--xmode',), dict(
230 230 type=str, dest='InteractiveShell.xmode', default=NoConfigDefault,
231 231 help="Exception mode ('Plain','Context','Verbose')",
232 232 metavar='InteractiveShell.xmode')
233 233 ),
234 234 (('--ext',), dict(
235 235 type=str, dest='Global.extra_extension', default=NoConfigDefault,
236 236 help="The dotted module name of an IPython extension to load.",
237 237 metavar='Global.extra_extension')
238 238 ),
239 239 (('-c',), dict(
240 240 type=str, dest='Global.code_to_run', default=NoConfigDefault,
241 241 help="Execute the given command string.",
242 242 metavar='Global.code_to_run')
243 243 ),
244 244 (('-i',), dict(
245 245 action='store_true', dest='Global.force_interact', default=NoConfigDefault,
246 246 help="If running code from the command line, become interactive afterwards.")
247 247 ),
248 248
249 249 # Options to start with GUI control enabled from the beginning
250 250 (('--gui',), dict(
251 251 type=str, dest='Global.gui', default=NoConfigDefault,
252 252 help="Enable GUI event loop integration ('qt', 'wx', 'gtk').",
253 253 metavar='gui-mode')
254 254 ),
255 255
256 256 (('--pylab','-pylab'), dict(
257 257 type=str, dest='Global.pylab', default=NoConfigDefault,
258 258 nargs='?', const='auto', metavar='gui-mode',
259 259 help="Pre-load matplotlib and numpy for interactive use. "+
260 260 "If no value is given, the gui backend is matplotlib's, else use "+
261 261 "one of: ['tk', 'qt', 'wx', 'gtk'].")
262 262 ),
263 263
264 264 # Legacy GUI options. Leave them in for backwards compatibility, but the
265 265 # 'thread' names are really a misnomer now.
266 266 (('--wthread','-wthread'), dict(
267 267 action='store_true', dest='Global.wthread', default=NoConfigDefault,
268 268 help="Enable wxPython event loop integration "+
269 269 "(DEPRECATED, use --gui wx)")
270 270 ),
271 271 (('--q4thread','--qthread','-q4thread','-qthread'), dict(
272 272 action='store_true', dest='Global.q4thread', default=NoConfigDefault,
273 273 help="Enable Qt4 event loop integration. Qt3 is no longer supported. "+
274 274 "(DEPRECATED, use --gui qt)")
275 275 ),
276 276 (('--gthread','-gthread'), dict(
277 277 action='store_true', dest='Global.gthread', default=NoConfigDefault,
278 278 help="Enable GTK event loop integration. "+
279 279 "(DEPRECATED, use --gui gtk)")
280 280 ),
281 281 )
282 282
283 283
284 284 default_config_file_name = u'ipython_config.py'
285 285
286 286 class IPythonApp(Application):
287 287 name = u'ipython'
288 288 description = 'IPython: an enhanced interactive Python shell.'
289 289 config_file_name = default_config_file_name
290 290
291 291 cl_arguments = Application.cl_arguments + cl_args
292 292
293 293 # Private and configuration attributes
294 294 _CrashHandler = crashhandler.IPythonCrashHandler
295 295
296 296 def __init__(self, argv=None, **shell_params):
297 297 """Create a new IPythonApp.
298 298
299 299 Parameters
300 300 ----------
301 301 argv : optional, list
302 302 If given, used as the command-line argv environment to read arguments
303 303 from.
304 304
305 305 shell_params : optional, dict
306 306 All other keywords are passed to the :class:`iplib.InteractiveShell`
307 307 constructor.
308 308 """
309 309 super(IPythonApp, self).__init__(argv)
310 310 self.shell_params = shell_params
311 311
312 312
313 313 def create_default_config(self):
314 314 super(IPythonApp, self).create_default_config()
315 315 # Eliminate multiple lookups
316 316 Global = self.default_config.Global
317 317
318 318 # Set all default values
319 319 Global.display_banner = True
320 320
321 321 # If the -c flag is given or a file is given to run at the cmd line
322 322 # like "ipython foo.py", normally we exit without starting the main
323 323 # loop. The force_interact config variable allows a user to override
324 324 # this and interact. It is also set by the -i cmd line flag, just
325 325 # like Python.
326 326 Global.force_interact = False
327 327
328 328 # By default always interact by starting the IPython mainloop.
329 329 Global.interact = True
330 330
331 331 # No GUI integration by default
332 332 Global.gui = False
333 333 # Pylab off by default
334 334 Global.pylab = False
335 335
336 336 # Deprecated versions of gui support that used threading, we support
337 337 # them just for bacwards compatibility as an alternate spelling for
338 338 # '--gui X'
339 339 Global.qthread = False
340 340 Global.q4thread = False
341 341 Global.wthread = False
342 342 Global.gthread = False
343 343
344 344 def load_file_config(self):
345 345 if hasattr(self.command_line_config.Global, 'quick'):
346 346 if self.command_line_config.Global.quick:
347 347 self.file_config = Config()
348 348 return
349 349 super(IPythonApp, self).load_file_config()
350 350
351 351 def post_load_file_config(self):
352 352 if hasattr(self.command_line_config.Global, 'extra_extension'):
353 353 if not hasattr(self.file_config.Global, 'extensions'):
354 354 self.file_config.Global.extensions = []
355 355 self.file_config.Global.extensions.append(
356 356 self.command_line_config.Global.extra_extension)
357 357 del self.command_line_config.Global.extra_extension
358 358
359 359 def pre_construct(self):
360 360 config = self.master_config
361 361
362 362 if hasattr(config.Global, 'classic'):
363 363 if config.Global.classic:
364 364 config.InteractiveShell.cache_size = 0
365 365 config.InteractiveShell.pprint = 0
366 366 config.InteractiveShell.prompt_in1 = '>>> '
367 367 config.InteractiveShell.prompt_in2 = '... '
368 368 config.InteractiveShell.prompt_out = ''
369 369 config.InteractiveShell.separate_in = \
370 370 config.InteractiveShell.separate_out = \
371 371 config.InteractiveShell.separate_out2 = ''
372 372 config.InteractiveShell.colors = 'NoColor'
373 373 config.InteractiveShell.xmode = 'Plain'
374 374
375 375 if hasattr(config.Global, 'nosep'):
376 376 if config.Global.nosep:
377 377 config.InteractiveShell.separate_in = \
378 378 config.InteractiveShell.separate_out = \
379 379 config.InteractiveShell.separate_out2 = ''
380 380
381 381 # if there is code of files to run from the cmd line, don't interact
382 382 # unless the -i flag (Global.force_interact) is true.
383 383 code_to_run = config.Global.get('code_to_run','')
384 384 file_to_run = False
385 385 if len(self.extra_args)>=1:
386 386 if self.extra_args[0]:
387 387 file_to_run = True
388 388 if file_to_run or code_to_run:
389 389 if not config.Global.force_interact:
390 390 config.Global.interact = False
391 391
392 392 def construct(self):
393 393 # I am a little hesitant to put these into InteractiveShell itself.
394 394 # But that might be the place for them
395 395 sys.path.insert(0, '')
396 396
397 397 # Create an InteractiveShell instance
398 398 self.shell = InteractiveShell(None, self.master_config,
399 399 **self.shell_params )
400 400
401 401 def post_construct(self):
402 402 """Do actions after construct, but before starting the app."""
403 403 config = self.master_config
404 404
405 405 # shell.display_banner should always be False for the terminal
406 406 # based app, because we call shell.show_banner() by hand below
407 407 # so the banner shows *before* all extension loading stuff.
408 408 self.shell.display_banner = False
409 409
410 410 if config.Global.display_banner and \
411 411 config.Global.interact:
412 412 self.shell.show_banner()
413 413
414 414 # Make sure there is a space below the banner.
415 415 if self.log_level <= logging.INFO: print
416 416
417 417 # Now a variety of things that happen after the banner is printed.
418 418 self._enable_gui_pylab()
419 419 self._load_extensions()
420 420 self._run_exec_lines()
421 421 self._run_exec_files()
422 422 self._run_cmd_line_code()
423 423 self._configure_xmode()
424 424
425 425 def _enable_gui_pylab(self):
426 426 """Enable GUI event loop integration, taking pylab into account."""
427 427 Global = self.master_config.Global
428 428
429 429 # Select which gui to use
430 430 if Global.gui:
431 431 gui = Global.gui
432 432 # The following are deprecated, but there's likely to be a lot of use
433 433 # of this form out there, so we might as well support it for now. But
434 434 # the --gui option above takes precedence.
435 435 elif Global.wthread:
436 436 gui = inputhook.GUI_WX
437 437 elif Global.qthread:
438 438 gui = inputhook.GUI_QT
439 439 elif Global.gthread:
440 440 gui = inputhook.GUI_GTK
441 441 else:
442 442 gui = None
443 443
444 444 # Using --pylab will also require gui activation, though which toolkit
445 445 # to use may be chosen automatically based on mpl configuration.
446 446 if Global.pylab:
447 447 activate = self.shell.enable_pylab
448 448 if Global.pylab == 'auto':
449 449 gui = None
450 450 else:
451 451 gui = Global.pylab
452 452 else:
453 453 # Enable only GUI integration, no pylab
454 454 activate = inputhook.enable_gui
455 455
456 456 if gui or Global.pylab:
457 457 try:
458 458 self.log.info("Enabling GUI event loop integration, "
459 459 "toolkit=%s, pylab=%s" % (gui, Global.pylab) )
460 460 activate(gui)
461 461 except:
462 462 self.log.warn("Error in enabling GUI event loop integration:")
463 463 self.shell.showtraceback()
464 464
465 465 def _load_extensions(self):
466 466 """Load all IPython extensions in Global.extensions.
467 467
468 468 This uses the :meth:`InteractiveShell.load_extensions` to load all
469 469 the extensions listed in ``self.master_config.Global.extensions``.
470 470 """
471 471 try:
472 472 if hasattr(self.master_config.Global, 'extensions'):
473 473 self.log.debug("Loading IPython extensions...")
474 474 extensions = self.master_config.Global.extensions
475 475 for ext in extensions:
476 476 try:
477 477 self.log.info("Loading IPython extension: %s" % ext)
478 478 self.shell.load_extension(ext)
479 479 except:
480 480 self.log.warn("Error in loading extension: %s" % ext)
481 481 self.shell.showtraceback()
482 482 except:
483 483 self.log.warn("Unknown error in loading extensions:")
484 484 self.shell.showtraceback()
485 485
486 486 def _run_exec_lines(self):
487 487 """Run lines of code in Global.exec_lines in the user's namespace."""
488 488 try:
489 489 if hasattr(self.master_config.Global, 'exec_lines'):
490 490 self.log.debug("Running code from Global.exec_lines...")
491 491 exec_lines = self.master_config.Global.exec_lines
492 492 for line in exec_lines:
493 493 try:
494 494 self.log.info("Running code in user namespace: %s" % line)
495 495 self.shell.runlines(line)
496 496 except:
497 497 self.log.warn("Error in executing line in user namespace: %s" % line)
498 498 self.shell.showtraceback()
499 499 except:
500 500 self.log.warn("Unknown error in handling Global.exec_lines:")
501 501 self.shell.showtraceback()
502 502
503 503 def _exec_file(self, fname):
504 504 full_filename = filefind(fname, [u'.', self.ipython_dir])
505 505 if os.path.isfile(full_filename):
506 506 if full_filename.endswith(u'.py'):
507 507 self.log.info("Running file in user namespace: %s" % full_filename)
508 508 self.shell.safe_execfile(full_filename, self.shell.user_ns)
509 509 elif full_filename.endswith('.ipy'):
510 510 self.log.info("Running file in user namespace: %s" % full_filename)
511 511 self.shell.safe_execfile_ipy(full_filename)
512 512 else:
513 513 self.log.warn("File does not have a .py or .ipy extension: <%s>" % full_filename)
514 514
515 515 def _run_exec_files(self):
516 516 try:
517 517 if hasattr(self.master_config.Global, 'exec_files'):
518 518 self.log.debug("Running files in Global.exec_files...")
519 519 exec_files = self.master_config.Global.exec_files
520 520 for fname in exec_files:
521 521 self._exec_file(fname)
522 522 except:
523 523 self.log.warn("Unknown error in handling Global.exec_files:")
524 524 self.shell.showtraceback()
525 525
526 526 def _run_cmd_line_code(self):
527 527 if hasattr(self.master_config.Global, 'code_to_run'):
528 528 line = self.master_config.Global.code_to_run
529 529 try:
530 530 self.log.info("Running code given at command line (-c): %s" % line)
531 531 self.shell.runlines(line)
532 532 except:
533 533 self.log.warn("Error in executing line in user namespace: %s" % line)
534 534 self.shell.showtraceback()
535 535 return
536 536 # Like Python itself, ignore the second if the first of these is present
537 537 try:
538 538 fname = self.extra_args[0]
539 539 except:
540 540 pass
541 541 else:
542 542 try:
543 543 self._exec_file(fname)
544 544 except:
545 545 self.log.warn("Error in executing file in user namespace: %s" % fname)
546 546 self.shell.showtraceback()
547 547
548 548 def _configure_xmode(self):
549 549 # XXX - shouldn't this be read from the config? I'm still a little
550 550 # lost with all the details of handling the new config guys...
551 551 self.shell.InteractiveTB.set_mode(mode=self.shell.xmode)
552 552
553 553 def start_app(self):
554 554 if self.master_config.Global.interact:
555 555 self.log.debug("Starting IPython's mainloop...")
556 556 self.shell.mainloop()
557 557 else:
558 558 self.log.debug("IPython not interactive, start_app is no-op...")
559 559
560 560
561 561 def load_default_config(ipython_dir=None):
562 562 """Load the default config file from the default ipython_dir.
563 563
564 564 This is useful for embedded shells.
565 565 """
566 566 if ipython_dir is None:
567 567 ipython_dir = get_ipython_dir()
568 568 cl = PyFileConfigLoader(default_config_file_name, ipython_dir)
569 569 config = cl.load_config()
570 570 return config
571 571
572 572
573 573 def launch_new_instance():
574 574 """Create and run a full blown IPython instance"""
575 575 app = IPythonApp()
576 576 app.start()
General Comments 0
You need to be logged in to leave comments. Login now