##// END OF EJS Templates
Work on startup related things....
Brian Granger -
Show More
@@ -0,0 +1,67
1 #!/usr/bin/env python
2 # encoding: utf-8
3 """
4 Context managers for adding things to sys.path temporarily.
5
6 Authors:
7
8 * Brian Granger
9 """
10
11 #-----------------------------------------------------------------------------
12 # Copyright (C) 2008-2009 The IPython Development Team
13 #
14 # Distributed under the terms of the BSD License. The full license is in
15 # the file COPYING, distributed as part of this software.
16 #-----------------------------------------------------------------------------
17
18 #-----------------------------------------------------------------------------
19 # Imports
20 #-----------------------------------------------------------------------------
21
22
23 import sys
24
25 class appended_to_syspath(object):
26 """A context for appending a directory to sys.path for a second."""
27
28 def __init__(self, dir):
29 self.dir = dir
30
31 def __enter__(self):
32 if self.dir not in sys.path:
33 sys.path.append(self.dir)
34 self.added = True
35 else:
36 self.added = False
37
38 def __exit__(self, type, value, traceback):
39 if self.added:
40 try:
41 sys.path.remove(self.dir)
42 except ValueError:
43 pass
44 # Returning False causes any exceptions to be re-raised.
45 return False
46
47 class prepended_to_syspath(object):
48 """A context for prepending a directory to sys.path for a second."""
49
50 def __init__(self, dir):
51 self.dir = dir
52
53 def __enter__(self):
54 if self.dir not in sys.path:
55 sys.path.insert(0,self.dir)
56 self.added = True
57 else:
58 self.added = False
59
60 def __exit__(self, type, value, traceback):
61 if self.added:
62 try:
63 sys.path.remove(self.dir)
64 except ValueError:
65 pass
66 # Returning False causes any exceptions to be re-raised.
67 return False
@@ -1,9 +1,8
1 1 from ipython_config import *
2 2
3 EXECUTE.extend([
3 Global.exec_lines.extend([
4 4 'import cmath',
5 5 'from math import *',
6 6 'print "*** math functions available globally, cmath as a module"'
7
8 7 ])
9 8
@@ -1,6 +1,6
1 1 from ipython_config import *
2 2
3 EXECUTE.extend([
3 Global.exec_lines.extend([
4 4 'import numpy',
5 5 'import scipy',
6 6 'import numpy as np',
@@ -1,7 +1,8
1 1 from ipython_config_numeric import *
2 2
3 EXECUTE.extend([
4
5
3 Global.exec_lines.extend([
4 'import matplotlib',
5 'from matplotlib import pyplot as plt',
6 'from matplotlib.pyplot import *'
6 7 ])
7 8
@@ -1,15 +1,13
1 1 from ipython_config import *
2 2
3 EXECUTE.insert(0, 'from IPython.extensions.InterpreterExec import *')
3 InteractiveShell.prompt_in2 = '\C_LightGreen\u@\h\C_LightBlue[\C_LightCyan\Y1\C_LightBlue]\C_Green|\#> '
4 InteractiveShell.prompt_in2 = '\C_Green|\C_LightGreen\D\C_Green> '
5 InteractiveShell.prompt_out = '<\#> '
4 6
5 PROMPT_IN1 = '\C_LightGreen\u@\h\C_LightBlue[\C_LightCyan\Y1\C_LightBlue]\C_Green|\#> '
6 PROMPT_IN2 = '\C_Green|\C_LightGreen\D\C_Green> '
7 PROMPT_OUT = '<\#> '
7 InteractiveShell.prompts_pad_left = True
8 8
9 PROMPTS_PAD_LEFT = True
9 InteractiveShell.separate_in = ''
10 InteractiveShell.separate_out = ''
11 InteractiveShell.separate_out2 = ''
10 12
11 SEPARATE_IN = 0
12 SEPARATE_OUT = 0
13 SEPARATE_OUT2 = 0
14
15 MULTI_LINE_SPECIALS = True No newline at end of file
13 PrefilterManager.multi_line_specials = True No newline at end of file
@@ -1,9 +1,9
1 1 from ipython_config import *
2 2
3 EXECUTE.extend([
4 'from __future__ import division'
5 'from sympy import *'
6 'x, y, z = symbols('xyz')'
7 'k, m, n = symbols('kmn', integer=True)'
8 'f, g, h = map(Function, 'fgh')'
3 Global.exec_lines.extend([
4 "from __future__ import division"
5 "from sympy import *"
6 "x, y, z = symbols('xyz')"
7 "k, m, n = symbols('kmn', integer=True)"
8 "f, g, h = map(Function, 'fgh')"
9 9 ])
@@ -112,11 +112,9 class AliasManager(Component):
112 112
113 113 @auto_attr
114 114 def shell(self):
115 shell = Component.get_instances(
115 return Component.get_instances(
116 116 root=self.root,
117 klass='IPython.core.iplib.InteractiveShell'
118 )[0]
119 return shell
117 klass='IPython.core.iplib.InteractiveShell')[0]
120 118
121 119 def __contains__(self, name):
122 120 if name in self.alias_table:
@@ -23,6 +23,7 Notes
23 23 # Imports
24 24 #-----------------------------------------------------------------------------
25 25
26 import logging
26 27 import os
27 28 import sys
28 29 import traceback
@@ -53,8 +54,8 class IPythonArgParseConfigLoader(ArgParseConfigLoader):
53 54 help='The string name of the ipython profile to be used.',
54 55 default=NoConfigDefault,
55 56 metavar='Global.profile')
56 self.parser.add_argument('-debug',dest="Global.debug",action='store_true',
57 help='Debug the application startup process.',
57 self.parser.add_argument('-log_level',dest="Global.log_level",type=int,
58 help='Set the log level (0,10,20,30,40,50). Default is 30.',
58 59 default=NoConfigDefault)
59 60 self.parser.add_argument('-config_file',dest='Global.config_file',type=str,
60 61 help='Set the config file name to override default.',
@@ -72,10 +73,26 class Application(object):
72 73
73 74 config_file_name = 'ipython_config.py'
74 75 name = 'ipython'
75 debug = False
76 76
77 77 def __init__(self):
78 pass
78 self.init_logger()
79
80 def init_logger(self):
81 self.log = logging.getLogger(self.__class__.__name__)
82 # This is used as the default until the command line arguments are read.
83 self.log.setLevel(logging.WARN)
84 self._log_handler = logging.StreamHandler()
85 self._log_formatter = logging.Formatter("[%(name)s] %(message)s")
86 self._log_handler.setFormatter(self._log_formatter)
87 self.log.addHandler(self._log_handler)
88
89 def _set_log_level(self, level):
90 self.log.setLevel(level)
91
92 def _get_log_level(self):
93 return self.log.level
94
95 log_level = property(_get_log_level, _set_log_level)
79 96
80 97 def start(self):
81 98 """Start the application."""
@@ -103,6 +120,8 class Application(object):
103 120 """Create defaults that can't be set elsewhere."""
104 121 self.default_config = Config()
105 122 self.default_config.Global.ipythondir = get_ipython_dir()
123 self.log.debug('Default config loaded:')
124 self.log.debug(repr(self.default_config))
106 125
107 126 def create_command_line_config(self):
108 127 """Create and return a command line config loader."""
@@ -120,12 +139,14 class Application(object):
120 139
121 140 loader = self.create_command_line_config()
122 141 self.command_line_config = loader.load_config()
142
123 143 try:
124 self.debug = self.command_line_config.Global.debug
144 self.log_level = self.command_line_config.Global.log_level
125 145 except AttributeError:
126 pass # use class default
127 self.log("Default config loaded:", self.default_config)
128 self.log("Command line config loaded:", self.command_line_config)
146 pass # Use existing value which is set in Application.init_logger.
147
148 self.log.debug("Command line config loaded:")
149 self.log.debug(repr(self.command_line_config))
129 150
130 151 def post_load_command_line_config(self):
131 152 """Do actions just after loading the command line config."""
@@ -148,7 +169,7 class Application(object):
148 169 sys.path.append(os.path.abspath(self.ipythondir))
149 170 if not os.path.isdir(self.ipythondir):
150 171 os.makedirs(self.ipythondir, mode = 0777)
151 self.log("IPYTHONDIR set to: %s" % self.ipythondir)
172 self.log.debug("IPYTHONDIR set to: %s" % self.ipythondir)
152 173
153 174 def find_config_file_name(self):
154 175 """Find the config file name for this application.
@@ -187,18 +208,28 class Application(object):
187 208 ``CONFIG_FILE`` config variable is set to the resolved config file
188 209 location. If not successful, an empty config is used.
189 210 """
211 self.log.debug("Attempting to load config file: <%s>" % self.config_file_name)
190 212 loader = PyFileConfigLoader(self.config_file_name,
191 213 path=self.config_file_paths)
192 214 try:
193 215 self.file_config = loader.load_config()
194 216 self.file_config.Global.config_file = loader.full_filename
195 217 except IOError:
196 self.log("Config file not found, skipping: %s" % \
197 self.config_file_name)
218 self.log.warn("Config file not found, skipping: <%s>" % \
219 self.config_file_name, exc_info=True)
220 self.file_config = Config()
221 except:
222 self.log.warn("Error loading config file: <%s>" % \
223 self.config_file_name, exc_info=True)
198 224 self.file_config = Config()
199 225 else:
200 self.log("Config file loaded: %s" % loader.full_filename,
201 self.file_config)
226 self.log.debug("Config file loaded: <%s>" % loader.full_filename)
227 self.log.debug(repr(self.file_config))
228 # We need to keeep self.log_level updated.
229 try:
230 self.log_level = self.file_config.Global.log_level
231 except AttributeError:
232 pass # Use existing value
202 233
203 234 def post_load_file_config(self):
204 235 """Do actions after the config file is loaded."""
@@ -211,7 +242,8 class Application(object):
211 242 config._merge(self.file_config)
212 243 config._merge(self.command_line_config)
213 244 self.master_config = config
214 self.log("Master config created:", self.master_config)
245 self.log.debug("Master config created:")
246 self.log.debug(repr(self.master_config))
215 247
216 248 def pre_construct(self):
217 249 """Do actions after the config has been built, but before construct."""
@@ -219,7 +251,7 class Application(object):
219 251
220 252 def construct(self):
221 253 """Construct the main components that make up this app."""
222 self.log("Constructing components for application...")
254 self.log.debug("Constructing components for application")
223 255
224 256 def post_construct(self):
225 257 """Do actions after construct, but before starting the app."""
@@ -227,7 +259,7 class Application(object):
227 259
228 260 def start_app(self):
229 261 """Actually start the app."""
230 self.log("Starting application...")
262 self.log.debug("Starting application")
231 263
232 264 #-------------------------------------------------------------------------
233 265 # Utility methods
@@ -235,11 +267,11 class Application(object):
235 267
236 268 def abort(self):
237 269 """Abort the starting of the application."""
238 print "Aborting application: ", self.name
270 self.log.critical("Aborting application: %s" % self.name, exc_info=True)
239 271 sys.exit(1)
240 272
241 273 def exit(self):
242 print "Exiting application: ", self.name
274 self.log.critical("Aborting application: %s" % self.name)
243 275 sys.exit(1)
244 276
245 277 def attempt(self, func, action='abort'):
@@ -249,17 +281,7 class Application(object):
249 281 self.exit()
250 282 except:
251 283 if action == 'abort':
252 self.print_traceback()
253 284 self.abort()
254 285 elif action == 'exit':
255 286 self.exit()
256
257 def print_traceback(self):
258 print "Error in appliction startup: ", self.name
259 print
260 traceback.print_exc()
261
262 def log(self, *args):
263 if self.debug:
264 for arg in args:
265 print "[%s] %s" % (self.name, arg) No newline at end of file
287 No newline at end of file
@@ -46,11 +46,9 class BuiltinTrap(Component):
46 46
47 47 @auto_attr
48 48 def shell(self):
49 shell = Component.get_instances(
49 return Component.get_instances(
50 50 root=self.root,
51 klass='IPython.core.iplib.InteractiveShell'
52 )[0]
53 return shell
51 klass='IPython.core.iplib.InteractiveShell')[0]
54 52
55 53 def __enter__(self):
56 54 if self._nested_level == 0:
@@ -48,11 +48,9 class DisplayTrap(Component):
48 48
49 49 @auto_attr
50 50 def shell(self):
51 shell = Component.get_instances(
51 return Component.get_instances(
52 52 root=self.root,
53 klass='IPython.core.iplib.InteractiveShell'
54 )[0]
55 return shell
53 klass='IPython.core.iplib.InteractiveShell')[0]
56 54
57 55 def __enter__(self):
58 56 if self._nested_level == 0:
@@ -64,10 +64,13 class InteractiveShellEmbed(InteractiveShell):
64 64 exit_msg = Str('')
65 65 embedded = CBool(True)
66 66 embedded_active = CBool(True)
67 # Like the base class display_banner is not configurable, but here it
68 # is True by default.
69 display_banner = CBool(True)
67 70
68 71 def __init__(self, parent=None, config=None, ipythondir=None, usage=None,
69 72 user_ns=None, user_global_ns=None,
70 banner1=None, banner2=None,
73 banner1=None, banner2=None, display_banner=None,
71 74 custom_exceptions=((),None), exit_msg=''):
72 75
73 76 self.save_sys_ipcompleter()
@@ -75,7 +78,7 class InteractiveShellEmbed(InteractiveShell):
75 78 super(InteractiveShellEmbed,self).__init__(
76 79 parent=parent, config=config, ipythondir=ipythondir, usage=usage,
77 80 user_ns=user_ns, user_global_ns=user_global_ns,
78 banner1=banner1, banner2=banner2,
81 banner1=banner1, banner2=banner2, display_banner=display_banner,
79 82 custom_exceptions=custom_exceptions)
80 83
81 84 self.exit_msg = exit_msg
@@ -148,23 +151,24 class InteractiveShellEmbed(InteractiveShell):
148 151 if self.has_readline:
149 152 self.set_completer()
150 153
151 if self.banner and header:
152 format = '%s\n%s\n'
153 else:
154 format = '%s%s\n'
155 banner = format % (self.banner,header)
154 # self.banner is auto computed
155 if header:
156 self.old_banner2 = self.banner2
157 self.banner2 = self.banner2 + '\n' + header + '\n'
156 158
157 159 # Call the embedding code with a stack depth of 1 so it can skip over
158 160 # our call and get the original caller's namespaces.
159 self.mainloop(banner, local_ns, global_ns,
160 stack_depth=stack_depth)
161 self.mainloop(local_ns, global_ns, stack_depth=stack_depth)
162
163 self.banner2 = self.old_banner2
161 164
162 165 if self.exit_msg is not None:
163 166 print self.exit_msg
164 167
165 168 self.restore_sys_ipcompleter()
166 169
167 def mainloop(self,header='',local_ns=None,global_ns=None,stack_depth=0):
170 def mainloop(self, local_ns=None, global_ns=None, stack_depth=0,
171 display_banner=None):
168 172 """Embeds IPython into a running python program.
169 173
170 174 Input:
@@ -221,7 +225,7 class InteractiveShellEmbed(InteractiveShell):
221 225 self.set_completer_frame()
222 226
223 227 with nested(self.builtin_trap, self.display_trap):
224 self.interact(header)
228 self.interact(display_banner=display_banner)
225 229
226 230 # now, purge out the user namespace from anything we might have added
227 231 # from the caller's local namespace
@@ -242,7 +246,7 _embedded_shell = None
242 246
243 247
244 248 def embed(header='', config=None, usage=None, banner1=None, banner2=None,
245 exit_msg=''):
249 display_banner=True, exit_msg=''):
246 250 """Call this to embed IPython at the current point in your program.
247 251
248 252 The first invocation of this will create an :class:`InteractiveShellEmbed`
@@ -264,9 +268,13 def embed(header='', config=None, usage=None, banner1=None, banner2=None,
264 268 """
265 269 if config is None:
266 270 config = load_default_config()
271 config.InteractiveShellEmbed = config.InteractiveShell
267 272 global _embedded_shell
268 273 if _embedded_shell is None:
269 _embedded_shell = InteractiveShellEmbed(config=config,
270 usage=usage, banner1=banner1, banner2=banner2, exit_msg=exit_msg)
274 _embedded_shell = InteractiveShellEmbed(
275 config=config, usage=usage,
276 banner1=banner1, banner2=banner2,
277 display_banner=display_banner, exit_msg=exit_msg
278 )
271 279 _embedded_shell(header=header, stack_depth=2)
272 280
@@ -23,6 +23,7 Notes
23 23 # Imports
24 24 #-----------------------------------------------------------------------------
25 25
26 import logging
26 27 import os
27 28 import sys
28 29 import warnings
@@ -33,11 +34,12 from IPython.core.iplib import InteractiveShell
33 34 from IPython.config.loader import (
34 35 NoConfigDefault,
35 36 Config,
37 ConfigError,
36 38 PyFileConfigLoader
37 39 )
38 40
39 41 from IPython.utils.ipstruct import Struct
40 from IPython.utils.genutils import get_ipython_dir
42 from IPython.utils.genutils import filefind, get_ipython_dir
41 43
42 44 #-----------------------------------------------------------------------------
43 45 # Utilities and helpers
@@ -95,11 +97,11 cl_args = (
95 97 help='Turn off auto editing of files with syntax errors.')
96 98 ),
97 99 (('-banner',), dict(
98 action='store_true', dest='InteractiveShell.display_banner', default=NoConfigDefault,
100 action='store_true', dest='Global.display_banner', default=NoConfigDefault,
99 101 help='Display a banner upon starting IPython.')
100 102 ),
101 103 (('-nobanner',), dict(
102 action='store_false', dest='InteractiveShell.display_banner', default=NoConfigDefault,
104 action='store_false', dest='Global.display_banner', default=NoConfigDefault,
103 105 help="Don't display a banner upon starting IPython.")
104 106 ),
105 107 (('-c',), dict(
@@ -244,6 +246,11 cl_args = (
244 246 help="Exception mode ('Plain','Context','Verbose')",
245 247 metavar='InteractiveShell.xmode')
246 248 ),
249 (('-ext',), dict(
250 type=str, dest='Global.extra_extension', default=NoConfigDefault,
251 help="The dotted module name of an IPython extension to load.",
252 metavar='Global.extra_extension')
253 ),
247 254 # These are only here to get the proper deprecation warnings
248 255 (('-pylab','-wthread','-qthread','-q4thread','-gthread'), dict(
249 256 action='store_true', dest='Global.threaded_shell', default=NoConfigDefault,
@@ -263,6 +270,14 class IPythonApp(Application):
263 270 name = 'ipython'
264 271 config_file_name = _default_config_file_name
265 272
273 def create_default_config(self):
274 super(IPythonApp, self).create_default_config()
275 self.default_config.Global.display_banner=True
276 # Let the parent class set the default, but each time log_level
277 # changes from config, we need to update self.log_level as that is
278 # what updates the actual log level in self.log.
279 self.default_config.Global.log_level = self.log_level
280
266 281 def create_command_line_config(self):
267 282 """Create and return a command line config loader."""
268 283 return IPythonAppCLConfigLoader(
@@ -286,7 +301,12 class IPythonApp(Application):
286 301 super(IPythonApp, self).load_file_config()
287 302
288 303 def post_load_file_config(self):
289 """Logic goes here."""
304 if hasattr(self.command_line_config.Global, 'extra_extension'):
305 if not hasattr(self.file_config.Global, 'extensions'):
306 self.file_config.Global.extensions = []
307 self.file_config.Global.extensions.append(
308 self.command_line_config.Global.extra_extension)
309 del self.command_line_config.Global.extra_extension
290 310
291 311 def pre_construct(self):
292 312 config = self.master_config
@@ -318,17 +338,90 class IPythonApp(Application):
318 338 # I am a little hesitant to put these into InteractiveShell itself.
319 339 # But that might be the place for them
320 340 sys.path.insert(0, '')
321 # add personal ipythondir to sys.path so that users can put things in
322 # there for customization
323 sys.path.append(os.path.abspath(self.ipythondir))
324
341
325 342 # Create an InteractiveShell instance
326 343 self.shell = InteractiveShell(
327 344 parent=None,
328 345 config=self.master_config
329 346 )
330
347
348 def post_construct(self):
349 """Do actions after construct, but before starting the app."""
350 # shell.display_banner should always be False for the terminal
351 # based app, because we call shell.show_banner() by hand below
352 # so the banner shows *before* all extension loading stuff.
353 self.shell.display_banner = False
354
355 if self.master_config.Global.display_banner:
356 self.shell.show_banner()
357
358 # Make sure there is a space below the banner.
359 if self.log_level <= logging.INFO: print
360
361 self._load_extensions()
362 self._run_exec_lines()
363 self._run_exec_files()
364
365 def _load_extensions(self):
366 """Load all IPython extensions in Global.extensions.
367
368 This uses the :meth:`InteractiveShell.load_extensions` to load all
369 the extensions listed in ``self.master_config.Global.extensions``.
370 """
371 try:
372 if hasattr(self.master_config.Global, 'extensions'):
373 self.log.debug("Loading IPython extensions...")
374 extensions = self.master_config.Global.extensions
375 for ext in extensions:
376 try:
377 self.log.info("Loading IPython extension: %s" % ext)
378 self.shell.load_extension(ext)
379 except:
380 self.log.warn("Error in loading extension: %s" % ext)
381 self.shell.showtraceback()
382 except:
383 self.log.warn("Unknown error in loading extensions:")
384 self.shell.showtraceback()
385
386 def _run_exec_lines(self):
387 """Run lines of code in Global.exec_lines in the user's namespace."""
388 try:
389 if hasattr(self.master_config.Global, 'exec_lines'):
390 self.log.debug("Running code from Global.exec_lines...")
391 exec_lines = self.master_config.Global.exec_lines
392 for line in exec_lines:
393 try:
394 self.log.info("Running code in user namespace: %s" % line)
395 self.shell.runlines(line)
396 except:
397 self.log.warn("Error in executing line in user namespace: %s" % line)
398 self.shell.showtraceback()
399 except:
400 self.log.warn("Unknown error in handling Global.exec_lines:")
401 self.shell.showtraceback()
402
403 def _run_exec_files(self):
404 try:
405 if hasattr(self.master_config.Global, 'exec_files'):
406 self.log.debug("Running files in Global.exec_files...")
407 exec_files = self.master_config.Global.exec_files
408 for fname in exec_files:
409 full_filename = filefind(fname, ['.', self.ipythondir])
410 if os.path.isfile(full_filename):
411 if full_filename.endswith('.py'):
412 self.log.info("Running file in user namespace: %s" % full_filename)
413 self.shell.safe_execfile(full_filename, self.shell.user_ns)
414 elif full_filename.endswith('.ipy'):
415 self.log.info("Running file in user namespace: %s" % full_filename)
416 self.shell.safe_execfile_ipy(full_filename)
417 else:
418 self.log.warn("File does not have a .py or .ipy extension: <%s>" % full_filename)
419 except:
420 self.log.warn("Unknown error in handling Global.exec_files:")
421 self.shell.showtraceback()
422
331 423 def start_app(self):
424 self.log.debug("Starting IPython's mainloop...")
332 425 self.shell.mainloop()
333 426
334 427
@@ -55,8 +55,9 from IPython.utils.ipstruct import Struct
55 55 from IPython.utils import PyColorize
56 56 from IPython.utils.genutils import *
57 57 from IPython.utils.genutils import get_ipython_dir
58 from IPython.utils.strdispatch import StrDispatch
59 58 from IPython.utils.platutils import toggle_set_term_title, set_term_title
59 from IPython.utils.strdispatch import StrDispatch
60 from IPython.utils.syspathcontext import prepended_to_syspath
60 61
61 62 # from IPython.utils import growl
62 63 # growl.start("IPython")
@@ -185,7 +186,6 class InteractiveShell(Component, Magic):
185 186 autoedit_syntax = CBool(False, config=True)
186 187 autoindent = CBool(True, config=True)
187 188 automagic = CBool(True, config=True)
188 display_banner = CBool(True, config=True)
189 189 banner = Str('')
190 190 banner1 = Str(default_banner, config=True)
191 191 banner2 = Str('', config=True)
@@ -197,6 +197,12 class InteractiveShell(Component, Magic):
197 197 confirm_exit = CBool(True, config=True)
198 198 debug = CBool(False, config=True)
199 199 deep_reload = CBool(False, config=True)
200 # This display_banner only controls whether or not self.show_banner()
201 # is called when mainloop/interact are called. The default is False
202 # because for the terminal based application, the banner behavior
203 # is controlled by Global.display_banner, which IPythonApp looks at
204 # to determine if *it* should call show_banner() by hand or not.
205 display_banner = CBool(False) # This isn't configurable!
200 206 embedded = CBool(False)
201 207 embedded_active = CBool(False)
202 208 editor = Str(get_default_editor(), config=True)
@@ -262,7 +268,7 class InteractiveShell(Component, Magic):
262 268
263 269 def __init__(self, parent=None, config=None, ipythondir=None, usage=None,
264 270 user_ns=None, user_global_ns=None,
265 banner1=None, banner2=None,
271 banner1=None, banner2=None, display_banner=None,
266 272 custom_exceptions=((),None)):
267 273
268 274 # This is where traitlets with a config_key argument are updated
@@ -274,7 +280,7 class InteractiveShell(Component, Magic):
274 280 self.init_instance_attrs()
275 281 self.init_term_title()
276 282 self.init_usage(usage)
277 self.init_banner(banner1, banner2)
283 self.init_banner(banner1, banner2, display_banner)
278 284
279 285 # Create namespaces (user_ns, user_global_ns, etc.)
280 286 self.init_create_namespaces(user_ns, user_global_ns)
@@ -331,6 +337,12 class InteractiveShell(Component, Magic):
331 337 def _ipythondir_changed(self, name, new):
332 338 if not os.path.isdir(new):
333 339 os.makedirs(new, mode = 0777)
340 if not os.path.isdir(self.ipython_extension_dir):
341 os.makedirs(self.ipython_extension_dir, mode = 0777)
342
343 @property
344 def ipython_extension_dir(self):
345 return os.path.join(self.ipythondir, 'extensions')
334 346
335 347 @property
336 348 def usable_screen_length(self):
@@ -429,22 +441,6 class InteractiveShell(Component, Magic):
429 441 else:
430 442 self.usage = usage
431 443
432 def init_banner(self, banner1, banner2):
433 if self.c: # regular python doesn't print the banner with -c
434 self.display_banner = False
435 if banner1 is not None:
436 self.banner1 = banner1
437 if banner2 is not None:
438 self.banner2 = banner2
439 self.compute_banner()
440
441 def compute_banner(self):
442 self.banner = self.banner1 + '\n'
443 if self.profile:
444 self.banner += '\nIPython profile: %s\n' % self.profile
445 if self.banner2:
446 self.banner += '\n' + self.banner2 + '\n'
447
448 444 def init_encoding(self):
449 445 # Get system encoding at startup time. Certain terminals (like Emacs
450 446 # under Win32 have it set to None, and we need to have a known valid
@@ -486,7 +482,7 class InteractiveShell(Component, Magic):
486 482 def init_logstart(self):
487 483 if self.logplay:
488 484 self.magic_logstart(self.logplay + ' append')
489 elif self.logfile:
485 elif self.logfile:
490 486 self.magic_logstart(self.logfile)
491 487 elif self.logstart:
492 488 self.magic_logstart()
@@ -532,6 +528,31 class InteractiveShell(Component, Magic):
532 528 warn("doctest module does not exist.")
533 529
534 530 #-------------------------------------------------------------------------
531 # Things related to the banner
532 #-------------------------------------------------------------------------
533
534 def init_banner(self, banner1, banner2, display_banner):
535 if banner1 is not None:
536 self.banner1 = banner1
537 if banner2 is not None:
538 self.banner2 = banner2
539 if display_banner is not None:
540 self.display_banner = display_banner
541 self.compute_banner()
542
543 def show_banner(self, banner=None):
544 if banner is None:
545 banner = self.banner
546 self.write(banner)
547
548 def compute_banner(self):
549 self.banner = self.banner1 + '\n'
550 if self.profile:
551 self.banner += '\nIPython profile: %s\n' % self.profile
552 if self.banner2:
553 self.banner += '\n' + self.banner2 + '\n'
554
555 #-------------------------------------------------------------------------
535 556 # Things related to injections into the sys module
536 557 #-------------------------------------------------------------------------
537 558
@@ -1673,7 +1694,7 class InteractiveShell(Component, Magic):
1673 1694 with nested(self.builtin_trap,):
1674 1695 return eval(expr, self.user_global_ns, self.user_ns)
1675 1696
1676 def mainloop(self, banner=None):
1697 def mainloop(self, display_banner=None):
1677 1698 """Start the mainloop.
1678 1699
1679 1700 If an optional banner argument is given, it will override the
@@ -1684,10 +1705,6 class InteractiveShell(Component, Magic):
1684 1705 if self.c: # Emulate Python's -c option
1685 1706 self.exec_init_cmd()
1686 1707
1687 if self.display_banner:
1688 if banner is None:
1689 banner = self.banner
1690
1691 1708 # if you run stuff with -c <cmd>, raw hist is not updated
1692 1709 # ensure that it's in sync
1693 1710 if len(self.input_hist) != len (self.input_hist_raw):
@@ -1695,7 +1712,7 class InteractiveShell(Component, Magic):
1695 1712
1696 1713 while 1:
1697 1714 try:
1698 self.interact()
1715 self.interact(display_banner=display_banner)
1699 1716 #self.interact_with_readline()
1700 1717 # XXX for testing of a readline-decoupled repl loop, call
1701 1718 # interact_with_readline above
@@ -1774,17 +1791,17 class InteractiveShell(Component, Magic):
1774 1791 line = raw_input_original().decode(self.stdin_encoding)
1775 1792 self.interact_handle_input(line)
1776 1793
1777 def interact(self, banner=None):
1794 def interact(self, display_banner=None):
1778 1795 """Closely emulate the interactive Python console."""
1779 1796
1780 1797 # batch run -> do not interact
1781 1798 if self.exit_now:
1782 1799 return
1783 1800
1784 if self.display_banner:
1785 if banner is None:
1786 banner = self.banner
1787 self.write(banner)
1801 if display_banner is None:
1802 display_banner = self.display_banner
1803 if display_banner:
1804 self.show_banner()
1788 1805
1789 1806 more = 0
1790 1807
@@ -1856,128 +1873,45 class InteractiveShell(Component, Magic):
1856 1873 # We are off again...
1857 1874 __builtin__.__dict__['__IPYTHON__active'] -= 1
1858 1875
1859 def safe_execfile(self,fname,*where,**kw):
1876 def safe_execfile(self, fname, *where, **kw):
1860 1877 """A safe version of the builtin execfile().
1861 1878
1862 This version will never throw an exception, and knows how to handle
1863 ipython logs as well.
1879 This version will never throw an exception, but instead print
1880 helpful error messages to the screen. This only works on pure
1881 Python files with the .py extension.
1864 1882
1865 :Parameters:
1866 fname : string
1867 Name of the file to be executed.
1868
1869 where : tuple
1883 Parameters
1884 ----------
1885 fname : string
1886 The name of the file to be executed.
1887 where : tuple
1870 1888 One or two namespaces, passed to execfile() as (globals,locals).
1871 1889 If only one is given, it is passed as both.
1890 exit_ignore : bool (False)
1891 If True, then don't print errors for non-zero exit statuses.
1892 """
1893 kw.setdefault('exit_ignore', False)
1872 1894
1873 :Keywords:
1874 islog : boolean (False)
1875
1876 quiet : boolean (True)
1895 fname = os.path.abspath(os.path.expanduser(fname))
1877 1896
1878 exit_ignore : boolean (False)
1879 """
1897 # Make sure we have a .py file
1898 if not fname.endswith('.py'):
1899 warn('File must end with .py to be run using execfile: <%s>' % fname)
1880 1900
1881 def syspath_cleanup():
1882 """Internal cleanup routine for sys.path."""
1883 if add_dname:
1884 try:
1885 sys.path.remove(dname)
1886 except ValueError:
1887 # For some reason the user has already removed it, ignore.
1888 pass
1889
1890 fname = os.path.expanduser(fname)
1901 # Make sure we can open the file
1902 try:
1903 with open(fname) as thefile:
1904 pass
1905 except:
1906 warn('Could not open file <%s> for safe execution.' % fname)
1907 return
1891 1908
1892 1909 # Find things also in current directory. This is needed to mimic the
1893 1910 # behavior of running a script from the system command line, where
1894 1911 # Python inserts the script's directory into sys.path
1895 dname = os.path.dirname(os.path.abspath(fname))
1896 add_dname = False
1897 if dname not in sys.path:
1898 sys.path.insert(0,dname)
1899 add_dname = True
1900
1901 try:
1902 xfile = open(fname)
1903 except:
1904 print >> Term.cerr, \
1905 'Could not open file <%s> for safe execution.' % fname
1906 syspath_cleanup()
1907 return None
1912 dname = os.path.dirname(fname)
1908 1913
1909 kw.setdefault('islog',0)
1910 kw.setdefault('quiet',1)
1911 kw.setdefault('exit_ignore',0)
1912
1913 first = xfile.readline()
1914 loghead = str(self.loghead_tpl).split('\n',1)[0].strip()
1915 xfile.close()
1916 # line by line execution
1917 if first.startswith(loghead) or kw['islog']:
1918 print 'Loading log file <%s> one line at a time...' % fname
1919 if kw['quiet']:
1920 stdout_save = sys.stdout
1921 sys.stdout = StringIO.StringIO()
1922 try:
1923 globs,locs = where[0:2]
1924 except:
1925 try:
1926 globs = locs = where[0]
1927 except:
1928 globs = locs = globals()
1929 badblocks = []
1930
1931 # we also need to identify indented blocks of code when replaying
1932 # logs and put them together before passing them to an exec
1933 # statement. This takes a bit of regexp and look-ahead work in the
1934 # file. It's easiest if we swallow the whole thing in memory
1935 # first, and manually walk through the lines list moving the
1936 # counter ourselves.
1937 indent_re = re.compile('\s+\S')
1938 xfile = open(fname)
1939 filelines = xfile.readlines()
1940 xfile.close()
1941 nlines = len(filelines)
1942 lnum = 0
1943 while lnum < nlines:
1944 line = filelines[lnum]
1945 lnum += 1
1946 # don't re-insert logger status info into cache
1947 if line.startswith('#log#'):
1948 continue
1949 else:
1950 # build a block of code (maybe a single line) for execution
1951 block = line
1952 try:
1953 next = filelines[lnum] # lnum has already incremented
1954 except:
1955 next = None
1956 while next and indent_re.match(next):
1957 block += next
1958 lnum += 1
1959 try:
1960 next = filelines[lnum]
1961 except:
1962 next = None
1963 # now execute the block of one or more lines
1964 try:
1965 exec block in globs,locs
1966 except SystemExit:
1967 pass
1968 except:
1969 badblocks.append(block.rstrip())
1970 if kw['quiet']: # restore stdout
1971 sys.stdout.close()
1972 sys.stdout = stdout_save
1973 print 'Finished replaying log file <%s>' % fname
1974 if badblocks:
1975 print >> sys.stderr, ('\nThe following lines/blocks in file '
1976 '<%s> reported errors:' % fname)
1977
1978 for badline in badblocks:
1979 print >> sys.stderr, badline
1980 else: # regular file execution
1914 with prepended_to_syspath(dname):
1981 1915 try:
1982 1916 if sys.platform == 'win32' and sys.version_info < (2,5,1):
1983 1917 # Work around a bug in Python for Windows. The bug was
@@ -1997,7 +1931,7 class InteractiveShell(Component, Magic):
1997 1931 except SyntaxError:
1998 1932 self.showsyntaxerror()
1999 1933 warn('Failure executing file: <%s>' % fname)
2000 except SystemExit,status:
1934 except SystemExit, status:
2001 1935 # Code that correctly sets the exit status flag to success (0)
2002 1936 # shouldn't be bothered with a traceback. Note that a plain
2003 1937 # sys.exit() does NOT set the message to 0 (it's empty) so that
@@ -2005,13 +1939,8 class InteractiveShell(Component, Magic):
2005 1939 # SystemExit exception changed between Python 2.4 and 2.5, so
2006 1940 # the checks must be done in a version-dependent way.
2007 1941 show = False
2008
2009 if sys.version_info[:2] > (2,5):
2010 if status.message!=0 and not kw['exit_ignore']:
2011 show = True
2012 else:
2013 if status.code and not kw['exit_ignore']:
2014 show = True
1942 if status.message!=0 and not kw['exit_ignore']:
1943 show = True
2015 1944 if show:
2016 1945 self.showtraceback()
2017 1946 warn('Failure executing file: <%s>' % fname)
@@ -2019,46 +1948,82 class InteractiveShell(Component, Magic):
2019 1948 self.showtraceback()
2020 1949 warn('Failure executing file: <%s>' % fname)
2021 1950
2022 syspath_cleanup()
1951 def safe_execfile_ipy(self, fname):
1952 """Like safe_execfile, but for .ipy files with IPython syntax.
1953
1954 Parameters
1955 ----------
1956 fname : str
1957 The name of the file to execute. The filename must have a
1958 .ipy extension.
1959 """
1960 fname = os.path.abspath(os.path.expanduser(fname))
1961
1962 # Make sure we have a .py file
1963 if not fname.endswith('.ipy'):
1964 warn('File must end with .py to be run using execfile: <%s>' % fname)
1965
1966 # Make sure we can open the file
1967 try:
1968 with open(fname) as thefile:
1969 pass
1970 except:
1971 warn('Could not open file <%s> for safe execution.' % fname)
1972 return
1973
1974 # Find things also in current directory. This is needed to mimic the
1975 # behavior of running a script from the system command line, where
1976 # Python inserts the script's directory into sys.path
1977 dname = os.path.dirname(fname)
1978
1979 with prepended_to_syspath(dname):
1980 try:
1981 with open(fname) as thefile:
1982 script = thefile.read()
1983 # self.runlines currently captures all exceptions
1984 # raise in user code. It would be nice if there were
1985 # versions of runlines, execfile that did raise, so
1986 # we could catch the errors.
1987 self.runlines(script, clean=True)
1988 except:
1989 self.showtraceback()
1990 warn('Unknown failure executing file: <%s>' % fname)
1991
1992 def _is_secondary_block_start(self, s):
1993 if not s.endswith(':'):
1994 return False
1995 if (s.startswith('elif') or
1996 s.startswith('else') or
1997 s.startswith('except') or
1998 s.startswith('finally')):
1999 return True
2023 2000
2024 2001 def cleanup_ipy_script(self, script):
2025 2002 """Make a script safe for self.runlines()
2026 2003
2027 Notes
2028 -----
2029 This was copied over from the old ipapi and probably can be done
2030 away with once we move to block based interpreter.
2031
2032 - Removes empty lines Suffixes all indented blocks that end with
2033 - unindented lines with empty lines
2004 Currently, IPython is lines based, with blocks being detected by
2005 empty lines. This is a problem for block based scripts that may
2006 not have empty lines after blocks. This script adds those empty
2007 lines to make scripts safe for running in the current line based
2008 IPython.
2034 2009 """
2035
2036 2010 res = []
2037 2011 lines = script.splitlines()
2038
2039 2012 level = 0
2013
2040 2014 for l in lines:
2041 2015 lstripped = l.lstrip()
2042 2016 stripped = l.strip()
2043 2017 if not stripped:
2044 2018 continue
2045 newlevel = len(l) - len(lstripped)
2046 def is_secondary_block_start(s):
2047 if not s.endswith(':'):
2048 return False
2049 if (s.startswith('elif') or
2050 s.startswith('else') or
2051 s.startswith('except') or
2052 s.startswith('finally')):
2053 return True
2054
2019 newlevel = len(l) - len(lstripped)
2055 2020 if level > 0 and newlevel == 0 and \
2056 not is_secondary_block_start(stripped):
2021 not self._is_secondary_block_start(stripped):
2057 2022 # add empty line
2058 2023 res.append('')
2059
2060 2024 res.append(l)
2061 2025 level = newlevel
2026
2062 2027 return '\n'.join(res) + '\n'
2063 2028
2064 2029 def runlines(self, lines, clean=False):
@@ -2091,7 +2056,8 class InteractiveShell(Component, Magic):
2091 2056 if line or more:
2092 2057 # push to raw history, so hist line numbers stay in sync
2093 2058 self.input_hist_raw.append("# " + line + "\n")
2094 more = self.push_line(self.prefilter_manager.prefilter_lines(line,more))
2059 prefiltered = self.prefilter_manager.prefilter_lines(line,more)
2060 more = self.push_line(prefiltered)
2095 2061 # IPython's runsource returns None if there was an error
2096 2062 # compiling the code. This allows us to stop processing right
2097 2063 # away, so the user gets the error message at the right place.
@@ -2304,7 +2270,7 class InteractiveShell(Component, Magic):
2304 2270 if line.strip():
2305 2271 if continue_prompt:
2306 2272 self.input_hist_raw[-1] += '%s\n' % line
2307 if self.has_readline: # and some config option is set?
2273 if self.has_readline and self.readline_use:
2308 2274 try:
2309 2275 histlen = self.readline.get_current_history_length()
2310 2276 if histlen > 1:
@@ -2349,37 +2315,56 class InteractiveShell(Component, Magic):
2349 2315 # if batchrun and not self.interactive:
2350 2316 # self.ask_exit()
2351 2317
2352 # def load(self, mod):
2353 # """ Load an extension.
2354 #
2355 # Some modules should (or must) be 'load()':ed, rather than just imported.
2356 #
2357 # Loading will do:
2358 #
2359 # - run init_ipython(ip)
2360 # - run ipython_firstrun(ip)
2361 # """
2362 #
2363 # if mod in self.extensions:
2364 # # just to make sure we don't init it twice
2365 # # note that if you 'load' a module that has already been
2366 # # imported, init_ipython gets run anyway
2367 #
2368 # return self.extensions[mod]
2369 # __import__(mod)
2370 # m = sys.modules[mod]
2371 # if hasattr(m,'init_ipython'):
2372 # m.init_ipython(self)
2373 #
2374 # if hasattr(m,'ipython_firstrun'):
2375 # already_loaded = self.db.get('firstrun_done', set())
2376 # if mod not in already_loaded:
2377 # m.ipython_firstrun(self)
2378 # already_loaded.add(mod)
2379 # self.db['firstrun_done'] = already_loaded
2380 #
2381 # self.extensions[mod] = m
2382 # return m
2318 #-------------------------------------------------------------------------
2319 # IPython extensions
2320 #-------------------------------------------------------------------------
2321
2322 def load_extension(self, module_str):
2323 """Load an IPython extension.
2324
2325 An IPython extension is an importable Python module that has
2326 a function with the signature::
2327
2328 def load_in_ipython(ipython):
2329 # Do things with ipython
2330
2331 This function is called after your extension is imported and the
2332 currently active :class:`InteractiveShell` instance is passed as
2333 the only argument. You can do anything you want with IPython at
2334 that point, including defining new magic and aliases, adding new
2335 components, etc.
2336
2337 You can put your extension modules anywhere you want, as long as
2338 they can be imported by Python's standard import mechanism. However,
2339 to make it easy to write extensions, you can also put your extensions
2340 in ``os.path.join(self.ipythondir, 'extensions')``. This directory
2341 is added to ``sys.path`` automatically.
2342 """
2343 from IPython.utils.syspathcontext import prepended_to_syspath
2344
2345 if module_str in sys.modules:
2346 return
2347
2348 with prepended_to_syspath(self.ipython_extension_dir):
2349 __import__(module_str)
2350 mod = sys.modules[module_str]
2351 self._call_load_in_ipython(mod)
2352
2353 def reload_extension(self, module_str):
2354 """Reload an IPython extension by doing reload."""
2355 from IPython.utils.syspathcontext import prepended_to_syspath
2356
2357 with prepended_to_syspath(self.ipython_extension_dir):
2358 if module_str in sys.modules:
2359 mod = sys.modules[module_str]
2360 reload(mod)
2361 self._call_load_in_ipython(mod)
2362 else:
2363 self.load_extension(self, module_str)
2364
2365 def _call_load_in_ipython(self, mod):
2366 if hasattr(mod, 'load_in_ipython'):
2367 mod.load_in_ipython(self)
2383 2368
2384 2369 #-------------------------------------------------------------------------
2385 2370 # Things related to the prefilter
@@ -1573,7 +1573,7 Currently the magic system has the following functions:\n"""
1573 1573 return
1574 1574
1575 1575 if filename.lower().endswith('.ipy'):
1576 self.runlines(open(filename).read(), clean=True)
1576 self.safe_execfile_ipy(filename)
1577 1577 return
1578 1578
1579 1579 # Control the response to exit() calls made by the script being run
@@ -1743,25 +1743,6 Currently the magic system has the following functions:\n"""
1743 1743
1744 1744 return stats
1745 1745
1746 def magic_runlog(self, parameter_s =''):
1747 """Run files as logs.
1748
1749 Usage:\\
1750 %runlog file1 file2 ...
1751
1752 Run the named files (treating them as log files) in sequence inside
1753 the interpreter, and return to the prompt. This is much slower than
1754 %run because each line is executed in a try/except block, but it
1755 allows running files with syntax errors in them.
1756
1757 Normally IPython will guess when a file is one of its own logfiles, so
1758 you can typically use %run even for logs. This shorthand allows you to
1759 force any file to be treated as a log file."""
1760
1761 for f in parameter_s.split():
1762 self.shell.safe_execfile(f,self.shell.user_ns,
1763 self.shell.user_ns,islog=1)
1764
1765 1746 @testdec.skip_doctest
1766 1747 def magic_timeit(self, parameter_s =''):
1767 1748 """Time execution of a Python statement or expression
@@ -127,12 +127,14 def page(strng,start=0,screen_lines=0,pager_cmd = None):
127 127
128 128 # auto-determine screen size
129 129 if screen_lines <= 0:
130 if TERM=='xterm':
130 if TERM=='xterm' or TERM=='xterm-color':
131 131 use_curses = USE_CURSES
132 132 else:
133 133 # curses causes problems on many terminals other than xterm.
134 134 use_curses = False
135 135 if use_curses:
136 import termios
137 import curses
136 138 # There is a bug in curses, where *sometimes* it fails to properly
137 139 # initialize, and then after the endwin() call is made, the
138 140 # terminal is left in an unusable state. Rather than trying to
@@ -32,6 +32,7 from IPython.core.alias import AliasManager
32 32 from IPython.core.autocall import IPyAutocall
33 33 from IPython.core.component import Component
34 34 from IPython.core.splitinput import split_user_input
35 from IPython.core.page import page
35 36
36 37 from IPython.utils.traitlets import List, Int, Any, Str, CBool
37 38 from IPython.utils.genutils import make_quoted_expr
@@ -183,11 +184,9 class PrefilterManager(Component):
183 184
184 185 @auto_attr
185 186 def shell(self):
186 shell = Component.get_instances(
187 return Component.get_instances(
187 188 root=self.root,
188 klass='IPython.core.iplib.InteractiveShell'
189 )[0]
190 return shell
189 klass='IPython.core.iplib.InteractiveShell')[0]
191 190
192 191 def init_checkers(self):
193 192 self._checkers = []
@@ -319,11 +318,9 class PrefilterChecker(Component):
319 318
320 319 @auto_attr
321 320 def shell(self):
322 shell = Component.get_instances(
321 return Component.get_instances(
323 322 root=self.root,
324 klass='IPython.core.iplib.InteractiveShell'
325 )[0]
326 return shell
323 klass='IPython.core.iplib.InteractiveShell')[0]
327 324
328 325 @auto_attr
329 326 def prefilter_manager(self):
@@ -523,11 +520,9 class PrefilterHandler(Component):
523 520
524 521 @auto_attr
525 522 def shell(self):
526 shell = Component.get_instances(
523 return Component.get_instances(
527 524 root=self.root,
528 klass='IPython.core.iplib.InteractiveShell'
529 )[0]
530 return shell
525 klass='IPython.core.iplib.InteractiveShell')[0]
531 526
532 527 @auto_attr
533 528 def prefilter_manager(self):
General Comments 0
You need to be logged in to leave comments. Login now