##// END OF EJS Templates
Move crash handling to the application level and simplify class structure....
Fernando Perez -
Show More
@@ -1,370 +1,373 b''
1 1 # coding: utf-8
2 2 """A simple configuration system.
3 3
4 4 Authors
5 5 -------
6 6 * Brian Granger
7 7 * Fernando Perez
8 8 """
9 9
10 10 #-----------------------------------------------------------------------------
11 11 # Copyright (C) 2008-2009 The IPython Development Team
12 12 #
13 13 # Distributed under the terms of the BSD License. The full license is in
14 14 # the file COPYING, distributed as part of this software.
15 15 #-----------------------------------------------------------------------------
16 16
17 17 #-----------------------------------------------------------------------------
18 18 # Imports
19 19 #-----------------------------------------------------------------------------
20 20
21 21 import __builtin__
22 22 import os
23 23 import sys
24 24
25 25 from IPython.external import argparse
26 26 from IPython.utils.genutils import filefind
27 27
28 28 #-----------------------------------------------------------------------------
29 29 # Exceptions
30 30 #-----------------------------------------------------------------------------
31 31
32 32
33 33 class ConfigError(Exception):
34 34 pass
35 35
36 36
37 37 class ConfigLoaderError(ConfigError):
38 38 pass
39 39
40 40 #-----------------------------------------------------------------------------
41 41 # Argparse fix
42 42 #-----------------------------------------------------------------------------
43 43 # Unfortunately argparse by default prints help messages to stderr instead of
44 44 # stdout. This makes it annoying to capture long help screens at the command
45 45 # line, since one must know how to pipe stderr, which many users don't know how
46 46 # to do. So we override the print_help method with one that defaults to
47 47 # stdout and use our class instead.
48 48
49 49 class ArgumentParser(argparse.ArgumentParser):
50 50 """Simple argparse subclass that prints help to stdout by default."""
51 51
52 52 def print_help(self, file=None):
53 53 if file is None:
54 54 file = sys.stdout
55 55 return super(ArgumentParser, self).print_help(file)
56 56
57 57 print_help.__doc__ = argparse.ArgumentParser.print_help.__doc__
58 58
59 59 #-----------------------------------------------------------------------------
60 60 # Config class for holding config information
61 61 #-----------------------------------------------------------------------------
62 62
63 63
64 64 class Config(dict):
65 65 """An attribute based dict that can do smart merges."""
66 66
67 67 def __init__(self, *args, **kwds):
68 68 dict.__init__(self, *args, **kwds)
69 69 # This sets self.__dict__ = self, but it has to be done this way
70 70 # because we are also overriding __setattr__.
71 71 dict.__setattr__(self, '__dict__', self)
72 72
73 73 def _merge(self, other):
74 74 to_update = {}
75 75 for k, v in other.items():
76 76 if not self.has_key(k):
77 77 to_update[k] = v
78 78 else: # I have this key
79 79 if isinstance(v, Config):
80 80 # Recursively merge common sub Configs
81 81 self[k]._merge(v)
82 82 else:
83 83 # Plain updates for non-Configs
84 84 to_update[k] = v
85 85
86 86 self.update(to_update)
87 87
88 88 def _is_section_key(self, key):
89 89 if key[0].upper()==key[0] and not key.startswith('_'):
90 90 return True
91 91 else:
92 92 return False
93 93
94 94 def has_key(self, key):
95 95 if self._is_section_key(key):
96 96 return True
97 97 else:
98 98 return dict.has_key(self, key)
99 99
100 100 def _has_section(self, key):
101 101 if self._is_section_key(key):
102 102 if dict.has_key(self, key):
103 103 return True
104 104 return False
105 105
106 106 def copy(self):
107 107 return type(self)(dict.copy(self))
108 108
109 109 def __copy__(self):
110 110 return self.copy()
111 111
112 112 def __deepcopy__(self, memo):
113 113 import copy
114 114 return type(self)(copy.deepcopy(self.items()))
115 115
116 116 def __getitem__(self, key):
117 117 # Because we use this for an exec namespace, we need to delegate
118 118 # the lookup of names in __builtin__ to itself. This means
119 119 # that you can't have section or attribute names that are
120 120 # builtins.
121 121 try:
122 122 return getattr(__builtin__, key)
123 123 except AttributeError:
124 124 pass
125 125 if self._is_section_key(key):
126 126 try:
127 127 return dict.__getitem__(self, key)
128 128 except KeyError:
129 129 c = Config()
130 130 dict.__setitem__(self, key, c)
131 131 return c
132 132 else:
133 133 return dict.__getitem__(self, key)
134 134
135 135 def __setitem__(self, key, value):
136 136 # Don't allow names in __builtin__ to be modified.
137 137 if hasattr(__builtin__, key):
138 138 raise ConfigError('Config variable names cannot have the same name '
139 139 'as a Python builtin: %s' % key)
140 140 if self._is_section_key(key):
141 141 if not isinstance(value, Config):
142 142 raise ValueError('values whose keys begin with an uppercase '
143 143 'char must be Config instances: %r, %r' % (key, value))
144 144 else:
145 145 dict.__setitem__(self, key, value)
146 146
147 147 def __getattr__(self, key):
148 148 try:
149 149 return self.__getitem__(key)
150 150 except KeyError, e:
151 151 raise AttributeError(e)
152 152
153 153 def __setattr__(self, key, value):
154 154 try:
155 155 self.__setitem__(key, value)
156 156 except KeyError, e:
157 157 raise AttributeError(e)
158 158
159 159 def __delattr__(self, key):
160 160 try:
161 161 dict.__delitem__(self, key)
162 162 except KeyError, e:
163 163 raise AttributeError(e)
164 164
165 165
166 166 #-----------------------------------------------------------------------------
167 167 # Config loading classes
168 168 #-----------------------------------------------------------------------------
169 169
170 170
171 171 class ConfigLoader(object):
172 172 """A object for loading configurations from just about anywhere.
173 173
174 174 The resulting configuration is packaged as a :class:`Struct`.
175 175
176 176 Notes
177 177 -----
178 178 A :class:`ConfigLoader` does one thing: load a config from a source
179 179 (file, command line arguments) and returns the data as a :class:`Struct`.
180 180 There are lots of things that :class:`ConfigLoader` does not do. It does
181 181 not implement complex logic for finding config files. It does not handle
182 182 default values or merge multiple configs. These things need to be
183 183 handled elsewhere.
184 184 """
185 185
186 186 def __init__(self):
187 187 """A base class for config loaders.
188 188
189 189 Examples
190 190 --------
191 191
192 192 >>> cl = ConfigLoader()
193 193 >>> config = cl.load_config()
194 194 >>> config
195 195 {}
196 196 """
197 197 self.clear()
198 198
199 199 def clear(self):
200 200 self.config = Config()
201 201
202 202 def load_config(self):
203 203 """Load a config from somewhere, return a Struct.
204 204
205 205 Usually, this will cause self.config to be set and then returned.
206 206 """
207 207 return self.config
208 208
209 209
210 210 class FileConfigLoader(ConfigLoader):
211 211 """A base class for file based configurations.
212 212
213 213 As we add more file based config loaders, the common logic should go
214 214 here.
215 215 """
216 216 pass
217 217
218 218
219 219 class PyFileConfigLoader(FileConfigLoader):
220 220 """A config loader for pure python files.
221 221
222 222 This calls execfile on a plain python file and looks for attributes
223 223 that are all caps. These attribute are added to the config Struct.
224 224 """
225 225
226 226 def __init__(self, filename, path=None):
227 227 """Build a config loader for a filename and path.
228 228
229 229 Parameters
230 230 ----------
231 231 filename : str
232 232 The file name of the config file.
233 233 path : str, list, tuple
234 234 The path to search for the config file on, or a sequence of
235 235 paths to try in order.
236 236 """
237 237 super(PyFileConfigLoader, self).__init__()
238 238 self.filename = filename
239 239 self.path = path
240 240 self.full_filename = ''
241 241 self.data = None
242 242
243 243 def load_config(self):
244 244 """Load the config from a file and return it as a Struct."""
245 245 self._find_file()
246 246 self._read_file_as_dict()
247 247 self._convert_to_config()
248 248 return self.config
249 249
250 250 def _find_file(self):
251 251 """Try to find the file by searching the paths."""
252 252 self.full_filename = filefind(self.filename, self.path)
253 253
254 254 def _read_file_as_dict(self):
255 255 """Load the config file into self.config, with recursive loading."""
256 256 # This closure is made available in the namespace that is used
257 257 # to exec the config file. This allows users to call
258 258 # load_subconfig('myconfig.py') to load config files recursively.
259 259 # It needs to be a closure because it has references to self.path
260 260 # and self.config. The sub-config is loaded with the same path
261 261 # as the parent, but it uses an empty config which is then merged
262 262 # with the parents.
263 263 def load_subconfig(fname):
264 264 loader = PyFileConfigLoader(fname, self.path)
265 265 try:
266 266 sub_config = loader.load_config()
267 267 except IOError:
268 268 # Pass silently if the sub config is not there. This happens
269 269 # when a user us using a profile, but not the default config.
270 270 pass
271 271 else:
272 272 self.config._merge(sub_config)
273 273
274 274 # Again, this needs to be a closure and should be used in config
275 275 # files to get the config being loaded.
276 276 def get_config():
277 277 return self.config
278 278
279 279 namespace = dict(load_subconfig=load_subconfig, get_config=get_config)
280 280 execfile(self.full_filename, namespace)
281 281
282 282 def _convert_to_config(self):
283 283 if self.data is None:
284 284 ConfigLoaderError('self.data does not exist')
285 285
286 286
287 287 class CommandLineConfigLoader(ConfigLoader):
288 288 """A config loader for command line arguments.
289 289
290 290 As we add more command line based loaders, the common logic should go
291 291 here.
292 292 """
293 293
294 294
295 295 class NoConfigDefault(object): pass
296 296 NoConfigDefault = NoConfigDefault()
297 297
298 298
299 299 class ArgParseConfigLoader(CommandLineConfigLoader):
300 300
301 # arguments = [(('-f','--file'),dict(type=str,dest='file'))]
302 arguments = ()
303
304 def __init__(self, argv=None, *args, **kw):
301 def __init__(self, argv=None, arguments=(), *args, **kw):
305 302 """Create a config loader for use with argparse.
306 303
307 With the exception of argv, other args and kwargs arguments here are
308 passed onto the constructor of :class:`argparse.ArgumentParser`.
304 With the exception of ``argv`` and ``arguments``, other args and kwargs
305 arguments here are passed onto the constructor of
306 :class:`argparse.ArgumentParser`.
309 307
310 308 Parameters
311 309 ----------
312 310
313 311 argv : optional, list
314 312 If given, used to read command-line arguments from, otherwise
315 313 sys.argv[1:] is used.
314
315 arguments : optional, tuple
316 Description of valid command-line arguments, to be called in sequence
317 with parser.add_argument() to configure the parser.
316 318 """
317 319 super(CommandLineConfigLoader, self).__init__()
318 320 if argv == None:
319 321 argv = sys.argv[1:]
320 322 self.argv = argv
323 self.arguments = arguments
321 324 self.args = args
322 325 self.kw = kw
323 326
324 327 def load_config(self, args=None):
325 328 """Parse command line arguments and return as a Struct.
326 329
327 330 Parameters
328 331 ----------
329 332
330 333 args : optional, list
331 334 If given, a list with the structure of sys.argv[1:] to parse arguments
332 335 from. If not given, the instance's self.argv attribute (given at
333 336 construction time) is used."""
334 337
335 338 if args is None:
336 339 args = self.argv
337 340 self._create_parser()
338 341 self._parse_args(args)
339 342 self._convert_to_config()
340 343 return self.config
341 344
342 345 def get_extra_args(self):
343 346 if hasattr(self, 'extra_args'):
344 347 return self.extra_args
345 348 else:
346 349 return []
347 350
348 351 def _create_parser(self):
349 352 self.parser = ArgumentParser(*self.args, **self.kw)
350 353 self._add_arguments()
351 354 self._add_other_arguments()
352 355
353 356 def _add_other_arguments(self):
354 357 pass
355 358
356 359 def _add_arguments(self):
357 360 for argument in self.arguments:
358 361 argument[1].setdefault('default', NoConfigDefault)
359 362 self.parser.add_argument(*argument[0],**argument[1])
360 363
361 364 def _parse_args(self, args):
362 365 """self.parser->self.parsed_data"""
363 366 self.parsed_data, self.extra_args = self.parser.parse_known_args(args)
364 367
365 368 def _convert_to_config(self):
366 369 """self.parsed_data->self.config"""
367 370 for k, v in vars(self.parsed_data).items():
368 371 if v is not NoConfigDefault:
369 372 exec_str = 'self.config.' + k + '= v'
370 373 exec exec_str in locals(), globals()
@@ -1,164 +1,162 b''
1 1 #!/usr/bin/env python
2 2 # encoding: utf-8
3 3 """
4 4 Tests for IPython.config.loader
5 5
6 6 Authors:
7 7
8 8 * Brian Granger
9 9 * Fernando Perez (design help)
10 10 """
11 11
12 12 #-----------------------------------------------------------------------------
13 13 # Copyright (C) 2008-2009 The IPython Development Team
14 14 #
15 15 # Distributed under the terms of the BSD License. The full license is in
16 16 # the file COPYING, distributed as part of this software.
17 17 #-----------------------------------------------------------------------------
18 18
19 19 #-----------------------------------------------------------------------------
20 20 # Imports
21 21 #-----------------------------------------------------------------------------
22 22
23 23 import os
24 24 from tempfile import mkstemp
25 25 from unittest import TestCase
26 26
27 27 from IPython.config.loader import (
28 28 Config,
29 29 PyFileConfigLoader,
30 30 ArgParseConfigLoader,
31 31 ConfigError
32 32 )
33 33
34 34 #-----------------------------------------------------------------------------
35 35 # Actual tests
36 36 #-----------------------------------------------------------------------------
37 37
38 38
39 39 pyfile = """
40 40 c = get_config()
41 41 c.a = 10
42 42 c.b = 20
43 43 c.Foo.Bar.value = 10
44 44 c.Foo.Bam.value = range(10)
45 45 c.D.C.value = 'hi there'
46 46 """
47 47
48 48 class TestPyFileCL(TestCase):
49 49
50 50 def test_basic(self):
51 51 fd, fname = mkstemp('.py')
52 52 f = os.fdopen(fd, 'w')
53 53 f.write(pyfile)
54 54 f.close()
55 55 # Unlink the file
56 56 cl = PyFileConfigLoader(fname)
57 57 config = cl.load_config()
58 58 self.assertEquals(config.a, 10)
59 59 self.assertEquals(config.b, 20)
60 60 self.assertEquals(config.Foo.Bar.value, 10)
61 61 self.assertEquals(config.Foo.Bam.value, range(10))
62 62 self.assertEquals(config.D.C.value, 'hi there')
63 63
64 64
65 65 class TestArgParseCL(TestCase):
66 66
67 67 def test_basic(self):
68 68
69 class MyLoader(ArgParseConfigLoader):
70 arguments = (
69 arguments = (
71 70 (('-f','--foo'), dict(dest='Global.foo', type=str)),
72 71 (('-b',), dict(dest='MyClass.bar', type=int)),
73 72 (('-n',), dict(dest='n', action='store_true')),
74 73 (('Global.bam',), dict(type=str))
75 74 )
76
77 cl = MyLoader()
75 cl = ArgParseConfigLoader(arguments=arguments)
78 76 config = cl.load_config('-f hi -b 10 -n wow'.split())
79 77 self.assertEquals(config.Global.foo, 'hi')
80 78 self.assertEquals(config.MyClass.bar, 10)
81 79 self.assertEquals(config.n, True)
82 80 self.assertEquals(config.Global.bam, 'wow')
83 81
84 82 def test_add_arguments(self):
85 83
86 84 class MyLoader(ArgParseConfigLoader):
87 85 def _add_arguments(self):
88 86 subparsers = self.parser.add_subparsers(dest='subparser_name')
89 87 subparser1 = subparsers.add_parser('1')
90 88 subparser1.add_argument('-x',dest='Global.x')
91 89 subparser2 = subparsers.add_parser('2')
92 90 subparser2.add_argument('y')
93 91
94 92 cl = MyLoader()
95 93 config = cl.load_config('2 frobble'.split())
96 94 self.assertEquals(config.subparser_name, '2')
97 95 self.assertEquals(config.y, 'frobble')
98 96 config = cl.load_config('1 -x frobble'.split())
99 97 self.assertEquals(config.subparser_name, '1')
100 98 self.assertEquals(config.Global.x, 'frobble')
101 99
102 100 class TestConfig(TestCase):
103 101
104 102 def test_setget(self):
105 103 c = Config()
106 104 c.a = 10
107 105 self.assertEquals(c.a, 10)
108 106 self.assertEquals(c.has_key('b'), False)
109 107
110 108 def test_auto_section(self):
111 109 c = Config()
112 110 self.assertEquals(c.has_key('A'), True)
113 111 self.assertEquals(c._has_section('A'), False)
114 112 A = c.A
115 113 A.foo = 'hi there'
116 114 self.assertEquals(c._has_section('A'), True)
117 115 self.assertEquals(c.A.foo, 'hi there')
118 116 del c.A
119 117 self.assertEquals(len(c.A.keys()),0)
120 118
121 119 def test_merge_doesnt_exist(self):
122 120 c1 = Config()
123 121 c2 = Config()
124 122 c2.bar = 10
125 123 c2.Foo.bar = 10
126 124 c1._merge(c2)
127 125 self.assertEquals(c1.Foo.bar, 10)
128 126 self.assertEquals(c1.bar, 10)
129 127 c2.Bar.bar = 10
130 128 c1._merge(c2)
131 129 self.assertEquals(c1.Bar.bar, 10)
132 130
133 131 def test_merge_exists(self):
134 132 c1 = Config()
135 133 c2 = Config()
136 134 c1.Foo.bar = 10
137 135 c1.Foo.bam = 30
138 136 c2.Foo.bar = 20
139 137 c2.Foo.wow = 40
140 138 c1._merge(c2)
141 139 self.assertEquals(c1.Foo.bam, 30)
142 140 self.assertEquals(c1.Foo.bar, 20)
143 141 self.assertEquals(c1.Foo.wow, 40)
144 142 c2.Foo.Bam.bam = 10
145 143 c1._merge(c2)
146 144 self.assertEquals(c1.Foo.Bam.bam, 10)
147 145
148 146 def test_deepcopy(self):
149 147 c1 = Config()
150 148 c1.Foo.bar = 10
151 149 c1.Foo.bam = 30
152 150 c1.a = 'asdf'
153 151 c1.b = range(10)
154 152 import copy
155 153 c2 = copy.deepcopy(c1)
156 154 self.assertEquals(c1, c2)
157 155 self.assert_(c1 is not c2)
158 156 self.assert_(c1.Foo is not c2.Foo)
159 157
160 158 def test_builtin(self):
161 159 c1 = Config()
162 160 exec 'foo = True' in c1
163 161 self.assertEquals(c1.foo, True)
164 162 self.assertRaises(ConfigError, setattr, c1, 'ValueError', 10)
@@ -1,390 +1,431 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 from IPython.core import release
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 49
50 50 class BaseAppArgParseConfigLoader(ArgParseConfigLoader):
51 51 """Default command line options for IPython based applications."""
52 52
53 53 def _add_other_arguments(self):
54 54 self.parser.add_argument('--ipython-dir',
55 55 dest='Global.ipython_dir',type=unicode,
56 56 help='Set to override default location of Global.ipython_dir.',
57 57 default=NoConfigDefault,
58 58 metavar='Global.ipython_dir')
59 59 self.parser.add_argument('-p', '--profile',
60 60 dest='Global.profile',type=unicode,
61 61 help='The string name of the ipython profile to be used.',
62 62 default=NoConfigDefault,
63 63 metavar='Global.profile')
64 64 self.parser.add_argument('--log-level',
65 65 dest="Global.log_level",type=int,
66 66 help='Set the log level (0,10,20,30,40,50). Default is 30.',
67 67 default=NoConfigDefault,
68 68 metavar='Global.log_level')
69 69 self.parser.add_argument('--config-file',
70 70 dest='Global.config_file',type=unicode,
71 71 help='Set the config file name to override default.',
72 72 default=NoConfigDefault,
73 73 metavar='Global.config_file')
74 74
75 75
76 76 class ApplicationError(Exception):
77 77 pass
78 78
79 79
80 app_cl_args = (
81 (('--ipython-dir', ), dict(
82 dest='Global.ipython_dir',type=unicode,
83 help='Set to override default location of Global.ipython_dir.',
84 default=NoConfigDefault,
85 metavar='Global.ipython_dir') ),
86 (('-p', '--profile',), dict(
87 dest='Global.profile',type=unicode,
88 help='The string name of the ipython profile to be used.',
89 default=NoConfigDefault,
90 metavar='Global.profile') ),
91 (('--log-level',), dict(
92 dest="Global.log_level",type=int,
93 help='Set the log level (0,10,20,30,40,50). Default is 30.',
94 default=NoConfigDefault,
95 metavar='Global.log_level')),
96 (('--config-file',), dict(
97 dest='Global.config_file',type=unicode,
98 help='Set the config file name to override default.',
99 default=NoConfigDefault,
100 metavar='Global.config_file')),
101 )
102
80 103 class Application(object):
81 104 """Load a config, construct components and set them running."""
82 105
83 106 name = u'ipython'
84 107 description = 'IPython: an enhanced interactive Python shell.'
85 108
86 109 config_file_name = u'ipython_config.py'
87 110 # Track the default and actual separately because some messages are
88 111 # only printed if we aren't using the default.
89 112 default_config_file_name = config_file_name
90 113 default_log_level = logging.WARN
91 114 # Set by --profile option
92 115 profile_name = None
93 116 #: User's ipython directory, typically ~/.ipython/
94 117 ipython_dir = None
95 118 #: A reference to the argv to be used (typically ends up being sys.argv[1:])
96 119 argv = None
120 #: Default command line arguments. Subclasses should create a new tuple
121 #: that *includes* these.
122 cl_arguments = app_cl_args
97 123
98 124 # Private attributes
99 125 _exiting = False
100 126 _initialized = False
101 127
128 # Class choices for things that will be instantiated at runtime.
129 _CrashHandler = crashhandler.CrashHandler
130
102 131 def __init__(self, argv=None):
103 132 self.argv = sys.argv[1:] if argv is None else argv
104 133 self.init_logger()
105 134
106 135 def init_logger(self):
107 136 self.log = logging.getLogger(self.__class__.__name__)
108 137 # This is used as the default until the command line arguments are read.
109 138 self.log.setLevel(self.default_log_level)
110 139 self._log_handler = logging.StreamHandler()
111 140 self._log_formatter = logging.Formatter("[%(name)s] %(message)s")
112 141 self._log_handler.setFormatter(self._log_formatter)
113 142 self.log.addHandler(self._log_handler)
114 143
115 144 def _set_log_level(self, level):
116 145 self.log.setLevel(level)
117 146
118 147 def _get_log_level(self):
119 148 return self.log.level
120 149
121 150 log_level = property(_get_log_level, _set_log_level)
122 151
123 152 def initialize(self):
124 153 """Start the application."""
125 154
126 155 if self._initialized:
127 156 return
128
129 self.attempt(self.create_default_config)
157
158 # The first part is protected with an 'attempt' wrapper, that will log
159 # failures with the basic system traceback machinery. Once our crash
160 # handler is in place, we can let any subsequent exception propagate,
161 # as our handler will log it with much better detail than the default.
162 self.attempt(self.create_crash_handler)
163 self.create_default_config()
130 164 self.log_default_config()
131 165 self.set_default_config_log_level()
132 self.attempt(self.pre_load_command_line_config)
133 self.attempt(self.load_command_line_config, action='abort')
166 self.pre_load_command_line_config()
167 self.load_command_line_config()
134 168 self.set_command_line_config_log_level()
135 self.attempt(self.post_load_command_line_config)
169 self.post_load_command_line_config()
136 170 self.log_command_line_config()
137 self.attempt(self.find_ipython_dir)
138 self.attempt(self.find_resources)
139 self.attempt(self.find_config_file_name)
140 self.attempt(self.find_config_file_paths)
141 self.attempt(self.pre_load_file_config)
142 self.attempt(self.load_file_config)
171 self.find_ipython_dir()
172 self.find_resources()
173 self.find_config_file_name()
174 self.find_config_file_paths()
175 self.pre_load_file_config()
176 self.load_file_config()
143 177 self.set_file_config_log_level()
144 self.attempt(self.post_load_file_config)
178 self.post_load_file_config()
145 179 self.log_file_config()
146 self.attempt(self.merge_configs)
180 self.merge_configs()
147 181 self.log_master_config()
148 self.attempt(self.pre_construct)
149 self.attempt(self.construct)
150 self.attempt(self.post_construct)
182 self.pre_construct()
183 self.construct()
184 self.post_construct()
151 185 self._initialized = True
152 186
153 187 def start(self):
154 188 self.initialize()
155 self.attempt(self.start_app)
189 self.start_app()
156 190
157 191 #-------------------------------------------------------------------------
158 192 # Various stages of Application creation
159 193 #-------------------------------------------------------------------------
160 194
195 def create_crash_handler(self):
196 """Create a crash handler, typically setting sys.excepthook to it."""
197 self.crash_handler = self._CrashHandler(self, self.name)
198 sys.excepthook = self.crash_handler
199
161 200 def create_default_config(self):
162 201 """Create defaults that can't be set elsewhere.
163 202
164 203 For the most part, we try to set default in the class attributes
165 204 of Components. But, defaults the top-level Application (which is
166 205 not a HasTraitlets or Component) are not set in this way. Instead
167 206 we set them here. The Global section is for variables like this that
168 207 don't belong to a particular component.
169 208 """
170 209 c = Config()
171 210 c.Global.ipython_dir = get_ipython_dir()
172 211 c.Global.log_level = self.log_level
173 212 self.default_config = c
174 213
175 214 def log_default_config(self):
176 215 self.log.debug('Default config loaded:')
177 216 self.log.debug(repr(self.default_config))
178 217
179 218 def set_default_config_log_level(self):
180 219 try:
181 220 self.log_level = self.default_config.Global.log_level
182 221 except AttributeError:
183 222 # Fallback to the default_log_level class attribute
184 223 pass
185 224
186 225 def create_command_line_config(self):
187 226 """Create and return a command line config loader."""
188 return BaseAppArgParseConfigLoader(self.argv,
189 description=self.description,
190 version=release.version
191 )
227 return ArgParseConfigLoader(self.argv, self.cl_arguments,
228 description=self.description,
229 version=release.version)
192 230
193 231 def pre_load_command_line_config(self):
194 232 """Do actions just before loading the command line config."""
195 233 pass
196 234
197 235 def load_command_line_config(self):
198 236 """Load the command line config."""
199 237 loader = self.create_command_line_config()
200 238 self.command_line_config = loader.load_config()
201 239 self.extra_args = loader.get_extra_args()
202 240
203 241 def set_command_line_config_log_level(self):
204 242 try:
205 243 self.log_level = self.command_line_config.Global.log_level
206 244 except AttributeError:
207 245 pass
208 246
209 247 def post_load_command_line_config(self):
210 248 """Do actions just after loading the command line config."""
211 249 pass
212 250
213 251 def log_command_line_config(self):
214 252 self.log.debug("Command line config loaded:")
215 253 self.log.debug(repr(self.command_line_config))
216 254
217 255 def find_ipython_dir(self):
218 256 """Set the IPython directory.
219 257
220 258 This sets ``self.ipython_dir``, but the actual value that is passed to
221 259 the application is kept in either ``self.default_config`` or
222 260 ``self.command_line_config``. This also adds ``self.ipython_dir`` to
223 261 ``sys.path`` so config files there can be referenced by other config
224 262 files.
225 263 """
226 264
227 265 try:
228 266 self.ipython_dir = self.command_line_config.Global.ipython_dir
229 267 except AttributeError:
230 268 self.ipython_dir = self.default_config.Global.ipython_dir
231 269 sys.path.append(os.path.abspath(self.ipython_dir))
232 270 if not os.path.isdir(self.ipython_dir):
233 271 os.makedirs(self.ipython_dir, mode=0777)
234 272 self.log.debug("IPYTHON_DIR set to: %s" % self.ipython_dir)
235 273
236 274 def find_resources(self):
237 275 """Find other resources that need to be in place.
238 276
239 277 Things like cluster directories need to be in place to find the
240 278 config file. These happen right after the IPython directory has
241 279 been set.
242 280 """
243 281 pass
244 282
245 283 def find_config_file_name(self):
246 284 """Find the config file name for this application.
247 285
248 286 This must set ``self.config_file_name`` to the filename of the
249 287 config file to use (just the filename). The search paths for the
250 288 config file are set in :meth:`find_config_file_paths` and then passed
251 289 to the config file loader where they are resolved to an absolute path.
252 290
253 291 If a profile has been set at the command line, this will resolve it.
254 292 """
255 293
256 294 try:
257 295 self.config_file_name = self.command_line_config.Global.config_file
258 296 except AttributeError:
259 297 pass
260 298
261 299 try:
262 300 self.profile_name = self.command_line_config.Global.profile
263 301 except AttributeError:
264 302 pass
265 303 else:
266 304 name_parts = self.config_file_name.split('.')
267 305 name_parts.insert(1, u'_' + self.profile_name + u'.')
268 306 self.config_file_name = ''.join(name_parts)
269 307
270 308 def find_config_file_paths(self):
271 309 """Set the search paths for resolving the config file.
272 310
273 311 This must set ``self.config_file_paths`` to a sequence of search
274 312 paths to pass to the config file loader.
275 313 """
276 314 # Include our own profiles directory last, so that users can still find
277 315 # our shipped copies of builtin profiles even if they don't have them
278 316 # in their local ipython directory.
279 317 prof_dir = os.path.join(get_ipython_package_dir(), 'config', 'profile')
280 318 self.config_file_paths = (os.getcwd(), self.ipython_dir, prof_dir)
281 319
282 320 def pre_load_file_config(self):
283 321 """Do actions before the config file is loaded."""
284 322 pass
285 323
286 324 def load_file_config(self):
287 325 """Load the config file.
288 326
289 327 This tries to load the config file from disk. If successful, the
290 328 ``CONFIG_FILE`` config variable is set to the resolved config file
291 329 location. If not successful, an empty config is used.
292 330 """
293 331 self.log.debug("Attempting to load config file: %s" %
294 332 self.config_file_name)
295 333 loader = PyFileConfigLoader(self.config_file_name,
296 334 path=self.config_file_paths)
297 335 try:
298 336 self.file_config = loader.load_config()
299 337 self.file_config.Global.config_file = loader.full_filename
300 338 except IOError:
301 339 # Only warn if the default config file was NOT being used.
302 340 if not self.config_file_name==self.default_config_file_name:
303 341 self.log.warn("Config file not found, skipping: %s" %
304 342 self.config_file_name, exc_info=True)
305 343 self.file_config = Config()
306 344 except:
307 345 self.log.warn("Error loading config file: %s" %
308 346 self.config_file_name, exc_info=True)
309 347 self.file_config = Config()
310 348
311 349 def set_file_config_log_level(self):
312 350 # We need to keeep self.log_level updated. But we only use the value
313 351 # of the file_config if a value was not specified at the command
314 352 # line, because the command line overrides everything.
315 353 if not hasattr(self.command_line_config.Global, 'log_level'):
316 354 try:
317 355 self.log_level = self.file_config.Global.log_level
318 356 except AttributeError:
319 357 pass # Use existing value
320 358
321 359 def post_load_file_config(self):
322 360 """Do actions after the config file is loaded."""
323 361 pass
324 362
325 363 def log_file_config(self):
326 364 if hasattr(self.file_config.Global, 'config_file'):
327 365 self.log.debug("Config file loaded: %s" %
328 366 self.file_config.Global.config_file)
329 367 self.log.debug(repr(self.file_config))
330 368
331 369 def merge_configs(self):
332 370 """Merge the default, command line and file config objects."""
333 371 config = Config()
334 372 config._merge(self.default_config)
335 373 config._merge(self.file_config)
336 374 config._merge(self.command_line_config)
337 375 self.master_config = config
338 376
339 377 def log_master_config(self):
340 378 self.log.debug("Master config created:")
341 379 self.log.debug(repr(self.master_config))
342 380
343 381 def pre_construct(self):
344 382 """Do actions after the config has been built, but before construct."""
345 383 pass
346 384
347 385 def construct(self):
348 386 """Construct the main components that make up this app."""
349 387 self.log.debug("Constructing components for application")
350 388
351 389 def post_construct(self):
352 390 """Do actions after construct, but before starting the app."""
353 391 pass
354 392
355 393 def start_app(self):
356 394 """Actually start the app."""
357 395 self.log.debug("Starting application")
358 396
359 397 #-------------------------------------------------------------------------
360 398 # Utility methods
361 399 #-------------------------------------------------------------------------
362 400
363 401 def abort(self):
364 402 """Abort the starting of the application."""
365 403 if self._exiting:
366 404 pass
367 405 else:
368 406 self.log.critical("Aborting application: %s" % self.name, exc_info=True)
369 407 self._exiting = True
370 408 sys.exit(1)
371 409
372 410 def exit(self, exit_status=0):
373 411 if self._exiting:
374 412 pass
375 413 else:
376 414 self.log.debug("Exiting application: %s" % self.name)
377 415 self._exiting = True
378 416 sys.exit(exit_status)
379 417
380 418 def attempt(self, func, action='abort'):
381 419 try:
382 420 func()
383 421 except SystemExit:
384 422 raise
385 423 except:
386 424 if action == 'abort':
425 self.log.critical("Aborting application: %s" % self.name,
426 exc_info=True)
387 427 self.abort()
428 raise
388 429 elif action == 'exit':
389 430 self.exit(0)
390 431
@@ -1,229 +1,220 b''
1 1 # -*- coding: utf-8 -*-
2 2 """sys.excepthook for IPython itself, leaves a detailed report on disk.
3 3
4 4
5 5 Authors
6 6 -------
7 7 - Fernando Perez <Fernando.Perez@berkeley.edu>
8 8 """
9 9
10 10 #*****************************************************************************
11 11 # Copyright (C) 2008-2009 The IPython Development Team
12 12 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
13 13 #
14 14 # Distributed under the terms of the BSD License. The full license is in
15 15 # the file COPYING, distributed as part of this software.
16 16 #*****************************************************************************
17 17
18 18 #****************************************************************************
19 19 # Required modules
20 20
21 21 # From the standard library
22 22 import os
23 23 import sys
24 24 from pprint import pformat
25 25
26 26 # Our own
27 27 from IPython.core import release
28 28 from IPython.core import ultratb
29 29 from IPython.external.Itpl import itpl
30 30
31 from IPython.utils.genutils import *
32
33 31 #****************************************************************************
34 class CrashHandler:
32 class CrashHandler(object):
35 33 """Customizable crash handlers for IPython-based systems.
36 34
37 35 Instances of this class provide a __call__ method which can be used as a
38 36 sys.excepthook, i.e., the __call__ signature is:
39 37
40 38 def __call__(self,etype, evalue, etb)
41 39
42 40 """
43 41
44 def __init__(self,IP,app_name,contact_name,contact_email,
45 bug_tracker,crash_report_fname,
42 def __init__(self,app, app_name, contact_name=None, contact_email=None,
43 bug_tracker=None, crash_report_fname='CrashReport.txt',
46 44 show_crash_traceback=True):
47 45 """New crash handler.
48 46
49 47 Inputs:
50 48
51 - IP: a running IPython instance, which will be queried at crash time
52 for internal information.
49 - app: a running application instance, which will be queried at crash
50 time for internal information.
53 51
54 52 - app_name: a string containing the name of your application.
55 53
56 54 - contact_name: a string with the name of the person to contact.
57 55
58 56 - contact_email: a string with the email address of the contact.
59 57
60 58 - bug_tracker: a string with the URL for your project's bug tracker.
61 59
62 60 - crash_report_fname: a string with the filename for the crash report
63 61 to be saved in. These reports are left in the ipython user directory
64 62 as determined by the running IPython instance.
65 63
66 64 Optional inputs:
67 65
68 66 - show_crash_traceback(True): if false, don't print the crash
69 67 traceback on stderr, only generate the on-disk report
70 68
71 69
72 70 Non-argument instance attributes:
73 71
74 72 These instances contain some non-argument attributes which allow for
75 73 further customization of the crash handler's behavior. Please see the
76 74 source for further details.
77 75 """
78 76
79 77 # apply args into instance
80 self.IP = IP # IPython instance
78 self.app = app
81 79 self.app_name = app_name
82 80 self.contact_name = contact_name
83 81 self.contact_email = contact_email
84 82 self.bug_tracker = bug_tracker
85 83 self.crash_report_fname = crash_report_fname
86 84 self.show_crash_traceback = show_crash_traceback
85 self.section_sep = '\n\n'+'*'*75+'\n\n'
87 86
88 87 # Hardcoded defaults, which can be overridden either by subclasses or
89 88 # at runtime for the instance.
90 89
91 90 # Template for the user message. Subclasses which completely override
92 91 # this, or user apps, can modify it to suit their tastes. It gets
93 92 # expanded using itpl, so calls of the kind $self.foo are valid.
94 93 self.user_message_template = """
95 94 Oops, $self.app_name crashed. We do our best to make it stable, but...
96 95
97 96 A crash report was automatically generated with the following information:
98 97 - A verbatim copy of the crash traceback.
99 98 - A copy of your input history during this session.
100 99 - Data on your current $self.app_name configuration.
101 100
102 101 It was left in the file named:
103 102 \t'$self.crash_report_fname'
104 103 If you can email this file to the developers, the information in it will help
105 104 them in understanding and correcting the problem.
106 105
107 106 You can mail it to: $self.contact_name at $self.contact_email
108 107 with the subject '$self.app_name Crash Report'.
109 108
110 109 If you want to do it now, the following command will work (under Unix):
111 110 mail -s '$self.app_name Crash Report' $self.contact_email < $self.crash_report_fname
112 111
113 112 To ensure accurate tracking of this issue, please file a report about it at:
114 113 $self.bug_tracker
115 114 """
116 115
117 116 def __call__(self,etype, evalue, etb):
118 117 """Handle an exception, call for compatible with sys.excepthook"""
119 118
120 119 # Report tracebacks shouldn't use color in general (safer for users)
121 120 color_scheme = 'NoColor'
122 121
123 122 # Use this ONLY for developer debugging (keep commented out for release)
124 123 #color_scheme = 'Linux' # dbg
125 124
126 125 try:
127 rptdir = self.IP.ipython_dir
126 rptdir = self.app.ipython_dir
128 127 except:
129 128 rptdir = os.getcwd()
130 129 if not os.path.isdir(rptdir):
131 130 rptdir = os.getcwd()
132 131 report_name = os.path.join(rptdir,self.crash_report_fname)
133 132 # write the report filename into the instance dict so it can get
134 133 # properly expanded out in the user message template
135 134 self.crash_report_fname = report_name
136 135 TBhandler = ultratb.VerboseTB(color_scheme=color_scheme,
137 long_header=1)
136 long_header=1)
138 137 traceback = TBhandler.text(etype,evalue,etb,context=31)
139 138
140 139 # print traceback to screen
141 140 if self.show_crash_traceback:
142 141 print >> sys.stderr, traceback
143 142
144 143 # and generate a complete report on disk
145 144 try:
146 145 report = open(report_name,'w')
147 146 except:
148 147 print >> sys.stderr, 'Could not create crash report on disk.'
149 148 return
150 149
151 150 # Inform user on stderr of what happened
152 151 msg = itpl('\n'+'*'*70+'\n'+self.user_message_template)
153 152 print >> sys.stderr, msg
154 153
155 154 # Construct report on disk
156 155 report.write(self.make_report(traceback))
157 156 report.close()
158 157 raw_input("Hit <Enter> to quit this message (your terminal may close):")
159 158
160 159 def make_report(self,traceback):
161 160 """Return a string containing a crash report."""
162
163 sec_sep = '\n\n'+'*'*75+'\n\n'
164
161 import platform
162
163 sec_sep = self.section_sep
164
165 165 report = []
166 166 rpt_add = report.append
167 167
168 168 rpt_add('*'*75+'\n\n'+'IPython post-mortem report\n\n')
169 rpt_add('IPython version: %s \n\n' % release.version)
170 rpt_add('BZR revision : %s \n\n' % release.revision)
171 rpt_add('Platform info : os.name -> %s, sys.platform -> %s' %
169 rpt_add('IPython version: %s \n' % release.version)
170 rpt_add('BZR revision : %s \n' % release.revision)
171 rpt_add('Platform info : os.name -> %s, sys.platform -> %s\n' %
172 172 (os.name,sys.platform) )
173 rpt_add(sec_sep+'Current user configuration structure:\n\n')
174 rpt_add(pformat(self.IP.dict()))
175 rpt_add(sec_sep+'Crash traceback:\n\n' + traceback)
173 rpt_add(' : %s\n' % platform.platform())
174 rpt_add('Python info : %s\n' % sys.version)
175
176 176 try:
177 rpt_add(sec_sep+"History of session input:")
178 for line in self.IP.user_ns['_ih']:
179 rpt_add(line)
180 rpt_add('\n*** Last line of input (may not be in above history):\n')
181 rpt_add(self.IP._last_input_line+'\n')
177 config = pformat(self.app.config)
178 rpt_add(sec_sep+'Current user configuration structure:\n\n')
179 rpt_add(config)
182 180 except:
183 181 pass
182 rpt_add(sec_sep+'Crash traceback:\n\n' + traceback)
184 183
185 184 return ''.join(report)
186 185
186
187 187 class IPythonCrashHandler(CrashHandler):
188 188 """sys.excepthook for IPython itself, leaves a detailed report on disk."""
189 189
190 def __init__(self,IP):
190 def __init__(self, app, app_name='IPython'):
191 191
192 192 # Set here which of the IPython authors should be listed as contact
193 193 AUTHOR_CONTACT = 'Fernando'
194 194
195 195 # Set argument defaults
196 app_name = 'IPython'
197 196 bug_tracker = 'https://bugs.launchpad.net/ipython/+filebug'
198 197 contact_name,contact_email = release.authors[AUTHOR_CONTACT][:2]
199 198 crash_report_fname = 'IPython_crash_report.txt'
200 199 # Call parent constructor
201 CrashHandler.__init__(self,IP,app_name,contact_name,contact_email,
200 CrashHandler.__init__(self,app,app_name,contact_name,contact_email,
202 201 bug_tracker,crash_report_fname)
203 202
204 203 def make_report(self,traceback):
205 204 """Return a string containing a crash report."""
206 205
207 sec_sep = '\n\n'+'*'*75+'\n\n'
208
209 report = []
206 sec_sep = self.section_sep
207 # Start with parent report
208 report = [super(IPythonCrashHandler, self).make_report(traceback)]
209 # Add interactive-specific info we may have
210 210 rpt_add = report.append
211
212 rpt_add('*'*75+'\n\n'+'IPython post-mortem report\n\n')
213 rpt_add('IPython version: %s \n\n' % release.version)
214 rpt_add('BZR revision : %s \n\n' % release.revision)
215 rpt_add('Platform info : os.name -> %s, sys.platform -> %s' %
216 (os.name,sys.platform) )
217 rpt_add(sec_sep+'Current user configuration structure:\n\n')
218 # rpt_add(pformat(self.IP.dict()))
219 rpt_add(sec_sep+'Crash traceback:\n\n' + traceback)
220 211 try:
221 212 rpt_add(sec_sep+"History of session input:")
222 for line in self.IP.user_ns['_ih']:
213 for line in self.app.shell.user_ns['_ih']:
223 214 rpt_add(line)
224 215 rpt_add('\n*** Last line of input (may not be in above history):\n')
225 rpt_add(self.IP._last_input_line+'\n')
216 rpt_add(self.app.shell._last_input_line+'\n')
226 217 except:
227 218 pass
228 219
229 220 return ''.join(report)
@@ -1,582 +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 from IPython.core import crashhandler
31 32 from IPython.core import release
32 33 from IPython.core.application import Application, BaseAppArgParseConfigLoader
33 34 from IPython.core.error import UsageError
34 35 from IPython.core.iplib import InteractiveShell
35 36 from IPython.core.pylabtools import pylab_activate
36 37 from IPython.config.loader import (
37 38 NoConfigDefault,
38 39 Config,
39 40 PyFileConfigLoader
40 41 )
41 42 from IPython.lib import inputhook
42 43 from IPython.utils.genutils import filefind, get_ipython_dir
43 44
44 45 #-----------------------------------------------------------------------------
45 46 # Utilities and helpers
46 47 #-----------------------------------------------------------------------------
47 48
48 49 ipython_desc = """
49 50 A Python shell with automatic history (input and output), dynamic object
50 51 introspection, easier configuration, command completion, access to the system
51 52 shell and more.
52 53 """
53 54
54 55 #-----------------------------------------------------------------------------
55 56 # Main classes and functions
56 57 #-----------------------------------------------------------------------------
57 58
58 59 cl_args = (
59 60 (('--autocall',), dict(
60 61 type=int, dest='InteractiveShell.autocall', default=NoConfigDefault,
61 62 help='Set the autocall value (0,1,2).',
62 63 metavar='InteractiveShell.autocall')
63 64 ),
64 65 (('--autoindent',), dict(
65 66 action='store_true', dest='InteractiveShell.autoindent', default=NoConfigDefault,
66 67 help='Turn on autoindenting.')
67 68 ),
68 69 (('--no-autoindent',), dict(
69 70 action='store_false', dest='InteractiveShell.autoindent', default=NoConfigDefault,
70 71 help='Turn off autoindenting.')
71 72 ),
72 73 (('--automagic',), dict(
73 74 action='store_true', dest='InteractiveShell.automagic', default=NoConfigDefault,
74 75 help='Turn on the auto calling of magic commands.')
75 76 ),
76 77 (('--no-automagic',), dict(
77 78 action='store_false', dest='InteractiveShell.automagic', default=NoConfigDefault,
78 79 help='Turn off the auto calling of magic commands.')
79 80 ),
80 81 (('--autoedit-syntax',), dict(
81 82 action='store_true', dest='InteractiveShell.autoedit_syntax', default=NoConfigDefault,
82 83 help='Turn on auto editing of files with syntax errors.')
83 84 ),
84 85 (('--no-autoedit-syntax',), dict(
85 86 action='store_false', dest='InteractiveShell.autoedit_syntax', default=NoConfigDefault,
86 87 help='Turn off auto editing of files with syntax errors.')
87 88 ),
88 89 (('--banner',), dict(
89 90 action='store_true', dest='Global.display_banner', default=NoConfigDefault,
90 91 help='Display a banner upon starting IPython.')
91 92 ),
92 93 (('--no-banner',), dict(
93 94 action='store_false', dest='Global.display_banner', default=NoConfigDefault,
94 95 help="Don't display a banner upon starting IPython.")
95 96 ),
96 97 (('--cache-size',), dict(
97 98 type=int, dest='InteractiveShell.cache_size', default=NoConfigDefault,
98 99 help="Set the size of the output cache.",
99 100 metavar='InteractiveShell.cache_size')
100 101 ),
101 102 (('--classic',), dict(
102 103 action='store_true', dest='Global.classic', default=NoConfigDefault,
103 104 help="Gives IPython a similar feel to the classic Python prompt.")
104 105 ),
105 106 (('--colors',), dict(
106 107 type=str, dest='InteractiveShell.colors', default=NoConfigDefault,
107 108 help="Set the color scheme (NoColor, Linux, and LightBG).",
108 109 metavar='InteractiveShell.colors')
109 110 ),
110 111 (('--color-info',), dict(
111 112 action='store_true', dest='InteractiveShell.color_info', default=NoConfigDefault,
112 113 help="Enable using colors for info related things.")
113 114 ),
114 115 (('--no-color-info',), dict(
115 116 action='store_false', dest='InteractiveShell.color_info', default=NoConfigDefault,
116 117 help="Disable using colors for info related things.")
117 118 ),
118 119 (('--confirm-exit',), dict(
119 120 action='store_true', dest='InteractiveShell.confirm_exit', default=NoConfigDefault,
120 121 help="Prompt the user when existing.")
121 122 ),
122 123 (('--no-confirm-exit',), dict(
123 124 action='store_false', dest='InteractiveShell.confirm_exit', default=NoConfigDefault,
124 125 help="Don't prompt the user when existing.")
125 126 ),
126 127 (('--deep-reload',), dict(
127 128 action='store_true', dest='InteractiveShell.deep_reload', default=NoConfigDefault,
128 129 help="Enable deep (recursive) reloading by default.")
129 130 ),
130 131 (('--no-deep-reload',), dict(
131 132 action='store_false', dest='InteractiveShell.deep_reload', default=NoConfigDefault,
132 133 help="Disable deep (recursive) reloading by default.")
133 134 ),
134 135 (('--editor',), dict(
135 136 type=str, dest='InteractiveShell.editor', default=NoConfigDefault,
136 137 help="Set the editor used by IPython (default to $EDITOR/vi/notepad).",
137 138 metavar='InteractiveShell.editor')
138 139 ),
139 140 (('--log','-l'), dict(
140 141 action='store_true', dest='InteractiveShell.logstart', default=NoConfigDefault,
141 142 help="Start logging to the default file (./ipython_log.py).")
142 143 ),
143 144 (('--logfile','-lf'), dict(
144 145 type=unicode, dest='InteractiveShell.logfile', default=NoConfigDefault,
145 146 help="Start logging to logfile.",
146 147 metavar='InteractiveShell.logfile')
147 148 ),
148 149 (('--log-append','-la'), dict(
149 150 type=unicode, dest='InteractiveShell.logappend', default=NoConfigDefault,
150 151 help="Start logging to the give file in append mode.",
151 152 metavar='InteractiveShell.logfile')
152 153 ),
153 154 (('--pdb',), dict(
154 155 action='store_true', dest='InteractiveShell.pdb', default=NoConfigDefault,
155 156 help="Enable auto calling the pdb debugger after every exception.")
156 157 ),
157 158 (('--no-pdb',), dict(
158 159 action='store_false', dest='InteractiveShell.pdb', default=NoConfigDefault,
159 160 help="Disable auto calling the pdb debugger after every exception.")
160 161 ),
161 162 (('--pprint',), dict(
162 163 action='store_true', dest='InteractiveShell.pprint', default=NoConfigDefault,
163 164 help="Enable auto pretty printing of results.")
164 165 ),
165 166 (('--no-pprint',), dict(
166 167 action='store_false', dest='InteractiveShell.pprint', default=NoConfigDefault,
167 168 help="Disable auto auto pretty printing of results.")
168 169 ),
169 170 (('--prompt-in1','-pi1'), dict(
170 171 type=str, dest='InteractiveShell.prompt_in1', default=NoConfigDefault,
171 172 help="Set the main input prompt ('In [\#]: ')",
172 173 metavar='InteractiveShell.prompt_in1')
173 174 ),
174 175 (('--prompt-in2','-pi2'), dict(
175 176 type=str, dest='InteractiveShell.prompt_in2', default=NoConfigDefault,
176 177 help="Set the secondary input prompt (' .\D.: ')",
177 178 metavar='InteractiveShell.prompt_in2')
178 179 ),
179 180 (('--prompt-out','-po'), dict(
180 181 type=str, dest='InteractiveShell.prompt_out', default=NoConfigDefault,
181 182 help="Set the output prompt ('Out[\#]:')",
182 183 metavar='InteractiveShell.prompt_out')
183 184 ),
184 185 (('--quick',), dict(
185 186 action='store_true', dest='Global.quick', default=NoConfigDefault,
186 187 help="Enable quick startup with no config files.")
187 188 ),
188 189 (('--readline',), dict(
189 190 action='store_true', dest='InteractiveShell.readline_use', default=NoConfigDefault,
190 191 help="Enable readline for command line usage.")
191 192 ),
192 193 (('--no-readline',), dict(
193 194 action='store_false', dest='InteractiveShell.readline_use', default=NoConfigDefault,
194 195 help="Disable readline for command line usage.")
195 196 ),
196 197 (('--screen-length','-sl'), dict(
197 198 type=int, dest='InteractiveShell.screen_length', default=NoConfigDefault,
198 199 help='Number of lines on screen, used to control printing of long strings.',
199 200 metavar='InteractiveShell.screen_length')
200 201 ),
201 202 (('--separate-in','-si'), dict(
202 203 type=str, dest='InteractiveShell.separate_in', default=NoConfigDefault,
203 204 help="Separator before input prompts. Default '\n'.",
204 205 metavar='InteractiveShell.separate_in')
205 206 ),
206 207 (('--separate-out','-so'), dict(
207 208 type=str, dest='InteractiveShell.separate_out', default=NoConfigDefault,
208 209 help="Separator before output prompts. Default 0 (nothing).",
209 210 metavar='InteractiveShell.separate_out')
210 211 ),
211 212 (('--separate-out2','-so2'), dict(
212 213 type=str, dest='InteractiveShell.separate_out2', default=NoConfigDefault,
213 214 help="Separator after output prompts. Default 0 (nonight).",
214 215 metavar='InteractiveShell.separate_out2')
215 216 ),
216 217 (('-no-sep',), dict(
217 218 action='store_true', dest='Global.nosep', default=NoConfigDefault,
218 219 help="Eliminate all spacing between prompts.")
219 220 ),
220 221 (('--term-title',), dict(
221 222 action='store_true', dest='InteractiveShell.term_title', default=NoConfigDefault,
222 223 help="Enable auto setting the terminal title.")
223 224 ),
224 225 (('--no-term-title',), dict(
225 226 action='store_false', dest='InteractiveShell.term_title', default=NoConfigDefault,
226 227 help="Disable auto setting the terminal title.")
227 228 ),
228 229 (('--xmode',), dict(
229 230 type=str, dest='InteractiveShell.xmode', default=NoConfigDefault,
230 231 help="Exception mode ('Plain','Context','Verbose')",
231 232 metavar='InteractiveShell.xmode')
232 233 ),
233 234 (('--ext',), dict(
234 235 type=str, dest='Global.extra_extension', default=NoConfigDefault,
235 236 help="The dotted module name of an IPython extension to load.",
236 237 metavar='Global.extra_extension')
237 238 ),
238 239 (('-c',), dict(
239 240 type=str, dest='Global.code_to_run', default=NoConfigDefault,
240 241 help="Execute the given command string.",
241 242 metavar='Global.code_to_run')
242 243 ),
243 244 (('-i',), dict(
244 245 action='store_true', dest='Global.force_interact', default=NoConfigDefault,
245 246 help="If running code from the command line, become interactive afterwards.")
246 247 ),
247 248
248 249 # Options to start with GUI control enabled from the beginning
249 250 (('--gui',), dict(
250 251 type=str, dest='Global.gui', default=NoConfigDefault,
251 252 help="Enable GUI event loop integration ('qt', 'wx', 'gtk').",
252 253 metavar='gui-mode')
253 254 ),
254 255
255 256 (('--pylab','-pylab'), dict(
256 257 type=str, dest='Global.pylab', default=NoConfigDefault,
257 258 nargs='?', const='auto', metavar='gui-mode',
258 259 help="Pre-load matplotlib and numpy for interactive use. "+
259 260 "If no value is given, the gui backend is matplotlib's, else use "+
260 261 "one of: ['tk', 'qt', 'wx', 'gtk'].")
261 262 ),
262 263
263 264 # Legacy GUI options. Leave them in for backwards compatibility, but the
264 265 # 'thread' names are really a misnomer now.
265 266 (('--wthread','-wthread'), dict(
266 267 action='store_true', dest='Global.wthread', default=NoConfigDefault,
267 268 help="Enable wxPython event loop integration "+
268 269 "(DEPRECATED, use --gui wx)")
269 270 ),
270 271 (('--q4thread','--qthread','-q4thread','-qthread'), dict(
271 272 action='store_true', dest='Global.q4thread', default=NoConfigDefault,
272 273 help="Enable Qt4 event loop integration. Qt3 is no longer supported. "+
273 274 "(DEPRECATED, use --gui qt)")
274 275 ),
275 276 (('--gthread','-gthread'), dict(
276 277 action='store_true', dest='Global.gthread', default=NoConfigDefault,
277 278 help="Enable GTK event loop integration. "+
278 279 "(DEPRECATED, use --gui gtk)")
279 280 ),
280 281 )
281 282
282 283
283 class IPythonAppCLConfigLoader(BaseAppArgParseConfigLoader):
284
285 arguments = cl_args
286
287
288 284 default_config_file_name = u'ipython_config.py'
289 285
290
291 286 class IPythonApp(Application):
292 287 name = u'ipython'
293 288 description = 'IPython: an enhanced interactive Python shell.'
294 289 config_file_name = default_config_file_name
295 290
291 cl_arguments = Application.cl_arguments + cl_args
292
293 # Private and configuration attributes
294 _CrashHandler = crashhandler.IPythonCrashHandler
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 def create_default_config(self):
313 314 super(IPythonApp, self).create_default_config()
314 315 # Eliminate multiple lookups
315 316 Global = self.default_config.Global
316 317
317 318 # Set all default values
318 319 Global.display_banner = True
319 320
320 321 # If the -c flag is given or a file is given to run at the cmd line
321 322 # like "ipython foo.py", normally we exit without starting the main
322 323 # loop. The force_interact config variable allows a user to override
323 324 # this and interact. It is also set by the -i cmd line flag, just
324 325 # like Python.
325 326 Global.force_interact = False
326 327
327 328 # By default always interact by starting the IPython mainloop.
328 329 Global.interact = True
329 330
330 331 # No GUI integration by default
331 332 Global.gui = False
332 333 # Pylab off by default
333 334 Global.pylab = False
334 335
335 336 # Deprecated versions of gui support that used threading, we support
336 337 # them just for bacwards compatibility as an alternate spelling for
337 338 # '--gui X'
338 339 Global.qthread = False
339 340 Global.q4thread = False
340 341 Global.wthread = False
341 342 Global.gthread = False
342 343
343 def create_command_line_config(self):
344 """Create and return a command line config loader."""
345 return IPythonAppCLConfigLoader(self.argv,
346 description=self.description,
347 version=release.version
348 )
349
350 344 def load_file_config(self):
351 345 if hasattr(self.command_line_config.Global, 'quick'):
352 346 if self.command_line_config.Global.quick:
353 347 self.file_config = Config()
354 348 return
355 349 super(IPythonApp, self).load_file_config()
356 350
357 351 def post_load_file_config(self):
358 352 if hasattr(self.command_line_config.Global, 'extra_extension'):
359 353 if not hasattr(self.file_config.Global, 'extensions'):
360 354 self.file_config.Global.extensions = []
361 355 self.file_config.Global.extensions.append(
362 356 self.command_line_config.Global.extra_extension)
363 357 del self.command_line_config.Global.extra_extension
364 358
365 359 def pre_construct(self):
366 360 config = self.master_config
367 361
368 362 if hasattr(config.Global, 'classic'):
369 363 if config.Global.classic:
370 364 config.InteractiveShell.cache_size = 0
371 365 config.InteractiveShell.pprint = 0
372 366 config.InteractiveShell.prompt_in1 = '>>> '
373 367 config.InteractiveShell.prompt_in2 = '... '
374 368 config.InteractiveShell.prompt_out = ''
375 369 config.InteractiveShell.separate_in = \
376 370 config.InteractiveShell.separate_out = \
377 371 config.InteractiveShell.separate_out2 = ''
378 372 config.InteractiveShell.colors = 'NoColor'
379 373 config.InteractiveShell.xmode = 'Plain'
380 374
381 375 if hasattr(config.Global, 'nosep'):
382 376 if config.Global.nosep:
383 377 config.InteractiveShell.separate_in = \
384 378 config.InteractiveShell.separate_out = \
385 379 config.InteractiveShell.separate_out2 = ''
386 380
387 381 # if there is code of files to run from the cmd line, don't interact
388 382 # unless the -i flag (Global.force_interact) is true.
389 383 code_to_run = config.Global.get('code_to_run','')
390 384 file_to_run = False
391 385 if len(self.extra_args)>=1:
392 386 if self.extra_args[0]:
393 387 file_to_run = True
394 388 if file_to_run or code_to_run:
395 389 if not config.Global.force_interact:
396 390 config.Global.interact = False
397 391
398 392 def construct(self):
399 393 # I am a little hesitant to put these into InteractiveShell itself.
400 394 # But that might be the place for them
401 395 sys.path.insert(0, '')
402 396
403 397 # Create an InteractiveShell instance
404 398 self.shell = InteractiveShell(None, self.master_config,
405 399 **self.shell_params )
406 400
407 401 def post_construct(self):
408 402 """Do actions after construct, but before starting the app."""
409 403 config = self.master_config
410 404
411 405 # shell.display_banner should always be False for the terminal
412 406 # based app, because we call shell.show_banner() by hand below
413 407 # so the banner shows *before* all extension loading stuff.
414 408 self.shell.display_banner = False
415 409
416 410 if config.Global.display_banner and \
417 411 config.Global.interact:
418 412 self.shell.show_banner()
419 413
420 414 # Make sure there is a space below the banner.
421 415 if self.log_level <= logging.INFO: print
422 416
423 417 # Now a variety of things that happen after the banner is printed.
424 418 self._enable_gui_pylab()
425 419 self._load_extensions()
426 420 self._run_exec_lines()
427 421 self._run_exec_files()
428 422 self._run_cmd_line_code()
429 423 self._configure_xmode()
430 424
431 425 def _enable_gui_pylab(self):
432 426 """Enable GUI event loop integration, taking pylab into account."""
433 427 Global = self.master_config.Global
434 428
435 429 # Select which gui to use
436 430 if Global.gui:
437 431 gui = Global.gui
438 432 # The following are deprecated, but there's likely to be a lot of use
439 433 # of this form out there, so we might as well support it for now. But
440 434 # the --gui option above takes precedence.
441 435 elif Global.wthread:
442 436 gui = inputhook.GUI_WX
443 437 elif Global.qthread:
444 438 gui = inputhook.GUI_QT
445 439 elif Global.gthread:
446 440 gui = inputhook.GUI_GTK
447 441 else:
448 442 gui = None
449 443
450 444 # Using --pylab will also require gui activation, though which toolkit
451 445 # to use may be chosen automatically based on mpl configuration.
452 446 if Global.pylab:
453 447 activate = self.shell.enable_pylab
454 448 if Global.pylab == 'auto':
455 449 gui = None
456 450 else:
457 451 gui = Global.pylab
458 452 else:
459 453 # Enable only GUI integration, no pylab
460 454 activate = inputhook.enable_gui
461 455
462 456 if gui or Global.pylab:
463 457 try:
464 458 self.log.info("Enabling GUI event loop integration, "
465 459 "toolkit=%s, pylab=%s" % (gui, Global.pylab) )
466 460 activate(gui)
467 461 except:
468 462 self.log.warn("Error in enabling GUI event loop integration:")
469 463 self.shell.showtraceback()
470 464
471 465 def _load_extensions(self):
472 466 """Load all IPython extensions in Global.extensions.
473 467
474 468 This uses the :meth:`InteractiveShell.load_extensions` to load all
475 469 the extensions listed in ``self.master_config.Global.extensions``.
476 470 """
477 471 try:
478 472 if hasattr(self.master_config.Global, 'extensions'):
479 473 self.log.debug("Loading IPython extensions...")
480 474 extensions = self.master_config.Global.extensions
481 475 for ext in extensions:
482 476 try:
483 477 self.log.info("Loading IPython extension: %s" % ext)
484 478 self.shell.load_extension(ext)
485 479 except:
486 480 self.log.warn("Error in loading extension: %s" % ext)
487 481 self.shell.showtraceback()
488 482 except:
489 483 self.log.warn("Unknown error in loading extensions:")
490 484 self.shell.showtraceback()
491 485
492 486 def _run_exec_lines(self):
493 487 """Run lines of code in Global.exec_lines in the user's namespace."""
494 488 try:
495 489 if hasattr(self.master_config.Global, 'exec_lines'):
496 490 self.log.debug("Running code from Global.exec_lines...")
497 491 exec_lines = self.master_config.Global.exec_lines
498 492 for line in exec_lines:
499 493 try:
500 494 self.log.info("Running code in user namespace: %s" % line)
501 495 self.shell.runlines(line)
502 496 except:
503 497 self.log.warn("Error in executing line in user namespace: %s" % line)
504 498 self.shell.showtraceback()
505 499 except:
506 500 self.log.warn("Unknown error in handling Global.exec_lines:")
507 501 self.shell.showtraceback()
508 502
509 503 def _exec_file(self, fname):
510 504 full_filename = filefind(fname, [u'.', self.ipython_dir])
511 505 if os.path.isfile(full_filename):
512 506 if full_filename.endswith(u'.py'):
513 507 self.log.info("Running file in user namespace: %s" % full_filename)
514 508 self.shell.safe_execfile(full_filename, self.shell.user_ns)
515 509 elif full_filename.endswith('.ipy'):
516 510 self.log.info("Running file in user namespace: %s" % full_filename)
517 511 self.shell.safe_execfile_ipy(full_filename)
518 512 else:
519 513 self.log.warn("File does not have a .py or .ipy extension: <%s>" % full_filename)
520 514
521 515 def _run_exec_files(self):
522 516 try:
523 517 if hasattr(self.master_config.Global, 'exec_files'):
524 518 self.log.debug("Running files in Global.exec_files...")
525 519 exec_files = self.master_config.Global.exec_files
526 520 for fname in exec_files:
527 521 self._exec_file(fname)
528 522 except:
529 523 self.log.warn("Unknown error in handling Global.exec_files:")
530 524 self.shell.showtraceback()
531 525
532 526 def _run_cmd_line_code(self):
533 527 if hasattr(self.master_config.Global, 'code_to_run'):
534 528 line = self.master_config.Global.code_to_run
535 529 try:
536 530 self.log.info("Running code given at command line (-c): %s" % line)
537 531 self.shell.runlines(line)
538 532 except:
539 533 self.log.warn("Error in executing line in user namespace: %s" % line)
540 534 self.shell.showtraceback()
541 535 return
542 536 # Like Python itself, ignore the second if the first of these is present
543 537 try:
544 538 fname = self.extra_args[0]
545 539 except:
546 540 pass
547 541 else:
548 542 try:
549 543 self._exec_file(fname)
550 544 except:
551 545 self.log.warn("Error in executing file in user namespace: %s" % fname)
552 546 self.shell.showtraceback()
553 547
554 548 def _configure_xmode(self):
555 549 # XXX - shouldn't this be read from the config? I'm still a little
556 550 # lost with all the details of handling the new config guys...
557 551 self.shell.InteractiveTB.set_mode(mode=self.shell.xmode)
558 552
559 553 def start_app(self):
560 554 if self.master_config.Global.interact:
561 555 self.log.debug("Starting IPython's mainloop...")
562 556 self.shell.mainloop()
563 557 else:
564 558 self.log.debug("IPython not interactive, start_app is no-op...")
565 559
566 560
567 561 def load_default_config(ipython_dir=None):
568 562 """Load the default config file from the default ipython_dir.
569 563
570 564 This is useful for embedded shells.
571 565 """
572 566 if ipython_dir is None:
573 567 ipython_dir = get_ipython_dir()
574 568 cl = PyFileConfigLoader(default_config_file_name, ipython_dir)
575 569 config = cl.load_config()
576 570 return config
577 571
578 572
579 573 def launch_new_instance():
580 574 """Create and run a full blown IPython instance"""
581 575 app = IPythonApp()
582 576 app.start()
@@ -1,2544 +1,2521 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 Main IPython Component
4 4 """
5 5
6 6 #-----------------------------------------------------------------------------
7 7 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
8 8 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
9 9 # Copyright (C) 2008-2009 The IPython Development Team
10 10 #
11 11 # Distributed under the terms of the BSD License. The full license is in
12 12 # the file COPYING, distributed as part of this software.
13 13 #-----------------------------------------------------------------------------
14 14
15 15 #-----------------------------------------------------------------------------
16 16 # Imports
17 17 #-----------------------------------------------------------------------------
18 18
19 19 from __future__ import with_statement
20 20
21 21 import __builtin__
22 22 import StringIO
23 23 import bdb
24 24 import codeop
25 25 import exceptions
26 26 import new
27 27 import os
28 28 import re
29 29 import string
30 30 import sys
31 31 import tempfile
32 32 from contextlib import nested
33 33
34 34 from IPython.core import debugger, oinspect
35 35 from IPython.core import history as ipcorehist
36 36 from IPython.core import prefilter
37 37 from IPython.core import shadowns
38 38 from IPython.core import ultratb
39 39 from IPython.core.alias import AliasManager
40 40 from IPython.core.builtin_trap import BuiltinTrap
41 41 from IPython.core.component import Component
42 42 from IPython.core.display_trap import DisplayTrap
43 43 from IPython.core.error import TryNext, UsageError
44 44 from IPython.core.fakemodule import FakeModule, init_fakemod_dict
45 45 from IPython.core.logger import Logger
46 46 from IPython.core.magic import Magic
47 47 from IPython.core.prefilter import PrefilterManager
48 48 from IPython.core.prompts import CachedOutput
49 49 from IPython.core.pylabtools import pylab_activate
50 50 from IPython.core.usage import interactive_usage, default_banner
51 51 from IPython.external.Itpl import ItplNS
52 52 from IPython.lib.inputhook import enable_gui
53 53 from IPython.lib.backgroundjobs import BackgroundJobManager
54 54 from IPython.utils import PyColorize
55 55 from IPython.utils import pickleshare
56 56 from IPython.utils.genutils import get_ipython_dir
57 57 from IPython.utils.ipstruct import Struct
58 58 from IPython.utils.platutils import toggle_set_term_title, set_term_title
59 59 from IPython.utils.strdispatch import StrDispatch
60 60 from IPython.utils.syspathcontext import prepended_to_syspath
61 61
62 62 # XXX - need to clean up this import * line
63 63 from IPython.utils.genutils import *
64 64
65 65 # from IPython.utils import growl
66 66 # growl.start("IPython")
67 67
68 68 from IPython.utils.traitlets import (
69 69 Int, Str, CBool, CaselessStrEnum, Enum, List, Unicode
70 70 )
71 71
72 72 #-----------------------------------------------------------------------------
73 73 # Globals
74 74 #-----------------------------------------------------------------------------
75 75
76 76 # store the builtin raw_input globally, and use this always, in case user code
77 77 # overwrites it (like wx.py.PyShell does)
78 78 raw_input_original = raw_input
79 79
80 80 # compiled regexps for autoindent management
81 81 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
82 82
83 83 #-----------------------------------------------------------------------------
84 84 # Utilities
85 85 #-----------------------------------------------------------------------------
86 86
87 87 ini_spaces_re = re.compile(r'^(\s+)')
88 88
89 89
90 90 def num_ini_spaces(strng):
91 91 """Return the number of initial spaces in a string"""
92 92
93 93 ini_spaces = ini_spaces_re.match(strng)
94 94 if ini_spaces:
95 95 return ini_spaces.end()
96 96 else:
97 97 return 0
98 98
99 99
100 100 def softspace(file, newvalue):
101 101 """Copied from code.py, to remove the dependency"""
102 102
103 103 oldvalue = 0
104 104 try:
105 105 oldvalue = file.softspace
106 106 except AttributeError:
107 107 pass
108 108 try:
109 109 file.softspace = newvalue
110 110 except (AttributeError, TypeError):
111 111 # "attribute-less object" or "read-only attributes"
112 112 pass
113 113 return oldvalue
114 114
115 115
116 116 def no_op(*a, **kw): pass
117 117
118 118 class SpaceInInput(exceptions.Exception): pass
119 119
120 120 class Bunch: pass
121 121
122 122 class InputList(list):
123 123 """Class to store user input.
124 124
125 125 It's basically a list, but slices return a string instead of a list, thus
126 126 allowing things like (assuming 'In' is an instance):
127 127
128 128 exec In[4:7]
129 129
130 130 or
131 131
132 132 exec In[5:9] + In[14] + In[21:25]"""
133 133
134 134 def __getslice__(self,i,j):
135 135 return ''.join(list.__getslice__(self,i,j))
136 136
137 137
138 138 class SyntaxTB(ultratb.ListTB):
139 139 """Extension which holds some state: the last exception value"""
140 140
141 141 def __init__(self,color_scheme = 'NoColor'):
142 142 ultratb.ListTB.__init__(self,color_scheme)
143 143 self.last_syntax_error = None
144 144
145 145 def __call__(self, etype, value, elist):
146 146 self.last_syntax_error = value
147 147 ultratb.ListTB.__call__(self,etype,value,elist)
148 148
149 149 def clear_err_state(self):
150 150 """Return the current error state and clear it"""
151 151 e = self.last_syntax_error
152 152 self.last_syntax_error = None
153 153 return e
154 154
155 155
156 156 def get_default_editor():
157 157 try:
158 158 ed = os.environ['EDITOR']
159 159 except KeyError:
160 160 if os.name == 'posix':
161 161 ed = 'vi' # the only one guaranteed to be there!
162 162 else:
163 163 ed = 'notepad' # same in Windows!
164 164 return ed
165 165
166 166
167 167 def get_default_colors():
168 168 if sys.platform=='darwin':
169 169 return "LightBG"
170 170 elif os.name=='nt':
171 171 return 'Linux'
172 172 else:
173 173 return 'Linux'
174 174
175 175
176 176 class SeparateStr(Str):
177 177 """A Str subclass to validate separate_in, separate_out, etc.
178 178
179 179 This is a Str based traitlet that converts '0'->'' and '\\n'->'\n'.
180 180 """
181 181
182 182 def validate(self, obj, value):
183 183 if value == '0': value = ''
184 184 value = value.replace('\\n','\n')
185 185 return super(SeparateStr, self).validate(obj, value)
186 186
187 187
188 188 def make_user_namespaces(user_ns=None, user_global_ns=None):
189 189 """Return a valid local and global user interactive namespaces.
190 190
191 191 This builds a dict with the minimal information needed to operate as a
192 192 valid IPython user namespace, which you can pass to the various
193 193 embedding classes in ipython. The default implementation returns the
194 194 same dict for both the locals and the globals to allow functions to
195 195 refer to variables in the namespace. Customized implementations can
196 196 return different dicts. The locals dictionary can actually be anything
197 197 following the basic mapping protocol of a dict, but the globals dict
198 198 must be a true dict, not even a subclass. It is recommended that any
199 199 custom object for the locals namespace synchronize with the globals
200 200 dict somehow.
201 201
202 202 Raises TypeError if the provided globals namespace is not a true dict.
203 203
204 204 Parameters
205 205 ----------
206 206 user_ns : dict-like, optional
207 207 The current user namespace. The items in this namespace should
208 208 be included in the output. If None, an appropriate blank
209 209 namespace should be created.
210 210 user_global_ns : dict, optional
211 211 The current user global namespace. The items in this namespace
212 212 should be included in the output. If None, an appropriate
213 213 blank namespace should be created.
214 214
215 215 Returns
216 216 -------
217 217 A pair of dictionary-like object to be used as the local namespace
218 218 of the interpreter and a dict to be used as the global namespace.
219 219 """
220 220
221 221 if user_ns is None:
222 222 # Set __name__ to __main__ to better match the behavior of the
223 223 # normal interpreter.
224 224 user_ns = {'__name__' :'__main__',
225 225 '__builtins__' : __builtin__,
226 226 }
227 227 else:
228 228 user_ns.setdefault('__name__','__main__')
229 229 user_ns.setdefault('__builtins__',__builtin__)
230 230
231 231 if user_global_ns is None:
232 232 user_global_ns = user_ns
233 233 if type(user_global_ns) is not dict:
234 234 raise TypeError("user_global_ns must be a true dict; got %r"
235 235 % type(user_global_ns))
236 236
237 237 return user_ns, user_global_ns
238 238
239 239 #-----------------------------------------------------------------------------
240 240 # Main IPython class
241 241 #-----------------------------------------------------------------------------
242 242
243 243
244 244 class InteractiveShell(Component, Magic):
245 245 """An enhanced, interactive shell for Python."""
246 246
247 247 autocall = Enum((0,1,2), default_value=1, config=True)
248 248 autoedit_syntax = CBool(False, config=True)
249 249 autoindent = CBool(True, config=True)
250 250 automagic = CBool(True, config=True)
251 251 banner = Str('')
252 252 banner1 = Str(default_banner, config=True)
253 253 banner2 = Str('', config=True)
254 254 cache_size = Int(1000, config=True)
255 255 color_info = CBool(True, config=True)
256 256 colors = CaselessStrEnum(('NoColor','LightBG','Linux'),
257 257 default_value=get_default_colors(), config=True)
258 258 confirm_exit = CBool(True, config=True)
259 259 debug = CBool(False, config=True)
260 260 deep_reload = CBool(False, config=True)
261 261 # This display_banner only controls whether or not self.show_banner()
262 262 # is called when mainloop/interact are called. The default is False
263 263 # because for the terminal based application, the banner behavior
264 264 # is controlled by Global.display_banner, which IPythonApp looks at
265 265 # to determine if *it* should call show_banner() by hand or not.
266 266 display_banner = CBool(False) # This isn't configurable!
267 267 embedded = CBool(False)
268 268 embedded_active = CBool(False)
269 269 editor = Str(get_default_editor(), config=True)
270 270 filename = Str("<ipython console>")
271 271 ipython_dir= Unicode('', config=True) # Set to get_ipython_dir() in __init__
272 272 logstart = CBool(False, config=True)
273 273 logfile = Str('', config=True)
274 274 logappend = Str('', config=True)
275 275 object_info_string_level = Enum((0,1,2), default_value=0,
276 276 config=True)
277 277 pager = Str('less', config=True)
278 278 pdb = CBool(False, config=True)
279 279 pprint = CBool(True, config=True)
280 280 profile = Str('', config=True)
281 281 prompt_in1 = Str('In [\\#]: ', config=True)
282 282 prompt_in2 = Str(' .\\D.: ', config=True)
283 283 prompt_out = Str('Out[\\#]: ', config=True)
284 284 prompts_pad_left = CBool(True, config=True)
285 285 quiet = CBool(False, config=True)
286 286
287 287 readline_use = CBool(True, config=True)
288 288 readline_merge_completions = CBool(True, config=True)
289 289 readline_omit__names = Enum((0,1,2), default_value=0, config=True)
290 290 readline_remove_delims = Str('-/~', config=True)
291 291 readline_parse_and_bind = List([
292 292 'tab: complete',
293 293 '"\C-l": possible-completions',
294 294 'set show-all-if-ambiguous on',
295 295 '"\C-o": tab-insert',
296 296 '"\M-i": " "',
297 297 '"\M-o": "\d\d\d\d"',
298 298 '"\M-I": "\d\d\d\d"',
299 299 '"\C-r": reverse-search-history',
300 300 '"\C-s": forward-search-history',
301 301 '"\C-p": history-search-backward',
302 302 '"\C-n": history-search-forward',
303 303 '"\e[A": history-search-backward',
304 304 '"\e[B": history-search-forward',
305 305 '"\C-k": kill-line',
306 306 '"\C-u": unix-line-discard',
307 307 ], allow_none=False, config=True)
308 308
309 309 screen_length = Int(0, config=True)
310 310
311 311 # Use custom TraitletTypes that convert '0'->'' and '\\n'->'\n'
312 312 separate_in = SeparateStr('\n', config=True)
313 313 separate_out = SeparateStr('', config=True)
314 314 separate_out2 = SeparateStr('', config=True)
315 315
316 316 system_header = Str('IPython system call: ', config=True)
317 317 system_verbose = CBool(False, config=True)
318 318 term_title = CBool(False, config=True)
319 319 wildcards_case_sensitive = CBool(True, config=True)
320 320 xmode = CaselessStrEnum(('Context','Plain', 'Verbose'),
321 321 default_value='Context', config=True)
322 322
323 323 autoexec = List(allow_none=False)
324 324
325 325 # class attribute to indicate whether the class supports threads or not.
326 326 # Subclasses with thread support should override this as needed.
327 327 isthreaded = False
328 328
329 329 def __init__(self, parent=None, config=None, ipython_dir=None, usage=None,
330 330 user_ns=None, user_global_ns=None,
331 331 banner1=None, banner2=None, display_banner=None,
332 332 custom_exceptions=((),None)):
333 333
334 334 # This is where traitlets with a config_key argument are updated
335 335 # from the values on config.
336 336 super(InteractiveShell, self).__init__(parent, config=config)
337 337
338 338 # These are relatively independent and stateless
339 339 self.init_ipython_dir(ipython_dir)
340 340 self.init_instance_attrs()
341 341 self.init_term_title()
342 342 self.init_usage(usage)
343 343 self.init_banner(banner1, banner2, display_banner)
344 344
345 345 # Create namespaces (user_ns, user_global_ns, etc.)
346 346 self.init_create_namespaces(user_ns, user_global_ns)
347 347 # This has to be done after init_create_namespaces because it uses
348 348 # something in self.user_ns, but before init_sys_modules, which
349 349 # is the first thing to modify sys.
350 350 self.save_sys_module_state()
351 351 self.init_sys_modules()
352 352
353 353 self.init_history()
354 354 self.init_encoding()
355 355 self.init_prefilter()
356 356
357 357 Magic.__init__(self, self)
358 358
359 359 self.init_syntax_highlighting()
360 360 self.init_hooks()
361 361 self.init_pushd_popd_magic()
362 362 self.init_traceback_handlers(custom_exceptions)
363 363 self.init_user_ns()
364 364 self.init_logger()
365 365 self.init_alias()
366 366 self.init_builtins()
367 367
368 368 # pre_config_initialization
369 369 self.init_shadow_hist()
370 370
371 371 # The next section should contain averything that was in ipmaker.
372 372 self.init_logstart()
373 373
374 374 # The following was in post_config_initialization
375 375 self.init_inspector()
376 376 self.init_readline()
377 377 self.init_prompts()
378 378 self.init_displayhook()
379 379 self.init_reload_doctest()
380 380 self.init_magics()
381 381 self.init_pdb()
382 382 self.hooks.late_startup_hook()
383 383
384 384 def get_ipython(self):
385 385 """Return the currently running IPython instance."""
386 386 return self
387 387
388 388 #-------------------------------------------------------------------------
389 389 # Traitlet changed handlers
390 390 #-------------------------------------------------------------------------
391 391
392 392 def _banner1_changed(self):
393 393 self.compute_banner()
394 394
395 395 def _banner2_changed(self):
396 396 self.compute_banner()
397 397
398 398 def _ipython_dir_changed(self, name, new):
399 399 if not os.path.isdir(new):
400 400 os.makedirs(new, mode = 0777)
401 401 if not os.path.isdir(self.ipython_extension_dir):
402 402 os.makedirs(self.ipython_extension_dir, mode = 0777)
403 403
404 404 @property
405 405 def ipython_extension_dir(self):
406 406 return os.path.join(self.ipython_dir, 'extensions')
407 407
408 408 @property
409 409 def usable_screen_length(self):
410 410 if self.screen_length == 0:
411 411 return 0
412 412 else:
413 413 num_lines_bot = self.separate_in.count('\n')+1
414 414 return self.screen_length - num_lines_bot
415 415
416 416 def _term_title_changed(self, name, new_value):
417 417 self.init_term_title()
418 418
419 419 def set_autoindent(self,value=None):
420 420 """Set the autoindent flag, checking for readline support.
421 421
422 422 If called with no arguments, it acts as a toggle."""
423 423
424 424 if not self.has_readline:
425 425 if os.name == 'posix':
426 426 warn("The auto-indent feature requires the readline library")
427 427 self.autoindent = 0
428 428 return
429 429 if value is None:
430 430 self.autoindent = not self.autoindent
431 431 else:
432 432 self.autoindent = value
433 433
434 434 #-------------------------------------------------------------------------
435 435 # init_* methods called by __init__
436 436 #-------------------------------------------------------------------------
437 437
438 438 def init_ipython_dir(self, ipython_dir):
439 439 if ipython_dir is not None:
440 440 self.ipython_dir = ipython_dir
441 441 self.config.Global.ipython_dir = self.ipython_dir
442 442 return
443 443
444 444 if hasattr(self.config.Global, 'ipython_dir'):
445 445 self.ipython_dir = self.config.Global.ipython_dir
446 446 else:
447 447 self.ipython_dir = get_ipython_dir()
448 448
449 449 # All children can just read this
450 450 self.config.Global.ipython_dir = self.ipython_dir
451 451
452 452 def init_instance_attrs(self):
453 453 self.jobs = BackgroundJobManager()
454 454 self.more = False
455 455
456 456 # command compiler
457 457 self.compile = codeop.CommandCompiler()
458 458
459 459 # User input buffer
460 460 self.buffer = []
461 461
462 462 # Make an empty namespace, which extension writers can rely on both
463 463 # existing and NEVER being used by ipython itself. This gives them a
464 464 # convenient location for storing additional information and state
465 465 # their extensions may require, without fear of collisions with other
466 466 # ipython names that may develop later.
467 467 self.meta = Struct()
468 468
469 469 # Object variable to store code object waiting execution. This is
470 470 # used mainly by the multithreaded shells, but it can come in handy in
471 471 # other situations. No need to use a Queue here, since it's a single
472 472 # item which gets cleared once run.
473 473 self.code_to_run = None
474 474
475 475 # Flag to mark unconditional exit
476 476 self.exit_now = False
477 477
478 478 # Temporary files used for various purposes. Deleted at exit.
479 479 self.tempfiles = []
480 480
481 481 # Keep track of readline usage (later set by init_readline)
482 482 self.has_readline = False
483 483
484 484 # keep track of where we started running (mainly for crash post-mortem)
485 485 # This is not being used anywhere currently.
486 486 self.starting_dir = os.getcwd()
487 487
488 488 # Indentation management
489 489 self.indent_current_nsp = 0
490 490
491 491 def init_term_title(self):
492 492 # Enable or disable the terminal title.
493 493 if self.term_title:
494 494 toggle_set_term_title(True)
495 495 set_term_title('IPython: ' + abbrev_cwd())
496 496 else:
497 497 toggle_set_term_title(False)
498 498
499 499 def init_usage(self, usage=None):
500 500 if usage is None:
501 501 self.usage = interactive_usage
502 502 else:
503 503 self.usage = usage
504 504
505 505 def init_encoding(self):
506 506 # Get system encoding at startup time. Certain terminals (like Emacs
507 507 # under Win32 have it set to None, and we need to have a known valid
508 508 # encoding to use in the raw_input() method
509 509 try:
510 510 self.stdin_encoding = sys.stdin.encoding or 'ascii'
511 511 except AttributeError:
512 512 self.stdin_encoding = 'ascii'
513 513
514 514 def init_syntax_highlighting(self):
515 515 # Python source parser/formatter for syntax highlighting
516 516 pyformat = PyColorize.Parser().format
517 517 self.pycolorize = lambda src: pyformat(src,'str',self.colors)
518 518
519 519 def init_pushd_popd_magic(self):
520 520 # for pushd/popd management
521 521 try:
522 522 self.home_dir = get_home_dir()
523 523 except HomeDirError, msg:
524 524 fatal(msg)
525 525
526 526 self.dir_stack = []
527 527
528 528 def init_logger(self):
529 529 self.logger = Logger(self, logfname='ipython_log.py', logmode='rotate')
530 530 # local shortcut, this is used a LOT
531 531 self.log = self.logger.log
532 532
533 533 def init_logstart(self):
534 534 if self.logappend:
535 535 self.magic_logstart(self.logappend + ' append')
536 536 elif self.logfile:
537 537 self.magic_logstart(self.logfile)
538 538 elif self.logstart:
539 539 self.magic_logstart()
540 540
541 541 def init_builtins(self):
542 542 self.builtin_trap = BuiltinTrap(self)
543 543
544 544 def init_inspector(self):
545 545 # Object inspector
546 546 self.inspector = oinspect.Inspector(oinspect.InspectColors,
547 547 PyColorize.ANSICodeColors,
548 548 'NoColor',
549 549 self.object_info_string_level)
550 550
551 551 def init_prompts(self):
552 552 # Initialize cache, set in/out prompts and printing system
553 553 self.outputcache = CachedOutput(self,
554 554 self.cache_size,
555 555 self.pprint,
556 556 input_sep = self.separate_in,
557 557 output_sep = self.separate_out,
558 558 output_sep2 = self.separate_out2,
559 559 ps1 = self.prompt_in1,
560 560 ps2 = self.prompt_in2,
561 561 ps_out = self.prompt_out,
562 562 pad_left = self.prompts_pad_left)
563 563
564 564 # user may have over-ridden the default print hook:
565 565 try:
566 566 self.outputcache.__class__.display = self.hooks.display
567 567 except AttributeError:
568 568 pass
569 569
570 570 def init_displayhook(self):
571 571 self.display_trap = DisplayTrap(self, self.outputcache)
572 572
573 573 def init_reload_doctest(self):
574 574 # Do a proper resetting of doctest, including the necessary displayhook
575 575 # monkeypatching
576 576 try:
577 577 doctest_reload()
578 578 except ImportError:
579 579 warn("doctest module does not exist.")
580 580
581 581 #-------------------------------------------------------------------------
582 582 # Things related to the banner
583 583 #-------------------------------------------------------------------------
584 584
585 585 def init_banner(self, banner1, banner2, display_banner):
586 586 if banner1 is not None:
587 587 self.banner1 = banner1
588 588 if banner2 is not None:
589 589 self.banner2 = banner2
590 590 if display_banner is not None:
591 591 self.display_banner = display_banner
592 592 self.compute_banner()
593 593
594 594 def show_banner(self, banner=None):
595 595 if banner is None:
596 596 banner = self.banner
597 597 self.write(banner)
598 598
599 599 def compute_banner(self):
600 600 self.banner = self.banner1 + '\n'
601 601 if self.profile:
602 602 self.banner += '\nIPython profile: %s\n' % self.profile
603 603 if self.banner2:
604 604 self.banner += '\n' + self.banner2 + '\n'
605 605
606 606 #-------------------------------------------------------------------------
607 607 # Things related to injections into the sys module
608 608 #-------------------------------------------------------------------------
609 609
610 610 def save_sys_module_state(self):
611 611 """Save the state of hooks in the sys module.
612 612
613 613 This has to be called after self.user_ns is created.
614 614 """
615 615 self._orig_sys_module_state = {}
616 616 self._orig_sys_module_state['stdin'] = sys.stdin
617 617 self._orig_sys_module_state['stdout'] = sys.stdout
618 618 self._orig_sys_module_state['stderr'] = sys.stderr
619 619 self._orig_sys_module_state['excepthook'] = sys.excepthook
620 620 try:
621 621 self._orig_sys_modules_main_name = self.user_ns['__name__']
622 622 except KeyError:
623 623 pass
624 624
625 625 def restore_sys_module_state(self):
626 626 """Restore the state of the sys module."""
627 627 try:
628 628 for k, v in self._orig_sys_module_state.items():
629 629 setattr(sys, k, v)
630 630 except AttributeError:
631 631 pass
632 632 try:
633 633 delattr(sys, 'ipcompleter')
634 634 except AttributeError:
635 635 pass
636 636 # Reset what what done in self.init_sys_modules
637 637 try:
638 638 sys.modules[self.user_ns['__name__']] = self._orig_sys_modules_main_name
639 639 except (AttributeError, KeyError):
640 640 pass
641 641
642 642 #-------------------------------------------------------------------------
643 643 # Things related to hooks
644 644 #-------------------------------------------------------------------------
645 645
646 646 def init_hooks(self):
647 647 # hooks holds pointers used for user-side customizations
648 648 self.hooks = Struct()
649 649
650 650 self.strdispatchers = {}
651 651
652 652 # Set all default hooks, defined in the IPython.hooks module.
653 653 import IPython.core.hooks
654 654 hooks = IPython.core.hooks
655 655 for hook_name in hooks.__all__:
656 656 # default hooks have priority 100, i.e. low; user hooks should have
657 657 # 0-100 priority
658 658 self.set_hook(hook_name,getattr(hooks,hook_name), 100)
659 659
660 660 def set_hook(self,name,hook, priority = 50, str_key = None, re_key = None):
661 661 """set_hook(name,hook) -> sets an internal IPython hook.
662 662
663 663 IPython exposes some of its internal API as user-modifiable hooks. By
664 664 adding your function to one of these hooks, you can modify IPython's
665 665 behavior to call at runtime your own routines."""
666 666
667 667 # At some point in the future, this should validate the hook before it
668 668 # accepts it. Probably at least check that the hook takes the number
669 669 # of args it's supposed to.
670 670
671 671 f = new.instancemethod(hook,self,self.__class__)
672 672
673 673 # check if the hook is for strdispatcher first
674 674 if str_key is not None:
675 675 sdp = self.strdispatchers.get(name, StrDispatch())
676 676 sdp.add_s(str_key, f, priority )
677 677 self.strdispatchers[name] = sdp
678 678 return
679 679 if re_key is not None:
680 680 sdp = self.strdispatchers.get(name, StrDispatch())
681 681 sdp.add_re(re.compile(re_key), f, priority )
682 682 self.strdispatchers[name] = sdp
683 683 return
684 684
685 685 dp = getattr(self.hooks, name, None)
686 686 if name not in IPython.core.hooks.__all__:
687 687 print "Warning! Hook '%s' is not one of %s" % (name, IPython.core.hooks.__all__ )
688 688 if not dp:
689 689 dp = IPython.core.hooks.CommandChainDispatcher()
690 690
691 691 try:
692 692 dp.add(f,priority)
693 693 except AttributeError:
694 694 # it was not commandchain, plain old func - replace
695 695 dp = f
696 696
697 697 setattr(self.hooks,name, dp)
698 698
699 699 #-------------------------------------------------------------------------
700 700 # Things related to the "main" module
701 701 #-------------------------------------------------------------------------
702 702
703 703 def new_main_mod(self,ns=None):
704 704 """Return a new 'main' module object for user code execution.
705 705 """
706 706 main_mod = self._user_main_module
707 707 init_fakemod_dict(main_mod,ns)
708 708 return main_mod
709 709
710 710 def cache_main_mod(self,ns,fname):
711 711 """Cache a main module's namespace.
712 712
713 713 When scripts are executed via %run, we must keep a reference to the
714 714 namespace of their __main__ module (a FakeModule instance) around so
715 715 that Python doesn't clear it, rendering objects defined therein
716 716 useless.
717 717
718 718 This method keeps said reference in a private dict, keyed by the
719 719 absolute path of the module object (which corresponds to the script
720 720 path). This way, for multiple executions of the same script we only
721 721 keep one copy of the namespace (the last one), thus preventing memory
722 722 leaks from old references while allowing the objects from the last
723 723 execution to be accessible.
724 724
725 725 Note: we can not allow the actual FakeModule instances to be deleted,
726 726 because of how Python tears down modules (it hard-sets all their
727 727 references to None without regard for reference counts). This method
728 728 must therefore make a *copy* of the given namespace, to allow the
729 729 original module's __dict__ to be cleared and reused.
730 730
731 731
732 732 Parameters
733 733 ----------
734 734 ns : a namespace (a dict, typically)
735 735
736 736 fname : str
737 737 Filename associated with the namespace.
738 738
739 739 Examples
740 740 --------
741 741
742 742 In [10]: import IPython
743 743
744 744 In [11]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
745 745
746 746 In [12]: IPython.__file__ in _ip._main_ns_cache
747 747 Out[12]: True
748 748 """
749 749 self._main_ns_cache[os.path.abspath(fname)] = ns.copy()
750 750
751 751 def clear_main_mod_cache(self):
752 752 """Clear the cache of main modules.
753 753
754 754 Mainly for use by utilities like %reset.
755 755
756 756 Examples
757 757 --------
758 758
759 759 In [15]: import IPython
760 760
761 761 In [16]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
762 762
763 763 In [17]: len(_ip._main_ns_cache) > 0
764 764 Out[17]: True
765 765
766 766 In [18]: _ip.clear_main_mod_cache()
767 767
768 768 In [19]: len(_ip._main_ns_cache) == 0
769 769 Out[19]: True
770 770 """
771 771 self._main_ns_cache.clear()
772 772
773 773 #-------------------------------------------------------------------------
774 774 # Things related to debugging
775 775 #-------------------------------------------------------------------------
776 776
777 777 def init_pdb(self):
778 778 # Set calling of pdb on exceptions
779 779 # self.call_pdb is a property
780 780 self.call_pdb = self.pdb
781 781
782 782 def _get_call_pdb(self):
783 783 return self._call_pdb
784 784
785 785 def _set_call_pdb(self,val):
786 786
787 787 if val not in (0,1,False,True):
788 788 raise ValueError,'new call_pdb value must be boolean'
789 789
790 790 # store value in instance
791 791 self._call_pdb = val
792 792
793 793 # notify the actual exception handlers
794 794 self.InteractiveTB.call_pdb = val
795 795 if self.isthreaded:
796 796 try:
797 797 self.sys_excepthook.call_pdb = val
798 798 except:
799 799 warn('Failed to activate pdb for threaded exception handler')
800 800
801 801 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
802 802 'Control auto-activation of pdb at exceptions')
803 803
804 804 def debugger(self,force=False):
805 805 """Call the pydb/pdb debugger.
806 806
807 807 Keywords:
808 808
809 809 - force(False): by default, this routine checks the instance call_pdb
810 810 flag and does not actually invoke the debugger if the flag is false.
811 811 The 'force' option forces the debugger to activate even if the flag
812 812 is false.
813 813 """
814 814
815 815 if not (force or self.call_pdb):
816 816 return
817 817
818 818 if not hasattr(sys,'last_traceback'):
819 819 error('No traceback has been produced, nothing to debug.')
820 820 return
821 821
822 822 # use pydb if available
823 823 if debugger.has_pydb:
824 824 from pydb import pm
825 825 else:
826 826 # fallback to our internal debugger
827 827 pm = lambda : self.InteractiveTB.debugger(force=True)
828 828 self.history_saving_wrapper(pm)()
829 829
830 830 #-------------------------------------------------------------------------
831 831 # Things related to IPython's various namespaces
832 832 #-------------------------------------------------------------------------
833 833
834 834 def init_create_namespaces(self, user_ns=None, user_global_ns=None):
835 835 # Create the namespace where the user will operate. user_ns is
836 836 # normally the only one used, and it is passed to the exec calls as
837 837 # the locals argument. But we do carry a user_global_ns namespace
838 838 # given as the exec 'globals' argument, This is useful in embedding
839 839 # situations where the ipython shell opens in a context where the
840 840 # distinction between locals and globals is meaningful. For
841 841 # non-embedded contexts, it is just the same object as the user_ns dict.
842 842
843 843 # FIXME. For some strange reason, __builtins__ is showing up at user
844 844 # level as a dict instead of a module. This is a manual fix, but I
845 845 # should really track down where the problem is coming from. Alex
846 846 # Schmolck reported this problem first.
847 847
848 848 # A useful post by Alex Martelli on this topic:
849 849 # Re: inconsistent value from __builtins__
850 850 # Von: Alex Martelli <aleaxit@yahoo.com>
851 851 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
852 852 # Gruppen: comp.lang.python
853 853
854 854 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
855 855 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
856 856 # > <type 'dict'>
857 857 # > >>> print type(__builtins__)
858 858 # > <type 'module'>
859 859 # > Is this difference in return value intentional?
860 860
861 861 # Well, it's documented that '__builtins__' can be either a dictionary
862 862 # or a module, and it's been that way for a long time. Whether it's
863 863 # intentional (or sensible), I don't know. In any case, the idea is
864 864 # that if you need to access the built-in namespace directly, you
865 865 # should start with "import __builtin__" (note, no 's') which will
866 866 # definitely give you a module. Yeah, it's somewhat confusing:-(.
867 867
868 868 # These routines return properly built dicts as needed by the rest of
869 869 # the code, and can also be used by extension writers to generate
870 870 # properly initialized namespaces.
871 871 user_ns, user_global_ns = make_user_namespaces(user_ns, user_global_ns)
872 872
873 873 # Assign namespaces
874 874 # This is the namespace where all normal user variables live
875 875 self.user_ns = user_ns
876 876 self.user_global_ns = user_global_ns
877 877
878 878 # An auxiliary namespace that checks what parts of the user_ns were
879 879 # loaded at startup, so we can list later only variables defined in
880 880 # actual interactive use. Since it is always a subset of user_ns, it
881 881 # doesn't need to be separately tracked in the ns_table.
882 882 self.user_config_ns = {}
883 883
884 884 # A namespace to keep track of internal data structures to prevent
885 885 # them from cluttering user-visible stuff. Will be updated later
886 886 self.internal_ns = {}
887 887
888 888 # Now that FakeModule produces a real module, we've run into a nasty
889 889 # problem: after script execution (via %run), the module where the user
890 890 # code ran is deleted. Now that this object is a true module (needed
891 891 # so docetst and other tools work correctly), the Python module
892 892 # teardown mechanism runs over it, and sets to None every variable
893 893 # present in that module. Top-level references to objects from the
894 894 # script survive, because the user_ns is updated with them. However,
895 895 # calling functions defined in the script that use other things from
896 896 # the script will fail, because the function's closure had references
897 897 # to the original objects, which are now all None. So we must protect
898 898 # these modules from deletion by keeping a cache.
899 899 #
900 900 # To avoid keeping stale modules around (we only need the one from the
901 901 # last run), we use a dict keyed with the full path to the script, so
902 902 # only the last version of the module is held in the cache. Note,
903 903 # however, that we must cache the module *namespace contents* (their
904 904 # __dict__). Because if we try to cache the actual modules, old ones
905 905 # (uncached) could be destroyed while still holding references (such as
906 906 # those held by GUI objects that tend to be long-lived)>
907 907 #
908 908 # The %reset command will flush this cache. See the cache_main_mod()
909 909 # and clear_main_mod_cache() methods for details on use.
910 910
911 911 # This is the cache used for 'main' namespaces
912 912 self._main_ns_cache = {}
913 913 # And this is the single instance of FakeModule whose __dict__ we keep
914 914 # copying and clearing for reuse on each %run
915 915 self._user_main_module = FakeModule()
916 916
917 917 # A table holding all the namespaces IPython deals with, so that
918 918 # introspection facilities can search easily.
919 919 self.ns_table = {'user':user_ns,
920 920 'user_global':user_global_ns,
921 921 'internal':self.internal_ns,
922 922 'builtin':__builtin__.__dict__
923 923 }
924 924
925 925 # Similarly, track all namespaces where references can be held and that
926 926 # we can safely clear (so it can NOT include builtin). This one can be
927 927 # a simple list.
928 928 self.ns_refs_table = [ user_ns, user_global_ns, self.user_config_ns,
929 929 self.internal_ns, self._main_ns_cache ]
930 930
931 931 def init_sys_modules(self):
932 932 # We need to insert into sys.modules something that looks like a
933 933 # module but which accesses the IPython namespace, for shelve and
934 934 # pickle to work interactively. Normally they rely on getting
935 935 # everything out of __main__, but for embedding purposes each IPython
936 936 # instance has its own private namespace, so we can't go shoving
937 937 # everything into __main__.
938 938
939 939 # note, however, that we should only do this for non-embedded
940 940 # ipythons, which really mimic the __main__.__dict__ with their own
941 941 # namespace. Embedded instances, on the other hand, should not do
942 942 # this because they need to manage the user local/global namespaces
943 943 # only, but they live within a 'normal' __main__ (meaning, they
944 944 # shouldn't overtake the execution environment of the script they're
945 945 # embedded in).
946 946
947 947 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
948 948
949 949 try:
950 950 main_name = self.user_ns['__name__']
951 951 except KeyError:
952 952 raise KeyError('user_ns dictionary MUST have a "__name__" key')
953 953 else:
954 954 sys.modules[main_name] = FakeModule(self.user_ns)
955 955
956 956 def init_user_ns(self):
957 957 """Initialize all user-visible namespaces to their minimum defaults.
958 958
959 959 Certain history lists are also initialized here, as they effectively
960 960 act as user namespaces.
961 961
962 962 Notes
963 963 -----
964 964 All data structures here are only filled in, they are NOT reset by this
965 965 method. If they were not empty before, data will simply be added to
966 966 therm.
967 967 """
968 968 # This function works in two parts: first we put a few things in
969 969 # user_ns, and we sync that contents into user_config_ns so that these
970 970 # initial variables aren't shown by %who. After the sync, we add the
971 971 # rest of what we *do* want the user to see with %who even on a new
972 972 # session.
973 973 ns = {}
974 974
975 975 # Put 'help' in the user namespace
976 976 try:
977 977 from site import _Helper
978 978 ns['help'] = _Helper()
979 979 except ImportError:
980 980 warn('help() not available - check site.py')
981 981
982 982 # make global variables for user access to the histories
983 983 ns['_ih'] = self.input_hist
984 984 ns['_oh'] = self.output_hist
985 985 ns['_dh'] = self.dir_hist
986 986
987 987 ns['_sh'] = shadowns
988 988
989 989 # Sync what we've added so far to user_config_ns so these aren't seen
990 990 # by %who
991 991 self.user_config_ns.update(ns)
992 992
993 993 # Now, continue adding more contents
994 994
995 995 # user aliases to input and output histories
996 996 ns['In'] = self.input_hist
997 997 ns['Out'] = self.output_hist
998 998
999 999 # Store myself as the public api!!!
1000 1000 ns['get_ipython'] = self.get_ipython
1001 1001
1002 1002 # And update the real user's namespace
1003 1003 self.user_ns.update(ns)
1004 1004
1005 1005
1006 1006 def reset(self):
1007 1007 """Clear all internal namespaces.
1008 1008
1009 1009 Note that this is much more aggressive than %reset, since it clears
1010 1010 fully all namespaces, as well as all input/output lists.
1011 1011 """
1012 1012 for ns in self.ns_refs_table:
1013 1013 ns.clear()
1014 1014
1015 1015 self.alias_manager.clear_aliases()
1016 1016
1017 1017 # Clear input and output histories
1018 1018 self.input_hist[:] = []
1019 1019 self.input_hist_raw[:] = []
1020 1020 self.output_hist.clear()
1021 1021
1022 1022 # Restore the user namespaces to minimal usability
1023 1023 self.init_user_ns()
1024 1024
1025 1025 # Restore the default and user aliases
1026 1026 self.alias_manager.init_aliases()
1027 1027
1028 1028 def push(self, variables, interactive=True):
1029 1029 """Inject a group of variables into the IPython user namespace.
1030 1030
1031 1031 Parameters
1032 1032 ----------
1033 1033 variables : dict, str or list/tuple of str
1034 1034 The variables to inject into the user's namespace. If a dict,
1035 1035 a simple update is done. If a str, the string is assumed to
1036 1036 have variable names separated by spaces. A list/tuple of str
1037 1037 can also be used to give the variable names. If just the variable
1038 1038 names are give (list/tuple/str) then the variable values looked
1039 1039 up in the callers frame.
1040 1040 interactive : bool
1041 1041 If True (default), the variables will be listed with the ``who``
1042 1042 magic.
1043 1043 """
1044 1044 vdict = None
1045 1045
1046 1046 # We need a dict of name/value pairs to do namespace updates.
1047 1047 if isinstance(variables, dict):
1048 1048 vdict = variables
1049 1049 elif isinstance(variables, (basestring, list, tuple)):
1050 1050 if isinstance(variables, basestring):
1051 1051 vlist = variables.split()
1052 1052 else:
1053 1053 vlist = variables
1054 1054 vdict = {}
1055 1055 cf = sys._getframe(1)
1056 1056 for name in vlist:
1057 1057 try:
1058 1058 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1059 1059 except:
1060 1060 print ('Could not get variable %s from %s' %
1061 1061 (name,cf.f_code.co_name))
1062 1062 else:
1063 1063 raise ValueError('variables must be a dict/str/list/tuple')
1064 1064
1065 1065 # Propagate variables to user namespace
1066 1066 self.user_ns.update(vdict)
1067 1067
1068 1068 # And configure interactive visibility
1069 1069 config_ns = self.user_config_ns
1070 1070 if interactive:
1071 1071 for name, val in vdict.iteritems():
1072 1072 config_ns.pop(name, None)
1073 1073 else:
1074 1074 for name,val in vdict.iteritems():
1075 1075 config_ns[name] = val
1076 1076
1077 1077 #-------------------------------------------------------------------------
1078 1078 # Things related to history management
1079 1079 #-------------------------------------------------------------------------
1080 1080
1081 1081 def init_history(self):
1082 1082 # List of input with multi-line handling.
1083 1083 self.input_hist = InputList()
1084 1084 # This one will hold the 'raw' input history, without any
1085 1085 # pre-processing. This will allow users to retrieve the input just as
1086 1086 # it was exactly typed in by the user, with %hist -r.
1087 1087 self.input_hist_raw = InputList()
1088 1088
1089 1089 # list of visited directories
1090 1090 try:
1091 1091 self.dir_hist = [os.getcwd()]
1092 1092 except OSError:
1093 1093 self.dir_hist = []
1094 1094
1095 1095 # dict of output history
1096 1096 self.output_hist = {}
1097 1097
1098 1098 # Now the history file
1099 1099 if self.profile:
1100 1100 histfname = 'history-%s' % self.profile
1101 1101 else:
1102 1102 histfname = 'history'
1103 1103 self.histfile = os.path.join(self.ipython_dir, histfname)
1104 1104
1105 1105 # Fill the history zero entry, user counter starts at 1
1106 1106 self.input_hist.append('\n')
1107 1107 self.input_hist_raw.append('\n')
1108 1108
1109 1109 def init_shadow_hist(self):
1110 1110 try:
1111 1111 self.db = pickleshare.PickleShareDB(self.ipython_dir + "/db")
1112 1112 except exceptions.UnicodeDecodeError:
1113 1113 print "Your ipython_dir can't be decoded to unicode!"
1114 1114 print "Please set HOME environment variable to something that"
1115 1115 print r"only has ASCII characters, e.g. c:\home"
1116 1116 print "Now it is", self.ipython_dir
1117 1117 sys.exit()
1118 1118 self.shadowhist = ipcorehist.ShadowHist(self.db)
1119 1119
1120 1120 def savehist(self):
1121 1121 """Save input history to a file (via readline library)."""
1122 1122
1123 1123 try:
1124 1124 self.readline.write_history_file(self.histfile)
1125 1125 except:
1126 1126 print 'Unable to save IPython command history to file: ' + \
1127 1127 `self.histfile`
1128 1128
1129 1129 def reloadhist(self):
1130 1130 """Reload the input history from disk file."""
1131 1131
1132 1132 try:
1133 1133 self.readline.clear_history()
1134 1134 self.readline.read_history_file(self.shell.histfile)
1135 1135 except AttributeError:
1136 1136 pass
1137 1137
1138 1138 def history_saving_wrapper(self, func):
1139 1139 """ Wrap func for readline history saving
1140 1140
1141 1141 Convert func into callable that saves & restores
1142 1142 history around the call """
1143 1143
1144 1144 if not self.has_readline:
1145 1145 return func
1146 1146
1147 1147 def wrapper():
1148 1148 self.savehist()
1149 1149 try:
1150 1150 func()
1151 1151 finally:
1152 1152 readline.read_history_file(self.histfile)
1153 1153 return wrapper
1154 1154
1155 1155 #-------------------------------------------------------------------------
1156 1156 # Things related to exception handling and tracebacks (not debugging)
1157 1157 #-------------------------------------------------------------------------
1158 1158
1159 1159 def init_traceback_handlers(self, custom_exceptions):
1160 1160 # Syntax error handler.
1161 1161 self.SyntaxTB = SyntaxTB(color_scheme='NoColor')
1162 1162
1163 1163 # The interactive one is initialized with an offset, meaning we always
1164 1164 # want to remove the topmost item in the traceback, which is our own
1165 1165 # internal code. Valid modes: ['Plain','Context','Verbose']
1166 1166 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1167 1167 color_scheme='NoColor',
1168 1168 tb_offset = 1)
1169 1169
1170 # IPython itself shouldn't crash. This will produce a detailed
1171 # post-mortem if it does. But we only install the crash handler for
1172 # non-threaded shells, the threaded ones use a normal verbose reporter
1173 # and lose the crash handler. This is because exceptions in the main
1174 # thread (such as in GUI code) propagate directly to sys.excepthook,
1175 # and there's no point in printing crash dumps for every user exception.
1176 if self.isthreaded:
1177 ipCrashHandler = ultratb.FormattedTB()
1178 else:
1179 from IPython.core import crashhandler
1180 ipCrashHandler = crashhandler.IPythonCrashHandler(self)
1181 self.set_crash_handler(ipCrashHandler)
1170 # The instance will store a pointer to the system-wide exception hook,
1171 # so that runtime code (such as magics) can access it. This is because
1172 # during the read-eval loop, it may get temporarily overwritten.
1173 self.sys_excepthook = sys.excepthook
1182 1174
1183 1175 # and add any custom exception handlers the user may have specified
1184 1176 self.set_custom_exc(*custom_exceptions)
1185 1177
1186 def set_crash_handler(self, crashHandler):
1187 """Set the IPython crash handler.
1188
1189 This must be a callable with a signature suitable for use as
1190 sys.excepthook."""
1191
1192 # Install the given crash handler as the Python exception hook
1193 sys.excepthook = crashHandler
1194
1195 # The instance will store a pointer to this, so that runtime code
1196 # (such as magics) can access it. This is because during the
1197 # read-eval loop, it gets temporarily overwritten (to deal with GUI
1198 # frameworks).
1199 self.sys_excepthook = sys.excepthook
1200
1201 1178 def set_custom_exc(self,exc_tuple,handler):
1202 1179 """set_custom_exc(exc_tuple,handler)
1203 1180
1204 1181 Set a custom exception handler, which will be called if any of the
1205 1182 exceptions in exc_tuple occur in the mainloop (specifically, in the
1206 1183 runcode() method.
1207 1184
1208 1185 Inputs:
1209 1186
1210 1187 - exc_tuple: a *tuple* of valid exceptions to call the defined
1211 1188 handler for. It is very important that you use a tuple, and NOT A
1212 1189 LIST here, because of the way Python's except statement works. If
1213 1190 you only want to trap a single exception, use a singleton tuple:
1214 1191
1215 1192 exc_tuple == (MyCustomException,)
1216 1193
1217 1194 - handler: this must be defined as a function with the following
1218 1195 basic interface: def my_handler(self,etype,value,tb).
1219 1196
1220 1197 This will be made into an instance method (via new.instancemethod)
1221 1198 of IPython itself, and it will be called if any of the exceptions
1222 1199 listed in the exc_tuple are caught. If the handler is None, an
1223 1200 internal basic one is used, which just prints basic info.
1224 1201
1225 1202 WARNING: by putting in your own exception handler into IPython's main
1226 1203 execution loop, you run a very good chance of nasty crashes. This
1227 1204 facility should only be used if you really know what you are doing."""
1228 1205
1229 1206 assert type(exc_tuple)==type(()) , \
1230 1207 "The custom exceptions must be given AS A TUPLE."
1231 1208
1232 1209 def dummy_handler(self,etype,value,tb):
1233 1210 print '*** Simple custom exception handler ***'
1234 1211 print 'Exception type :',etype
1235 1212 print 'Exception value:',value
1236 1213 print 'Traceback :',tb
1237 1214 print 'Source code :','\n'.join(self.buffer)
1238 1215
1239 1216 if handler is None: handler = dummy_handler
1240 1217
1241 1218 self.CustomTB = new.instancemethod(handler,self,self.__class__)
1242 1219 self.custom_exceptions = exc_tuple
1243 1220
1244 1221 def excepthook(self, etype, value, tb):
1245 1222 """One more defense for GUI apps that call sys.excepthook.
1246 1223
1247 1224 GUI frameworks like wxPython trap exceptions and call
1248 1225 sys.excepthook themselves. I guess this is a feature that
1249 1226 enables them to keep running after exceptions that would
1250 1227 otherwise kill their mainloop. This is a bother for IPython
1251 1228 which excepts to catch all of the program exceptions with a try:
1252 1229 except: statement.
1253 1230
1254 1231 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1255 1232 any app directly invokes sys.excepthook, it will look to the user like
1256 1233 IPython crashed. In order to work around this, we can disable the
1257 1234 CrashHandler and replace it with this excepthook instead, which prints a
1258 1235 regular traceback using our InteractiveTB. In this fashion, apps which
1259 1236 call sys.excepthook will generate a regular-looking exception from
1260 1237 IPython, and the CrashHandler will only be triggered by real IPython
1261 1238 crashes.
1262 1239
1263 1240 This hook should be used sparingly, only in places which are not likely
1264 1241 to be true IPython errors.
1265 1242 """
1266 1243 self.showtraceback((etype,value,tb),tb_offset=0)
1267 1244
1268 1245 def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None):
1269 1246 """Display the exception that just occurred.
1270 1247
1271 1248 If nothing is known about the exception, this is the method which
1272 1249 should be used throughout the code for presenting user tracebacks,
1273 1250 rather than directly invoking the InteractiveTB object.
1274 1251
1275 1252 A specific showsyntaxerror() also exists, but this method can take
1276 1253 care of calling it if needed, so unless you are explicitly catching a
1277 1254 SyntaxError exception, don't try to analyze the stack manually and
1278 1255 simply call this method."""
1279 1256
1280 1257
1281 1258 # Though this won't be called by syntax errors in the input line,
1282 1259 # there may be SyntaxError cases whith imported code.
1283 1260
1284 1261 try:
1285 1262 if exc_tuple is None:
1286 1263 etype, value, tb = sys.exc_info()
1287 1264 else:
1288 1265 etype, value, tb = exc_tuple
1289 1266
1290 1267 if etype is SyntaxError:
1291 1268 self.showsyntaxerror(filename)
1292 1269 elif etype is UsageError:
1293 1270 print "UsageError:", value
1294 1271 else:
1295 1272 # WARNING: these variables are somewhat deprecated and not
1296 1273 # necessarily safe to use in a threaded environment, but tools
1297 1274 # like pdb depend on their existence, so let's set them. If we
1298 1275 # find problems in the field, we'll need to revisit their use.
1299 1276 sys.last_type = etype
1300 1277 sys.last_value = value
1301 1278 sys.last_traceback = tb
1302 1279
1303 1280 if etype in self.custom_exceptions:
1304 1281 self.CustomTB(etype,value,tb)
1305 1282 else:
1306 1283 self.InteractiveTB(etype,value,tb,tb_offset=tb_offset)
1307 1284 if self.InteractiveTB.call_pdb:
1308 1285 # pdb mucks up readline, fix it back
1309 1286 self.set_completer()
1310 1287 except KeyboardInterrupt:
1311 1288 self.write("\nKeyboardInterrupt\n")
1312 1289
1313 1290 def showsyntaxerror(self, filename=None):
1314 1291 """Display the syntax error that just occurred.
1315 1292
1316 1293 This doesn't display a stack trace because there isn't one.
1317 1294
1318 1295 If a filename is given, it is stuffed in the exception instead
1319 1296 of what was there before (because Python's parser always uses
1320 1297 "<string>" when reading from a string).
1321 1298 """
1322 1299 etype, value, last_traceback = sys.exc_info()
1323 1300
1324 1301 # See note about these variables in showtraceback() below
1325 1302 sys.last_type = etype
1326 1303 sys.last_value = value
1327 1304 sys.last_traceback = last_traceback
1328 1305
1329 1306 if filename and etype is SyntaxError:
1330 1307 # Work hard to stuff the correct filename in the exception
1331 1308 try:
1332 1309 msg, (dummy_filename, lineno, offset, line) = value
1333 1310 except:
1334 1311 # Not the format we expect; leave it alone
1335 1312 pass
1336 1313 else:
1337 1314 # Stuff in the right filename
1338 1315 try:
1339 1316 # Assume SyntaxError is a class exception
1340 1317 value = SyntaxError(msg, (filename, lineno, offset, line))
1341 1318 except:
1342 1319 # If that failed, assume SyntaxError is a string
1343 1320 value = msg, (filename, lineno, offset, line)
1344 1321 self.SyntaxTB(etype,value,[])
1345 1322
1346 1323 def edit_syntax_error(self):
1347 1324 """The bottom half of the syntax error handler called in the main loop.
1348 1325
1349 1326 Loop until syntax error is fixed or user cancels.
1350 1327 """
1351 1328
1352 1329 while self.SyntaxTB.last_syntax_error:
1353 1330 # copy and clear last_syntax_error
1354 1331 err = self.SyntaxTB.clear_err_state()
1355 1332 if not self._should_recompile(err):
1356 1333 return
1357 1334 try:
1358 1335 # may set last_syntax_error again if a SyntaxError is raised
1359 1336 self.safe_execfile(err.filename,self.user_ns)
1360 1337 except:
1361 1338 self.showtraceback()
1362 1339 else:
1363 1340 try:
1364 1341 f = file(err.filename)
1365 1342 try:
1366 1343 # This should be inside a display_trap block and I
1367 1344 # think it is.
1368 1345 sys.displayhook(f.read())
1369 1346 finally:
1370 1347 f.close()
1371 1348 except:
1372 1349 self.showtraceback()
1373 1350
1374 1351 def _should_recompile(self,e):
1375 1352 """Utility routine for edit_syntax_error"""
1376 1353
1377 1354 if e.filename in ('<ipython console>','<input>','<string>',
1378 1355 '<console>','<BackgroundJob compilation>',
1379 1356 None):
1380 1357
1381 1358 return False
1382 1359 try:
1383 1360 if (self.autoedit_syntax and
1384 1361 not self.ask_yes_no('Return to editor to correct syntax error? '
1385 1362 '[Y/n] ','y')):
1386 1363 return False
1387 1364 except EOFError:
1388 1365 return False
1389 1366
1390 1367 def int0(x):
1391 1368 try:
1392 1369 return int(x)
1393 1370 except TypeError:
1394 1371 return 0
1395 1372 # always pass integer line and offset values to editor hook
1396 1373 try:
1397 1374 self.hooks.fix_error_editor(e.filename,
1398 1375 int0(e.lineno),int0(e.offset),e.msg)
1399 1376 except TryNext:
1400 1377 warn('Could not open editor')
1401 1378 return False
1402 1379 return True
1403 1380
1404 1381 #-------------------------------------------------------------------------
1405 1382 # Things related to tab completion
1406 1383 #-------------------------------------------------------------------------
1407 1384
1408 1385 def complete(self, text):
1409 1386 """Return a sorted list of all possible completions on text.
1410 1387
1411 1388 Inputs:
1412 1389
1413 1390 - text: a string of text to be completed on.
1414 1391
1415 1392 This is a wrapper around the completion mechanism, similar to what
1416 1393 readline does at the command line when the TAB key is hit. By
1417 1394 exposing it as a method, it can be used by other non-readline
1418 1395 environments (such as GUIs) for text completion.
1419 1396
1420 1397 Simple usage example:
1421 1398
1422 1399 In [7]: x = 'hello'
1423 1400
1424 1401 In [8]: x
1425 1402 Out[8]: 'hello'
1426 1403
1427 1404 In [9]: print x
1428 1405 hello
1429 1406
1430 1407 In [10]: _ip.complete('x.l')
1431 1408 Out[10]: ['x.ljust', 'x.lower', 'x.lstrip']
1432 1409 """
1433 1410
1434 1411 # Inject names into __builtin__ so we can complete on the added names.
1435 1412 with self.builtin_trap:
1436 1413 complete = self.Completer.complete
1437 1414 state = 0
1438 1415 # use a dict so we get unique keys, since ipyhton's multiple
1439 1416 # completers can return duplicates. When we make 2.4 a requirement,
1440 1417 # start using sets instead, which are faster.
1441 1418 comps = {}
1442 1419 while True:
1443 1420 newcomp = complete(text,state,line_buffer=text)
1444 1421 if newcomp is None:
1445 1422 break
1446 1423 comps[newcomp] = 1
1447 1424 state += 1
1448 1425 outcomps = comps.keys()
1449 1426 outcomps.sort()
1450 1427 #print "T:",text,"OC:",outcomps # dbg
1451 1428 #print "vars:",self.user_ns.keys()
1452 1429 return outcomps
1453 1430
1454 1431 def set_custom_completer(self,completer,pos=0):
1455 1432 """Adds a new custom completer function.
1456 1433
1457 1434 The position argument (defaults to 0) is the index in the completers
1458 1435 list where you want the completer to be inserted."""
1459 1436
1460 1437 newcomp = new.instancemethod(completer,self.Completer,
1461 1438 self.Completer.__class__)
1462 1439 self.Completer.matchers.insert(pos,newcomp)
1463 1440
1464 1441 def set_completer(self):
1465 1442 """Reset readline's completer to be our own."""
1466 1443 self.readline.set_completer(self.Completer.complete)
1467 1444
1468 1445 def set_completer_frame(self, frame=None):
1469 1446 """Set the frame of the completer."""
1470 1447 if frame:
1471 1448 self.Completer.namespace = frame.f_locals
1472 1449 self.Completer.global_namespace = frame.f_globals
1473 1450 else:
1474 1451 self.Completer.namespace = self.user_ns
1475 1452 self.Completer.global_namespace = self.user_global_ns
1476 1453
1477 1454 #-------------------------------------------------------------------------
1478 1455 # Things related to readline
1479 1456 #-------------------------------------------------------------------------
1480 1457
1481 1458 def init_readline(self):
1482 1459 """Command history completion/saving/reloading."""
1483 1460
1484 1461 if self.readline_use:
1485 1462 import IPython.utils.rlineimpl as readline
1486 1463
1487 1464 self.rl_next_input = None
1488 1465 self.rl_do_indent = False
1489 1466
1490 1467 if not self.readline_use or not readline.have_readline:
1491 1468 self.has_readline = False
1492 1469 self.readline = None
1493 1470 # Set a number of methods that depend on readline to be no-op
1494 1471 self.savehist = no_op
1495 1472 self.reloadhist = no_op
1496 1473 self.set_completer = no_op
1497 1474 self.set_custom_completer = no_op
1498 1475 self.set_completer_frame = no_op
1499 1476 warn('Readline services not available or not loaded.')
1500 1477 else:
1501 1478 self.has_readline = True
1502 1479 self.readline = readline
1503 1480 sys.modules['readline'] = readline
1504 1481 import atexit
1505 1482 from IPython.core.completer import IPCompleter
1506 1483 self.Completer = IPCompleter(self,
1507 1484 self.user_ns,
1508 1485 self.user_global_ns,
1509 1486 self.readline_omit__names,
1510 1487 self.alias_manager.alias_table)
1511 1488 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
1512 1489 self.strdispatchers['complete_command'] = sdisp
1513 1490 self.Completer.custom_completers = sdisp
1514 1491 # Platform-specific configuration
1515 1492 if os.name == 'nt':
1516 1493 self.readline_startup_hook = readline.set_pre_input_hook
1517 1494 else:
1518 1495 self.readline_startup_hook = readline.set_startup_hook
1519 1496
1520 1497 # Load user's initrc file (readline config)
1521 1498 # Or if libedit is used, load editrc.
1522 1499 inputrc_name = os.environ.get('INPUTRC')
1523 1500 if inputrc_name is None:
1524 1501 home_dir = get_home_dir()
1525 1502 if home_dir is not None:
1526 1503 inputrc_name = '.inputrc'
1527 1504 if readline.uses_libedit:
1528 1505 inputrc_name = '.editrc'
1529 1506 inputrc_name = os.path.join(home_dir, inputrc_name)
1530 1507 if os.path.isfile(inputrc_name):
1531 1508 try:
1532 1509 readline.read_init_file(inputrc_name)
1533 1510 except:
1534 1511 warn('Problems reading readline initialization file <%s>'
1535 1512 % inputrc_name)
1536 1513
1537 1514 # save this in sys so embedded copies can restore it properly
1538 1515 sys.ipcompleter = self.Completer.complete
1539 1516 self.set_completer()
1540 1517
1541 1518 # Configure readline according to user's prefs
1542 1519 # This is only done if GNU readline is being used. If libedit
1543 1520 # is being used (as on Leopard) the readline config is
1544 1521 # not run as the syntax for libedit is different.
1545 1522 if not readline.uses_libedit:
1546 1523 for rlcommand in self.readline_parse_and_bind:
1547 1524 #print "loading rl:",rlcommand # dbg
1548 1525 readline.parse_and_bind(rlcommand)
1549 1526
1550 1527 # Remove some chars from the delimiters list. If we encounter
1551 1528 # unicode chars, discard them.
1552 1529 delims = readline.get_completer_delims().encode("ascii", "ignore")
1553 1530 delims = delims.translate(string._idmap,
1554 1531 self.readline_remove_delims)
1555 1532 readline.set_completer_delims(delims)
1556 1533 # otherwise we end up with a monster history after a while:
1557 1534 readline.set_history_length(1000)
1558 1535 try:
1559 1536 #print '*** Reading readline history' # dbg
1560 1537 readline.read_history_file(self.histfile)
1561 1538 except IOError:
1562 1539 pass # It doesn't exist yet.
1563 1540
1564 1541 atexit.register(self.atexit_operations)
1565 1542 del atexit
1566 1543
1567 1544 # Configure auto-indent for all platforms
1568 1545 self.set_autoindent(self.autoindent)
1569 1546
1570 1547 def set_next_input(self, s):
1571 1548 """ Sets the 'default' input string for the next command line.
1572 1549
1573 1550 Requires readline.
1574 1551
1575 1552 Example:
1576 1553
1577 1554 [D:\ipython]|1> _ip.set_next_input("Hello Word")
1578 1555 [D:\ipython]|2> Hello Word_ # cursor is here
1579 1556 """
1580 1557
1581 1558 self.rl_next_input = s
1582 1559
1583 1560 def pre_readline(self):
1584 1561 """readline hook to be used at the start of each line.
1585 1562
1586 1563 Currently it handles auto-indent only."""
1587 1564
1588 1565 #debugx('self.indent_current_nsp','pre_readline:')
1589 1566
1590 1567 if self.rl_do_indent:
1591 1568 self.readline.insert_text(self._indent_current_str())
1592 1569 if self.rl_next_input is not None:
1593 1570 self.readline.insert_text(self.rl_next_input)
1594 1571 self.rl_next_input = None
1595 1572
1596 1573 def _indent_current_str(self):
1597 1574 """return the current level of indentation as a string"""
1598 1575 return self.indent_current_nsp * ' '
1599 1576
1600 1577 #-------------------------------------------------------------------------
1601 1578 # Things related to magics
1602 1579 #-------------------------------------------------------------------------
1603 1580
1604 1581 def init_magics(self):
1605 1582 # Set user colors (don't do it in the constructor above so that it
1606 1583 # doesn't crash if colors option is invalid)
1607 1584 self.magic_colors(self.colors)
1608 1585
1609 1586 def magic(self,arg_s):
1610 1587 """Call a magic function by name.
1611 1588
1612 1589 Input: a string containing the name of the magic function to call and any
1613 1590 additional arguments to be passed to the magic.
1614 1591
1615 1592 magic('name -opt foo bar') is equivalent to typing at the ipython
1616 1593 prompt:
1617 1594
1618 1595 In[1]: %name -opt foo bar
1619 1596
1620 1597 To call a magic without arguments, simply use magic('name').
1621 1598
1622 1599 This provides a proper Python function to call IPython's magics in any
1623 1600 valid Python code you can type at the interpreter, including loops and
1624 1601 compound statements.
1625 1602 """
1626 1603
1627 1604 args = arg_s.split(' ',1)
1628 1605 magic_name = args[0]
1629 1606 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
1630 1607
1631 1608 try:
1632 1609 magic_args = args[1]
1633 1610 except IndexError:
1634 1611 magic_args = ''
1635 1612 fn = getattr(self,'magic_'+magic_name,None)
1636 1613 if fn is None:
1637 1614 error("Magic function `%s` not found." % magic_name)
1638 1615 else:
1639 1616 magic_args = self.var_expand(magic_args,1)
1640 1617 with nested(self.builtin_trap,):
1641 1618 result = fn(magic_args)
1642 1619 return result
1643 1620
1644 1621 def define_magic(self, magicname, func):
1645 1622 """Expose own function as magic function for ipython
1646 1623
1647 1624 def foo_impl(self,parameter_s=''):
1648 1625 'My very own magic!. (Use docstrings, IPython reads them).'
1649 1626 print 'Magic function. Passed parameter is between < >:'
1650 1627 print '<%s>' % parameter_s
1651 1628 print 'The self object is:',self
1652 1629
1653 1630 self.define_magic('foo',foo_impl)
1654 1631 """
1655 1632
1656 1633 import new
1657 1634 im = new.instancemethod(func,self, self.__class__)
1658 1635 old = getattr(self, "magic_" + magicname, None)
1659 1636 setattr(self, "magic_" + magicname, im)
1660 1637 return old
1661 1638
1662 1639 #-------------------------------------------------------------------------
1663 1640 # Things related to macros
1664 1641 #-------------------------------------------------------------------------
1665 1642
1666 1643 def define_macro(self, name, themacro):
1667 1644 """Define a new macro
1668 1645
1669 1646 Parameters
1670 1647 ----------
1671 1648 name : str
1672 1649 The name of the macro.
1673 1650 themacro : str or Macro
1674 1651 The action to do upon invoking the macro. If a string, a new
1675 1652 Macro object is created by passing the string to it.
1676 1653 """
1677 1654
1678 1655 from IPython.core import macro
1679 1656
1680 1657 if isinstance(themacro, basestring):
1681 1658 themacro = macro.Macro(themacro)
1682 1659 if not isinstance(themacro, macro.Macro):
1683 1660 raise ValueError('A macro must be a string or a Macro instance.')
1684 1661 self.user_ns[name] = themacro
1685 1662
1686 1663 #-------------------------------------------------------------------------
1687 1664 # Things related to the running of system commands
1688 1665 #-------------------------------------------------------------------------
1689 1666
1690 1667 def system(self, cmd):
1691 1668 """Make a system call, using IPython."""
1692 1669 return self.hooks.shell_hook(self.var_expand(cmd, depth=2))
1693 1670
1694 1671 #-------------------------------------------------------------------------
1695 1672 # Things related to aliases
1696 1673 #-------------------------------------------------------------------------
1697 1674
1698 1675 def init_alias(self):
1699 1676 self.alias_manager = AliasManager(self, config=self.config)
1700 1677 self.ns_table['alias'] = self.alias_manager.alias_table,
1701 1678
1702 1679 #-------------------------------------------------------------------------
1703 1680 # Things related to the running of code
1704 1681 #-------------------------------------------------------------------------
1705 1682
1706 1683 def ex(self, cmd):
1707 1684 """Execute a normal python statement in user namespace."""
1708 1685 with nested(self.builtin_trap,):
1709 1686 exec cmd in self.user_global_ns, self.user_ns
1710 1687
1711 1688 def ev(self, expr):
1712 1689 """Evaluate python expression expr in user namespace.
1713 1690
1714 1691 Returns the result of evaluation
1715 1692 """
1716 1693 with nested(self.builtin_trap,):
1717 1694 return eval(expr, self.user_global_ns, self.user_ns)
1718 1695
1719 1696 def mainloop(self, display_banner=None):
1720 1697 """Start the mainloop.
1721 1698
1722 1699 If an optional banner argument is given, it will override the
1723 1700 internally created default banner.
1724 1701 """
1725 1702
1726 1703 with nested(self.builtin_trap, self.display_trap):
1727 1704
1728 1705 # if you run stuff with -c <cmd>, raw hist is not updated
1729 1706 # ensure that it's in sync
1730 1707 if len(self.input_hist) != len (self.input_hist_raw):
1731 1708 self.input_hist_raw = InputList(self.input_hist)
1732 1709
1733 1710 while 1:
1734 1711 try:
1735 1712 self.interact(display_banner=display_banner)
1736 1713 #self.interact_with_readline()
1737 1714 # XXX for testing of a readline-decoupled repl loop, call
1738 1715 # interact_with_readline above
1739 1716 break
1740 1717 except KeyboardInterrupt:
1741 1718 # this should not be necessary, but KeyboardInterrupt
1742 1719 # handling seems rather unpredictable...
1743 1720 self.write("\nKeyboardInterrupt in interact()\n")
1744 1721
1745 1722 def interact_prompt(self):
1746 1723 """ Print the prompt (in read-eval-print loop)
1747 1724
1748 1725 Provided for those who want to implement their own read-eval-print loop (e.g. GUIs), not
1749 1726 used in standard IPython flow.
1750 1727 """
1751 1728 if self.more:
1752 1729 try:
1753 1730 prompt = self.hooks.generate_prompt(True)
1754 1731 except:
1755 1732 self.showtraceback()
1756 1733 if self.autoindent:
1757 1734 self.rl_do_indent = True
1758 1735
1759 1736 else:
1760 1737 try:
1761 1738 prompt = self.hooks.generate_prompt(False)
1762 1739 except:
1763 1740 self.showtraceback()
1764 1741 self.write(prompt)
1765 1742
1766 1743 def interact_handle_input(self,line):
1767 1744 """ Handle the input line (in read-eval-print loop)
1768 1745
1769 1746 Provided for those who want to implement their own read-eval-print loop (e.g. GUIs), not
1770 1747 used in standard IPython flow.
1771 1748 """
1772 1749 if line.lstrip() == line:
1773 1750 self.shadowhist.add(line.strip())
1774 1751 lineout = self.prefilter_manager.prefilter_lines(line,self.more)
1775 1752
1776 1753 if line.strip():
1777 1754 if self.more:
1778 1755 self.input_hist_raw[-1] += '%s\n' % line
1779 1756 else:
1780 1757 self.input_hist_raw.append('%s\n' % line)
1781 1758
1782 1759
1783 1760 self.more = self.push_line(lineout)
1784 1761 if (self.SyntaxTB.last_syntax_error and
1785 1762 self.autoedit_syntax):
1786 1763 self.edit_syntax_error()
1787 1764
1788 1765 def interact_with_readline(self):
1789 1766 """ Demo of using interact_handle_input, interact_prompt
1790 1767
1791 1768 This is the main read-eval-print loop. If you need to implement your own (e.g. for GUI),
1792 1769 it should work like this.
1793 1770 """
1794 1771 self.readline_startup_hook(self.pre_readline)
1795 1772 while not self.exit_now:
1796 1773 self.interact_prompt()
1797 1774 if self.more:
1798 1775 self.rl_do_indent = True
1799 1776 else:
1800 1777 self.rl_do_indent = False
1801 1778 line = raw_input_original().decode(self.stdin_encoding)
1802 1779 self.interact_handle_input(line)
1803 1780
1804 1781 def interact(self, display_banner=None):
1805 1782 """Closely emulate the interactive Python console."""
1806 1783
1807 1784 # batch run -> do not interact
1808 1785 if self.exit_now:
1809 1786 return
1810 1787
1811 1788 if display_banner is None:
1812 1789 display_banner = self.display_banner
1813 1790 if display_banner:
1814 1791 self.show_banner()
1815 1792
1816 1793 more = 0
1817 1794
1818 1795 # Mark activity in the builtins
1819 1796 __builtin__.__dict__['__IPYTHON__active'] += 1
1820 1797
1821 1798 if self.has_readline:
1822 1799 self.readline_startup_hook(self.pre_readline)
1823 1800 # exit_now is set by a call to %Exit or %Quit, through the
1824 1801 # ask_exit callback.
1825 1802
1826 1803 while not self.exit_now:
1827 1804 self.hooks.pre_prompt_hook()
1828 1805 if more:
1829 1806 try:
1830 1807 prompt = self.hooks.generate_prompt(True)
1831 1808 except:
1832 1809 self.showtraceback()
1833 1810 if self.autoindent:
1834 1811 self.rl_do_indent = True
1835 1812
1836 1813 else:
1837 1814 try:
1838 1815 prompt = self.hooks.generate_prompt(False)
1839 1816 except:
1840 1817 self.showtraceback()
1841 1818 try:
1842 1819 line = self.raw_input(prompt, more)
1843 1820 if self.exit_now:
1844 1821 # quick exit on sys.std[in|out] close
1845 1822 break
1846 1823 if self.autoindent:
1847 1824 self.rl_do_indent = False
1848 1825
1849 1826 except KeyboardInterrupt:
1850 1827 #double-guard against keyboardinterrupts during kbdint handling
1851 1828 try:
1852 1829 self.write('\nKeyboardInterrupt\n')
1853 1830 self.resetbuffer()
1854 1831 # keep cache in sync with the prompt counter:
1855 1832 self.outputcache.prompt_count -= 1
1856 1833
1857 1834 if self.autoindent:
1858 1835 self.indent_current_nsp = 0
1859 1836 more = 0
1860 1837 except KeyboardInterrupt:
1861 1838 pass
1862 1839 except EOFError:
1863 1840 if self.autoindent:
1864 1841 self.rl_do_indent = False
1865 1842 if self.has_readline:
1866 1843 self.readline_startup_hook(None)
1867 1844 self.write('\n')
1868 1845 self.exit()
1869 1846 except bdb.BdbQuit:
1870 1847 warn('The Python debugger has exited with a BdbQuit exception.\n'
1871 1848 'Because of how pdb handles the stack, it is impossible\n'
1872 1849 'for IPython to properly format this particular exception.\n'
1873 1850 'IPython will resume normal operation.')
1874 1851 except:
1875 1852 # exceptions here are VERY RARE, but they can be triggered
1876 1853 # asynchronously by signal handlers, for example.
1877 1854 self.showtraceback()
1878 1855 else:
1879 1856 more = self.push_line(line)
1880 1857 if (self.SyntaxTB.last_syntax_error and
1881 1858 self.autoedit_syntax):
1882 1859 self.edit_syntax_error()
1883
1860
1884 1861 # We are off again...
1885 1862 __builtin__.__dict__['__IPYTHON__active'] -= 1
1886 1863
1887 1864 def safe_execfile(self, fname, *where, **kw):
1888 1865 """A safe version of the builtin execfile().
1889 1866
1890 1867 This version will never throw an exception, but instead print
1891 1868 helpful error messages to the screen. This only works on pure
1892 1869 Python files with the .py extension.
1893 1870
1894 1871 Parameters
1895 1872 ----------
1896 1873 fname : string
1897 1874 The name of the file to be executed.
1898 1875 where : tuple
1899 1876 One or two namespaces, passed to execfile() as (globals,locals).
1900 1877 If only one is given, it is passed as both.
1901 1878 exit_ignore : bool (False)
1902 1879 If True, then don't print errors for non-zero exit statuses.
1903 1880 """
1904 1881 kw.setdefault('exit_ignore', False)
1905 1882
1906 1883 fname = os.path.abspath(os.path.expanduser(fname))
1907 1884
1908 1885 # Make sure we have a .py file
1909 1886 if not fname.endswith('.py'):
1910 1887 warn('File must end with .py to be run using execfile: <%s>' % fname)
1911 1888
1912 1889 # Make sure we can open the file
1913 1890 try:
1914 1891 with open(fname) as thefile:
1915 1892 pass
1916 1893 except:
1917 1894 warn('Could not open file <%s> for safe execution.' % fname)
1918 1895 return
1919 1896
1920 1897 # Find things also in current directory. This is needed to mimic the
1921 1898 # behavior of running a script from the system command line, where
1922 1899 # Python inserts the script's directory into sys.path
1923 1900 dname = os.path.dirname(fname)
1924 1901
1925 1902 with prepended_to_syspath(dname):
1926 1903 try:
1927 1904 if sys.platform == 'win32' and sys.version_info < (2,5,1):
1928 1905 # Work around a bug in Python for Windows. The bug was
1929 1906 # fixed in in Python 2.5 r54159 and 54158, but that's still
1930 1907 # SVN Python as of March/07. For details, see:
1931 1908 # http://projects.scipy.org/ipython/ipython/ticket/123
1932 1909 try:
1933 1910 globs,locs = where[0:2]
1934 1911 except:
1935 1912 try:
1936 1913 globs = locs = where[0]
1937 1914 except:
1938 1915 globs = locs = globals()
1939 1916 exec file(fname) in globs,locs
1940 1917 else:
1941 1918 execfile(fname,*where)
1942 1919 except SyntaxError:
1943 1920 self.showsyntaxerror()
1944 1921 warn('Failure executing file: <%s>' % fname)
1945 1922 except SystemExit, status:
1946 1923 # Code that correctly sets the exit status flag to success (0)
1947 1924 # shouldn't be bothered with a traceback. Note that a plain
1948 1925 # sys.exit() does NOT set the message to 0 (it's empty) so that
1949 1926 # will still get a traceback. Note that the structure of the
1950 1927 # SystemExit exception changed between Python 2.4 and 2.5, so
1951 1928 # the checks must be done in a version-dependent way.
1952 1929 show = False
1953 1930 if status.args[0]==0 and not kw['exit_ignore']:
1954 1931 show = True
1955 1932 if show:
1956 1933 self.showtraceback()
1957 1934 warn('Failure executing file: <%s>' % fname)
1958 1935 except:
1959 1936 self.showtraceback()
1960 1937 warn('Failure executing file: <%s>' % fname)
1961 1938
1962 1939 def safe_execfile_ipy(self, fname):
1963 1940 """Like safe_execfile, but for .ipy files with IPython syntax.
1964 1941
1965 1942 Parameters
1966 1943 ----------
1967 1944 fname : str
1968 1945 The name of the file to execute. The filename must have a
1969 1946 .ipy extension.
1970 1947 """
1971 1948 fname = os.path.abspath(os.path.expanduser(fname))
1972 1949
1973 1950 # Make sure we have a .py file
1974 1951 if not fname.endswith('.ipy'):
1975 1952 warn('File must end with .py to be run using execfile: <%s>' % fname)
1976 1953
1977 1954 # Make sure we can open the file
1978 1955 try:
1979 1956 with open(fname) as thefile:
1980 1957 pass
1981 1958 except:
1982 1959 warn('Could not open file <%s> for safe execution.' % fname)
1983 1960 return
1984 1961
1985 1962 # Find things also in current directory. This is needed to mimic the
1986 1963 # behavior of running a script from the system command line, where
1987 1964 # Python inserts the script's directory into sys.path
1988 1965 dname = os.path.dirname(fname)
1989 1966
1990 1967 with prepended_to_syspath(dname):
1991 1968 try:
1992 1969 with open(fname) as thefile:
1993 1970 script = thefile.read()
1994 1971 # self.runlines currently captures all exceptions
1995 1972 # raise in user code. It would be nice if there were
1996 1973 # versions of runlines, execfile that did raise, so
1997 1974 # we could catch the errors.
1998 1975 self.runlines(script, clean=True)
1999 1976 except:
2000 1977 self.showtraceback()
2001 1978 warn('Unknown failure executing file: <%s>' % fname)
2002 1979
2003 1980 def _is_secondary_block_start(self, s):
2004 1981 if not s.endswith(':'):
2005 1982 return False
2006 1983 if (s.startswith('elif') or
2007 1984 s.startswith('else') or
2008 1985 s.startswith('except') or
2009 1986 s.startswith('finally')):
2010 1987 return True
2011 1988
2012 1989 def cleanup_ipy_script(self, script):
2013 1990 """Make a script safe for self.runlines()
2014 1991
2015 1992 Currently, IPython is lines based, with blocks being detected by
2016 1993 empty lines. This is a problem for block based scripts that may
2017 1994 not have empty lines after blocks. This script adds those empty
2018 1995 lines to make scripts safe for running in the current line based
2019 1996 IPython.
2020 1997 """
2021 1998 res = []
2022 1999 lines = script.splitlines()
2023 2000 level = 0
2024 2001
2025 2002 for l in lines:
2026 2003 lstripped = l.lstrip()
2027 2004 stripped = l.strip()
2028 2005 if not stripped:
2029 2006 continue
2030 2007 newlevel = len(l) - len(lstripped)
2031 2008 if level > 0 and newlevel == 0 and \
2032 2009 not self._is_secondary_block_start(stripped):
2033 2010 # add empty line
2034 2011 res.append('')
2035 2012 res.append(l)
2036 2013 level = newlevel
2037 2014
2038 2015 return '\n'.join(res) + '\n'
2039 2016
2040 2017 def runlines(self, lines, clean=False):
2041 2018 """Run a string of one or more lines of source.
2042 2019
2043 2020 This method is capable of running a string containing multiple source
2044 2021 lines, as if they had been entered at the IPython prompt. Since it
2045 2022 exposes IPython's processing machinery, the given strings can contain
2046 2023 magic calls (%magic), special shell access (!cmd), etc.
2047 2024 """
2048 2025
2049 2026 if isinstance(lines, (list, tuple)):
2050 2027 lines = '\n'.join(lines)
2051 2028
2052 2029 if clean:
2053 2030 lines = self.cleanup_ipy_script(lines)
2054 2031
2055 2032 # We must start with a clean buffer, in case this is run from an
2056 2033 # interactive IPython session (via a magic, for example).
2057 2034 self.resetbuffer()
2058 2035 lines = lines.splitlines()
2059 2036 more = 0
2060 2037
2061 2038 with nested(self.builtin_trap, self.display_trap):
2062 2039 for line in lines:
2063 2040 # skip blank lines so we don't mess up the prompt counter, but do
2064 2041 # NOT skip even a blank line if we are in a code block (more is
2065 2042 # true)
2066 2043
2067 2044 if line or more:
2068 2045 # push to raw history, so hist line numbers stay in sync
2069 2046 self.input_hist_raw.append("# " + line + "\n")
2070 2047 prefiltered = self.prefilter_manager.prefilter_lines(line,more)
2071 2048 more = self.push_line(prefiltered)
2072 2049 # IPython's runsource returns None if there was an error
2073 2050 # compiling the code. This allows us to stop processing right
2074 2051 # away, so the user gets the error message at the right place.
2075 2052 if more is None:
2076 2053 break
2077 2054 else:
2078 2055 self.input_hist_raw.append("\n")
2079 2056 # final newline in case the input didn't have it, so that the code
2080 2057 # actually does get executed
2081 2058 if more:
2082 2059 self.push_line('\n')
2083 2060
2084 2061 def runsource(self, source, filename='<input>', symbol='single'):
2085 2062 """Compile and run some source in the interpreter.
2086 2063
2087 2064 Arguments are as for compile_command().
2088 2065
2089 2066 One several things can happen:
2090 2067
2091 2068 1) The input is incorrect; compile_command() raised an
2092 2069 exception (SyntaxError or OverflowError). A syntax traceback
2093 2070 will be printed by calling the showsyntaxerror() method.
2094 2071
2095 2072 2) The input is incomplete, and more input is required;
2096 2073 compile_command() returned None. Nothing happens.
2097 2074
2098 2075 3) The input is complete; compile_command() returned a code
2099 2076 object. The code is executed by calling self.runcode() (which
2100 2077 also handles run-time exceptions, except for SystemExit).
2101 2078
2102 2079 The return value is:
2103 2080
2104 2081 - True in case 2
2105 2082
2106 2083 - False in the other cases, unless an exception is raised, where
2107 2084 None is returned instead. This can be used by external callers to
2108 2085 know whether to continue feeding input or not.
2109 2086
2110 2087 The return value can be used to decide whether to use sys.ps1 or
2111 2088 sys.ps2 to prompt the next line."""
2112 2089
2113 2090 # if the source code has leading blanks, add 'if 1:\n' to it
2114 2091 # this allows execution of indented pasted code. It is tempting
2115 2092 # to add '\n' at the end of source to run commands like ' a=1'
2116 2093 # directly, but this fails for more complicated scenarios
2117 2094 source=source.encode(self.stdin_encoding)
2118 2095 if source[:1] in [' ', '\t']:
2119 2096 source = 'if 1:\n%s' % source
2120 2097
2121 2098 try:
2122 2099 code = self.compile(source,filename,symbol)
2123 2100 except (OverflowError, SyntaxError, ValueError, TypeError, MemoryError):
2124 2101 # Case 1
2125 2102 self.showsyntaxerror(filename)
2126 2103 return None
2127 2104
2128 2105 if code is None:
2129 2106 # Case 2
2130 2107 return True
2131 2108
2132 2109 # Case 3
2133 2110 # We store the code object so that threaded shells and
2134 2111 # custom exception handlers can access all this info if needed.
2135 2112 # The source corresponding to this can be obtained from the
2136 2113 # buffer attribute as '\n'.join(self.buffer).
2137 2114 self.code_to_run = code
2138 2115 # now actually execute the code object
2139 2116 if self.runcode(code) == 0:
2140 2117 return False
2141 2118 else:
2142 2119 return None
2143 2120
2144 2121 def runcode(self,code_obj):
2145 2122 """Execute a code object.
2146 2123
2147 2124 When an exception occurs, self.showtraceback() is called to display a
2148 2125 traceback.
2149 2126
2150 2127 Return value: a flag indicating whether the code to be run completed
2151 2128 successfully:
2152 2129
2153 2130 - 0: successful execution.
2154 2131 - 1: an error occurred.
2155 2132 """
2156 2133
2157 2134 # Set our own excepthook in case the user code tries to call it
2158 2135 # directly, so that the IPython crash handler doesn't get triggered
2159 2136 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
2160 2137
2161 2138 # we save the original sys.excepthook in the instance, in case config
2162 2139 # code (such as magics) needs access to it.
2163 2140 self.sys_excepthook = old_excepthook
2164 2141 outflag = 1 # happens in more places, so it's easier as default
2165 2142 try:
2166 2143 try:
2167 2144 self.hooks.pre_runcode_hook()
2168 2145 exec code_obj in self.user_global_ns, self.user_ns
2169 2146 finally:
2170 2147 # Reset our crash handler in place
2171 2148 sys.excepthook = old_excepthook
2172 2149 except SystemExit:
2173 2150 self.resetbuffer()
2174 2151 self.showtraceback()
2175 2152 warn("Type %exit or %quit to exit IPython "
2176 2153 "(%Exit or %Quit do so unconditionally).",level=1)
2177 2154 except self.custom_exceptions:
2178 2155 etype,value,tb = sys.exc_info()
2179 2156 self.CustomTB(etype,value,tb)
2180 2157 except:
2181 2158 self.showtraceback()
2182 2159 else:
2183 2160 outflag = 0
2184 2161 if softspace(sys.stdout, 0):
2185 2162 print
2186 2163 # Flush out code object which has been run (and source)
2187 2164 self.code_to_run = None
2188 2165 return outflag
2189 2166
2190 2167 def push_line(self, line):
2191 2168 """Push a line to the interpreter.
2192 2169
2193 2170 The line should not have a trailing newline; it may have
2194 2171 internal newlines. The line is appended to a buffer and the
2195 2172 interpreter's runsource() method is called with the
2196 2173 concatenated contents of the buffer as source. If this
2197 2174 indicates that the command was executed or invalid, the buffer
2198 2175 is reset; otherwise, the command is incomplete, and the buffer
2199 2176 is left as it was after the line was appended. The return
2200 2177 value is 1 if more input is required, 0 if the line was dealt
2201 2178 with in some way (this is the same as runsource()).
2202 2179 """
2203 2180
2204 2181 # autoindent management should be done here, and not in the
2205 2182 # interactive loop, since that one is only seen by keyboard input. We
2206 2183 # need this done correctly even for code run via runlines (which uses
2207 2184 # push).
2208 2185
2209 2186 #print 'push line: <%s>' % line # dbg
2210 2187 for subline in line.splitlines():
2211 2188 self._autoindent_update(subline)
2212 2189 self.buffer.append(line)
2213 2190 more = self.runsource('\n'.join(self.buffer), self.filename)
2214 2191 if not more:
2215 2192 self.resetbuffer()
2216 2193 return more
2217 2194
2218 2195 def _autoindent_update(self,line):
2219 2196 """Keep track of the indent level."""
2220 2197
2221 2198 #debugx('line')
2222 2199 #debugx('self.indent_current_nsp')
2223 2200 if self.autoindent:
2224 2201 if line:
2225 2202 inisp = num_ini_spaces(line)
2226 2203 if inisp < self.indent_current_nsp:
2227 2204 self.indent_current_nsp = inisp
2228 2205
2229 2206 if line[-1] == ':':
2230 2207 self.indent_current_nsp += 4
2231 2208 elif dedent_re.match(line):
2232 2209 self.indent_current_nsp -= 4
2233 2210 else:
2234 2211 self.indent_current_nsp = 0
2235 2212
2236 2213 def resetbuffer(self):
2237 2214 """Reset the input buffer."""
2238 2215 self.buffer[:] = []
2239 2216
2240 2217 def raw_input(self,prompt='',continue_prompt=False):
2241 2218 """Write a prompt and read a line.
2242 2219
2243 2220 The returned line does not include the trailing newline.
2244 2221 When the user enters the EOF key sequence, EOFError is raised.
2245 2222
2246 2223 Optional inputs:
2247 2224
2248 2225 - prompt(''): a string to be printed to prompt the user.
2249 2226
2250 2227 - continue_prompt(False): whether this line is the first one or a
2251 2228 continuation in a sequence of inputs.
2252 2229 """
2253 2230 # growl.notify("raw_input: ", "prompt = %r\ncontinue_prompt = %s" % (prompt, continue_prompt))
2254 2231
2255 2232 # Code run by the user may have modified the readline completer state.
2256 2233 # We must ensure that our completer is back in place.
2257 2234
2258 2235 if self.has_readline:
2259 2236 self.set_completer()
2260 2237
2261 2238 try:
2262 2239 line = raw_input_original(prompt).decode(self.stdin_encoding)
2263 2240 except ValueError:
2264 2241 warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
2265 2242 " or sys.stdout.close()!\nExiting IPython!")
2266 2243 self.ask_exit()
2267 2244 return ""
2268 2245
2269 2246 # Try to be reasonably smart about not re-indenting pasted input more
2270 2247 # than necessary. We do this by trimming out the auto-indent initial
2271 2248 # spaces, if the user's actual input started itself with whitespace.
2272 2249 #debugx('self.buffer[-1]')
2273 2250
2274 2251 if self.autoindent:
2275 2252 if num_ini_spaces(line) > self.indent_current_nsp:
2276 2253 line = line[self.indent_current_nsp:]
2277 2254 self.indent_current_nsp = 0
2278 2255
2279 2256 # store the unfiltered input before the user has any chance to modify
2280 2257 # it.
2281 2258 if line.strip():
2282 2259 if continue_prompt:
2283 2260 self.input_hist_raw[-1] += '%s\n' % line
2284 2261 if self.has_readline and self.readline_use:
2285 2262 try:
2286 2263 histlen = self.readline.get_current_history_length()
2287 2264 if histlen > 1:
2288 2265 newhist = self.input_hist_raw[-1].rstrip()
2289 2266 self.readline.remove_history_item(histlen-1)
2290 2267 self.readline.replace_history_item(histlen-2,
2291 2268 newhist.encode(self.stdin_encoding))
2292 2269 except AttributeError:
2293 2270 pass # re{move,place}_history_item are new in 2.4.
2294 2271 else:
2295 2272 self.input_hist_raw.append('%s\n' % line)
2296 2273 # only entries starting at first column go to shadow history
2297 2274 if line.lstrip() == line:
2298 2275 self.shadowhist.add(line.strip())
2299 2276 elif not continue_prompt:
2300 2277 self.input_hist_raw.append('\n')
2301 2278 try:
2302 2279 lineout = self.prefilter_manager.prefilter_lines(line,continue_prompt)
2303 2280 except:
2304 2281 # blanket except, in case a user-defined prefilter crashes, so it
2305 2282 # can't take all of ipython with it.
2306 2283 self.showtraceback()
2307 2284 return ''
2308 2285 else:
2309 2286 return lineout
2310 2287
2311 2288 #-------------------------------------------------------------------------
2312 2289 # Working with components
2313 2290 #-------------------------------------------------------------------------
2314 2291
2315 2292 def get_component(self, name=None, klass=None):
2316 2293 """Fetch a component by name and klass in my tree."""
2317 2294 c = Component.get_instances(root=self, name=name, klass=klass)
2318 2295 if len(c) == 0:
2319 2296 return None
2320 2297 if len(c) == 1:
2321 2298 return c[0]
2322 2299 else:
2323 2300 return c
2324 2301
2325 2302 #-------------------------------------------------------------------------
2326 2303 # IPython extensions
2327 2304 #-------------------------------------------------------------------------
2328 2305
2329 2306 def load_extension(self, module_str):
2330 2307 """Load an IPython extension by its module name.
2331 2308
2332 2309 An IPython extension is an importable Python module that has
2333 2310 a function with the signature::
2334 2311
2335 2312 def load_ipython_extension(ipython):
2336 2313 # Do things with ipython
2337 2314
2338 2315 This function is called after your extension is imported and the
2339 2316 currently active :class:`InteractiveShell` instance is passed as
2340 2317 the only argument. You can do anything you want with IPython at
2341 2318 that point, including defining new magic and aliases, adding new
2342 2319 components, etc.
2343 2320
2344 2321 The :func:`load_ipython_extension` will be called again is you
2345 2322 load or reload the extension again. It is up to the extension
2346 2323 author to add code to manage that.
2347 2324
2348 2325 You can put your extension modules anywhere you want, as long as
2349 2326 they can be imported by Python's standard import mechanism. However,
2350 2327 to make it easy to write extensions, you can also put your extensions
2351 2328 in ``os.path.join(self.ipython_dir, 'extensions')``. This directory
2352 2329 is added to ``sys.path`` automatically.
2353 2330 """
2354 2331 from IPython.utils.syspathcontext import prepended_to_syspath
2355 2332
2356 2333 if module_str not in sys.modules:
2357 2334 with prepended_to_syspath(self.ipython_extension_dir):
2358 2335 __import__(module_str)
2359 2336 mod = sys.modules[module_str]
2360 2337 self._call_load_ipython_extension(mod)
2361 2338
2362 2339 def unload_extension(self, module_str):
2363 2340 """Unload an IPython extension by its module name.
2364 2341
2365 2342 This function looks up the extension's name in ``sys.modules`` and
2366 2343 simply calls ``mod.unload_ipython_extension(self)``.
2367 2344 """
2368 2345 if module_str in sys.modules:
2369 2346 mod = sys.modules[module_str]
2370 2347 self._call_unload_ipython_extension(mod)
2371 2348
2372 2349 def reload_extension(self, module_str):
2373 2350 """Reload an IPython extension by calling reload.
2374 2351
2375 2352 If the module has not been loaded before,
2376 2353 :meth:`InteractiveShell.load_extension` is called. Otherwise
2377 2354 :func:`reload` is called and then the :func:`load_ipython_extension`
2378 2355 function of the module, if it exists is called.
2379 2356 """
2380 2357 from IPython.utils.syspathcontext import prepended_to_syspath
2381 2358
2382 2359 with prepended_to_syspath(self.ipython_extension_dir):
2383 2360 if module_str in sys.modules:
2384 2361 mod = sys.modules[module_str]
2385 2362 reload(mod)
2386 2363 self._call_load_ipython_extension(mod)
2387 2364 else:
2388 2365 self.load_extension(module_str)
2389 2366
2390 2367 def _call_load_ipython_extension(self, mod):
2391 2368 if hasattr(mod, 'load_ipython_extension'):
2392 2369 mod.load_ipython_extension(self)
2393 2370
2394 2371 def _call_unload_ipython_extension(self, mod):
2395 2372 if hasattr(mod, 'unload_ipython_extension'):
2396 2373 mod.unload_ipython_extension(self)
2397 2374
2398 2375 #-------------------------------------------------------------------------
2399 2376 # Things related to the prefilter
2400 2377 #-------------------------------------------------------------------------
2401 2378
2402 2379 def init_prefilter(self):
2403 2380 self.prefilter_manager = PrefilterManager(self, config=self.config)
2404 2381
2405 2382 #-------------------------------------------------------------------------
2406 2383 # Utilities
2407 2384 #-------------------------------------------------------------------------
2408 2385
2409 2386 def getoutput(self, cmd):
2410 2387 return getoutput(self.var_expand(cmd,depth=2),
2411 2388 header=self.system_header,
2412 2389 verbose=self.system_verbose)
2413 2390
2414 2391 def getoutputerror(self, cmd):
2415 2392 return getoutputerror(self.var_expand(cmd,depth=2),
2416 2393 header=self.system_header,
2417 2394 verbose=self.system_verbose)
2418 2395
2419 2396 def var_expand(self,cmd,depth=0):
2420 2397 """Expand python variables in a string.
2421 2398
2422 2399 The depth argument indicates how many frames above the caller should
2423 2400 be walked to look for the local namespace where to expand variables.
2424 2401
2425 2402 The global namespace for expansion is always the user's interactive
2426 2403 namespace.
2427 2404 """
2428 2405
2429 2406 return str(ItplNS(cmd,
2430 2407 self.user_ns, # globals
2431 2408 # Skip our own frame in searching for locals:
2432 2409 sys._getframe(depth+1).f_locals # locals
2433 2410 ))
2434 2411
2435 2412 def mktempfile(self,data=None):
2436 2413 """Make a new tempfile and return its filename.
2437 2414
2438 2415 This makes a call to tempfile.mktemp, but it registers the created
2439 2416 filename internally so ipython cleans it up at exit time.
2440 2417
2441 2418 Optional inputs:
2442 2419
2443 2420 - data(None): if data is given, it gets written out to the temp file
2444 2421 immediately, and the file is closed again."""
2445 2422
2446 2423 filename = tempfile.mktemp('.py','ipython_edit_')
2447 2424 self.tempfiles.append(filename)
2448 2425
2449 2426 if data:
2450 2427 tmp_file = open(filename,'w')
2451 2428 tmp_file.write(data)
2452 2429 tmp_file.close()
2453 2430 return filename
2454 2431
2455 2432 def write(self,data):
2456 2433 """Write a string to the default output"""
2457 2434 Term.cout.write(data)
2458 2435
2459 2436 def write_err(self,data):
2460 2437 """Write a string to the default error output"""
2461 2438 Term.cerr.write(data)
2462 2439
2463 2440 def ask_yes_no(self,prompt,default=True):
2464 2441 if self.quiet:
2465 2442 return True
2466 2443 return ask_yes_no(prompt,default)
2467 2444
2468 2445 #-------------------------------------------------------------------------
2469 2446 # Things related to GUI support and pylab
2470 2447 #-------------------------------------------------------------------------
2471 2448
2472 2449 def enable_pylab(self, gui=None):
2473 2450 """Activate pylab support at runtime.
2474 2451
2475 2452 This turns on support for matplotlib, preloads into the interactive
2476 2453 namespace all of numpy and pylab, and configures IPython to correcdtly
2477 2454 interact with the GUI event loop. The GUI backend to be used can be
2478 2455 optionally selected with the optional :param:`gui` argument.
2479 2456
2480 2457 Parameters
2481 2458 ----------
2482 2459 gui : optional, string
2483 2460
2484 2461 If given, dictates the choice of matplotlib GUI backend to use
2485 2462 (should be one of IPython's supported backends, 'tk', 'qt', 'wx' or
2486 2463 'gtk'), otherwise we use the default chosen by matplotlib (as
2487 2464 dictated by the matplotlib build-time options plus the user's
2488 2465 matplotlibrc configuration file).
2489 2466 """
2490 2467 # We want to prevent the loading of pylab to pollute the user's
2491 2468 # namespace as shown by the %who* magics, so we execute the activation
2492 2469 # code in an empty namespace, and we update *both* user_ns and
2493 2470 # user_config_ns with this information.
2494 2471 ns = {}
2495 2472 gui = pylab_activate(ns, gui)
2496 2473 self.user_ns.update(ns)
2497 2474 self.user_config_ns.update(ns)
2498 2475 # Now we must activate the gui pylab wants to use, and fix %run to take
2499 2476 # plot updates into account
2500 2477 enable_gui(gui)
2501 2478 self.magic_run = self._pylab_magic_run
2502 2479
2503 2480 #-------------------------------------------------------------------------
2504 2481 # Things related to IPython exiting
2505 2482 #-------------------------------------------------------------------------
2506 2483
2507 2484 def ask_exit(self):
2508 2485 """ Ask the shell to exit. Can be overiden and used as a callback. """
2509 2486 self.exit_now = True
2510 2487
2511 2488 def exit(self):
2512 2489 """Handle interactive exit.
2513 2490
2514 2491 This method calls the ask_exit callback."""
2515 2492 if self.confirm_exit:
2516 2493 if self.ask_yes_no('Do you really want to exit ([y]/n)?','y'):
2517 2494 self.ask_exit()
2518 2495 else:
2519 2496 self.ask_exit()
2520 2497
2521 2498 def atexit_operations(self):
2522 2499 """This will be executed at the time of exit.
2523 2500
2524 2501 Saving of persistent data should be performed here.
2525 2502 """
2526 2503 self.savehist()
2527 2504
2528 2505 # Cleanup all tempfiles left around
2529 2506 for tfile in self.tempfiles:
2530 2507 try:
2531 2508 os.unlink(tfile)
2532 2509 except OSError:
2533 2510 pass
2534 2511
2535 2512 # Clear all user namespaces to release all references cleanly.
2536 2513 self.reset()
2537 2514
2538 2515 # Run user hooks
2539 2516 self.hooks.shutdown_hook()
2540 2517
2541 2518 def cleanup(self):
2542 2519 self.restore_sys_module_state()
2543 2520
2544 2521
@@ -1,270 +1,264 b''
1 1 """
2 2 Frontend class that uses IPython0 to prefilter the inputs.
3 3
4 4 Using the IPython0 mechanism gives us access to the magics.
5 5
6 6 This is a transitory class, used here to do the transition between
7 7 ipython0 and ipython1. This class is meant to be short-lived as more
8 8 functionnality is abstracted out of ipython0 in reusable functions and
9 9 is added on the interpreter. This class can be a used to guide this
10 10 refactoring.
11 11 """
12 12
13 13 #-------------------------------------------------------------------------------
14 14 # Copyright (C) 2008 The IPython Development Team
15 15 #
16 16 # Distributed under the terms of the BSD License. The full license is in
17 17 # the file COPYING, distributed as part of this software.
18 18 #-------------------------------------------------------------------------------
19 19
20 20 #-------------------------------------------------------------------------------
21 21 # Imports
22 22 #-------------------------------------------------------------------------------
23 23 import sys
24 24 import pydoc
25 25 import os
26 26 import re
27 27 import __builtin__
28 28
29 29 from IPython.core.ipapp import IPythonApp
30 30 from IPython.kernel.core.redirector_output_trap import RedirectorOutputTrap
31 31
32 32 from IPython.kernel.core.sync_traceback_trap import SyncTracebackTrap
33 33
34 34 from IPython.utils.genutils import Term
35 35
36 36 from linefrontendbase import LineFrontEndBase, common_prefix
37 37
38 38 #-----------------------------------------------------------------------------
39 39 # Utility functions
40 40 #-----------------------------------------------------------------------------
41 41
42 42 def mk_system_call(system_call_function, command):
43 43 """ given a os.system replacement, and a leading string command,
44 44 returns a function that will execute the command with the given
45 45 argument string.
46 46 """
47 47 def my_system_call(args):
48 48 system_call_function("%s %s" % (command, args))
49 49
50 50 my_system_call.__doc__ = "Calls %s" % command
51 51 return my_system_call
52 52
53 53 #-------------------------------------------------------------------------------
54 54 # Frontend class using ipython0 to do the prefiltering.
55 55 #-------------------------------------------------------------------------------
56 56 class PrefilterFrontEnd(LineFrontEndBase):
57 57 """ Class that uses ipython0 to do prefilter the input, do the
58 58 completion and the magics.
59 59
60 60 The core trick is to use an ipython0 instance to prefilter the
61 61 input, and share the namespace between the interpreter instance used
62 62 to execute the statements and the ipython0 used for code
63 63 completion...
64 64 """
65 65
66 66 debug = False
67 67
68 68 def __init__(self, ipython0=None, argv=None, *args, **kwargs):
69 69 """ Parameters
70 70 ----------
71 71
72 72 ipython0: an optional ipython0 instance to use for command
73 73 prefiltering and completion.
74 74
75 75 argv : list, optional
76 76 Used as the instance's argv value. If not given, [] is used.
77 77 """
78 78 if argv is None:
79 79 argv = ['--no-banner']
80 # This is a hack to avoid the IPython exception hook to trigger
81 # on exceptions (https://bugs.launchpad.net/bugs/337105)
82 # XXX: This is horrible: module-leve monkey patching -> side
83 # effects.
84 from IPython.core import iplib
85 iplib.InteractiveShell.isthreaded = True
86 80
87 81 LineFrontEndBase.__init__(self, *args, **kwargs)
88 82 self.shell.output_trap = RedirectorOutputTrap(
89 83 out_callback=self.write,
90 84 err_callback=self.write,
91 85 )
92 86 self.shell.traceback_trap = SyncTracebackTrap(
93 87 formatters=self.shell.traceback_trap.formatters,
94 88 )
95 89
96 90 # Start the ipython0 instance:
97 91 self.save_output_hooks()
98 92 if ipython0 is None:
99 93 # Instanciate an IPython0 interpreter to be able to use the
100 94 # prefiltering.
101 95 # Suppress all key input, to avoid waiting
102 96 def my_rawinput(x=None):
103 97 return '\n'
104 98 old_rawinput = __builtin__.raw_input
105 99 __builtin__.raw_input = my_rawinput
106 100 ipython0 = IPythonApp(argv=argv,
107 101 user_ns=self.shell.user_ns,
108 102 user_global_ns=self.shell.user_global_ns)
109 103 ipython0.initialize()
110 104 __builtin__.raw_input = old_rawinput
111 105 # XXX This will need to be updated as we refactor things, but for now,
112 106 # the .shell attribute of the ipythonapp instance conforms to the old
113 107 # api.
114 108 self.ipython0 = ipython0.shell
115 109 # Set the pager:
116 110 self.ipython0.set_hook('show_in_pager',
117 111 lambda s, string: self.write("\n" + string))
118 112 self.ipython0.write = self.write
119 113 self._ip = _ip = self.ipython0
120 114 # Make sure the raw system call doesn't get called, as we don't
121 115 # have a stdin accessible.
122 116 self._ip.system = self.system_call
123 117 # XXX: Muck around with magics so that they work better
124 118 # in our environment
125 119 if not sys.platform.startswith('win'):
126 120 self.ipython0.magic_ls = mk_system_call(self.system_call,
127 121 'ls -CF')
128 122 # And now clean up the mess created by ipython0
129 123 self.release_output()
130 124
131 125
132 126 if not 'banner' in kwargs and self.banner is None:
133 127 self.banner = self.ipython0.banner
134 128
135 129 # FIXME: __init__ and start should be two different steps
136 130 self.start()
137 131
138 132 #--------------------------------------------------------------------------
139 133 # FrontEndBase interface
140 134 #--------------------------------------------------------------------------
141 135
142 136 def show_traceback(self):
143 137 """ Use ipython0 to capture the last traceback and display it.
144 138 """
145 139 # Don't do the capture; the except_hook has already done some
146 140 # modifications to the IO streams, if we store them, we'll be
147 141 # storing the wrong ones.
148 142 #self.capture_output()
149 143 self.ipython0.showtraceback(tb_offset=-1)
150 144 self.release_output()
151 145
152 146
153 147 def execute(self, python_string, raw_string=None):
154 148 if self.debug:
155 149 print 'Executing Python code:', repr(python_string)
156 150 self.capture_output()
157 151 LineFrontEndBase.execute(self, python_string,
158 152 raw_string=raw_string)
159 153 self.release_output()
160 154
161 155
162 156 def save_output_hooks(self):
163 157 """ Store all the output hooks we can think of, to be able to
164 158 restore them.
165 159
166 160 We need to do this early, as starting the ipython0 instance will
167 161 screw ouput hooks.
168 162 """
169 163 self.__old_cout_write = Term.cout.write
170 164 self.__old_cerr_write = Term.cerr.write
171 165 self.__old_stdout = sys.stdout
172 166 self.__old_stderr= sys.stderr
173 167 self.__old_help_output = pydoc.help.output
174 168 self.__old_display_hook = sys.displayhook
175 169
176 170
177 171 def capture_output(self):
178 172 """ Capture all the output mechanisms we can think of.
179 173 """
180 174 self.save_output_hooks()
181 175 Term.cout.write = self.write
182 176 Term.cerr.write = self.write
183 177 sys.stdout = Term.cout
184 178 sys.stderr = Term.cerr
185 179 pydoc.help.output = self.shell.output_trap.out
186 180
187 181
188 182 def release_output(self):
189 183 """ Release all the different captures we have made.
190 184 """
191 185 Term.cout.write = self.__old_cout_write
192 186 Term.cerr.write = self.__old_cerr_write
193 187 sys.stdout = self.__old_stdout
194 188 sys.stderr = self.__old_stderr
195 189 pydoc.help.output = self.__old_help_output
196 190 sys.displayhook = self.__old_display_hook
197 191
198 192
199 193 def complete(self, line):
200 194 # FIXME: This should be factored out in the linefrontendbase
201 195 # method.
202 196 word = self._get_completion_text(line)
203 197 completions = self.ipython0.complete(word)
204 198 # FIXME: The proper sort should be done in the complete method.
205 199 key = lambda x: x.replace('_', '')
206 200 completions.sort(key=key)
207 201 if completions:
208 202 prefix = common_prefix(completions)
209 203 line = line[:-len(word)] + prefix
210 204 return line, completions
211 205
212 206 #--------------------------------------------------------------------------
213 207 # LineFrontEndBase interface
214 208 #--------------------------------------------------------------------------
215 209
216 210 def prefilter_input(self, input_string):
217 211 """ Using IPython0 to prefilter the commands to turn them
218 212 in executable statements that are valid Python strings.
219 213 """
220 214 input_string = LineFrontEndBase.prefilter_input(self, input_string)
221 215 filtered_lines = []
222 216 # The IPython0 prefilters sometime produce output. We need to
223 217 # capture it.
224 218 self.capture_output()
225 219 self.last_result = dict(number=self.prompt_number)
226 220
227 221 try:
228 222 try:
229 223 for line in input_string.split('\n'):
230 224 pf = self.ipython0.prefilter_manager.prefilter_lines
231 225 filtered_lines.append(pf(line, False).rstrip())
232 226 except:
233 227 # XXX: probably not the right thing to do.
234 228 self.ipython0.showsyntaxerror()
235 229 self.after_execute()
236 230 finally:
237 231 self.release_output()
238 232
239 233 # Clean up the trailing whitespace, to avoid indentation errors
240 234 filtered_string = '\n'.join(filtered_lines)
241 235 return filtered_string
242 236
243 237 #--------------------------------------------------------------------------
244 238 # PrefilterFrontEnd interface
245 239 #--------------------------------------------------------------------------
246 240
247 241 def system_call(self, command_string):
248 242 """ Allows for frontend to define their own system call, to be
249 243 able capture output and redirect input.
250 244 """
251 245 return os.system(command_string)
252 246
253 247 def do_exit(self):
254 248 """ Exit the shell, cleanup and save the history.
255 249 """
256 250 self.ipython0.atexit_operations()
257 251
258 252 def _get_completion_text(self, line):
259 253 """ Returns the text to be completed by breaking the line at specified
260 254 delimiters.
261 255 """
262 256 # Break at: spaces, '=', all parentheses (except if balanced).
263 257 # FIXME2: In the future, we need to make the implementation similar to
264 258 # that in the 'pyreadline' module (modes/basemode.py) where we break at
265 259 # each delimiter and try to complete the residual line, until we get a
266 260 # successful list of completions.
267 261 expression = '\s|=|,|:|\((?!.*\))|\[(?!.*\])|\{(?!.*\})'
268 262 complete_sep = re.compile(expression)
269 263 text = complete_sep.split(line)[-1]
270 264 return text
@@ -1,272 +1,269 b''
1 1 # encoding: utf-8
2 2 """
3 3 Test process execution and IO redirection.
4 4 """
5 5
6 6 __docformat__ = "restructuredtext en"
7 7
8 8 #-------------------------------------------------------------------------------
9 9 # Copyright (C) 2008 The IPython Development Team
10 10 #
11 11 # Distributed under the terms of the BSD License. The full license is
12 12 # in the file COPYING, distributed as part of this software.
13 13 #-------------------------------------------------------------------------------
14 14
15 15 from copy import copy, deepcopy
16 16 from cStringIO import StringIO
17 17 import string
18 18 import sys
19 19
20 20 from nose.tools import assert_equal
21 21
22 22 from IPython.frontend.prefilterfrontend import PrefilterFrontEnd
23 23 from IPython.core.ipapi import get as get_ipython0
24 24 from IPython.testing.plugin.ipdoctest import default_argv
25 25
26 26 #-----------------------------------------------------------------------------
27 27 # Support utilities
28 28 #-----------------------------------------------------------------------------
29 29
30 30 class TestPrefilterFrontEnd(PrefilterFrontEnd):
31 31
32 32 input_prompt_template = string.Template('')
33 33 output_prompt_template = string.Template('')
34 34 banner = ''
35 35
36 36 def __init__(self):
37 37 self.out = StringIO()
38 38 PrefilterFrontEnd.__init__(self,argv=default_argv())
39 39 # Some more code for isolation (yeah, crazy)
40 40 self._on_enter()
41 41 self.out.flush()
42 42 self.out.reset()
43 43 self.out.truncate()
44 44
45 45 def write(self, string, *args, **kwargs):
46 46 self.out.write(string)
47 47
48 48 def _on_enter(self):
49 49 self.input_buffer += '\n'
50 50 PrefilterFrontEnd._on_enter(self)
51 51
52 52
53 53 def isolate_ipython0(func):
54 54 """ Decorator to isolate execution that involves an iptyhon0.
55 55
56 56 Notes
57 57 -----
58 58
59 59 Apply only to functions with no arguments. Nose skips functions
60 60 with arguments.
61 61 """
62 62 def my_func():
63 63 ip0 = get_ipython0()
64 64 if ip0 is None:
65 65 return func()
66 66 # We have a real ipython running...
67 67 user_ns = ip0.user_ns
68 68 user_global_ns = ip0.user_global_ns
69 69
70 70 # Previously the isolation was attempted with a deep copy of the user
71 71 # dicts, but we found cases where this didn't work correctly. I'm not
72 72 # quite sure why, but basically it did damage the user namespace, such
73 73 # that later tests stopped working correctly. Instead we use a simpler
74 74 # approach, just computing the list of added keys to the namespace and
75 75 # eliminating those afterwards. Existing keys that may have been
76 76 # modified remain modified. So far this has proven to be robust.
77 77
78 78 # Compute set of old local/global keys
79 79 old_locals = set(user_ns.keys())
80 80 old_globals = set(user_global_ns.keys())
81 81 try:
82 82 out = func()
83 83 finally:
84 84 # Find new keys, and if any, remove them
85 85 new_locals = set(user_ns.keys()) - old_locals
86 86 new_globals = set(user_global_ns.keys()) - old_globals
87 87 for k in new_locals:
88 88 del user_ns[k]
89 89 for k in new_globals:
90 90 del user_global_ns[k]
91 # Undo the hack at creation of PrefilterFrontEnd
92 from IPython.core import iplib
93 iplib.InteractiveShell.isthreaded = False
94 91 return out
95 92
96 93 my_func.__name__ = func.__name__
97 94 return my_func
98 95
99 96 #-----------------------------------------------------------------------------
100 97 # Tests
101 98 #-----------------------------------------------------------------------------
102 99
103 100 @isolate_ipython0
104 101 def test_execution():
105 102 """ Test execution of a command.
106 103 """
107 104 f = TestPrefilterFrontEnd()
108 105 f.input_buffer = 'print(1)'
109 106 f._on_enter()
110 107 out_value = f.out.getvalue()
111 108 assert_equal(out_value, '1\n')
112 109
113 110
114 111 @isolate_ipython0
115 112 def test_multiline():
116 113 """ Test execution of a multiline command.
117 114 """
118 115 f = TestPrefilterFrontEnd()
119 116 f.input_buffer = 'if True:'
120 117 f._on_enter()
121 118 f.input_buffer += 'print 1'
122 119 f._on_enter()
123 120 out_value = f.out.getvalue()
124 121 yield assert_equal, out_value, ''
125 122 f._on_enter()
126 123 out_value = f.out.getvalue()
127 124 yield assert_equal, out_value, '1\n'
128 125 f = TestPrefilterFrontEnd()
129 126 f.input_buffer='(1 +'
130 127 f._on_enter()
131 128 f.input_buffer += '0)'
132 129 f._on_enter()
133 130 out_value = f.out.getvalue()
134 131 yield assert_equal, out_value, ''
135 132 f._on_enter()
136 133 out_value = f.out.getvalue()
137 134 yield assert_equal, out_value, '1\n'
138 135
139 136
140 137 @isolate_ipython0
141 138 def test_capture():
142 139 """ Test the capture of output in different channels.
143 140 """
144 141 # Test on the OS-level stdout, stderr.
145 142 f = TestPrefilterFrontEnd()
146 143 f.input_buffer = \
147 144 'import os; out=os.fdopen(1, "w"); out.write("1") ; out.flush()'
148 145 f._on_enter()
149 146 out_value = f.out.getvalue()
150 147 yield assert_equal, out_value, '1'
151 148 f = TestPrefilterFrontEnd()
152 149 f.input_buffer = \
153 150 'import os; out=os.fdopen(2, "w"); out.write("1") ; out.flush()'
154 151 f._on_enter()
155 152 out_value = f.out.getvalue()
156 153 yield assert_equal, out_value, '1'
157 154
158 155
159 156 @isolate_ipython0
160 157 def test_magic():
161 158 """ Test the magic expansion and history.
162 159
163 160 This test is fairly fragile and will break when magics change.
164 161 """
165 162 f = TestPrefilterFrontEnd()
166 163 # Before checking the interactive namespace, make sure it's clear (it can
167 164 # otherwise pick up things stored in the user's local db)
168 165 f.input_buffer += '%reset -f'
169 166 f._on_enter()
170 167 f.complete_current_input()
171 168 # Now, run the %who magic and check output
172 169 f.input_buffer += '%who'
173 170 f._on_enter()
174 171 out_value = f.out.getvalue()
175 172 assert_equal(out_value, 'In\tOut\tget_ipython\t\n')
176 173
177 174
178 175 @isolate_ipython0
179 176 def test_help():
180 177 """ Test object inspection.
181 178 """
182 179 f = TestPrefilterFrontEnd()
183 180 f.input_buffer += "def f():"
184 181 f._on_enter()
185 182 f.input_buffer += "'foobar'"
186 183 f._on_enter()
187 184 f.input_buffer += "pass"
188 185 f._on_enter()
189 186 f._on_enter()
190 187 f.input_buffer += "f?"
191 188 f._on_enter()
192 189 assert 'traceback' not in f.last_result
193 190 ## XXX: ipython doctest magic breaks this. I have no clue why
194 191 #out_value = f.out.getvalue()
195 192 #assert out_value.split()[-1] == 'foobar'
196 193
197 194
198 195 @isolate_ipython0
199 196 def test_completion_simple():
200 197 """ Test command-line completion on trivial examples.
201 198 """
202 199 f = TestPrefilterFrontEnd()
203 200 f.input_buffer = 'zzza = 1'
204 201 f._on_enter()
205 202 f.input_buffer = 'zzzb = 2'
206 203 f._on_enter()
207 204 f.input_buffer = 'zz'
208 205 f.complete_current_input()
209 206 out_value = f.out.getvalue()
210 207 yield assert_equal, out_value, '\nzzza zzzb '
211 208 yield assert_equal, f.input_buffer, 'zzz'
212 209
213 210
214 211 @isolate_ipython0
215 212 def test_completion_parenthesis():
216 213 """ Test command-line completion when a parenthesis is open.
217 214 """
218 215 f = TestPrefilterFrontEnd()
219 216 f.input_buffer = 'zzza = 1'
220 217 f._on_enter()
221 218 f.input_buffer = 'zzzb = 2'
222 219 f._on_enter()
223 220 f.input_buffer = 'map(zz'
224 221 f.complete_current_input()
225 222 out_value = f.out.getvalue()
226 223 yield assert_equal, out_value, '\nzzza zzzb '
227 224 yield assert_equal, f.input_buffer, 'map(zzz'
228 225
229 226
230 227 @isolate_ipython0
231 228 def test_completion_indexing():
232 229 """ Test command-line completion when indexing on objects.
233 230 """
234 231 f = TestPrefilterFrontEnd()
235 232 f.input_buffer = 'a = [0]'
236 233 f._on_enter()
237 234 f.input_buffer = 'a[0].'
238 235 f.complete_current_input()
239 236
240 237 if sys.version_info[:2] >= (2,6):
241 238 # In Python 2.6, ints picked up a few non __ methods, so now there are
242 239 # no completions.
243 240 assert_equal(f.input_buffer, 'a[0].')
244 241 else:
245 242 # Right answer for 2.4/2.5
246 243 assert_equal(f.input_buffer, 'a[0].__')
247 244
248 245
249 246 @isolate_ipython0
250 247 def test_completion_equal():
251 248 """ Test command-line completion when the delimiter is "=", not " ".
252 249 """
253 250 f = TestPrefilterFrontEnd()
254 251 f.input_buffer = 'a=1.'
255 252 f.complete_current_input()
256 253 if sys.version_info[:2] >= (2,6):
257 254 # In Python 2.6, ints picked up a few non __ methods, so now there are
258 255 # no completions.
259 256 assert_equal(f.input_buffer, 'a=1.')
260 257 else:
261 258 # Right answer for 2.4/2.5
262 259 assert_equal(f.input_buffer, 'a=1.__')
263 260
264 261
265 262 if __name__ == '__main__':
266 263 test_magic()
267 264 test_help()
268 265 test_execution()
269 266 test_multiline()
270 267 test_capture()
271 268 test_completion_simple()
272 269 test_completion_complex()
General Comments 0
You need to be logged in to leave comments. Login now