##// END OF EJS Templates
Massive refactoring of of the core....
Brian Granger -
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -1,120 +1,115 b''
1 #-----------------------------------------------------------------------------
1 #-----------------------------------------------------------------------------
2 # IPython Shell Configuration Defaults
2 # Global options
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4
4
5 Global.classic = False
6 Global.nosep = False
7
5 #-----------------------------------------------------------------------------
8 #-----------------------------------------------------------------------------
6 # Startup
9 # InteractiveShell options
7 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
8
11
9 AUTOCALL = True
10
11 AUTOEDIT_SYNTAX = False
12
13 AUTOINDENT = True
14
15 AUTOMAGIC = True
16
17 CACHE_SIZE = 1000
18
12
19 CLASSIC = False
13 InteractiveShell.autocall = 1
20
14
21 COLORS = 'Linux'
15 InteractiveShell.autoedit_syntax = False
22
16
23 COLOR_INFO = True
17 InteractiveShell.autoindent = True
24
18
25 CONFIRM_EXIT = True
19 InteractiveShell.automagic = False
26
20
27 DEEP_RELOAD = False
21 InteractiveShell.banner1 = 'This if for overriding the default IPython banner'
22
23 InteractiveShell.banner2 = "This is for extra banner text"
28
24
29 EDITOR = 0
25 InteractiveShell.cache_size = 1000
30
26
31 LOG = True
27 InteractiveShell.colors = 'LightBG'
32
28
33 LOGFILE = ''
29 InteractiveShell.color_info = True
34
30
35 BANNER = True
31 InteractiveShell.confirm_exit = True
36
32
37 MESSAGES = True
33 InteractiveShell.deep_reload = False
38
34
39 PDB = False
35 InteractiveShell.display_banner = True
40
36
41 PPRINT = True
37 InteractiveShell.editor = 'nano'
42
38
43 PROMPT_IN1 = 'In [\#]: '
39 InteractiveShell.logstart = True
44
40
45 PROMPT_IN2 = ' .\D.: '
41 InteractiveShell.logfile = 'ipython_log.py'
46
42
47 PROMPT_OUT = 'Out[\#]: '
43 InteractiveShell.logplay = 'mylog.py'
48
44
49 PROMPTS_PAD_LEFT = True
45 InteractiveShell.object_info_string_level = 0
50
46
51 QUICK = False
47 InteractiveShell.pager = 'less'
52
48
53 SCREEN_LENGTH = 0
49 InteractiveShell.pdb = False
54
50
55 SEPARATE_IN = '\n'
51 InteractiveShell.pprint = True
56 SEPARATE_OUT = ''
57 SEPARATE_OUT2 = ''
58 NOSEP = False
59
52
60 WILDCARDS_CASE_SENSITIVE = True
53 InteractiveShell.prompt_in1 = 'In [\#]: '
54 InteractiveShell.prompt_in2 = ' .\D.: '
55 InteractiveShell.prompt_out = 'Out[\#]: '
56 InteractiveShell.prompts_pad_left = True
61
57
62 OBJECT_INFO_STRING_LEVEL = 0
58 InteractiveShell.quiet = False
63
59
64 XMODE = 'Context'
60 # Readline
61 InteractiveShell.readline_use = False
65
62
66 MULTI_LINE_SPECIALS = True
63 InteractiveShell.readline_parse_and_bind = [
67
68 SYSTEM_HEADER = "IPython system call: "
69
70 SYSTEM_VERBOSE = True
71
72 #-----------------------------------------------------------------------------
73 # Readline
74 #-----------------------------------------------------------------------------
75
76 READLINE = True
77
78 READLINE_PARSE_AND_BIND = [
79 'tab: complete',
64 'tab: complete',
80 '"\C-l": possible-completions',
65 '"\C-l": possible-completions',
81 'set show-all-if-ambiguous on',
66 'set show-all-if-ambiguous on',
82 '"\C-o": tab-insert',
67 '"\C-o": tab-insert',
83 '"\M-i": " "',
68 '"\M-i": " "',
84 '"\M-o": "\d\d\d\d"',
69 '"\M-o": "\d\d\d\d"',
85 '"\M-I": "\d\d\d\d"',
70 '"\M-I": "\d\d\d\d"',
86 '"\C-r": reverse-search-history',
71 '"\C-r": reverse-search-history',
87 '"\C-s": forward-search-history',
72 '"\C-s": forward-search-history',
88 '"\C-p": history-search-backward',
73 '"\C-p": history-search-backward',
89 '"\C-n": history-search-forward',
74 '"\C-n": history-search-forward',
90 '"\e[A": history-search-backward',
75 '"\e[A": history-search-backward',
91 '"\e[B": history-search-forward',
76 '"\e[B": history-search-forward',
92 '"\C-k": kill-line',
77 '"\C-k": kill-line',
93 '"\C-u": unix-line-discard',
78 '"\C-u": unix-line-discard',
94 ]
79 ]
80 InteractiveShell.readline_remove_delims = '-/~'
81 InteractiveShell.readline_merge_completions = True
82 InteractiveShell.readline_omit_names = 0
83
84 InteractiveShell.screen_length = 0
85
86 InteractiveShell.separate_in = '\n'
87 InteractiveShell.separate_out = ''
88 InteractiveShell.separate_out2 = ''
89
90 InteractiveShell.system_header = "IPython system call: "
95
91
96 READLINE_REMOVE_DELIMS = '-/~'
92 InteractiveShell.system_verbose = True
97
93
98 READLINE_MERGE_COMPLETIONS = True
94 InteractiveShell.term_title = False
99
95
100 READLINE_OMIT_NAMES = 0
96 InteractiveShell.wildcards_case_sensitive = True
97
98 InteractiveShell.xmode = 'Context'
101
99
102 #-----------------------------------------------------------------------------
100 #-----------------------------------------------------------------------------
103 # Code to execute
101 # PrefilterManager options
104 #-----------------------------------------------------------------------------
102 #-----------------------------------------------------------------------------
105
103
106 EXECUTE = [
104 PrefilterManager.multi_line_specials = True
107 'import numpy as np',
108 'import sympy',
109 'a = 10'
110 ]
111
112 EXECFILE = []
113
105
114 #-----------------------------------------------------------------------------
106 #-----------------------------------------------------------------------------
115 # Alias
107 # AliasManager options
116 #-----------------------------------------------------------------------------
108 #-----------------------------------------------------------------------------
117
109
118 ALIAS = [
110 # Do this to enable all defaults
119 ('myls', 'ls -la')
111 # AliasManager.default_aliases = []
112
113 AliasManger.user_aliases = [
114 ('foo', 'echo Hi')
120 ] No newline at end of file
115 ]
@@ -1,203 +1,305 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 """A factory for creating configuration objects.
3 """A simple configuration system.
4
5 Authors:
6
7 * Brian Granger
4 """
8 """
5
9
6 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
7 # Copyright (C) 2008-2009 The IPython Development Team
11 # Copyright (C) 2008-2009 The IPython Development Team
8 #
12 #
9 # Distributed under the terms of the BSD License. The full license is in
13 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
14 # the file COPYING, distributed as part of this software.
11 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
12
16
13 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
14 # Imports
18 # Imports
15 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
16
20
21 import __builtin__
17 import os
22 import os
18 import sys
23 import sys
19
24
20 from IPython.external import argparse
25 from IPython.external import argparse
21 from IPython.utils.ipstruct import Struct
22 from IPython.utils.genutils import filefind
26 from IPython.utils.genutils import filefind
23
27
24 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
25 # Code
29 # Exceptions
26 #-----------------------------------------------------------------------------
30 #-----------------------------------------------------------------------------
27
31
28
32
29 class ConfigLoaderError(Exception):
33 class ConfigError(Exception):
30 pass
34 pass
31
35
32
36
37 class ConfigLoaderError(ConfigError):
38 pass
39
40
41 #-----------------------------------------------------------------------------
42 # Config class for holding config information
43 #-----------------------------------------------------------------------------
44
45
46 class Config(dict):
47 """An attribute based dict that can do smart merges."""
48
49 def __init__(self, *args, **kwds):
50 dict.__init__(self, *args, **kwds)
51 # This sets self.__dict__ = self, but it has to be done this way
52 # because we are also overriding __setattr__.
53 dict.__setattr__(self, '__dict__', self)
54
55 def _merge(self, other):
56 to_update = {}
57 for k, v in other.items():
58 if not self.has_key(k):
59 to_update[k] = v
60 else: # I have this key
61 if isinstance(v, Config):
62 # Recursively merge common sub Configs
63 self[k]._merge(v)
64 else:
65 # Plain updates for non-Configs
66 to_update[k] = v
67
68 self.update(to_update)
69
70 def _is_section_key(self, key):
71 if key[0].upper()==key[0] and not key.startswith('_'):
72 return True
73 else:
74 return False
75
76 def has_key(self, key):
77 if self._is_section_key(key):
78 return True
79 else:
80 return dict.has_key(self, key)
81
82 def _has_section(self, key):
83 if self._is_section_key(key):
84 if dict.has_key(self, key):
85 return True
86 return False
87
88 def copy(self):
89 return type(self)(dict.copy(self))
90
91 def __copy__(self):
92 return self.copy()
93
94 def __deepcopy__(self, memo):
95 import copy
96 return type(self)(copy.deepcopy(self.items()))
97
98 def __getitem__(self, key):
99 # Because we use this for an exec namespace, we need to delegate
100 # the lookup of names in __builtin__ to itself. This means
101 # that you can't have section or attribute names that are
102 # builtins.
103 try:
104 return getattr(__builtin__, key)
105 except AttributeError:
106 pass
107 if self._is_section_key(key):
108 try:
109 return dict.__getitem__(self, key)
110 except KeyError:
111 c = Config()
112 dict.__setitem__(self, key, c)
113 return c
114 else:
115 return dict.__getitem__(self, key)
116
117 def __setitem__(self, key, value):
118 # Don't allow names in __builtin__ to be modified.
119 if hasattr(__builtin__, key):
120 raise ConfigError('Config variable names cannot have the same name '
121 'as a Python builtin: %s' % key)
122 if self._is_section_key(key):
123 if not isinstance(value, Config):
124 raise ValueError('values whose keys begin with an uppercase '
125 'char must be Config instances: %r, %r' % (key, value))
126 else:
127 dict.__setitem__(self, key, value)
128
129 def __getattr__(self, key):
130 try:
131 return self.__getitem__(key)
132 except KeyError, e:
133 raise AttributeError(e)
134
135 def __setattr__(self, key, value):
136 try:
137 self.__setitem__(key, value)
138 except KeyError, e:
139 raise AttributeError(e)
140
141 def __delattr__(self, key):
142 try:
143 dict.__delitem__(self, key)
144 except KeyError, e:
145 raise AttributeError(e)
146
147
148 #-----------------------------------------------------------------------------
149 # Config loading classes
150 #-----------------------------------------------------------------------------
151
152
33 class ConfigLoader(object):
153 class ConfigLoader(object):
34 """A object for loading configurations from just about anywhere.
154 """A object for loading configurations from just about anywhere.
35
155
36 The resulting configuration is packaged as a :class:`Struct`.
156 The resulting configuration is packaged as a :class:`Struct`.
37
157
38 Notes
158 Notes
39 -----
159 -----
40 A :class:`ConfigLoader` does one thing: load a config from a source
160 A :class:`ConfigLoader` does one thing: load a config from a source
41 (file, command line arguments) and returns the data as a :class:`Struct`.
161 (file, command line arguments) and returns the data as a :class:`Struct`.
42 There are lots of things that :class:`ConfigLoader` does not do. It does
162 There are lots of things that :class:`ConfigLoader` does not do. It does
43 not implement complex logic for finding config files. It does not handle
163 not implement complex logic for finding config files. It does not handle
44 default values or merge multiple configs. These things need to be
164 default values or merge multiple configs. These things need to be
45 handled elsewhere.
165 handled elsewhere.
46 """
166 """
47
167
48 def __init__(self):
168 def __init__(self):
49 """A base class for config loaders.
169 """A base class for config loaders.
50
170
51 Examples
171 Examples
52 --------
172 --------
53
173
54 >>> cl = ConfigLoader()
174 >>> cl = ConfigLoader()
55 >>> config = cl.load_config()
175 >>> config = cl.load_config()
56 >>> config
176 >>> config
57 {}
177 {}
58 """
178 """
59 self.clear()
179 self.clear()
60
180
61 def clear(self):
181 def clear(self):
62 self.config = Struct()
182 self.config = Config()
63
183
64 def load_config(self):
184 def load_config(self):
65 """Load a config from somewhere, return a Struct.
185 """Load a config from somewhere, return a Struct.
66
186
67 Usually, this will cause self.config to be set and then returned.
187 Usually, this will cause self.config to be set and then returned.
68 """
188 """
69 return self.config
189 return self.config
70
190
71
191
72 class FileConfigLoader(ConfigLoader):
192 class FileConfigLoader(ConfigLoader):
73 """A base class for file based configurations.
193 """A base class for file based configurations.
74
194
75 As we add more file based config loaders, the common logic should go
195 As we add more file based config loaders, the common logic should go
76 here.
196 here.
77 """
197 """
78 pass
198 pass
79
199
80
200
81 class PyFileConfigLoader(FileConfigLoader):
201 class PyFileConfigLoader(FileConfigLoader):
82 """A config loader for pure python files.
202 """A config loader for pure python files.
83
203
84 This calls execfile on a plain python file and looks for attributes
204 This calls execfile on a plain python file and looks for attributes
85 that are all caps. These attribute are added to the config Struct.
205 that are all caps. These attribute are added to the config Struct.
86 """
206 """
87
207
88 def __init__(self, filename, path=None):
208 def __init__(self, filename, path=None):
89 """Build a config loader for a filename and path.
209 """Build a config loader for a filename and path.
90
210
91 Parameters
211 Parameters
92 ----------
212 ----------
93 filename : str
213 filename : str
94 The file name of the config file.
214 The file name of the config file.
95 path : str, list, tuple
215 path : str, list, tuple
96 The path to search for the config file on, or a sequence of
216 The path to search for the config file on, or a sequence of
97 paths to try in order.
217 paths to try in order.
98 """
218 """
99 super(PyFileConfigLoader, self).__init__()
219 super(PyFileConfigLoader, self).__init__()
100 self.filename = filename
220 self.filename = filename
101 self.path = path
221 self.path = path
102 self.full_filename = ''
222 self.full_filename = ''
103 self.data = None
223 self.data = None
104
224
105 def load_config(self):
225 def load_config(self):
106 """Load the config from a file and return it as a Struct."""
226 """Load the config from a file and return it as a Struct."""
107 self._find_file()
227 self._find_file()
108 self._read_file_as_dict()
228 self._read_file_as_dict()
109 self._convert_to_struct()
229 self._convert_to_config()
110 return self.config
230 return self.config
111
231
112 def _find_file(self):
232 def _find_file(self):
113 """Try to find the file by searching the paths."""
233 """Try to find the file by searching the paths."""
114 self.full_filename = filefind(self.filename, self.path)
234 self.full_filename = filefind(self.filename, self.path)
115
235
116 def _read_file_as_dict(self):
236 def _read_file_as_dict(self):
117 self.data = {}
237 execfile(self.full_filename, self.config)
118 execfile(self.full_filename, self.data)
119
238
120 def _convert_to_struct(self):
239 def _convert_to_config(self):
121 if self.data is None:
240 if self.data is None:
122 ConfigLoaderError('self.data does not exist')
241 ConfigLoaderError('self.data does not exist')
123 for k, v in self.data.iteritems():
242 del self.config['__builtins__']
124 if k == k.upper():
125 self.config[k] = v
126
243
127
244
128 class CommandLineConfigLoader(ConfigLoader):
245 class CommandLineConfigLoader(ConfigLoader):
129 """A config loader for command line arguments.
246 """A config loader for command line arguments.
130
247
131 As we add more command line based loaders, the common logic should go
248 As we add more command line based loaders, the common logic should go
132 here.
249 here.
133 """
250 """
134
251
135
252
136 class NoDefault(object): pass
253 class NoConfigDefault(object): pass
137 NoDefault = NoDefault()
254 NoConfigDefault = NoConfigDefault()
138
255
139 class ArgParseConfigLoader(CommandLineConfigLoader):
256 class ArgParseConfigLoader(CommandLineConfigLoader):
140
257
141 # arguments = [(('-f','--file'),dict(type=str,dest='file'))]
258 # arguments = [(('-f','--file'),dict(type=str,dest='file'))]
142 arguments = ()
259 arguments = ()
143
260
144 def __init__(self, *args, **kw):
261 def __init__(self, *args, **kw):
145 """Create a config loader for use with argparse.
262 """Create a config loader for use with argparse.
146
263
147 The args and kwargs arguments here are passed onto the constructor
264 The args and kwargs arguments here are passed onto the constructor
148 of :class:`argparse.ArgumentParser`.
265 of :class:`argparse.ArgumentParser`.
149 """
266 """
150 super(CommandLineConfigLoader, self).__init__()
267 super(CommandLineConfigLoader, self).__init__()
151 self.args = args
268 self.args = args
152 self.kw = kw
269 self.kw = kw
153
270
154 def load_config(self, args=None):
271 def load_config(self, args=None):
155 """Parse command line arguments and return as a Struct."""
272 """Parse command line arguments and return as a Struct."""
156 self._create_parser()
273 self._create_parser()
157 self._parse_args(args)
274 self._parse_args(args)
158 self._convert_to_struct()
275 self._convert_to_config()
159 return self.config
276 return self.config
160
277
161 def _create_parser(self):
278 def _create_parser(self):
162 self.parser = argparse.ArgumentParser(*self.args, **self.kw)
279 self.parser = argparse.ArgumentParser(*self.args, **self.kw)
163 self._add_arguments()
280 self._add_arguments()
164 self._add_other_arguments()
281 self._add_other_arguments()
165
282
166 def _add_other_arguments(self):
283 def _add_other_arguments(self):
167 pass
284 pass
168
285
169 def _add_arguments(self):
286 def _add_arguments(self):
170 for argument in self.arguments:
287 for argument in self.arguments:
171 if not argument[1].has_key('default'):
288 if not argument[1].has_key('default'):
172 argument[1]['default'] = NoDefault
289 argument[1]['default'] = NoConfigDefault
173 self.parser.add_argument(*argument[0],**argument[1])
290 self.parser.add_argument(*argument[0],**argument[1])
174
291
175 def _parse_args(self, args=None):
292 def _parse_args(self, args=None):
176 """self.parser->self.parsed_data"""
293 """self.parser->self.parsed_data"""
177 if args is None:
294 if args is None:
178 self.parsed_data = self.parser.parse_args()
295 self.parsed_data = self.parser.parse_args()
179 else:
296 else:
180 self.parsed_data = self.parser.parse_args(args)
297 self.parsed_data = self.parser.parse_args(args)
181
298
182 def _convert_to_struct(self):
299 def _convert_to_config(self):
183 """self.parsed_data->self.config"""
300 """self.parsed_data->self.config"""
184 self.config = Struct()
185 for k, v in vars(self.parsed_data).items():
301 for k, v in vars(self.parsed_data).items():
186 if v is not NoDefault:
302 if v is not NoConfigDefault:
187 setattr(self.config, k, v)
303 exec_str = 'self.config.' + k + '= v'
188
304 exec exec_str in locals(), globals()
189 class IPythonArgParseConfigLoader(ArgParseConfigLoader):
190
305
191 def _add_other_arguments(self):
192 self.parser.add_argument('-ipythondir',dest='IPYTHONDIR',type=str,
193 help='Set to override default location of IPYTHONDIR.',
194 default=NoDefault)
195 self.parser.add_argument('-p','-profile',dest='PROFILE',type=str,
196 help='The string name of the ipython profile to be used.',
197 default=NoDefault)
198 self.parser.add_argument('-debug',dest="DEBUG",action='store_true',
199 help='Debug the application startup process.',
200 default=NoDefault)
201 self.parser.add_argument('-config_file',dest='CONFIG_FILE',type=str,
202 help='Set the config file name to override default.',
203 default=NoDefault)
@@ -1,93 +1,163 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 """
3 """
4 Tests for IPython.config.loader
4 Tests for IPython.config.loader
5
5
6 Authors:
6 Authors:
7
7
8 * Brian Granger
8 * Brian Granger
9 * Fernando Perez (design help)
9 * Fernando Perez (design help)
10 """
10 """
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Copyright (C) 2008-2009 The IPython Development Team
13 # Copyright (C) 2008-2009 The IPython Development Team
14 #
14 #
15 # Distributed under the terms of the BSD License. The full license is in
15 # Distributed under the terms of the BSD License. The full license is in
16 # the file COPYING, distributed as part of this software.
16 # the file COPYING, distributed as part of this software.
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Imports
20 # Imports
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22
22
23 import os
23 import os
24 from tempfile import mkstemp
24 from tempfile import mkstemp
25 from unittest import TestCase
25 from unittest import TestCase
26
26
27 from IPython.config.loader import PyFileConfigLoader, ArgParseConfigLoader
27 from IPython.config.loader import (
28 Config,
29 PyFileConfigLoader,
30 ArgParseConfigLoader,
31 ConfigError
32 )
28
33
29 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
30 # Actual tests
35 # Actual tests
31 #-----------------------------------------------------------------------------
36 #-----------------------------------------------------------------------------
32
37
33
38
34 pyfile = """
39 pyfile = """
35 A = 10
40 a = 10
36 B = range(10)
41 b = 20
37 C = True
42 Foo.Bar.value = 10
38 D = 'hi there'
43 Foo.Bam.value = range(10)
44 D.C.value = 'hi there'
39 """
45 """
40
46
41 class TestPyFileCL(TestCase):
47 class TestPyFileCL(TestCase):
42
48
43 def test_basic(self):
49 def test_basic(self):
44 fd, fname = mkstemp()
50 fd, fname = mkstemp()
45 f = os.fdopen(fd, 'w')
51 f = os.fdopen(fd, 'w')
46 f.write(pyfile)
52 f.write(pyfile)
47 f.close()
53 f.close()
48 # Unlink the file
54 # Unlink the file
49 cl = PyFileConfigLoader(fname)
55 cl = PyFileConfigLoader(fname)
50 config = cl.load_config()
56 config = cl.load_config()
51 self.assertEquals(config.A, 10)
57 self.assertEquals(config.a, 10)
52 self.assertEquals(config.B, range(10))
58 self.assertEquals(config.b, 20)
53 self.assertEquals(config.C, True)
59 self.assertEquals(config.Foo.Bar.value, 10)
54 self.assertEquals(config.D, 'hi there')
60 self.assertEquals(config.Foo.Bam.value, range(10))
61 self.assertEquals(config.D.C.value, 'hi there')
55
62
56
63
57 class TestArgParseCL(TestCase):
64 class TestArgParseCL(TestCase):
58
65
59 def test_basic(self):
66 def test_basic(self):
60
67
61 class MyLoader(ArgParseConfigLoader):
68 class MyLoader(ArgParseConfigLoader):
62 arguments = (
69 arguments = (
63 (('-f','--foo'), dict(dest='FOO', type=str)),
70 (('-f','--foo'), dict(dest='Global.foo', type=str)),
64 (('-b',), dict(dest='BAR', type=int)),
71 (('-b',), dict(dest='MyClass.bar', type=int)),
65 (('-n',), dict(dest='N', action='store_true')),
72 (('-n',), dict(dest='n', action='store_true')),
66 (('BAM',), dict(type=str))
73 (('Global.bam',), dict(type=str))
67 )
74 )
68
75
69 cl = MyLoader()
76 cl = MyLoader()
70 config = cl.load_config('-f hi -b 10 -n wow'.split())
77 config = cl.load_config('-f hi -b 10 -n wow'.split())
71 self.assertEquals(config.FOO, 'hi')
78 self.assertEquals(config.Global.foo, 'hi')
72 self.assertEquals(config.BAR, 10)
79 self.assertEquals(config.MyClass.bar, 10)
73 self.assertEquals(config.N, True)
80 self.assertEquals(config.n, True)
74 self.assertEquals(config.BAM, 'wow')
81 self.assertEquals(config.Global.bam, 'wow')
75
82
76 def test_add_arguments(self):
83 def test_add_arguments(self):
77
84
78 class MyLoader(ArgParseConfigLoader):
85 class MyLoader(ArgParseConfigLoader):
79 def _add_arguments(self):
86 def _add_arguments(self):
80 subparsers = self.parser.add_subparsers(dest='subparser_name')
87 subparsers = self.parser.add_subparsers(dest='subparser_name')
81 subparser1 = subparsers.add_parser('1')
88 subparser1 = subparsers.add_parser('1')
82 subparser1.add_argument('-x')
89 subparser1.add_argument('-x',dest='Global.x')
83 subparser2 = subparsers.add_parser('2')
90 subparser2 = subparsers.add_parser('2')
84 subparser2.add_argument('y')
91 subparser2.add_argument('y')
85
92
86 cl = MyLoader()
93 cl = MyLoader()
87 config = cl.load_config('2 frobble'.split())
94 config = cl.load_config('2 frobble'.split())
88 self.assertEquals(config.subparser_name, '2')
95 self.assertEquals(config.subparser_name, '2')
89 self.assertEquals(config.y, 'frobble')
96 self.assertEquals(config.y, 'frobble')
90 config = cl.load_config('1 -x frobble'.split())
97 config = cl.load_config('1 -x frobble'.split())
91 self.assertEquals(config.subparser_name, '1')
98 self.assertEquals(config.subparser_name, '1')
92 self.assertEquals(config.x, 'frobble')
99 self.assertEquals(config.Global.x, 'frobble')
93
100
101 class TestConfig(TestCase):
102
103 def test_setget(self):
104 c = Config()
105 c.a = 10
106 self.assertEquals(c.a, 10)
107 self.assertEquals(c.has_key('b'), False)
108
109 def test_auto_section(self):
110 c = Config()
111 self.assertEquals(c.has_key('A'), True)
112 self.assertEquals(c._has_section('A'), False)
113 A = c.A
114 A.foo = 'hi there'
115 self.assertEquals(c._has_section('A'), True)
116 self.assertEquals(c.A.foo, 'hi there')
117 del c.A
118 self.assertEquals(len(c.A.keys()),0)
119
120 def test_merge_doesnt_exist(self):
121 c1 = Config()
122 c2 = Config()
123 c2.bar = 10
124 c2.Foo.bar = 10
125 c1._merge(c2)
126 self.assertEquals(c1.Foo.bar, 10)
127 self.assertEquals(c1.bar, 10)
128 c2.Bar.bar = 10
129 c1._merge(c2)
130 self.assertEquals(c1.Bar.bar, 10)
131
132 def test_merge_exists(self):
133 c1 = Config()
134 c2 = Config()
135 c1.Foo.bar = 10
136 c1.Foo.bam = 30
137 c2.Foo.bar = 20
138 c2.Foo.wow = 40
139 c1._merge(c2)
140 self.assertEquals(c1.Foo.bam, 30)
141 self.assertEquals(c1.Foo.bar, 20)
142 self.assertEquals(c1.Foo.wow, 40)
143 c2.Foo.Bam.bam = 10
144 c1._merge(c2)
145 self.assertEquals(c1.Foo.Bam.bam, 10)
146
147 def test_deepcopy(self):
148 c1 = Config()
149 c1.Foo.bar = 10
150 c1.Foo.bam = 30
151 c1.a = 'asdf'
152 c1.b = range(10)
153 import copy
154 c2 = copy.deepcopy(c1)
155 self.assertEquals(c1, c2)
156 self.assert_(c1 is not c2)
157 self.assert_(c1.Foo is not c2.Foo)
158
159 def test_builtin(self):
160 c1 = Config()
161 exec 'foo = True' in c1
162 self.assertEquals(c1.foo, True)
163 self.assertRaises(ConfigError, setattr, c1, 'ValueError', 10)
@@ -1,257 +1,264 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 """
3 """
4 IPython's alias component
4 IPython's alias component
5
5
6 Authors:
6 Authors:
7
7
8 * Brian Granger
8 * Brian Granger
9 """
9 """
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Copyright (C) 2008-2009 The IPython Development Team
12 # Copyright (C) 2008-2009 The IPython Development Team
13 #
13 #
14 # Distributed under the terms of the BSD License. The full license is in
14 # Distributed under the terms of the BSD License. The full license is in
15 # the file COPYING, distributed as part of this software.
15 # the file COPYING, distributed as part of this software.
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17
17
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19 # Imports
19 # Imports
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21
21
22 import __builtin__
22 import __builtin__
23 import keyword
23 import keyword
24 import os
24 import os
25 import re
25 import re
26 import sys
26 import sys
27
27
28 from IPython.core.component import Component
28 from IPython.core.component import Component
29 from IPython.core.splitinput import split_user_input
29 from IPython.core.splitinput import split_user_input
30
30
31 from IPython.utils.traitlets import CBool, List, Instance
31 from IPython.utils.traitlets import CBool, List, Instance
32 from IPython.utils.genutils import error
32 from IPython.utils.genutils import error
33 from IPython.utils.autoattr import auto_attr
33 from IPython.utils.autoattr import auto_attr
34
34
35 #-----------------------------------------------------------------------------
35 #-----------------------------------------------------------------------------
36 # Utilities
36 # Utilities
37 #-----------------------------------------------------------------------------
37 #-----------------------------------------------------------------------------
38
38
39 # This is used as the pattern for calls to split_user_input.
39 # This is used as the pattern for calls to split_user_input.
40 shell_line_split = re.compile(r'^(\s*)(\S*\s*)(.*$)')
40 shell_line_split = re.compile(r'^(\s*)(\S*\s*)(.*$)')
41
41
42 def default_aliases():
42 def default_aliases():
43 # Make some aliases automatically
43 # Make some aliases automatically
44 # Prepare list of shell aliases to auto-define
44 # Prepare list of shell aliases to auto-define
45 if os.name == 'posix':
45 if os.name == 'posix':
46 auto_alias = ('mkdir mkdir', 'rmdir rmdir',
46 default_aliases = ('mkdir mkdir', 'rmdir rmdir',
47 'mv mv -i','rm rm -i','cp cp -i',
47 'mv mv -i','rm rm -i','cp cp -i',
48 'cat cat','less less','clear clear',
48 'cat cat','less less','clear clear',
49 # a better ls
49 # a better ls
50 'ls ls -F',
50 'ls ls -F',
51 # long ls
51 # long ls
52 'll ls -lF')
52 'll ls -lF')
53 # Extra ls aliases with color, which need special treatment on BSD
53 # Extra ls aliases with color, which need special treatment on BSD
54 # variants
54 # variants
55 ls_extra = ( # color ls
55 ls_extra = ( # color ls
56 'lc ls -F -o --color',
56 'lc ls -F -o --color',
57 # ls normal files only
57 # ls normal files only
58 'lf ls -F -o --color %l | grep ^-',
58 'lf ls -F -o --color %l | grep ^-',
59 # ls symbolic links
59 # ls symbolic links
60 'lk ls -F -o --color %l | grep ^l',
60 'lk ls -F -o --color %l | grep ^l',
61 # directories or links to directories,
61 # directories or links to directories,
62 'ldir ls -F -o --color %l | grep /$',
62 'ldir ls -F -o --color %l | grep /$',
63 # things which are executable
63 # things which are executable
64 'lx ls -F -o --color %l | grep ^-..x',
64 'lx ls -F -o --color %l | grep ^-..x',
65 )
65 )
66 # The BSDs don't ship GNU ls, so they don't understand the
66 # The BSDs don't ship GNU ls, so they don't understand the
67 # --color switch out of the box
67 # --color switch out of the box
68 if 'bsd' in sys.platform:
68 if 'bsd' in sys.platform:
69 ls_extra = ( # ls normal files only
69 ls_extra = ( # ls normal files only
70 'lf ls -lF | grep ^-',
70 'lf ls -lF | grep ^-',
71 # ls symbolic links
71 # ls symbolic links
72 'lk ls -lF | grep ^l',
72 'lk ls -lF | grep ^l',
73 # directories or links to directories,
73 # directories or links to directories,
74 'ldir ls -lF | grep /$',
74 'ldir ls -lF | grep /$',
75 # things which are executable
75 # things which are executable
76 'lx ls -lF | grep ^-..x',
76 'lx ls -lF | grep ^-..x',
77 )
77 )
78 auto_alias = auto_alias + ls_extra
78 default_aliases = default_aliases + ls_extra
79 elif os.name in ['nt','dos']:
79 elif os.name in ['nt','dos']:
80 auto_alias = ('ls dir /on',
80 default_aliases = ('ls dir /on',
81 'ddir dir /ad /on', 'ldir dir /ad /on',
81 'ddir dir /ad /on', 'ldir dir /ad /on',
82 'mkdir mkdir','rmdir rmdir','echo echo',
82 'mkdir mkdir','rmdir rmdir','echo echo',
83 'ren ren','cls cls','copy copy')
83 'ren ren','cls cls','copy copy')
84 else:
84 else:
85 auto_alias = ()
85 default_aliases = ()
86 return [s.split(None,1) for s in auto_alias]
86 return [s.split(None,1) for s in default_aliases]
87
87
88
88
89 class AliasError(Exception):
89 class AliasError(Exception):
90 pass
90 pass
91
91
92
92
93 class InvalidAliasError(AliasError):
93 class InvalidAliasError(AliasError):
94 pass
94 pass
95
95
96
96
97 #-----------------------------------------------------------------------------
97 #-----------------------------------------------------------------------------
98 # Main AliasManager class
98 # Main AliasManager class
99 #-----------------------------------------------------------------------------
99 #-----------------------------------------------------------------------------
100
100
101
101
102 class AliasManager(Component):
102 class AliasManager(Component):
103
103
104 auto_alias = List(default_aliases())
104 default_aliases = List(default_aliases(), config=True)
105 user_alias = List(default_value=[], config_key='USER_ALIAS')
105 user_aliases = List(default_value=[], config=True)
106
106
107 def __init__(self, parent, config=None):
107 def __init__(self, parent, config=None):
108 super(AliasManager, self).__init__(parent, config=config)
108 super(AliasManager, self).__init__(parent, config=config)
109 self.alias_table = {}
109 self.alias_table = {}
110 self.exclude_aliases()
110 self.exclude_aliases()
111 self.init_aliases()
111 self.init_aliases()
112
112
113 @auto_attr
113 @auto_attr
114 def shell(self):
114 def shell(self):
115 shell = Component.get_instances(
115 shell = Component.get_instances(
116 root=self.root,
116 root=self.root,
117 klass='IPython.core.iplib.InteractiveShell'
117 klass='IPython.core.iplib.InteractiveShell'
118 )[0]
118 )[0]
119 return shell
119 return shell
120
120
121 def __contains__(self, name):
121 def __contains__(self, name):
122 if name in self.alias_table:
122 if name in self.alias_table:
123 return True
123 return True
124 else:
124 else:
125 return False
125 return False
126
126
127 @property
127 @property
128 def aliases(self):
128 def aliases(self):
129 return [(item[0], item[1][1]) for item in self.alias_table.iteritems()]
129 return [(item[0], item[1][1]) for item in self.alias_table.iteritems()]
130
130
131 def exclude_aliases(self):
131 def exclude_aliases(self):
132 # set of things NOT to alias (keywords, builtins and some magics)
132 # set of things NOT to alias (keywords, builtins and some magics)
133 no_alias = set(['cd','popd','pushd','dhist','alias','unalias'])
133 no_alias = set(['cd','popd','pushd','dhist','alias','unalias'])
134 no_alias.update(set(keyword.kwlist))
134 no_alias.update(set(keyword.kwlist))
135 no_alias.update(set(__builtin__.__dict__.keys()))
135 no_alias.update(set(__builtin__.__dict__.keys()))
136 self.no_alias = no_alias
136 self.no_alias = no_alias
137
137
138 def init_aliases(self):
138 def init_aliases(self):
139 # Load default aliases
139 # Load default aliases
140 for name, cmd in self.auto_alias:
140 for name, cmd in self.default_aliases:
141 self.soft_define_alias(name, cmd)
141 self.soft_define_alias(name, cmd)
142
142
143 # Load user aliases
143 # Load user aliases
144 for name, cmd in self.user_alias:
144 for name, cmd in self.user_aliases:
145 self.soft_define_alias(name, cmd)
145 self.soft_define_alias(name, cmd)
146
146
147 def clear_aliases(self):
148 self.alias_table.clear()
149
147 def soft_define_alias(self, name, cmd):
150 def soft_define_alias(self, name, cmd):
148 """Define an alias, but don't raise on an AliasError."""
151 """Define an alias, but don't raise on an AliasError."""
149 try:
152 try:
150 self.define_alias(name, cmd)
153 self.define_alias(name, cmd)
151 except AliasError, e:
154 except AliasError, e:
152 error("Invalid alias: %s" % e)
155 error("Invalid alias: %s" % e)
153
156
154 def define_alias(self, name, cmd):
157 def define_alias(self, name, cmd):
155 """Define a new alias after validating it.
158 """Define a new alias after validating it.
156
159
157 This will raise an :exc:`AliasError` if there are validation
160 This will raise an :exc:`AliasError` if there are validation
158 problems.
161 problems.
159 """
162 """
160 nargs = self.validate_alias(name, cmd)
163 nargs = self.validate_alias(name, cmd)
161 self.alias_table[name] = (nargs, cmd)
164 self.alias_table[name] = (nargs, cmd)
162
165
166 def undefine_alias(self, name):
167 if self.alias_table.has_key(name):
168 del self.alias_table[name]
169
163 def validate_alias(self, name, cmd):
170 def validate_alias(self, name, cmd):
164 """Validate an alias and return the its number of arguments."""
171 """Validate an alias and return the its number of arguments."""
165 if name in self.no_alias:
172 if name in self.no_alias:
166 raise InvalidAliasError("The name %s can't be aliased "
173 raise InvalidAliasError("The name %s can't be aliased "
167 "because it is a keyword or builtin." % name)
174 "because it is a keyword or builtin." % name)
168 if not (isinstance(cmd, basestring)):
175 if not (isinstance(cmd, basestring)):
169 raise InvalidAliasError("An alias command must be a string, "
176 raise InvalidAliasError("An alias command must be a string, "
170 "got: %r" % name)
177 "got: %r" % name)
171 nargs = cmd.count('%s')
178 nargs = cmd.count('%s')
172 if nargs>0 and cmd.find('%l')>=0:
179 if nargs>0 and cmd.find('%l')>=0:
173 raise InvalidAliasError('The %s and %l specifiers are mutually '
180 raise InvalidAliasError('The %s and %l specifiers are mutually '
174 'exclusive in alias definitions.')
181 'exclusive in alias definitions.')
175 return nargs
182 return nargs
176
183
177 def call_alias(self, alias, rest=''):
184 def call_alias(self, alias, rest=''):
178 """Call an alias given its name and the rest of the line."""
185 """Call an alias given its name and the rest of the line."""
179 cmd = self.transform_alias(alias, rest)
186 cmd = self.transform_alias(alias, rest)
180 try:
187 try:
181 self.shell.system(cmd)
188 self.shell.system(cmd)
182 except:
189 except:
183 self.shell.showtraceback()
190 self.shell.showtraceback()
184
191
185 def transform_alias(self, alias,rest=''):
192 def transform_alias(self, alias,rest=''):
186 """Transform alias to system command string."""
193 """Transform alias to system command string."""
187 nargs, cmd = self.alias_table[alias]
194 nargs, cmd = self.alias_table[alias]
188
195
189 if ' ' in cmd and os.path.isfile(cmd):
196 if ' ' in cmd and os.path.isfile(cmd):
190 cmd = '"%s"' % cmd
197 cmd = '"%s"' % cmd
191
198
192 # Expand the %l special to be the user's input line
199 # Expand the %l special to be the user's input line
193 if cmd.find('%l') >= 0:
200 if cmd.find('%l') >= 0:
194 cmd = cmd.replace('%l', rest)
201 cmd = cmd.replace('%l', rest)
195 rest = ''
202 rest = ''
196 if nargs==0:
203 if nargs==0:
197 # Simple, argument-less aliases
204 # Simple, argument-less aliases
198 cmd = '%s %s' % (cmd, rest)
205 cmd = '%s %s' % (cmd, rest)
199 else:
206 else:
200 # Handle aliases with positional arguments
207 # Handle aliases with positional arguments
201 args = rest.split(None, nargs)
208 args = rest.split(None, nargs)
202 if len(args) < nargs:
209 if len(args) < nargs:
203 raise AliasError('Alias <%s> requires %s arguments, %s given.' %
210 raise AliasError('Alias <%s> requires %s arguments, %s given.' %
204 (alias, nargs, len(args)))
211 (alias, nargs, len(args)))
205 cmd = '%s %s' % (cmd % tuple(args[:nargs]),' '.join(args[nargs:]))
212 cmd = '%s %s' % (cmd % tuple(args[:nargs]),' '.join(args[nargs:]))
206 return cmd
213 return cmd
207
214
208 def expand_alias(self, line):
215 def expand_alias(self, line):
209 """ Expand an alias in the command line
216 """ Expand an alias in the command line
210
217
211 Returns the provided command line, possibly with the first word
218 Returns the provided command line, possibly with the first word
212 (command) translated according to alias expansion rules.
219 (command) translated according to alias expansion rules.
213
220
214 [ipython]|16> _ip.expand_aliases("np myfile.txt")
221 [ipython]|16> _ip.expand_aliases("np myfile.txt")
215 <16> 'q:/opt/np/notepad++.exe myfile.txt'
222 <16> 'q:/opt/np/notepad++.exe myfile.txt'
216 """
223 """
217
224
218 pre,fn,rest = split_user_input(line)
225 pre,fn,rest = split_user_input(line)
219 res = pre + self.expand_aliases(fn, rest)
226 res = pre + self.expand_aliases(fn, rest)
220 return res
227 return res
221
228
222 def expand_aliases(self, fn, rest):
229 def expand_aliases(self, fn, rest):
223 """Expand multiple levels of aliases:
230 """Expand multiple levels of aliases:
224
231
225 if:
232 if:
226
233
227 alias foo bar /tmp
234 alias foo bar /tmp
228 alias baz foo
235 alias baz foo
229
236
230 then:
237 then:
231
238
232 baz huhhahhei -> bar /tmp huhhahhei
239 baz huhhahhei -> bar /tmp huhhahhei
233
240
234 """
241 """
235 line = fn + " " + rest
242 line = fn + " " + rest
236
243
237 done = set()
244 done = set()
238 while 1:
245 while 1:
239 pre,fn,rest = split_user_input(line, shell_line_split)
246 pre,fn,rest = split_user_input(line, shell_line_split)
240 if fn in self.alias_table:
247 if fn in self.alias_table:
241 if fn in done:
248 if fn in done:
242 warn("Cyclic alias definition, repeated '%s'" % fn)
249 warn("Cyclic alias definition, repeated '%s'" % fn)
243 return ""
250 return ""
244 done.add(fn)
251 done.add(fn)
245
252
246 l2 = self.transform_alias(fn, rest)
253 l2 = self.transform_alias(fn, rest)
247 if l2 == line:
254 if l2 == line:
248 break
255 break
249 # ls -> ls -F should not recurse forever
256 # ls -> ls -F should not recurse forever
250 if l2.split(None,1)[0] == line.split(None,1)[0]:
257 if l2.split(None,1)[0] == line.split(None,1)[0]:
251 line = l2
258 line = l2
252 break
259 break
253 line=l2
260 line=l2
254 else:
261 else:
255 break
262 break
256
263
257 return line
264 return line
@@ -1,242 +1,265 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 """
3 """
4 An application for IPython
4 An application for IPython
5
5
6 Authors:
6 Authors:
7
7
8 * Brian Granger
8 * Brian Granger
9 * Fernando Perez
9 * Fernando Perez
10
10
11 Notes
11 Notes
12 -----
12 -----
13 """
13 """
14
14
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 # Copyright (C) 2008-2009 The IPython Development Team
16 # Copyright (C) 2008-2009 The IPython Development Team
17 #
17 #
18 # Distributed under the terms of the BSD License. The full license is in
18 # Distributed under the terms of the BSD License. The full license is in
19 # the file COPYING, distributed as part of this software.
19 # the file COPYING, distributed as part of this software.
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21
21
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23 # Imports
23 # Imports
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25
25
26 import os
26 import os
27 import sys
27 import sys
28 import traceback
28 import traceback
29
30 from copy import deepcopy
29 from copy import deepcopy
31 from IPython.utils.ipstruct import Struct
30
32 from IPython.utils.genutils import get_ipython_dir, filefind
31 from IPython.utils.genutils import get_ipython_dir, filefind
33 from IPython.config.loader import (
32 from IPython.config.loader import (
34 IPythonArgParseConfigLoader,
33 PyFileConfigLoader,
35 PyFileConfigLoader
34 ArgParseConfigLoader,
35 Config,
36 NoConfigDefault
36 )
37 )
37
38
38 #-----------------------------------------------------------------------------
39 #-----------------------------------------------------------------------------
39 # Classes and functions
40 # Classes and functions
40 #-----------------------------------------------------------------------------
41 #-----------------------------------------------------------------------------
41
42
42
43
44 class IPythonArgParseConfigLoader(ArgParseConfigLoader):
45 """Default command line options for IPython based applications."""
46
47 def _add_other_arguments(self):
48 self.parser.add_argument('-ipythondir',dest='Global.ipythondir',type=str,
49 help='Set to override default location of Global.ipythondir.',
50 default=NoConfigDefault,
51 metavar='Global.ipythondir')
52 self.parser.add_argument('-p','-profile',dest='Global.profile',type=str,
53 help='The string name of the ipython profile to be used.',
54 default=NoConfigDefault,
55 metavar='Global.profile')
56 self.parser.add_argument('-debug',dest="Global.debug",action='store_true',
57 help='Debug the application startup process.',
58 default=NoConfigDefault)
59 self.parser.add_argument('-config_file',dest='Global.config_file',type=str,
60 help='Set the config file name to override default.',
61 default=NoConfigDefault,
62 metavar='Global.config_file')
63
64
43 class ApplicationError(Exception):
65 class ApplicationError(Exception):
44 pass
66 pass
45
67
46
68
47 class Application(object):
69 class Application(object):
48 """Load a config, construct an app and run it.
70 """Load a config, construct an app and run it.
49 """
71 """
50
72
51 config_file_name = 'ipython_config.py'
73 config_file_name = 'ipython_config.py'
52 name = 'ipython'
74 name = 'ipython'
53 debug = False
75 debug = False
54
76
55 def __init__(self):
77 def __init__(self):
56 pass
78 pass
57
79
58 def start(self):
80 def start(self):
59 """Start the application."""
81 """Start the application."""
60 self.attempt(self.create_default_config)
82 self.attempt(self.create_default_config)
61 self.attempt(self.pre_load_command_line_config)
83 self.attempt(self.pre_load_command_line_config)
62 self.attempt(self.load_command_line_config, action='abort')
84 self.attempt(self.load_command_line_config, action='abort')
63 self.attempt(self.post_load_command_line_config)
85 self.attempt(self.post_load_command_line_config)
64 self.attempt(self.find_ipythondir)
86 self.attempt(self.find_ipythondir)
65 self.attempt(self.find_config_file_name)
87 self.attempt(self.find_config_file_name)
66 self.attempt(self.find_config_file_paths)
88 self.attempt(self.find_config_file_paths)
67 self.attempt(self.pre_load_file_config)
89 self.attempt(self.pre_load_file_config)
68 self.attempt(self.load_file_config)
90 self.attempt(self.load_file_config)
69 self.attempt(self.post_load_file_config)
91 self.attempt(self.post_load_file_config)
70 self.attempt(self.merge_configs)
92 self.attempt(self.merge_configs)
71 self.attempt(self.pre_construct)
93 self.attempt(self.pre_construct)
72 self.attempt(self.construct)
94 self.attempt(self.construct)
73 self.attempt(self.post_construct)
95 self.attempt(self.post_construct)
74 self.attempt(self.start_app)
96 self.attempt(self.start_app)
75
97
76 #-------------------------------------------------------------------------
98 #-------------------------------------------------------------------------
77 # Various stages of Application creation
99 # Various stages of Application creation
78 #-------------------------------------------------------------------------
100 #-------------------------------------------------------------------------
79
101
80 def create_default_config(self):
102 def create_default_config(self):
81 """Create defaults that can't be set elsewhere."""
103 """Create defaults that can't be set elsewhere."""
82 self.default_config = Struct()
104 self.default_config = Config()
83 self.default_config.IPYTHONDIR = get_ipython_dir()
105 self.default_config.Global.ipythondir = get_ipython_dir()
84
106
85 def create_command_line_config(self):
107 def create_command_line_config(self):
86 """Create and return a command line config loader."""
108 """Create and return a command line config loader."""
87 return IPythonArgParseConfigLoader(description=self.name)
109 return IPythonArgParseConfigLoader(description=self.name)
88
110
89 def pre_load_command_line_config(self):
111 def pre_load_command_line_config(self):
90 """Do actions just before loading the command line config."""
112 """Do actions just before loading the command line config."""
91 pass
113 pass
92
114
93 def load_command_line_config(self):
115 def load_command_line_config(self):
94 """Load the command line config.
116 """Load the command line config.
95
117
96 This method also sets ``self.debug``.
118 This method also sets ``self.debug``.
97 """
119 """
98
120
99 loader = self.create_command_line_config()
121 loader = self.create_command_line_config()
100 self.command_line_config = loader.load_config()
122 self.command_line_config = loader.load_config()
101 try:
123 try:
102 self.debug = self.command_line_config.DEBUG
124 self.debug = self.command_line_config.Global.debug
103 except AttributeError:
125 except AttributeError:
104 pass # use class default
126 pass # use class default
105 self.log("Default config loaded:", self.default_config)
127 self.log("Default config loaded:", self.default_config)
106 self.log("Command line config loaded:", self.command_line_config)
128 self.log("Command line config loaded:", self.command_line_config)
107
129
108 def post_load_command_line_config(self):
130 def post_load_command_line_config(self):
109 """Do actions just after loading the command line config."""
131 """Do actions just after loading the command line config."""
110 pass
132 pass
111
133
112 def find_ipythondir(self):
134 def find_ipythondir(self):
113 """Set the IPython directory.
135 """Set the IPython directory.
114
136
115 This sets ``self.ipythondir``, but the actual value that is passed
137 This sets ``self.ipythondir``, but the actual value that is passed
116 to the application is kept in either ``self.default_config`` or
138 to the application is kept in either ``self.default_config`` or
117 ``self.command_line_config``. This also added ``self.ipythondir`` to
139 ``self.command_line_config``. This also added ``self.ipythondir`` to
118 ``sys.path`` so config files there can be references by other config
140 ``sys.path`` so config files there can be references by other config
119 files.
141 files.
120 """
142 """
121
143
122 try:
144 try:
123 self.ipythondir = self.command_line_config.IPYTHONDIR
145 self.ipythondir = self.command_line_config.Global.ipythondir
124 except AttributeError:
146 except AttributeError:
125 self.ipythondir = self.default_config.IPYTHONDIR
147 self.ipythondir = self.default_config.Global.ipythondir
126 sys.path.append(os.path.abspath(self.ipythondir))
148 sys.path.append(os.path.abspath(self.ipythondir))
127 if not os.path.isdir(self.ipythondir):
149 if not os.path.isdir(self.ipythondir):
128 os.makedirs(self.ipythondir, mode = 0777)
150 os.makedirs(self.ipythondir, mode = 0777)
129 self.log("IPYTHONDIR set to: %s" % self.ipythondir)
151 self.log("IPYTHONDIR set to: %s" % self.ipythondir)
130
152
131 def find_config_file_name(self):
153 def find_config_file_name(self):
132 """Find the config file name for this application.
154 """Find the config file name for this application.
133
155
134 If a profile has been set at the command line, this will resolve
156 If a profile has been set at the command line, this will resolve
135 it. The search paths for the config file are set in
157 it. The search paths for the config file are set in
136 :meth:`find_config_file_paths` and then passed to the config file
158 :meth:`find_config_file_paths` and then passed to the config file
137 loader where they are resolved to an absolute path.
159 loader where they are resolved to an absolute path.
138 """
160 """
139
161
140 try:
162 try:
141 self.config_file_name = self.command_line_config.CONFIG_FILE
163 self.config_file_name = self.command_line_config.Global.config_file
142 except AttributeError:
164 except AttributeError:
143 pass
165 pass
144
166
145 try:
167 try:
146 self.profile_name = self.command_line_config.PROFILE
168 self.profile_name = self.command_line_config.Global.profile
147 name_parts = self.config_file_name.split('.')
169 name_parts = self.config_file_name.split('.')
148 name_parts.insert(1, '_' + self.profile_name + '.')
170 name_parts.insert(1, '_' + self.profile_name + '.')
149 self.config_file_name = ''.join(name_parts)
171 self.config_file_name = ''.join(name_parts)
150 except AttributeError:
172 except AttributeError:
151 pass
173 pass
152
174
153 def find_config_file_paths(self):
175 def find_config_file_paths(self):
154 """Set the search paths for resolving the config file."""
176 """Set the search paths for resolving the config file."""
155 self.config_file_paths = (os.getcwd(), self.ipythondir)
177 self.config_file_paths = (os.getcwd(), self.ipythondir)
156
178
157 def pre_load_file_config(self):
179 def pre_load_file_config(self):
158 """Do actions before the config file is loaded."""
180 """Do actions before the config file is loaded."""
159 pass
181 pass
160
182
161 def load_file_config(self):
183 def load_file_config(self):
162 """Load the config file.
184 """Load the config file.
163
185
164 This tries to load the config file from disk. If successful, the
186 This tries to load the config file from disk. If successful, the
165 ``CONFIG_FILE`` config variable is set to the resolved config file
187 ``CONFIG_FILE`` config variable is set to the resolved config file
166 location. If not successful, an empty config is used.
188 location. If not successful, an empty config is used.
167 """
189 """
168 loader = PyFileConfigLoader(self.config_file_name,
190 loader = PyFileConfigLoader(self.config_file_name,
169 self.config_file_paths)
191 path=self.config_file_paths)
170 try:
192 try:
171 self.file_config = loader.load_config()
193 self.file_config = loader.load_config()
172 self.file_config.CONFIG_FILE = loader.full_filename
194 self.file_config.Global.config_file = loader.full_filename
173 except IOError:
195 except IOError:
174 self.log("Config file not found, skipping: %s" % \
196 self.log("Config file not found, skipping: %s" % \
175 self.config_file_name)
197 self.config_file_name)
176 self.file_config = Struct()
198 self.file_config = Config()
177 else:
199 else:
178 self.log("Config file loaded: %s" % loader.full_filename,
200 self.log("Config file loaded: %s" % loader.full_filename,
179 self.file_config)
201 self.file_config)
180
202
181 def post_load_file_config(self):
203 def post_load_file_config(self):
182 """Do actions after the config file is loaded."""
204 """Do actions after the config file is loaded."""
183 pass
205 pass
184
206
185 def merge_configs(self):
207 def merge_configs(self):
186 """Merge the default, command line and file config objects."""
208 """Merge the default, command line and file config objects."""
187 config = Struct()
209 config = Config()
188 config.update(self.default_config)
210 config._merge(self.default_config)
189 config.update(self.file_config)
211 config._merge(self.file_config)
190 config.update(self.command_line_config)
212 config._merge(self.command_line_config)
191 self.master_config = config
213 self.master_config = config
192 self.log("Master config created:", self.master_config)
214 self.log("Master config created:", self.master_config)
193
215
194 def pre_construct(self):
216 def pre_construct(self):
195 """Do actions after the config has been built, but before construct."""
217 """Do actions after the config has been built, but before construct."""
196 pass
218 pass
197
219
198 def construct(self):
220 def construct(self):
199 """Construct the main components that make up this app."""
221 """Construct the main components that make up this app."""
200 self.log("Constructing components for application...")
222 self.log("Constructing components for application...")
201
223
202 def post_construct(self):
224 def post_construct(self):
203 """Do actions after construct, but before starting the app."""
225 """Do actions after construct, but before starting the app."""
204 pass
226 pass
205
227
206 def start_app(self):
228 def start_app(self):
207 """Actually start the app."""
229 """Actually start the app."""
208 self.log("Starting application...")
230 self.log("Starting application...")
209
231
210 #-------------------------------------------------------------------------
232 #-------------------------------------------------------------------------
211 # Utility methods
233 # Utility methods
212 #-------------------------------------------------------------------------
234 #-------------------------------------------------------------------------
213
235
214 def abort(self):
236 def abort(self):
215 """Abort the starting of the application."""
237 """Abort the starting of the application."""
216 print "Aborting application: ", self.name
238 print "Aborting application: ", self.name
217 sys.exit(1)
239 sys.exit(1)
218
240
219 def exit(self):
241 def exit(self):
220 print "Exiting application: ", self.name
242 print "Exiting application: ", self.name
221 sys.exit(1)
243 sys.exit(1)
222
244
223 def attempt(self, func, action='abort'):
245 def attempt(self, func, action='abort'):
224 try:
246 try:
225 func()
247 func()
248 except SystemExit:
249 self.exit()
226 except:
250 except:
227 if action == 'abort':
251 if action == 'abort':
228 self.print_traceback()
252 self.print_traceback()
229 self.abort()
253 self.abort()
230 elif action == 'exit':
254 elif action == 'exit':
231 self.print_traceback()
232 self.exit()
255 self.exit()
233
256
234 def print_traceback(self):
257 def print_traceback(self):
235 print "Error in appliction startup: ", self.name
258 print "Error in appliction startup: ", self.name
236 print
259 print
237 traceback.print_exc()
260 traceback.print_exc()
238
261
239 def log(self, *args):
262 def log(self, *args):
240 if self.debug:
263 if self.debug:
241 for arg in args:
264 for arg in args:
242 print "[%s] %s" % (self.name, arg) No newline at end of file
265 print "[%s] %s" % (self.name, arg)
@@ -1,111 +1,118 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 """
3 """
4 A context manager for managing things injected into :mod:`__builtin__`.
4 A context manager for managing things injected into :mod:`__builtin__`.
5
5
6 Authors:
6 Authors:
7
7
8 * Brian Granger
8 * Brian Granger
9 """
9 """
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Copyright (C) 2008-2009 The IPython Development Team
12 # Copyright (C) 2008-2009 The IPython Development Team
13 #
13 #
14 # Distributed under the terms of the BSD License. The full license is in
14 # Distributed under the terms of the BSD License. The full license is in
15 # the file COPYING, distributed as part of this software.
15 # the file COPYING, distributed as part of this software.
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17
17
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19 # Imports
19 # Imports
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21
21
22 import __builtin__
22 import __builtin__
23
23
24 from IPython.core.component import Component
24 from IPython.core.component import Component
25 from IPython.core.quitter import Quitter
25 from IPython.core.quitter import Quitter
26
26
27 from IPython.utils.autoattr import auto_attr
27 from IPython.utils.autoattr import auto_attr
28
28
29 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
30 # Classes and functions
30 # Classes and functions
31 #-----------------------------------------------------------------------------
31 #-----------------------------------------------------------------------------
32
32
33
33
34 class BuiltinUndefined(object): pass
34 class BuiltinUndefined(object): pass
35 BuiltinUndefined = BuiltinUndefined()
35 BuiltinUndefined = BuiltinUndefined()
36
36
37
37
38 class BuiltinTrap(Component):
38 class BuiltinTrap(Component):
39
39
40 def __init__(self, parent):
40 def __init__(self, parent):
41 super(BuiltinTrap, self).__init__(parent, None, None)
41 super(BuiltinTrap, self).__init__(parent, None, None)
42 self._orig_builtins = {}
42 self._orig_builtins = {}
43 # We define this to track if a single BuiltinTrap is nested.
44 # Only turn off the trap when the outermost call to __exit__ is made.
45 self._nested_level = 0
43
46
44 @auto_attr
47 @auto_attr
45 def shell(self):
48 def shell(self):
46 shell = Component.get_instances(
49 shell = Component.get_instances(
47 root=self.root,
50 root=self.root,
48 klass='IPython.core.iplib.InteractiveShell'
51 klass='IPython.core.iplib.InteractiveShell'
49 )[0]
52 )[0]
50 return shell
53 return shell
51
54
52 def __enter__(self):
55 def __enter__(self):
53 self.set()
56 if self._nested_level == 0:
57 self.set()
58 self._nested_level += 1
54 # I return self, so callers can use add_builtin in a with clause.
59 # I return self, so callers can use add_builtin in a with clause.
55 return self
60 return self
56
61
57 def __exit__(self, type, value, traceback):
62 def __exit__(self, type, value, traceback):
58 self.unset()
63 if self._nested_level == 1:
64 self.unset()
65 self._nested_level -= 1
59 return True
66 return True
60
67
61 def add_builtin(self, key, value):
68 def add_builtin(self, key, value):
62 """Add a builtin and save the original."""
69 """Add a builtin and save the original."""
63 orig = __builtin__.__dict__.get(key, BuiltinUndefined)
70 orig = __builtin__.__dict__.get(key, BuiltinUndefined)
64 self._orig_builtins[key] = orig
71 self._orig_builtins[key] = orig
65 __builtin__.__dict__[key] = value
72 __builtin__.__dict__[key] = value
66
73
67 def remove_builtin(self, key):
74 def remove_builtin(self, key):
68 """Remove an added builtin and re-set the original."""
75 """Remove an added builtin and re-set the original."""
69 try:
76 try:
70 orig = self._orig_builtins.pop(key)
77 orig = self._orig_builtins.pop(key)
71 except KeyError:
78 except KeyError:
72 pass
79 pass
73 else:
80 else:
74 if orig is BuiltinUndefined:
81 if orig is BuiltinUndefined:
75 del __builtin__.__dict__[key]
82 del __builtin__.__dict__[key]
76 else:
83 else:
77 __builtin__.__dict__[key] = orig
84 __builtin__.__dict__[key] = orig
78
85
79 def set(self):
86 def set(self):
80 """Store ipython references in the __builtin__ namespace."""
87 """Store ipython references in the __builtin__ namespace."""
81 self.add_builtin('exit', Quitter(self.shell, 'exit'))
88 self.add_builtin('exit', Quitter(self.shell, 'exit'))
82 self.add_builtin('quit', Quitter(self.shell, 'quit'))
89 self.add_builtin('quit', Quitter(self.shell, 'quit'))
83
90
84 # Recursive reload function
91 # Recursive reload function
85 try:
92 try:
86 from IPython.lib import deepreload
93 from IPython.lib import deepreload
87 if self.shell.deep_reload:
94 if self.shell.deep_reload:
88 self.add_builtin('reload', deepreload.reload)
95 self.add_builtin('reload', deepreload.reload)
89 else:
96 else:
90 self.add_builtin('dreload', deepreload.reload)
97 self.add_builtin('dreload', deepreload.reload)
91 del deepreload
98 del deepreload
92 except ImportError:
99 except ImportError:
93 pass
100 pass
94
101
95 # Keep in the builtins a flag for when IPython is active. We set it
102 # Keep in the builtins a flag for when IPython is active. We set it
96 # with setdefault so that multiple nested IPythons don't clobber one
103 # with setdefault so that multiple nested IPythons don't clobber one
97 # another. Each will increase its value by one upon being activated,
104 # another. Each will increase its value by one upon being activated,
98 # which also gives us a way to determine the nesting level.
105 # which also gives us a way to determine the nesting level.
99 __builtin__.__dict__.setdefault('__IPYTHON__active',0)
106 __builtin__.__dict__.setdefault('__IPYTHON__active',0)
100
107
101 def unset(self):
108 def unset(self):
102 """Remove any builtins which might have been added by add_builtins, or
109 """Remove any builtins which might have been added by add_builtins, or
103 restore overwritten ones to their previous values."""
110 restore overwritten ones to their previous values."""
104 for key in self._orig_builtins.keys():
111 for key in self._orig_builtins.keys():
105 self.remove_builtin(key)
112 self.remove_builtin(key)
106 self._orig_builtins.clear()
113 self._orig_builtins.clear()
107 self._builtins_added = False
114 self._builtins_added = False
108 try:
115 try:
109 del __builtin__.__dict__['__IPYTHON__active']
116 del __builtin__.__dict__['__IPYTHON__active']
110 except KeyError:
117 except KeyError:
111 pass No newline at end of file
118 pass
@@ -1,304 +1,309 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 """
3 """
4 A lightweight component system for IPython.
4 A lightweight component system for IPython.
5
5
6 Authors:
6 Authors:
7
7
8 * Brian Granger
8 * Brian Granger
9 * Fernando Perez
9 * Fernando Perez
10 """
10 """
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Copyright (C) 2008-2009 The IPython Development Team
13 # Copyright (C) 2008-2009 The IPython Development Team
14 #
14 #
15 # Distributed under the terms of the BSD License. The full license is in
15 # Distributed under the terms of the BSD License. The full license is in
16 # the file COPYING, distributed as part of this software.
16 # the file COPYING, distributed as part of this software.
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Imports
20 # Imports
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22
22
23 from copy import deepcopy
23 from copy import deepcopy
24 import datetime
24 import datetime
25 from weakref import WeakValueDictionary
25 from weakref import WeakValueDictionary
26
26
27 from IPython.utils.importstring import import_item
27 from IPython.utils.importstring import import_item
28 from IPython.utils.ipstruct import Struct
28 from IPython.config.loader import Config
29 from IPython.utils.traitlets import (
29 from IPython.utils.traitlets import (
30 HasTraitlets, TraitletError, MetaHasTraitlets, Instance, This
30 HasTraitlets, TraitletError, MetaHasTraitlets, Instance, This
31 )
31 )
32
32
33
33
34 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
35 # Helper classes for Components
35 # Helper classes for Components
36 #-----------------------------------------------------------------------------
36 #-----------------------------------------------------------------------------
37
37
38
38
39 class ComponentError(Exception):
39 class ComponentError(Exception):
40 pass
40 pass
41
41
42 class MetaComponentTracker(type):
42 class MetaComponentTracker(type):
43 """A metaclass that tracks instances of Components and its subclasses."""
43 """A metaclass that tracks instances of Components and its subclasses."""
44
44
45 def __init__(cls, name, bases, d):
45 def __init__(cls, name, bases, d):
46 super(MetaComponentTracker, cls).__init__(name, bases, d)
46 super(MetaComponentTracker, cls).__init__(name, bases, d)
47 cls.__instance_refs = WeakValueDictionary()
47 cls.__instance_refs = WeakValueDictionary()
48 cls.__numcreated = 0
48 cls.__numcreated = 0
49
49
50 def __call__(cls, *args, **kw):
50 def __call__(cls, *args, **kw):
51 """Called when a class is called (instantiated)!!!
51 """Called when a class is called (instantiated)!!!
52
52
53 When a Component or subclass is instantiated, this is called and
53 When a Component or subclass is instantiated, this is called and
54 the instance is saved in a WeakValueDictionary for tracking.
54 the instance is saved in a WeakValueDictionary for tracking.
55 """
55 """
56 instance = cls.__new__(cls, *args, **kw)
56 instance = cls.__new__(cls, *args, **kw)
57
57
58 # Register the instance before __init__ is called so get_instances
58 # Register the instance before __init__ is called so get_instances
59 # works inside __init__ methods!
59 # works inside __init__ methods!
60 indices = cls.register_instance(instance)
60 indices = cls.register_instance(instance)
61
61
62 # This is in a try/except because of the __init__ method fails, the
62 # This is in a try/except because of the __init__ method fails, the
63 # instance is discarded and shouldn't be tracked.
63 # instance is discarded and shouldn't be tracked.
64 try:
64 try:
65 if isinstance(instance, cls):
65 if isinstance(instance, cls):
66 cls.__init__(instance, *args, **kw)
66 cls.__init__(instance, *args, **kw)
67 except:
67 except:
68 # Unregister the instance because __init__ failed!
68 # Unregister the instance because __init__ failed!
69 cls.unregister_instances(indices)
69 cls.unregister_instances(indices)
70 raise
70 raise
71 else:
71 else:
72 return instance
72 return instance
73
73
74 def register_instance(cls, instance):
74 def register_instance(cls, instance):
75 """Register instance with cls and its subclasses."""
75 """Register instance with cls and its subclasses."""
76 # indices is a list of the keys used to register the instance
76 # indices is a list of the keys used to register the instance
77 # with. This list is needed if the instance needs to be unregistered.
77 # with. This list is needed if the instance needs to be unregistered.
78 indices = []
78 indices = []
79 for c in cls.__mro__:
79 for c in cls.__mro__:
80 if issubclass(cls, c) and issubclass(c, Component):
80 if issubclass(cls, c) and issubclass(c, Component):
81 c.__numcreated += 1
81 c.__numcreated += 1
82 indices.append(c.__numcreated)
82 indices.append(c.__numcreated)
83 c.__instance_refs[c.__numcreated] = instance
83 c.__instance_refs[c.__numcreated] = instance
84 else:
84 else:
85 break
85 break
86 return indices
86 return indices
87
87
88 def unregister_instances(cls, indices):
88 def unregister_instances(cls, indices):
89 """Unregister instance with cls and its subclasses."""
89 """Unregister instance with cls and its subclasses."""
90 for c, index in zip(cls.__mro__, indices):
90 for c, index in zip(cls.__mro__, indices):
91 try:
91 try:
92 del c.__instance_refs[index]
92 del c.__instance_refs[index]
93 except KeyError:
93 except KeyError:
94 pass
94 pass
95
95
96 def clear_instances(cls):
96 def clear_instances(cls):
97 """Clear all instances tracked by cls."""
97 """Clear all instances tracked by cls."""
98 cls.__instance_refs.clear()
98 cls.__instance_refs.clear()
99 cls.__numcreated = 0
99 cls.__numcreated = 0
100
100
101 def get_instances(cls, name=None, root=None, klass=None):
101 def get_instances(cls, name=None, root=None, klass=None):
102 """Get all instances of cls and its subclasses.
102 """Get all instances of cls and its subclasses.
103
103
104 Parameters
104 Parameters
105 ----------
105 ----------
106 name : str
106 name : str
107 Limit to components with this name.
107 Limit to components with this name.
108 root : Component or subclass
108 root : Component or subclass
109 Limit to components having this root.
109 Limit to components having this root.
110 klass : class or str
110 klass : class or str
111 Limits to instances of the class or its subclasses. If a str
111 Limits to instances of the class or its subclasses. If a str
112 is given ut must be in the form 'foo.bar.MyClass'. The str
112 is given ut must be in the form 'foo.bar.MyClass'. The str
113 form of this argument is useful for forward declarations.
113 form of this argument is useful for forward declarations.
114 """
114 """
115 if klass is not None:
115 if klass is not None:
116 if isinstance(klass, basestring):
116 if isinstance(klass, basestring):
117 klass = import_item(klass)
117 klass = import_item(klass)
118 # Limit search to instances of klass for performance
118 # Limit search to instances of klass for performance
119 if issubclass(klass, Component):
119 if issubclass(klass, Component):
120 return klass.get_instances(name=name, root=root)
120 return klass.get_instances(name=name, root=root)
121 instances = cls.__instance_refs.values()
121 instances = cls.__instance_refs.values()
122 if name is not None:
122 if name is not None:
123 instances = [i for i in instances if i.name == name]
123 instances = [i for i in instances if i.name == name]
124 if klass is not None:
124 if klass is not None:
125 instances = [i for i in instances if isinstance(i, klass)]
125 instances = [i for i in instances if isinstance(i, klass)]
126 if root is not None:
126 if root is not None:
127 instances = [i for i in instances if i.root == root]
127 instances = [i for i in instances if i.root == root]
128 return instances
128 return instances
129
129
130 def get_instances_by_condition(cls, call, name=None, root=None,
130 def get_instances_by_condition(cls, call, name=None, root=None,
131 klass=None):
131 klass=None):
132 """Get all instances of cls, i such that call(i)==True.
132 """Get all instances of cls, i such that call(i)==True.
133
133
134 This also takes the ``name`` and ``root`` and ``classname``
134 This also takes the ``name`` and ``root`` and ``classname``
135 arguments of :meth:`get_instance`
135 arguments of :meth:`get_instance`
136 """
136 """
137 return [i for i in cls.get_instances(name, root, klass) if call(i)]
137 return [i for i in cls.get_instances(name, root, klass) if call(i)]
138
138
139
139
140 def masquerade_as(instance, cls):
140 def masquerade_as(instance, cls):
141 """Let instance masquerade as an instance of cls.
141 """Let instance masquerade as an instance of cls.
142
142
143 Sometimes, such as in testing code, it is useful to let a class
143 Sometimes, such as in testing code, it is useful to let a class
144 masquerade as another. Python, being duck typed, allows this by
144 masquerade as another. Python, being duck typed, allows this by
145 default. But, instances of components are tracked by their class type.
145 default. But, instances of components are tracked by their class type.
146
146
147 After calling this, cls.get_instances() will return ``instance``. This
147 After calling this, cls.get_instances() will return ``instance``. This
148 does not, however, cause isinstance(instance, cls) to return ``True``.
148 does not, however, cause isinstance(instance, cls) to return ``True``.
149
149
150 Parameters
150 Parameters
151 ----------
151 ----------
152 instance : an instance of a Component or Component subclass
152 instance : an instance of a Component or Component subclass
153 The instance that will pretend to be a cls.
153 The instance that will pretend to be a cls.
154 cls : subclass of Component
154 cls : subclass of Component
155 The Component subclass that instance will pretend to be.
155 The Component subclass that instance will pretend to be.
156 """
156 """
157 cls.register_instance(instance)
157 cls.register_instance(instance)
158
158
159
159
160 class ComponentNameGenerator(object):
160 class ComponentNameGenerator(object):
161 """A Singleton to generate unique component names."""
161 """A Singleton to generate unique component names."""
162
162
163 def __init__(self, prefix):
163 def __init__(self, prefix):
164 self.prefix = prefix
164 self.prefix = prefix
165 self.i = 0
165 self.i = 0
166
166
167 def __call__(self):
167 def __call__(self):
168 count = self.i
168 count = self.i
169 self.i += 1
169 self.i += 1
170 return "%s%s" % (self.prefix, count)
170 return "%s%s" % (self.prefix, count)
171
171
172
172
173 ComponentNameGenerator = ComponentNameGenerator('ipython.component')
173 ComponentNameGenerator = ComponentNameGenerator('ipython.component')
174
174
175
175
176 class MetaComponent(MetaHasTraitlets, MetaComponentTracker):
176 class MetaComponent(MetaHasTraitlets, MetaComponentTracker):
177 pass
177 pass
178
178
179
179
180 #-----------------------------------------------------------------------------
180 #-----------------------------------------------------------------------------
181 # Component implementation
181 # Component implementation
182 #-----------------------------------------------------------------------------
182 #-----------------------------------------------------------------------------
183
183
184
184
185 class Component(HasTraitlets):
185 class Component(HasTraitlets):
186
186
187 __metaclass__ = MetaComponent
187 __metaclass__ = MetaComponent
188
188
189 # Traitlets are fun!
189 # Traitlets are fun!
190 config = Instance(Struct,(),{})
190 config = Instance(Config,(),{})
191 parent = This()
191 parent = This()
192 root = This()
192 root = This()
193 created = None
193 created = None
194
194
195 def __init__(self, parent, name=None, config=None):
195 def __init__(self, parent, name=None, config=None):
196 """Create a component given a parent and possibly and name and config.
196 """Create a component given a parent and possibly and name and config.
197
197
198 Parameters
198 Parameters
199 ----------
199 ----------
200 parent : Component subclass
200 parent : Component subclass
201 The parent in the component graph. The parent is used
201 The parent in the component graph. The parent is used
202 to get the root of the component graph.
202 to get the root of the component graph.
203 name : str
203 name : str
204 The unique name of the component. If empty, then a unique
204 The unique name of the component. If empty, then a unique
205 one will be autogenerated.
205 one will be autogenerated.
206 config : Struct
206 config : Config
207 If this is empty, self.config = parent.config, otherwise
207 If this is empty, self.config = parent.config, otherwise
208 self.config = config and root.config is ignored. This argument
208 self.config = config and root.config is ignored. This argument
209 should only be used to *override* the automatic inheritance of
209 should only be used to *override* the automatic inheritance of
210 parent.config. If a caller wants to modify parent.config
210 parent.config. If a caller wants to modify parent.config
211 (not override), the caller should make a copy and change
211 (not override), the caller should make a copy and change
212 attributes and then pass the copy to this argument.
212 attributes and then pass the copy to this argument.
213
213
214 Notes
214 Notes
215 -----
215 -----
216 Subclasses of Component must call the :meth:`__init__` method of
216 Subclasses of Component must call the :meth:`__init__` method of
217 :class:`Component` *before* doing anything else and using
217 :class:`Component` *before* doing anything else and using
218 :func:`super`::
218 :func:`super`::
219
219
220 class MyComponent(Component):
220 class MyComponent(Component):
221 def __init__(self, parent, name=None, config=None):
221 def __init__(self, parent, name=None, config=None):
222 super(MyComponent, self).__init__(parent, name, config)
222 super(MyComponent, self).__init__(parent, name, config)
223 # Then any other code you need to finish initialization.
223 # Then any other code you need to finish initialization.
224
224
225 This ensures that the :attr:`parent`, :attr:`name` and :attr:`config`
225 This ensures that the :attr:`parent`, :attr:`name` and :attr:`config`
226 attributes are handled properly.
226 attributes are handled properly.
227 """
227 """
228 super(Component, self).__init__()
228 super(Component, self).__init__()
229 self._children = []
229 self._children = []
230 if name is None:
230 if name is None:
231 self.name = ComponentNameGenerator()
231 self.name = ComponentNameGenerator()
232 else:
232 else:
233 self.name = name
233 self.name = name
234 self.root = self # This is the default, it is set when parent is set
234 self.root = self # This is the default, it is set when parent is set
235 self.parent = parent
235 self.parent = parent
236 if config is not None:
236 if config is not None:
237 self.config = deepcopy(config)
237 self.config = deepcopy(config)
238 else:
238 else:
239 if self.parent is not None:
239 if self.parent is not None:
240 self.config = deepcopy(self.parent.config)
240 self.config = deepcopy(self.parent.config)
241
241
242 self.created = datetime.datetime.now()
242 self.created = datetime.datetime.now()
243
243
244 #-------------------------------------------------------------------------
244 #-------------------------------------------------------------------------
245 # Static traitlet notifiations
245 # Static traitlet notifiations
246 #-------------------------------------------------------------------------
246 #-------------------------------------------------------------------------
247
247
248 def _parent_changed(self, name, old, new):
248 def _parent_changed(self, name, old, new):
249 if old is not None:
249 if old is not None:
250 old._remove_child(self)
250 old._remove_child(self)
251 if new is not None:
251 if new is not None:
252 new._add_child(self)
252 new._add_child(self)
253
253
254 if new is None:
254 if new is None:
255 self.root = self
255 self.root = self
256 else:
256 else:
257 self.root = new.root
257 self.root = new.root
258
258
259 def _root_changed(self, name, old, new):
259 def _root_changed(self, name, old, new):
260 if self.parent is None:
260 if self.parent is None:
261 if not (new is self):
261 if not (new is self):
262 raise ComponentError("Root not self, but parent is None.")
262 raise ComponentError("Root not self, but parent is None.")
263 else:
263 else:
264 if not self.parent.root is new:
264 if not self.parent.root is new:
265 raise ComponentError("Error in setting the root attribute: "
265 raise ComponentError("Error in setting the root attribute: "
266 "root != parent.root")
266 "root != parent.root")
267
267
268 def _config_changed(self, name, old, new):
268 def _config_changed(self, name, old, new):
269 """Update all the class traits having a config_key with the config.
269 """Update all the class traits having a config_key with the config.
270
270
271 For any class traitlet with a ``config_key`` metadata attribute, we
271 For any class traitlet with a ``config_key`` metadata attribute, we
272 update the traitlet with the value of the corresponding config entry.
272 update the traitlet with the value of the corresponding config entry.
273
273
274 In the future, we might want to do a pop here so stale config info
274 In the future, we might want to do a pop here so stale config info
275 is not passed onto children.
275 is not passed onto children.
276 """
276 """
277 # Get all traitlets with a config_key metadata entry
277 # Get all traitlets with a config metadata entry that is True
278 traitlets = self.traitlets('config_key')
278 traitlets = self.traitlets(config=True)
279 for k, v in traitlets.items():
279
280 try:
280 # Don't do a blind getattr as that would cause the config to
281 config_value = new[v.get_metadata('config_key')]
281 # dynamically create the section with name self.__class__.__name__.
282 except KeyError:
282 if new._has_section(self.__class__.__name__):
283 pass
283 my_config = new[self.__class__.__name__]
284 else:
284 for k, v in traitlets.items():
285 setattr(self, k, config_value)
285 try:
286 config_value = my_config[k]
287 except KeyError:
288 pass
289 else:
290 setattr(self, k, config_value)
286
291
287 @property
292 @property
288 def children(self):
293 def children(self):
289 """A list of all my child components."""
294 """A list of all my child components."""
290 return self._children
295 return self._children
291
296
292 def _remove_child(self, child):
297 def _remove_child(self, child):
293 """A private method for removing children components."""
298 """A private method for removing children components."""
294 if child in self._children:
299 if child in self._children:
295 index = self._children.index(child)
300 index = self._children.index(child)
296 del self._children[index]
301 del self._children[index]
297
302
298 def _add_child(self, child):
303 def _add_child(self, child):
299 """A private method for adding children components."""
304 """A private method for adding children components."""
300 if child not in self._children:
305 if child not in self._children:
301 self._children.append(child)
306 self._children.append(child)
302
307
303 def __repr__(self):
308 def __repr__(self):
304 return "<%s('%s')>" % (self.__class__.__name__, self.name)
309 return "<%s('%s')>" % (self.__class__.__name__, self.name)
@@ -1,72 +1,78 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 """
3 """
4 A context manager for handling sys.displayhook.
4 A context manager for handling sys.displayhook.
5
5
6 Authors:
6 Authors:
7
7
8 * Robert Kern
8 * Robert Kern
9 * Brian Granger
9 * Brian Granger
10 """
10 """
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Copyright (C) 2008-2009 The IPython Development Team
13 # Copyright (C) 2008-2009 The IPython Development Team
14 #
14 #
15 # Distributed under the terms of the BSD License. The full license is in
15 # Distributed under the terms of the BSD License. The full license is in
16 # the file COPYING, distributed as part of this software.
16 # the file COPYING, distributed as part of this software.
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Imports
20 # Imports
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22
22
23 import sys
23 import sys
24
24
25 from IPython.core.component import Component
25 from IPython.core.component import Component
26
26
27 from IPython.utils.autoattr import auto_attr
27 from IPython.utils.autoattr import auto_attr
28
28
29 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
30 # Classes and functions
30 # Classes and functions
31 #-----------------------------------------------------------------------------
31 #-----------------------------------------------------------------------------
32
32
33
33
34 class DisplayTrap(Component):
34 class DisplayTrap(Component):
35 """Object to manage sys.displayhook.
35 """Object to manage sys.displayhook.
36
36
37 This came from IPython.core.kernel.display_hook, but is simplified
37 This came from IPython.core.kernel.display_hook, but is simplified
38 (no callbacks or formatters) until more of the core is refactored.
38 (no callbacks or formatters) until more of the core is refactored.
39 """
39 """
40
40
41 def __init__(self, parent, hook):
41 def __init__(self, parent, hook):
42 super(DisplayTrap, self).__init__(parent, None, None)
42 super(DisplayTrap, self).__init__(parent, None, None)
43
44 self.hook = hook
43 self.hook = hook
45 self.old_hook = None
44 self.old_hook = None
45 # We define this to track if a single BuiltinTrap is nested.
46 # Only turn off the trap when the outermost call to __exit__ is made.
47 self._nested_level = 0
46
48
47 @auto_attr
49 @auto_attr
48 def shell(self):
50 def shell(self):
49 shell = Component.get_instances(
51 shell = Component.get_instances(
50 root=self.root,
52 root=self.root,
51 klass='IPython.core.iplib.InteractiveShell'
53 klass='IPython.core.iplib.InteractiveShell'
52 )[0]
54 )[0]
53 return shell
55 return shell
54
56
55 def __enter__(self):
57 def __enter__(self):
56 self.set()
58 if self._nested_level == 0:
59 self.set()
60 self._nested_level += 1
57 return self
61 return self
58
62
59 def __exit__(self, type, value, traceback):
63 def __exit__(self, type, value, traceback):
60 self.unset()
64 if self._nested_level == 1:
65 self.unset()
66 self._nested_level -= 1
61 return True
67 return True
62
68
63 def set(self):
69 def set(self):
64 """Set the hook."""
70 """Set the hook."""
65 if sys.displayhook is not self.hook:
71 if sys.displayhook is not self.hook:
66 self.old_hook = sys.displayhook
72 self.old_hook = sys.displayhook
67 sys.displayhook = self.hook
73 sys.displayhook = self.hook
68
74
69 def unset(self):
75 def unset(self):
70 """Unset the hook."""
76 """Unset the hook."""
71 sys.displayhook = self.old_hook
77 sys.displayhook = self.old_hook
72
78
@@ -1,268 +1,272 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 """
3 """
4 An embedded IPython shell.
4 An embedded IPython shell.
5
5
6 Authors:
6 Authors:
7
7
8 * Brian Granger
8 * Brian Granger
9 * Fernando Perez
9 * Fernando Perez
10
10
11 Notes
11 Notes
12 -----
12 -----
13 """
13 """
14
14
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 # Copyright (C) 2008-2009 The IPython Development Team
16 # Copyright (C) 2008-2009 The IPython Development Team
17 #
17 #
18 # Distributed under the terms of the BSD License. The full license is in
18 # Distributed under the terms of the BSD License. The full license is in
19 # the file COPYING, distributed as part of this software.
19 # the file COPYING, distributed as part of this software.
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21
21
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23 # Imports
23 # Imports
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25
25
26 from __future__ import with_statement
26 from __future__ import with_statement
27
27
28 import sys
28 import sys
29 from contextlib import nested
29 from contextlib import nested
30
30
31 from IPython.core import ultratb
31 from IPython.core import ultratb
32 from IPython.core.iplib import InteractiveShell
32 from IPython.core.iplib import InteractiveShell
33 from IPython.core.ipapp import load_default_config
33
34
34 from IPython.utils.traitlets import Bool, Str, CBool
35 from IPython.utils.traitlets import Bool, Str, CBool
35 from IPython.utils.genutils import ask_yes_no
36 from IPython.utils.genutils import ask_yes_no
36
37
38
37 #-----------------------------------------------------------------------------
39 #-----------------------------------------------------------------------------
38 # Classes and functions
40 # Classes and functions
39 #-----------------------------------------------------------------------------
41 #-----------------------------------------------------------------------------
40
42
41 # This is an additional magic that is exposed in embedded shells.
43 # This is an additional magic that is exposed in embedded shells.
42 def kill_embedded(self,parameter_s=''):
44 def kill_embedded(self,parameter_s=''):
43 """%kill_embedded : deactivate for good the current embedded IPython.
45 """%kill_embedded : deactivate for good the current embedded IPython.
44
46
45 This function (after asking for confirmation) sets an internal flag so that
47 This function (after asking for confirmation) sets an internal flag so that
46 an embedded IPython will never activate again. This is useful to
48 an embedded IPython will never activate again. This is useful to
47 permanently disable a shell that is being called inside a loop: once you've
49 permanently disable a shell that is being called inside a loop: once you've
48 figured out what you needed from it, you may then kill it and the program
50 figured out what you needed from it, you may then kill it and the program
49 will then continue to run without the interactive shell interfering again.
51 will then continue to run without the interactive shell interfering again.
50 """
52 """
51
53
52 kill = ask_yes_no("Are you sure you want to kill this embedded instance "
54 kill = ask_yes_no("Are you sure you want to kill this embedded instance "
53 "(y/n)? [y/N] ",'n')
55 "(y/n)? [y/N] ",'n')
54 if kill:
56 if kill:
55 self.embedded_active = False
57 self.embedded_active = False
56 print "This embedded IPython will not reactivate anymore once you exit."
58 print "This embedded IPython will not reactivate anymore once you exit."
57
59
58
60
59 class InteractiveShellEmbed(InteractiveShell):
61 class InteractiveShellEmbed(InteractiveShell):
60
62
61 dummy_mode = Bool(False)
63 dummy_mode = Bool(False)
62 exit_msg = Str('')
64 exit_msg = Str('')
63 embedded = CBool(True)
65 embedded = CBool(True)
64 embedded_active = CBool(True)
66 embedded_active = CBool(True)
65
67
66 def __init__(self, parent=None, config=None, ipythondir=None, usage=None,
68 def __init__(self, parent=None, config=None, ipythondir=None, usage=None,
67 user_ns=None, user_global_ns=None,
69 user_ns=None, user_global_ns=None,
68 banner1=None, banner2=None,
70 banner1=None, banner2=None,
69 custom_exceptions=((),None), exit_msg=''):
71 custom_exceptions=((),None), exit_msg=''):
70
72
71 self.save_sys_ipcompleter()
73 self.save_sys_ipcompleter()
72
74
73 super(InteractiveShellEmbed,self).__init__(
75 super(InteractiveShellEmbed,self).__init__(
74 parent=parent, config=config, ipythondir=ipythondir, usage=usage,
76 parent=parent, config=config, ipythondir=ipythondir, usage=usage,
75 user_ns=user_ns, user_global_ns=user_global_ns,
77 user_ns=user_ns, user_global_ns=user_global_ns,
76 banner1=banner1, banner2=banner2,
78 banner1=banner1, banner2=banner2,
77 custom_exceptions=custom_exceptions)
79 custom_exceptions=custom_exceptions)
78
80
79 self.exit_msg = exit_msg
81 self.exit_msg = exit_msg
80 self.define_magic("kill_embedded", kill_embedded)
82 self.define_magic("kill_embedded", kill_embedded)
81
83
82 # don't use the ipython crash handler so that user exceptions aren't
84 # don't use the ipython crash handler so that user exceptions aren't
83 # trapped
85 # trapped
84 sys.excepthook = ultratb.FormattedTB(color_scheme=self.colors,
86 sys.excepthook = ultratb.FormattedTB(color_scheme=self.colors,
85 mode=self.xmode,
87 mode=self.xmode,
86 call_pdb=self.pdb)
88 call_pdb=self.pdb)
87
89
88 self.restore_sys_ipcompleter()
90 self.restore_sys_ipcompleter()
89
91
90 def init_sys_modules(self):
92 def init_sys_modules(self):
91 pass
93 pass
92
94
93 def save_sys_ipcompleter(self):
95 def save_sys_ipcompleter(self):
94 """Save readline completer status."""
96 """Save readline completer status."""
95 try:
97 try:
96 #print 'Save completer',sys.ipcompleter # dbg
98 #print 'Save completer',sys.ipcompleter # dbg
97 self.sys_ipcompleter_orig = sys.ipcompleter
99 self.sys_ipcompleter_orig = sys.ipcompleter
98 except:
100 except:
99 pass # not nested with IPython
101 pass # not nested with IPython
100
102
101 def restore_sys_ipcompleter(self):
103 def restore_sys_ipcompleter(self):
102 """Restores the readline completer which was in place.
104 """Restores the readline completer which was in place.
103
105
104 This allows embedded IPython within IPython not to disrupt the
106 This allows embedded IPython within IPython not to disrupt the
105 parent's completion.
107 parent's completion.
106 """
108 """
107 try:
109 try:
108 self.readline.set_completer(self.sys_ipcompleter_orig)
110 self.readline.set_completer(self.sys_ipcompleter_orig)
109 sys.ipcompleter = self.sys_ipcompleter_orig
111 sys.ipcompleter = self.sys_ipcompleter_orig
110 except:
112 except:
111 pass
113 pass
112
114
113 def __call__(self, header='', local_ns=None, global_ns=None, dummy=None,
115 def __call__(self, header='', local_ns=None, global_ns=None, dummy=None,
114 stack_depth=1):
116 stack_depth=1):
115 """Activate the interactive interpreter.
117 """Activate the interactive interpreter.
116
118
117 __call__(self,header='',local_ns=None,global_ns,dummy=None) -> Start
119 __call__(self,header='',local_ns=None,global_ns,dummy=None) -> Start
118 the interpreter shell with the given local and global namespaces, and
120 the interpreter shell with the given local and global namespaces, and
119 optionally print a header string at startup.
121 optionally print a header string at startup.
120
122
121 The shell can be globally activated/deactivated using the
123 The shell can be globally activated/deactivated using the
122 set/get_dummy_mode methods. This allows you to turn off a shell used
124 set/get_dummy_mode methods. This allows you to turn off a shell used
123 for debugging globally.
125 for debugging globally.
124
126
125 However, *each* time you call the shell you can override the current
127 However, *each* time you call the shell you can override the current
126 state of dummy_mode with the optional keyword parameter 'dummy'. For
128 state of dummy_mode with the optional keyword parameter 'dummy'. For
127 example, if you set dummy mode on with IPShell.set_dummy_mode(1), you
129 example, if you set dummy mode on with IPShell.set_dummy_mode(1), you
128 can still have a specific call work by making it as IPShell(dummy=0).
130 can still have a specific call work by making it as IPShell(dummy=0).
129
131
130 The optional keyword parameter dummy controls whether the call
132 The optional keyword parameter dummy controls whether the call
131 actually does anything.
133 actually does anything.
132 """
134 """
133
135
134 # If the user has turned it off, go away
136 # If the user has turned it off, go away
135 if not self.embedded_active:
137 if not self.embedded_active:
136 return
138 return
137
139
138 # Normal exits from interactive mode set this flag, so the shell can't
140 # Normal exits from interactive mode set this flag, so the shell can't
139 # re-enter (it checks this variable at the start of interactive mode).
141 # re-enter (it checks this variable at the start of interactive mode).
140 self.exit_now = False
142 self.exit_now = False
141
143
142 # Allow the dummy parameter to override the global __dummy_mode
144 # Allow the dummy parameter to override the global __dummy_mode
143 if dummy or (dummy != 0 and self.dummy_mode):
145 if dummy or (dummy != 0 and self.dummy_mode):
144 return
146 return
145
147
146 if self.has_readline:
148 if self.has_readline:
147 self.set_completer()
149 self.set_completer()
148
150
149 if self.banner and header:
151 if self.banner and header:
150 format = '%s\n%s\n'
152 format = '%s\n%s\n'
151 else:
153 else:
152 format = '%s%s\n'
154 format = '%s%s\n'
153 banner = format % (self.banner,header)
155 banner = format % (self.banner,header)
154
156
155 # Call the embedding code with a stack depth of 1 so it can skip over
157 # Call the embedding code with a stack depth of 1 so it can skip over
156 # our call and get the original caller's namespaces.
158 # our call and get the original caller's namespaces.
157 self.mainloop(banner, local_ns, global_ns,
159 self.mainloop(banner, local_ns, global_ns,
158 stack_depth=stack_depth)
160 stack_depth=stack_depth)
159
161
160 if self.exit_msg is not None:
162 if self.exit_msg is not None:
161 print self.exit_msg
163 print self.exit_msg
162
164
163 self.restore_sys_ipcompleter()
165 self.restore_sys_ipcompleter()
164
166
165 def mainloop(self,header='',local_ns=None,global_ns=None,stack_depth=0):
167 def mainloop(self,header='',local_ns=None,global_ns=None,stack_depth=0):
166 """Embeds IPython into a running python program.
168 """Embeds IPython into a running python program.
167
169
168 Input:
170 Input:
169
171
170 - header: An optional header message can be specified.
172 - header: An optional header message can be specified.
171
173
172 - local_ns, global_ns: working namespaces. If given as None, the
174 - local_ns, global_ns: working namespaces. If given as None, the
173 IPython-initialized one is updated with __main__.__dict__, so that
175 IPython-initialized one is updated with __main__.__dict__, so that
174 program variables become visible but user-specific configuration
176 program variables become visible but user-specific configuration
175 remains possible.
177 remains possible.
176
178
177 - stack_depth: specifies how many levels in the stack to go to
179 - stack_depth: specifies how many levels in the stack to go to
178 looking for namespaces (when local_ns and global_ns are None). This
180 looking for namespaces (when local_ns and global_ns are None). This
179 allows an intermediate caller to make sure that this function gets
181 allows an intermediate caller to make sure that this function gets
180 the namespace from the intended level in the stack. By default (0)
182 the namespace from the intended level in the stack. By default (0)
181 it will get its locals and globals from the immediate caller.
183 it will get its locals and globals from the immediate caller.
182
184
183 Warning: it's possible to use this in a program which is being run by
185 Warning: it's possible to use this in a program which is being run by
184 IPython itself (via %run), but some funny things will happen (a few
186 IPython itself (via %run), but some funny things will happen (a few
185 globals get overwritten). In the future this will be cleaned up, as
187 globals get overwritten). In the future this will be cleaned up, as
186 there is no fundamental reason why it can't work perfectly."""
188 there is no fundamental reason why it can't work perfectly."""
187
189
188 # Get locals and globals from caller
190 # Get locals and globals from caller
189 if local_ns is None or global_ns is None:
191 if local_ns is None or global_ns is None:
190 call_frame = sys._getframe(stack_depth).f_back
192 call_frame = sys._getframe(stack_depth).f_back
191
193
192 if local_ns is None:
194 if local_ns is None:
193 local_ns = call_frame.f_locals
195 local_ns = call_frame.f_locals
194 if global_ns is None:
196 if global_ns is None:
195 global_ns = call_frame.f_globals
197 global_ns = call_frame.f_globals
196
198
197 # Update namespaces and fire up interpreter
199 # Update namespaces and fire up interpreter
198
200
199 # The global one is easy, we can just throw it in
201 # The global one is easy, we can just throw it in
200 self.user_global_ns = global_ns
202 self.user_global_ns = global_ns
201
203
202 # but the user/local one is tricky: ipython needs it to store internal
204 # but the user/local one is tricky: ipython needs it to store internal
203 # data, but we also need the locals. We'll copy locals in the user
205 # data, but we also need the locals. We'll copy locals in the user
204 # one, but will track what got copied so we can delete them at exit.
206 # one, but will track what got copied so we can delete them at exit.
205 # This is so that a later embedded call doesn't see locals from a
207 # This is so that a later embedded call doesn't see locals from a
206 # previous call (which most likely existed in a separate scope).
208 # previous call (which most likely existed in a separate scope).
207 local_varnames = local_ns.keys()
209 local_varnames = local_ns.keys()
208 self.user_ns.update(local_ns)
210 self.user_ns.update(local_ns)
209 #self.user_ns['local_ns'] = local_ns # dbg
211 #self.user_ns['local_ns'] = local_ns # dbg
210
212
211 # Patch for global embedding to make sure that things don't overwrite
213 # Patch for global embedding to make sure that things don't overwrite
212 # user globals accidentally. Thanks to Richard <rxe@renre-europe.com>
214 # user globals accidentally. Thanks to Richard <rxe@renre-europe.com>
213 # FIXME. Test this a bit more carefully (the if.. is new)
215 # FIXME. Test this a bit more carefully (the if.. is new)
214 if local_ns is None and global_ns is None:
216 if local_ns is None and global_ns is None:
215 self.user_global_ns.update(__main__.__dict__)
217 self.user_global_ns.update(__main__.__dict__)
216
218
217 # make sure the tab-completer has the correct frame information, so it
219 # make sure the tab-completer has the correct frame information, so it
218 # actually completes using the frame's locals/globals
220 # actually completes using the frame's locals/globals
219 self.set_completer_frame()
221 self.set_completer_frame()
220
222
221 with nested(self.builtin_trap, self.display_trap):
223 with nested(self.builtin_trap, self.display_trap):
222 self.interact(header)
224 self.interact(header)
223
225
224 # now, purge out the user namespace from anything we might have added
226 # now, purge out the user namespace from anything we might have added
225 # from the caller's local namespace
227 # from the caller's local namespace
226 delvar = self.user_ns.pop
228 delvar = self.user_ns.pop
227 for var in local_varnames:
229 for var in local_varnames:
228 delvar(var,None)
230 delvar(var,None)
229
231
230 def set_completer_frame(self, frame=None):
232 def set_completer_frame(self, frame=None):
231 if frame:
233 if frame:
232 self.Completer.namespace = frame.f_locals
234 self.Completer.namespace = frame.f_locals
233 self.Completer.global_namespace = frame.f_globals
235 self.Completer.global_namespace = frame.f_globals
234 else:
236 else:
235 self.Completer.namespace = self.user_ns
237 self.Completer.namespace = self.user_ns
236 self.Completer.global_namespace = self.user_global_ns
238 self.Completer.global_namespace = self.user_global_ns
237
239
238
240
239 _embedded_shell = None
241 _embedded_shell = None
240
242
241
243
242 def embed(header='', config=None, usage=None, banner1=None, banner2=None,
244 def embed(header='', config=None, usage=None, banner1=None, banner2=None,
243 exit_msg=''):
245 exit_msg=''):
244 """Call this to embed IPython at the current point in your program.
246 """Call this to embed IPython at the current point in your program.
245
247
246 The first invocation of this will create an :class:`InteractiveShellEmbed`
248 The first invocation of this will create an :class:`InteractiveShellEmbed`
247 instance and then call it. Consecutive calls just call the already
249 instance and then call it. Consecutive calls just call the already
248 created instance.
250 created instance.
249
251
250 Here is a simple example::
252 Here is a simple example::
251
253
252 from IPython import embed
254 from IPython import embed
253 a = 10
255 a = 10
254 b = 20
256 b = 20
255 embed('First time')
257 embed('First time')
256 c = 30
258 c = 30
257 d = 40
259 d = 40
258 embed
260 embed
259
261
260 Full customization can be done by passing a :class:`Struct` in as the
262 Full customization can be done by passing a :class:`Struct` in as the
261 config argument.
263 config argument.
262 """
264 """
265 if config is None:
266 config = load_default_config()
263 global _embedded_shell
267 global _embedded_shell
264 if _embedded_shell is None:
268 if _embedded_shell is None:
265 _embedded_shell = InteractiveShellEmbed(config=config,
269 _embedded_shell = InteractiveShellEmbed(config=config,
266 usage=usage, banner1=banner1, banner2=banner2, exit_msg=exit_msg)
270 usage=usage, banner1=banner1, banner2=banner2, exit_msg=exit_msg)
267 _embedded_shell(header=header, stack_depth=2)
271 _embedded_shell(header=header, stack_depth=2)
268
272
@@ -1,318 +1,349 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 """
3 """
4 The main IPython application object
4 The main IPython application object
5
5
6 Authors:
6 Authors:
7
7
8 * Brian Granger
8 * Brian Granger
9 * Fernando Perez
9 * Fernando Perez
10
10
11 Notes
11 Notes
12 -----
12 -----
13 """
13 """
14
14
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 # Copyright (C) 2008-2009 The IPython Development Team
16 # Copyright (C) 2008-2009 The IPython Development Team
17 #
17 #
18 # Distributed under the terms of the BSD License. The full license is in
18 # Distributed under the terms of the BSD License. The full license is in
19 # the file COPYING, distributed as part of this software.
19 # the file COPYING, distributed as part of this software.
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21
21
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23 # Imports
23 # Imports
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25
25
26 import os
26 import os
27 import sys
27 import sys
28 import warnings
28 import warnings
29
29
30 from IPython.core.application import Application
30 from IPython.core.application import Application, IPythonArgParseConfigLoader
31 from IPython.core import release
31 from IPython.core import release
32 from IPython.core.iplib import InteractiveShell
32 from IPython.core.iplib import InteractiveShell
33 from IPython.config.loader import IPythonArgParseConfigLoader, NoDefault
33 from IPython.config.loader import (
34 NoConfigDefault,
35 Config,
36 PyFileConfigLoader
37 )
34
38
35 from IPython.utils.ipstruct import Struct
39 from IPython.utils.ipstruct import Struct
36
40 from IPython.utils.genutils import get_ipython_dir
37
41
38 #-----------------------------------------------------------------------------
42 #-----------------------------------------------------------------------------
39 # Utilities and helpers
43 # Utilities and helpers
40 #-----------------------------------------------------------------------------
44 #-----------------------------------------------------------------------------
41
45
42
46
43 ipython_desc = """
47 ipython_desc = """
44 A Python shell with automatic history (input and output), dynamic object
48 A Python shell with automatic history (input and output), dynamic object
45 introspection, easier configuration, command completion, access to the system
49 introspection, easier configuration, command completion, access to the system
46 shell and more.
50 shell and more.
47 """
51 """
48
52
49 def threaded_shell_warning():
53 def threaded_shell_warning():
50 msg = """
54 msg = """
51
55
52 The IPython threaded shells and their associated command line
56 The IPython threaded shells and their associated command line
53 arguments (pylab/wthread/gthread/qthread/q4thread) have been
57 arguments (pylab/wthread/gthread/qthread/q4thread) have been
54 deprecated. See the %gui magic for information on the new interface.
58 deprecated. See the %gui magic for information on the new interface.
55 """
59 """
56 warnings.warn(msg, category=DeprecationWarning, stacklevel=1)
60 warnings.warn(msg, category=DeprecationWarning, stacklevel=1)
57
61
58
62
59 #-----------------------------------------------------------------------------
63 #-----------------------------------------------------------------------------
60 # Main classes and functions
64 # Main classes and functions
61 #-----------------------------------------------------------------------------
65 #-----------------------------------------------------------------------------
62
66
63 cl_args = (
67 cl_args = (
64 (('-autocall',), dict(
68 (('-autocall',), dict(
65 type=int, dest='AUTOCALL', default=NoDefault,
69 type=int, dest='InteractiveShell.autocall', default=NoConfigDefault,
66 help='Set the autocall value (0,1,2).')
70 help='Set the autocall value (0,1,2).',
71 metavar='InteractiveShell.autocall')
67 ),
72 ),
68 (('-autoindent',), dict(
73 (('-autoindent',), dict(
69 action='store_true', dest='AUTOINDENT', default=NoDefault,
74 action='store_true', dest='InteractiveShell.autoindent', default=NoConfigDefault,
70 help='Turn on autoindenting.')
75 help='Turn on autoindenting.')
71 ),
76 ),
72 (('-noautoindent',), dict(
77 (('-noautoindent',), dict(
73 action='store_false', dest='AUTOINDENT', default=NoDefault,
78 action='store_false', dest='InteractiveShell.autoindent', default=NoConfigDefault,
74 help='Turn off autoindenting.')
79 help='Turn off autoindenting.')
75 ),
80 ),
76 (('-automagic',), dict(
81 (('-automagic',), dict(
77 action='store_true', dest='AUTOMAGIC', default=NoDefault,
82 action='store_true', dest='InteractiveShell.automagic', default=NoConfigDefault,
78 help='Turn on the auto calling of magic commands.')
83 help='Turn on the auto calling of magic commands.')
79 ),
84 ),
80 (('-noautomagic',), dict(
85 (('-noautomagic',), dict(
81 action='store_false', dest='AUTOMAGIC', default=NoDefault,
86 action='store_false', dest='InteractiveShell.automagic', default=NoConfigDefault,
82 help='Turn off the auto calling of magic commands.')
87 help='Turn off the auto calling of magic commands.')
83 ),
88 ),
84 (('-autoedit_syntax',), dict(
89 (('-autoedit_syntax',), dict(
85 action='store_true', dest='AUTOEDIT_SYNTAX', default=NoDefault,
90 action='store_true', dest='InteractiveShell.autoedit_syntax', default=NoConfigDefault,
86 help='Turn on auto editing of files with syntax errors.')
91 help='Turn on auto editing of files with syntax errors.')
87 ),
92 ),
88 (('-noautoedit_syntax',), dict(
93 (('-noautoedit_syntax',), dict(
89 action='store_false', dest='AUTOEDIT_SYNTAX', default=NoDefault,
94 action='store_false', dest='InteractiveShell.autoedit_syntax', default=NoConfigDefault,
90 help='Turn off auto editing of files with syntax errors.')
95 help='Turn off auto editing of files with syntax errors.')
91 ),
96 ),
92 (('-banner',), dict(
97 (('-banner',), dict(
93 action='store_true', dest='DISPLAY_BANNER', default=NoDefault,
98 action='store_true', dest='InteractiveShell.display_banner', default=NoConfigDefault,
94 help='Display a banner upon starting IPython.')
99 help='Display a banner upon starting IPython.')
95 ),
100 ),
96 (('-nobanner',), dict(
101 (('-nobanner',), dict(
97 action='store_false', dest='DISPLAY_BANNER', default=NoDefault,
102 action='store_false', dest='InteractiveShell.display_banner', default=NoConfigDefault,
98 help="Don't display a banner upon starting IPython.")
103 help="Don't display a banner upon starting IPython.")
99 ),
104 ),
100 (('-c',), dict(
105 (('-c',), dict(
101 type=str, dest='C', default=NoDefault,
106 type=str, dest='InteractiveShell.c', default=NoConfigDefault,
102 help="Execute the given command string.")
107 help="Execute the given command string.",
108 metavar='InteractiveShell.c')
103 ),
109 ),
104 (('-cache_size',), dict(
110 (('-cache_size',), dict(
105 type=int, dest='CACHE_SIZE', default=NoDefault,
111 type=int, dest='InteractiveShell.cache_size', default=NoConfigDefault,
106 help="Set the size of the output cache.")
112 help="Set the size of the output cache.",
113 metavar='InteractiveShell.cache_size')
107 ),
114 ),
108 (('-classic',), dict(
115 (('-classic',), dict(
109 action='store_true', dest='CLASSIC', default=NoDefault,
116 action='store_true', dest='Global.classic', default=NoConfigDefault,
110 help="Gives IPython a similar feel to the classic Python prompt.")
117 help="Gives IPython a similar feel to the classic Python prompt.")
111 ),
118 ),
112 (('-colors',), dict(
119 (('-colors',), dict(
113 type=str, dest='COLORS', default=NoDefault,
120 type=str, dest='InteractiveShell.colors', default=NoConfigDefault,
114 help="Set the color scheme (NoColor, Linux, and LightBG).")
121 help="Set the color scheme (NoColor, Linux, and LightBG).",
122 metavar='InteractiveShell.colors')
115 ),
123 ),
116 (('-color_info',), dict(
124 (('-color_info',), dict(
117 action='store_true', dest='COLOR_INFO', default=NoDefault,
125 action='store_true', dest='InteractiveShell.color_info', default=NoConfigDefault,
118 help="Enable using colors for info related things.")
126 help="Enable using colors for info related things.")
119 ),
127 ),
120 (('-nocolor_info',), dict(
128 (('-nocolor_info',), dict(
121 action='store_false', dest='COLOR_INFO', default=NoDefault,
129 action='store_false', dest='InteractiveShell.color_info', default=NoConfigDefault,
122 help="Disable using colors for info related things.")
130 help="Disable using colors for info related things.")
123 ),
131 ),
124 (('-confirm_exit',), dict(
132 (('-confirm_exit',), dict(
125 action='store_true', dest='CONFIRM_EXIT', default=NoDefault,
133 action='store_true', dest='InteractiveShell.confirm_exit', default=NoConfigDefault,
126 help="Prompt the user when existing.")
134 help="Prompt the user when existing.")
127 ),
135 ),
128 (('-noconfirm_exit',), dict(
136 (('-noconfirm_exit',), dict(
129 action='store_false', dest='CONFIRM_EXIT', default=NoDefault,
137 action='store_false', dest='InteractiveShell.confirm_exit', default=NoConfigDefault,
130 help="Don't prompt the user when existing.")
138 help="Don't prompt the user when existing.")
131 ),
139 ),
132 (('-deep_reload',), dict(
140 (('-deep_reload',), dict(
133 action='store_true', dest='DEEP_RELOAD', default=NoDefault,
141 action='store_true', dest='InteractiveShell.deep_reload', default=NoConfigDefault,
134 help="Enable deep (recursive) reloading by default.")
142 help="Enable deep (recursive) reloading by default.")
135 ),
143 ),
136 (('-nodeep_reload',), dict(
144 (('-nodeep_reload',), dict(
137 action='store_false', dest='DEEP_RELOAD', default=NoDefault,
145 action='store_false', dest='InteractiveShell.deep_reload', default=NoConfigDefault,
138 help="Disable deep (recursive) reloading by default.")
146 help="Disable deep (recursive) reloading by default.")
139 ),
147 ),
140 (('-editor',), dict(
148 (('-editor',), dict(
141 type=str, dest='EDITOR', default=NoDefault,
149 type=str, dest='InteractiveShell.editor', default=NoConfigDefault,
142 help="Set the editor used by IPython (default to $EDITOR/vi/notepad).")
150 help="Set the editor used by IPython (default to $EDITOR/vi/notepad).",
151 metavar='InteractiveShell.editor')
143 ),
152 ),
144 (('-log','-l'), dict(
153 (('-log','-l'), dict(
145 action='store_true', dest='LOGSTART', default=NoDefault,
154 action='store_true', dest='InteractiveShell.logstart', default=NoConfigDefault,
146 help="Start logging to the default file (./ipython_log.py).")
155 help="Start logging to the default file (./ipython_log.py).")
147 ),
156 ),
148 (('-logfile','-lf'), dict(
157 (('-logfile','-lf'), dict(
149 type=str, dest='LOGFILE', default=NoDefault,
158 type=str, dest='InteractiveShell.logfile', default=NoConfigDefault,
150 help="Specify the name of your logfile.")
159 help="Specify the name of your logfile.",
160 metavar='InteractiveShell.logfile')
151 ),
161 ),
152 (('-logplay','-lp'), dict(
162 (('-logplay','-lp'), dict(
153 type=str, dest='LOGPLAY', default=NoDefault,
163 type=str, dest='InteractiveShell.logplay', default=NoConfigDefault,
154 help="Re-play a log file and then append to it.")
164 help="Re-play a log file and then append to it.",
165 metavar='InteractiveShell.logplay')
155 ),
166 ),
156 (('-pdb',), dict(
167 (('-pdb',), dict(
157 action='store_true', dest='PDB', default=NoDefault,
168 action='store_true', dest='InteractiveShell.pdb', default=NoConfigDefault,
158 help="Enable auto calling the pdb debugger after every exception.")
169 help="Enable auto calling the pdb debugger after every exception.")
159 ),
170 ),
160 (('-nopdb',), dict(
171 (('-nopdb',), dict(
161 action='store_false', dest='PDB', default=NoDefault,
172 action='store_false', dest='InteractiveShell.pdb', default=NoConfigDefault,
162 help="Disable auto calling the pdb debugger after every exception.")
173 help="Disable auto calling the pdb debugger after every exception.")
163 ),
174 ),
164 (('-pprint',), dict(
175 (('-pprint',), dict(
165 action='store_true', dest='PPRINT', default=NoDefault,
176 action='store_true', dest='InteractiveShell.pprint', default=NoConfigDefault,
166 help="Enable auto pretty printing of results.")
177 help="Enable auto pretty printing of results.")
167 ),
178 ),
168 (('-nopprint',), dict(
179 (('-nopprint',), dict(
169 action='store_false', dest='PPRINT', default=NoDefault,
180 action='store_false', dest='InteractiveShell.pprint', default=NoConfigDefault,
170 help="Disable auto auto pretty printing of results.")
181 help="Disable auto auto pretty printing of results.")
171 ),
182 ),
172 (('-prompt_in1','-pi1'), dict(
183 (('-prompt_in1','-pi1'), dict(
173 type=str, dest='PROMPT_IN1', default=NoDefault,
184 type=str, dest='InteractiveShell.prompt_in1', default=NoConfigDefault,
174 help="Set the main input prompt ('In [\#]: ')")
185 help="Set the main input prompt ('In [\#]: ')",
186 metavar='InteractiveShell.prompt_in1')
175 ),
187 ),
176 (('-prompt_in2','-pi2'), dict(
188 (('-prompt_in2','-pi2'), dict(
177 type=str, dest='PROMPT_IN2', default=NoDefault,
189 type=str, dest='InteractiveShell.prompt_in2', default=NoConfigDefault,
178 help="Set the secondary input prompt (' .\D.: ')")
190 help="Set the secondary input prompt (' .\D.: ')",
191 metavar='InteractiveShell.prompt_in2')
179 ),
192 ),
180 (('-prompt_out','-po'), dict(
193 (('-prompt_out','-po'), dict(
181 type=str, dest='PROMPT_OUT', default=NoDefault,
194 type=str, dest='InteractiveShell.prompt_out', default=NoConfigDefault,
182 help="Set the output prompt ('Out[\#]:')")
195 help="Set the output prompt ('Out[\#]:')",
196 metavar='InteractiveShell.prompt_out')
183 ),
197 ),
184 (('-quick',), dict(
198 (('-quick',), dict(
185 action='store_true', dest='QUICK', default=NoDefault,
199 action='store_true', dest='Global.quick', default=NoConfigDefault,
186 help="Enable quick startup with no config files.")
200 help="Enable quick startup with no config files.")
187 ),
201 ),
188 (('-readline',), dict(
202 (('-readline',), dict(
189 action='store_true', dest='READLINE_USE', default=NoDefault,
203 action='store_true', dest='InteractiveShell.readline_use', default=NoConfigDefault,
190 help="Enable readline for command line usage.")
204 help="Enable readline for command line usage.")
191 ),
205 ),
192 (('-noreadline',), dict(
206 (('-noreadline',), dict(
193 action='store_false', dest='READLINE_USE', default=NoDefault,
207 action='store_false', dest='InteractiveShell.readline_use', default=NoConfigDefault,
194 help="Disable readline for command line usage.")
208 help="Disable readline for command line usage.")
195 ),
209 ),
196 (('-screen_length','-sl'), dict(
210 (('-screen_length','-sl'), dict(
197 type=int, dest='SCREEN_LENGTH', default=NoDefault,
211 type=int, dest='InteractiveShell.screen_length', default=NoConfigDefault,
198 help='Number of lines on screen, used to control printing of long strings.')
212 help='Number of lines on screen, used to control printing of long strings.',
213 metavar='InteractiveShell.screen_length')
199 ),
214 ),
200 (('-separate_in','-si'), dict(
215 (('-separate_in','-si'), dict(
201 type=str, dest='SEPARATE_IN', default=NoDefault,
216 type=str, dest='InteractiveShell.separate_in', default=NoConfigDefault,
202 help="Separator before input prompts. Default '\n'.")
217 help="Separator before input prompts. Default '\n'.",
218 metavar='InteractiveShell.separate_in')
203 ),
219 ),
204 (('-separate_out','-so'), dict(
220 (('-separate_out','-so'), dict(
205 type=str, dest='SEPARATE_OUT', default=NoDefault,
221 type=str, dest='InteractiveShell.separate_out', default=NoConfigDefault,
206 help="Separator before output prompts. Default 0 (nothing).")
222 help="Separator before output prompts. Default 0 (nothing).",
223 metavar='InteractiveShell.separate_out')
207 ),
224 ),
208 (('-separate_out2','-so2'), dict(
225 (('-separate_out2','-so2'), dict(
209 type=str, dest='SEPARATE_OUT2', default=NoDefault,
226 type=str, dest='InteractiveShell.separate_out2', default=NoConfigDefault,
210 help="Separator after output prompts. Default 0 (nonight).")
227 help="Separator after output prompts. Default 0 (nonight).",
228 metavar='InteractiveShell.separate_out2')
211 ),
229 ),
212 (('-nosep',), dict(
230 (('-nosep',), dict(
213 action='store_true', dest='NOSEP', default=NoDefault,
231 action='store_true', dest='Global.nosep', default=NoConfigDefault,
214 help="Eliminate all spacing between prompts.")
232 help="Eliminate all spacing between prompts.")
215 ),
233 ),
216 (('-term_title',), dict(
234 (('-term_title',), dict(
217 action='store_true', dest='TERM_TITLE', default=NoDefault,
235 action='store_true', dest='InteractiveShell.term_title', default=NoConfigDefault,
218 help="Enable auto setting the terminal title.")
236 help="Enable auto setting the terminal title.")
219 ),
237 ),
220 (('-noterm_title',), dict(
238 (('-noterm_title',), dict(
221 action='store_false', dest='TERM_TITLE', default=NoDefault,
239 action='store_false', dest='InteractiveShell.term_title', default=NoConfigDefault,
222 help="Disable auto setting the terminal title.")
240 help="Disable auto setting the terminal title.")
223 ),
241 ),
224 (('-xmode',), dict(
242 (('-xmode',), dict(
225 type=str, dest='XMODE', default=NoDefault,
243 type=str, dest='InteractiveShell.xmode', default=NoConfigDefault,
226 help="Exception mode ('Plain','Context','Verbose')")
244 help="Exception mode ('Plain','Context','Verbose')",
245 metavar='InteractiveShell.xmode')
227 ),
246 ),
228 # These are only here to get the proper deprecation warnings
247 # These are only here to get the proper deprecation warnings
229 (('-pylab','-wthread','-qthread','-q4thread','-gthread'), dict(
248 (('-pylab','-wthread','-qthread','-q4thread','-gthread'), dict(
230 action='store_true', dest='THREADED_SHELL', default=NoDefault,
249 action='store_true', dest='Global.threaded_shell', default=NoConfigDefault,
231 help="These command line flags are deprecated, see the 'gui' magic.")
250 help="These command line flags are deprecated, see the 'gui' magic.")
232 ),
251 ),
233 )
252 )
234
253
235
254
236 class IPythonAppCLConfigLoader(IPythonArgParseConfigLoader):
255 class IPythonAppCLConfigLoader(IPythonArgParseConfigLoader):
237
256
238 arguments = cl_args
257 arguments = cl_args
239
258
240
259
260 _default_config_file_name = 'ipython_config.py'
261
241 class IPythonApp(Application):
262 class IPythonApp(Application):
242 name = 'ipython'
263 name = 'ipython'
243 config_file_name = 'ipython_config.py'
264 config_file_name = _default_config_file_name
244
265
245 def create_command_line_config(self):
266 def create_command_line_config(self):
246 """Create and return a command line config loader."""
267 """Create and return a command line config loader."""
247 return IPythonAppCLConfigLoader(
268 return IPythonAppCLConfigLoader(
248 description=ipython_desc,
269 description=ipython_desc,
249 version=release.version)
270 version=release.version)
250
271
251 def post_load_command_line_config(self):
272 def post_load_command_line_config(self):
252 """Do actions after loading cl config."""
273 """Do actions after loading cl config."""
253 clc = self.command_line_config
274 clc = self.command_line_config
254
275
255 # This needs to be set here, the rest are set in pre_construct.
256 if hasattr(clc, 'CLASSIC'):
257 if clc.CLASSIC: clc.QUICK = 1
258
259 # Display the deprecation warnings about threaded shells
276 # Display the deprecation warnings about threaded shells
260 if hasattr(clc, 'THREADED_SHELL'):
277 if hasattr(clc.Global, 'threaded_shell'):
261 threaded_shell_warning()
278 threaded_shell_warning()
262 del clc['THREADED_SHELL']
279 del clc.Global['threaded_shell']
263
280
264 def load_file_config(self):
281 def load_file_config(self):
265 if hasattr(self.command_line_config, 'QUICK'):
282 if hasattr(self.command_line_config.Global, 'quick'):
266 if self.command_line_config.QUICK:
283 if self.command_line_config.Global.quick:
267 self.file_config = Struct()
284 self.file_config = Config()
268 return
285 return
269 super(IPythonApp, self).load_file_config()
286 super(IPythonApp, self).load_file_config()
270
287
271 def post_load_file_config(self):
288 def post_load_file_config(self):
272 """Logic goes here."""
289 """Logic goes here."""
273
290
274 def pre_construct(self):
291 def pre_construct(self):
275 config = self.master_config
292 config = self.master_config
276
293
277 if hasattr(config, 'CLASSIC'):
294 if hasattr(config.Global, 'classic'):
278 if config.CLASSIC:
295 if config.Global.classic:
279 config.QUICK = 1
296 config.InteractiveShell.cache_size = 0
280 config.CACHE_SIZE = 0
297 config.InteractiveShell.pprint = 0
281 config.PPRINT = 0
298 config.InteractiveShell.prompt_in1 = '>>> '
282 config.PROMPT_IN1 = '>>> '
299 config.InteractiveShell.prompt_in2 = '... '
283 config.PROMPT_IN2 = '... '
300 config.InteractiveShell.prompt_out = ''
284 config.PROMPT_OUT = ''
301 config.InteractiveShell.separate_in = \
285 config.SEPARATE_IN = config.SEPARATE_OUT = config.SEPARATE_OUT2 = ''
302 config.InteractiveShell.separate_out = \
286 config.COLORS = 'NoColor'
303 config.InteractiveShell.separate_out2 = ''
287 config.XMODE = 'Plain'
304 config.InteractiveShell.colors = 'NoColor'
305 config.InteractiveShell.xmode = 'Plain'
288
306
289 # All this should be moved to traitlet handlers in InteractiveShell
307 # All this should be moved to traitlet handlers in InteractiveShell
290 # But, currently InteractiveShell doesn't have support for changing
308 # But, currently InteractiveShell doesn't have support for changing
291 # these values at runtime. Once we support that, this should
309 # these values at runtime. Once we support that, this should
292 # be moved there!!!
310 # be moved there!!!
293 if hasattr(config, 'NOSEP'):
311 if hasattr(config.Global, 'nosep'):
294 if config.NOSEP:
312 if config.Global.nosep:
295 config.SEPARATE_IN = config.SEPARATE_OUT = config.SEPARATE_OUT2 = '0'
313 config.InteractiveShell.separate_in = \
314 config.InteractiveShell.separate_out = \
315 config.InteractiveShell.separate_out2 = '0'
296
316
297 def construct(self):
317 def construct(self):
298 # I am a little hesitant to put these into InteractiveShell itself.
318 # I am a little hesitant to put these into InteractiveShell itself.
299 # But that might be the place for them
319 # But that might be the place for them
300 sys.path.insert(0, '')
320 sys.path.insert(0, '')
301 # add personal ipythondir to sys.path so that users can put things in
321 # add personal ipythondir to sys.path so that users can put things in
302 # there for customization
322 # there for customization
303 sys.path.append(os.path.abspath(self.ipythondir))
323 sys.path.append(os.path.abspath(self.ipythondir))
304
324
305 # Create an InteractiveShell instance
325 # Create an InteractiveShell instance
306 self.shell = InteractiveShell(
326 self.shell = InteractiveShell(
307 parent=None,
327 parent=None,
308 config=self.master_config
328 config=self.master_config
309 )
329 )
310 print self.shell
311
330
312 def start_app(self):
331 def start_app(self):
313 self.shell.mainloop()
332 self.shell.mainloop()
314
333
315
334
335 def load_default_config(ipythondir=None):
336 """Load the default config file from the default ipythondir.
337
338 This is useful for embedded shells.
339 """
340 if ipythondir is None:
341 ipythondir = get_ipython_dir()
342 cl = PyFileConfigLoader(_default_config_file_name, ipythondir)
343 config = cl.load_config()
344 return config
345
346
316 if __name__ == '__main__':
347 if __name__ == '__main__':
317 app = IPythonApp()
348 app = IPythonApp()
318 app.start() No newline at end of file
349 app.start()
@@ -1,2506 +1,2503 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 Main IPython Component
3 Main IPython Component
4 """
4 """
5
5
6 #-----------------------------------------------------------------------------
6 #-----------------------------------------------------------------------------
7 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
7 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
8 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
8 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
9 # Copyright (C) 2008-2009 The IPython Development Team
9 # Copyright (C) 2008-2009 The IPython Development Team
10 #
10 #
11 # Distributed under the terms of the BSD License. The full license is in
11 # Distributed under the terms of the BSD License. The full license is in
12 # the file COPYING, distributed as part of this software.
12 # the file COPYING, distributed as part of this software.
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 # Imports
16 # Imports
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 from __future__ import with_statement
19 from __future__ import with_statement
20
20
21 import __main__
21 import __main__
22 import __builtin__
22 import __builtin__
23 import StringIO
23 import StringIO
24 import bdb
24 import bdb
25 import codeop
25 import codeop
26 import exceptions
26 import exceptions
27 import glob
27 import glob
28 import keyword
28 import keyword
29 import new
29 import new
30 import os
30 import os
31 import re
31 import re
32 import shutil
32 import shutil
33 import string
33 import string
34 import sys
34 import sys
35 import tempfile
35 import tempfile
36 from contextlib import nested
36 from contextlib import nested
37
37
38 from IPython.core import ultratb
38 from IPython.core import ultratb
39 from IPython.core import debugger, oinspect
39 from IPython.core import debugger, oinspect
40 from IPython.core import shadowns
40 from IPython.core import shadowns
41 from IPython.core import history as ipcorehist
41 from IPython.core import history as ipcorehist
42 from IPython.core import prefilter
42 from IPython.core import prefilter
43 from IPython.core.alias import AliasManager
43 from IPython.core.alias import AliasManager
44 from IPython.core.autocall import IPyAutocall
44 from IPython.core.autocall import IPyAutocall
45 from IPython.core.builtin_trap import BuiltinTrap
45 from IPython.core.builtin_trap import BuiltinTrap
46 from IPython.core.display_trap import DisplayTrap
46 from IPython.core.display_trap import DisplayTrap
47 from IPython.core.fakemodule import FakeModule, init_fakemod_dict
47 from IPython.core.fakemodule import FakeModule, init_fakemod_dict
48 from IPython.core.logger import Logger
48 from IPython.core.logger import Logger
49 from IPython.core.magic import Magic
49 from IPython.core.magic import Magic
50 from IPython.core.prompts import CachedOutput
50 from IPython.core.prompts import CachedOutput
51 from IPython.core.page import page
51 from IPython.core.page import page
52 from IPython.core.prefilter import PrefilterManager
52 from IPython.core.prefilter import PrefilterManager
53 from IPython.core.component import Component
53 from IPython.core.component import Component
54 from IPython.core.oldusersetup import user_setup
54 from IPython.core.oldusersetup import user_setup
55 from IPython.core.usage import interactive_usage, default_banner
55 from IPython.core.usage import interactive_usage, default_banner
56 from IPython.core.error import TryNext, UsageError
56 from IPython.core.error import TryNext, UsageError
57 from IPython.core.splitinput import split_user_input
57 from IPython.core.splitinput import split_user_input
58
58
59 from IPython.extensions import pickleshare
59 from IPython.extensions import pickleshare
60 from IPython.external.Itpl import ItplNS
60 from IPython.external.Itpl import ItplNS
61 from IPython.lib.backgroundjobs import BackgroundJobManager
61 from IPython.lib.backgroundjobs import BackgroundJobManager
62 from IPython.utils.ipstruct import Struct
62 from IPython.utils.ipstruct import Struct
63 from IPython.utils import PyColorize
63 from IPython.utils import PyColorize
64 from IPython.utils.genutils import *
64 from IPython.utils.genutils import *
65 from IPython.utils.genutils import get_ipython_dir
65 from IPython.utils.strdispatch import StrDispatch
66 from IPython.utils.strdispatch import StrDispatch
66 from IPython.utils.platutils import toggle_set_term_title, set_term_title
67 from IPython.utils.platutils import toggle_set_term_title, set_term_title
67
68
68 # from IPython.utils import growl
69 # from IPython.utils import growl
69 # growl.start("IPython")
70 # growl.start("IPython")
70
71
71 from IPython.utils.traitlets import (
72 from IPython.utils.traitlets import (
72 Int, Float, Str, CBool, CaselessStrEnum, Enum, List, Unicode
73 Int, Float, Str, CBool, CaselessStrEnum, Enum, List, Unicode
73 )
74 )
74
75
75 #-----------------------------------------------------------------------------
76 #-----------------------------------------------------------------------------
76 # Globals
77 # Globals
77 #-----------------------------------------------------------------------------
78 #-----------------------------------------------------------------------------
78
79
79
80
80 # store the builtin raw_input globally, and use this always, in case user code
81 # store the builtin raw_input globally, and use this always, in case user code
81 # overwrites it (like wx.py.PyShell does)
82 # overwrites it (like wx.py.PyShell does)
82 raw_input_original = raw_input
83 raw_input_original = raw_input
83
84
84 # compiled regexps for autoindent management
85 # compiled regexps for autoindent management
85 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
86 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
86
87
87
88
88 #-----------------------------------------------------------------------------
89 #-----------------------------------------------------------------------------
89 # Utilities
90 # Utilities
90 #-----------------------------------------------------------------------------
91 #-----------------------------------------------------------------------------
91
92
92
93
93 ini_spaces_re = re.compile(r'^(\s+)')
94 ini_spaces_re = re.compile(r'^(\s+)')
94
95
95
96
96 def num_ini_spaces(strng):
97 def num_ini_spaces(strng):
97 """Return the number of initial spaces in a string"""
98 """Return the number of initial spaces in a string"""
98
99
99 ini_spaces = ini_spaces_re.match(strng)
100 ini_spaces = ini_spaces_re.match(strng)
100 if ini_spaces:
101 if ini_spaces:
101 return ini_spaces.end()
102 return ini_spaces.end()
102 else:
103 else:
103 return 0
104 return 0
104
105
105
106
106 def softspace(file, newvalue):
107 def softspace(file, newvalue):
107 """Copied from code.py, to remove the dependency"""
108 """Copied from code.py, to remove the dependency"""
108
109
109 oldvalue = 0
110 oldvalue = 0
110 try:
111 try:
111 oldvalue = file.softspace
112 oldvalue = file.softspace
112 except AttributeError:
113 except AttributeError:
113 pass
114 pass
114 try:
115 try:
115 file.softspace = newvalue
116 file.softspace = newvalue
116 except (AttributeError, TypeError):
117 except (AttributeError, TypeError):
117 # "attribute-less object" or "read-only attributes"
118 # "attribute-less object" or "read-only attributes"
118 pass
119 pass
119 return oldvalue
120 return oldvalue
120
121
121
122
122 class SpaceInInput(exceptions.Exception): pass
123 class SpaceInInput(exceptions.Exception): pass
123
124
124 class Bunch: pass
125 class Bunch: pass
125
126
126 class InputList(list):
127 class InputList(list):
127 """Class to store user input.
128 """Class to store user input.
128
129
129 It's basically a list, but slices return a string instead of a list, thus
130 It's basically a list, but slices return a string instead of a list, thus
130 allowing things like (assuming 'In' is an instance):
131 allowing things like (assuming 'In' is an instance):
131
132
132 exec In[4:7]
133 exec In[4:7]
133
134
134 or
135 or
135
136
136 exec In[5:9] + In[14] + In[21:25]"""
137 exec In[5:9] + In[14] + In[21:25]"""
137
138
138 def __getslice__(self,i,j):
139 def __getslice__(self,i,j):
139 return ''.join(list.__getslice__(self,i,j))
140 return ''.join(list.__getslice__(self,i,j))
140
141
141
142
142 class SyntaxTB(ultratb.ListTB):
143 class SyntaxTB(ultratb.ListTB):
143 """Extension which holds some state: the last exception value"""
144 """Extension which holds some state: the last exception value"""
144
145
145 def __init__(self,color_scheme = 'NoColor'):
146 def __init__(self,color_scheme = 'NoColor'):
146 ultratb.ListTB.__init__(self,color_scheme)
147 ultratb.ListTB.__init__(self,color_scheme)
147 self.last_syntax_error = None
148 self.last_syntax_error = None
148
149
149 def __call__(self, etype, value, elist):
150 def __call__(self, etype, value, elist):
150 self.last_syntax_error = value
151 self.last_syntax_error = value
151 ultratb.ListTB.__call__(self,etype,value,elist)
152 ultratb.ListTB.__call__(self,etype,value,elist)
152
153
153 def clear_err_state(self):
154 def clear_err_state(self):
154 """Return the current error state and clear it"""
155 """Return the current error state and clear it"""
155 e = self.last_syntax_error
156 e = self.last_syntax_error
156 self.last_syntax_error = None
157 self.last_syntax_error = None
157 return e
158 return e
158
159
159
160
160 def get_default_editor():
161 def get_default_editor():
161 try:
162 try:
162 ed = os.environ['EDITOR']
163 ed = os.environ['EDITOR']
163 except KeyError:
164 except KeyError:
164 if os.name == 'posix':
165 if os.name == 'posix':
165 ed = 'vi' # the only one guaranteed to be there!
166 ed = 'vi' # the only one guaranteed to be there!
166 else:
167 else:
167 ed = 'notepad' # same in Windows!
168 ed = 'notepad' # same in Windows!
168 return ed
169 return ed
169
170
170
171
171 class SeparateStr(Str):
172 class SeparateStr(Str):
172 """A Str subclass to validate separate_in, separate_out, etc.
173 """A Str subclass to validate separate_in, separate_out, etc.
173
174
174 This is a Str based traitlet that converts '0'->'' and '\\n'->'\n'.
175 This is a Str based traitlet that converts '0'->'' and '\\n'->'\n'.
175 """
176 """
176
177
177 def validate(self, obj, value):
178 def validate(self, obj, value):
178 if value == '0': value = ''
179 if value == '0': value = ''
179 value = value.replace('\\n','\n')
180 value = value.replace('\\n','\n')
180 return super(SeparateStr, self).validate(obj, value)
181 return super(SeparateStr, self).validate(obj, value)
181
182
182
183
183 #-----------------------------------------------------------------------------
184 #-----------------------------------------------------------------------------
184 # Main IPython class
185 # Main IPython class
185 #-----------------------------------------------------------------------------
186 #-----------------------------------------------------------------------------
186
187
187
188
188 class InteractiveShell(Component, Magic):
189 class InteractiveShell(Component, Magic):
189 """An enhanced, interactive shell for Python."""
190 """An enhanced, interactive shell for Python."""
190
191
191 autocall = Enum((0,1,2), config_key='AUTOCALL')
192 autocall = Enum((0,1,2), config=True)
192 autoedit_syntax = CBool(False, config_key='AUTOEDIT_SYNTAX')
193 autoedit_syntax = CBool(False, config=True)
193 autoindent = CBool(True, config_key='AUTOINDENT')
194 autoindent = CBool(True, config=True)
194 automagic = CBool(True, config_key='AUTOMAGIC')
195 automagic = CBool(True, config=True)
195 display_banner = CBool(True, config_key='DISPLAY_BANNER')
196 display_banner = CBool(True, config=True)
196 banner = Str('')
197 banner = Str('')
197 banner1 = Str(default_banner, config_key='BANNER1')
198 banner1 = Str(default_banner, config=True)
198 banner2 = Str('', config_key='BANNER2')
199 banner2 = Str('', config=True)
199 c = Str('', config_key='C')
200 c = Str('', config=True)
200 cache_size = Int(1000, config_key='CACHE_SIZE')
201 cache_size = Int(1000, config=True)
201 classic = CBool(False, config_key='CLASSIC')
202 color_info = CBool(True, config=True)
202 color_info = CBool(True, config_key='COLOR_INFO')
203 colors = CaselessStrEnum(('NoColor','LightBG','Linux'),
203 colors = CaselessStrEnum(('NoColor','LightBG','Linux'),
204 default_value='LightBG', config_key='COLORS')
204 default_value='LightBG', config=True)
205 confirm_exit = CBool(True, config_key='CONFIRM_EXIT')
205 confirm_exit = CBool(True, config=True)
206 debug = CBool(False, config_key='DEBUG')
206 debug = CBool(False, config=True)
207 deep_reload = CBool(False, config_key='DEEP_RELOAD')
207 deep_reload = CBool(False, config=True)
208 embedded = CBool(False)
208 embedded = CBool(False)
209 embedded_active = CBool(False)
209 embedded_active = CBool(False)
210 editor = Str(get_default_editor(), config_key='EDITOR')
210 editor = Str(get_default_editor(), config=True)
211 filename = Str("<ipython console>")
211 filename = Str("<ipython console>")
212 interactive = CBool(False, config_key='INTERACTIVE')
212 interactive = CBool(False, config=True)
213 ipythondir= Unicode('', config_key='IPYTHONDIR') # Set to os.getcwd() in __init__
213 ipythondir= Unicode('', config=True) # Set to get_ipython_dir() in __init__
214 logstart = CBool(False, config_key='LOGSTART')
214 logstart = CBool(False, config=True)
215 logfile = Str('', config_key='LOGFILE')
215 logfile = Str('', config=True)
216 logplay = Str('', config_key='LOGPLAY')
216 logplay = Str('', config=True)
217 object_info_string_level = Enum((0,1,2), default_value=0,
217 object_info_string_level = Enum((0,1,2), default_value=0,
218 config_keys='OBJECT_INFO_STRING_LEVEL')
218 config=True)
219 pager = Str('less', config_key='PAGER')
219 pager = Str('less', config=True)
220 pdb = CBool(False, config_key='PDB')
220 pdb = CBool(False, config=True)
221 pprint = CBool(True, config_key='PPRINT')
221 pprint = CBool(True, config=True)
222 profile = Str('', config_key='PROFILE')
222 profile = Str('', config=True)
223 prompt_in1 = Str('In [\\#]: ', config_key='PROMPT_IN1')
223 prompt_in1 = Str('In [\\#]: ', config=True)
224 prompt_in2 = Str(' .\\D.: ', config_key='PROMPT_IN2')
224 prompt_in2 = Str(' .\\D.: ', config=True)
225 prompt_out = Str('Out[\\#]: ', config_key='PROMPT_OUT1')
225 prompt_out = Str('Out[\\#]: ', config=True)
226 prompts_pad_left = CBool(True, config_key='PROMPTS_PAD_LEFT')
226 prompts_pad_left = CBool(True, config=True)
227 quiet = CBool(False, config_key='QUIET')
227 quiet = CBool(False, config=True)
228
228
229 readline_use = CBool(True, config_key='READLINE_USE')
229 readline_use = CBool(True, config=True)
230 readline_merge_completions = CBool(True,
230 readline_merge_completions = CBool(True, config=True)
231 config_key='READLINE_MERGE_COMPLETIONS')
231 readline_omit__names = Enum((0,1,2), default_value=0, config=True)
232 readline_omit__names = Enum((0,1,2), default_value=0,
232 readline_remove_delims = Str('-/~', config=True)
233 config_key='READLINE_OMIT_NAMES')
234 readline_remove_delims = Str('-/~', config_key='READLINE_REMOVE_DELIMS')
235 readline_parse_and_bind = List([
233 readline_parse_and_bind = List([
236 'tab: complete',
234 'tab: complete',
237 '"\C-l": possible-completions',
235 '"\C-l": possible-completions',
238 'set show-all-if-ambiguous on',
236 'set show-all-if-ambiguous on',
239 '"\C-o": tab-insert',
237 '"\C-o": tab-insert',
240 '"\M-i": " "',
238 '"\M-i": " "',
241 '"\M-o": "\d\d\d\d"',
239 '"\M-o": "\d\d\d\d"',
242 '"\M-I": "\d\d\d\d"',
240 '"\M-I": "\d\d\d\d"',
243 '"\C-r": reverse-search-history',
241 '"\C-r": reverse-search-history',
244 '"\C-s": forward-search-history',
242 '"\C-s": forward-search-history',
245 '"\C-p": history-search-backward',
243 '"\C-p": history-search-backward',
246 '"\C-n": history-search-forward',
244 '"\C-n": history-search-forward',
247 '"\e[A": history-search-backward',
245 '"\e[A": history-search-backward',
248 '"\e[B": history-search-forward',
246 '"\e[B": history-search-forward',
249 '"\C-k": kill-line',
247 '"\C-k": kill-line',
250 '"\C-u": unix-line-discard',
248 '"\C-u": unix-line-discard',
251 ], allow_none=False, config_key='READLINE_PARSE_AND_BIND'
249 ], allow_none=False, config=True)
252 )
253
250
254 screen_length = Int(0, config_key='SCREEN_LENGTH')
251 screen_length = Int(0, config=True)
255
252
256 # Use custom TraitletTypes that convert '0'->'' and '\\n'->'\n'
253 # Use custom TraitletTypes that convert '0'->'' and '\\n'->'\n'
257 separate_in = SeparateStr('\n', config_key='SEPARATE_IN')
254 separate_in = SeparateStr('\n', config=True)
258 separate_out = SeparateStr('', config_key='SEPARATE_OUT')
255 separate_out = SeparateStr('', config=True)
259 separate_out2 = SeparateStr('', config_key='SEPARATE_OUT2')
256 separate_out2 = SeparateStr('', config=True)
260
257
261 system_header = Str('IPython system call: ', config_key='SYSTEM_HEADER')
258 system_header = Str('IPython system call: ', config=True)
262 system_verbose = CBool(False, config_key='SYSTEM_VERBOSE')
259 system_verbose = CBool(False, config=True)
263 term_title = CBool(False, config_key='TERM_TITLE')
260 term_title = CBool(False, config=True)
264 wildcards_case_sensitive = CBool(True, config_key='WILDCARDS_CASE_SENSITIVE')
261 wildcards_case_sensitive = CBool(True, config=True)
265 xmode = CaselessStrEnum(('Context','Plain', 'Verbose'),
262 xmode = CaselessStrEnum(('Context','Plain', 'Verbose'),
266 default_value='Context', config_key='XMODE')
263 default_value='Context', config=True)
267
264
268 alias = List(allow_none=False, config_key='ALIAS')
269 autoexec = List(allow_none=False)
265 autoexec = List(allow_none=False)
270
266
271 # class attribute to indicate whether the class supports threads or not.
267 # class attribute to indicate whether the class supports threads or not.
272 # Subclasses with thread support should override this as needed.
268 # Subclasses with thread support should override this as needed.
273 isthreaded = False
269 isthreaded = False
274
270
275 def __init__(self, parent=None, config=None, ipythondir=None, usage=None,
271 def __init__(self, parent=None, config=None, ipythondir=None, usage=None,
276 user_ns=None, user_global_ns=None,
272 user_ns=None, user_global_ns=None,
277 banner1=None, banner2=None,
273 banner1=None, banner2=None,
278 custom_exceptions=((),None)):
274 custom_exceptions=((),None)):
279
275
280 # This is where traitlets with a config_key argument are updated
276 # This is where traitlets with a config_key argument are updated
281 # from the values on config.
277 # from the values on config.
282 super(InteractiveShell, self).__init__(parent, config=config, name='__IP')
278 super(InteractiveShell, self).__init__(parent, config=config)
283
279
284 # These are relatively independent and stateless
280 # These are relatively independent and stateless
285 self.init_ipythondir(ipythondir)
281 self.init_ipythondir(ipythondir)
286 self.init_instance_attrs()
282 self.init_instance_attrs()
287 self.init_term_title()
283 self.init_term_title()
288 self.init_usage(usage)
284 self.init_usage(usage)
289 self.init_banner(banner1, banner2)
285 self.init_banner(banner1, banner2)
290
286
291 # Create namespaces (user_ns, user_global_ns, alias_table, etc.)
287 # Create namespaces (user_ns, user_global_ns, etc.)
292 self.init_create_namespaces(user_ns, user_global_ns)
288 self.init_create_namespaces(user_ns, user_global_ns)
293 # This has to be done after init_create_namespaces because it uses
289 # This has to be done after init_create_namespaces because it uses
294 # something in self.user_ns, but before init_sys_modules, which
290 # something in self.user_ns, but before init_sys_modules, which
295 # is the first thing to modify sys.
291 # is the first thing to modify sys.
296 self.save_sys_module_state()
292 self.save_sys_module_state()
297 self.init_sys_modules()
293 self.init_sys_modules()
298
294
299 self.init_history()
295 self.init_history()
300 self.init_encoding()
296 self.init_encoding()
301 self.init_prefilter()
297 self.init_prefilter()
302
298
303 Magic.__init__(self, self)
299 Magic.__init__(self, self)
304
300
305 self.init_syntax_highlighting()
301 self.init_syntax_highlighting()
306 self.init_hooks()
302 self.init_hooks()
307 self.init_pushd_popd_magic()
303 self.init_pushd_popd_magic()
308 self.init_traceback_handlers(custom_exceptions)
304 self.init_traceback_handlers(custom_exceptions)
309 self.init_user_ns()
305 self.init_user_ns()
310 self.init_logger()
306 self.init_logger()
311 self.init_alias()
307 self.init_alias()
312 self.init_builtins()
308 self.init_builtins()
313
309
314 # pre_config_initialization
310 # pre_config_initialization
315 self.init_shadow_hist()
311 self.init_shadow_hist()
316
312
317 # The next section should contain averything that was in ipmaker.
313 # The next section should contain averything that was in ipmaker.
318 self.init_logstart()
314 self.init_logstart()
319
315
320 # The following was in post_config_initialization
316 # The following was in post_config_initialization
321 self.init_inspector()
317 self.init_inspector()
322 self.init_readline()
318 self.init_readline()
323 self.init_prompts()
319 self.init_prompts()
324 self.init_displayhook()
320 self.init_displayhook()
325 self.init_reload_doctest()
321 self.init_reload_doctest()
326 self.init_magics()
322 self.init_magics()
327 self.init_pdb()
323 self.init_pdb()
328 self.hooks.late_startup_hook()
324 self.hooks.late_startup_hook()
329
325
326 def get_ipython(self):
327 return self
328
330 #-------------------------------------------------------------------------
329 #-------------------------------------------------------------------------
331 # Traitlet changed handlers
330 # Traitlet changed handlers
332 #-------------------------------------------------------------------------
331 #-------------------------------------------------------------------------
333
332
334 def _banner1_changed(self):
333 def _banner1_changed(self):
335 self.compute_banner()
334 self.compute_banner()
336
335
337 def _banner2_changed(self):
336 def _banner2_changed(self):
338 self.compute_banner()
337 self.compute_banner()
339
338
339 def _ipythondir_changed(self, name, new):
340 if not os.path.isdir(new):
341 os.makedirs(new, mode = 0777)
342
340 @property
343 @property
341 def usable_screen_length(self):
344 def usable_screen_length(self):
342 if self.screen_length == 0:
345 if self.screen_length == 0:
343 return 0
346 return 0
344 else:
347 else:
345 num_lines_bot = self.separate_in.count('\n')+1
348 num_lines_bot = self.separate_in.count('\n')+1
346 return self.screen_length - num_lines_bot
349 return self.screen_length - num_lines_bot
347
350
348 def _term_title_changed(self, name, new_value):
351 def _term_title_changed(self, name, new_value):
349 self.init_term_title()
352 self.init_term_title()
350
353
351 def set_autoindent(self,value=None):
354 def set_autoindent(self,value=None):
352 """Set the autoindent flag, checking for readline support.
355 """Set the autoindent flag, checking for readline support.
353
356
354 If called with no arguments, it acts as a toggle."""
357 If called with no arguments, it acts as a toggle."""
355
358
356 if not self.has_readline:
359 if not self.has_readline:
357 if os.name == 'posix':
360 if os.name == 'posix':
358 warn("The auto-indent feature requires the readline library")
361 warn("The auto-indent feature requires the readline library")
359 self.autoindent = 0
362 self.autoindent = 0
360 return
363 return
361 if value is None:
364 if value is None:
362 self.autoindent = not self.autoindent
365 self.autoindent = not self.autoindent
363 else:
366 else:
364 self.autoindent = value
367 self.autoindent = value
365
368
366 #-------------------------------------------------------------------------
369 #-------------------------------------------------------------------------
367 # init_* methods called by __init__
370 # init_* methods called by __init__
368 #-------------------------------------------------------------------------
371 #-------------------------------------------------------------------------
369
372
370 def init_ipythondir(self, ipythondir):
373 def init_ipythondir(self, ipythondir):
371 if ipythondir is not None:
374 if ipythondir is not None:
372 self.ipythondir = ipythondir
375 self.ipythondir = ipythondir
373 self.config.IPYTHONDIR = self.ipythondir
376 self.config.Global.ipythondir = self.ipythondir
374 return
377 return
375
378
376 if hasattr(self.config, 'IPYTHONDIR'):
379 if hasattr(self.config.Global, 'ipythondir'):
377 self.ipythondir = self.config.IPYTHONDIR
380 self.ipythondir = self.config.Global.ipythondir
378 if not hasattr(self.config, 'IPYTHONDIR'):
381 else:
379 # cdw is always defined
382 self.ipythondir = get_ipython_dir()
380 self.ipythondir = os.getcwd()
381
382 # The caller must make sure that ipythondir exists. We should
383 # probably handle this using a Dir traitlet.
384 if not os.path.isdir(self.ipythondir):
385 raise IOError('IPython dir does not exist: %s' % self.ipythondir)
386
383
387 # All children can just read this
384 # All children can just read this
388 self.config.IPYTHONDIR = self.ipythondir
385 self.config.Global.ipythondir = self.ipythondir
389
386
390 def init_instance_attrs(self):
387 def init_instance_attrs(self):
391 self.jobs = BackgroundJobManager()
388 self.jobs = BackgroundJobManager()
392 self.more = False
389 self.more = False
393
390
394 # command compiler
391 # command compiler
395 self.compile = codeop.CommandCompiler()
392 self.compile = codeop.CommandCompiler()
396
393
397 # User input buffer
394 # User input buffer
398 self.buffer = []
395 self.buffer = []
399
396
400 # Make an empty namespace, which extension writers can rely on both
397 # Make an empty namespace, which extension writers can rely on both
401 # existing and NEVER being used by ipython itself. This gives them a
398 # existing and NEVER being used by ipython itself. This gives them a
402 # convenient location for storing additional information and state
399 # convenient location for storing additional information and state
403 # their extensions may require, without fear of collisions with other
400 # their extensions may require, without fear of collisions with other
404 # ipython names that may develop later.
401 # ipython names that may develop later.
405 self.meta = Struct()
402 self.meta = Struct()
406
403
407 # Object variable to store code object waiting execution. This is
404 # Object variable to store code object waiting execution. This is
408 # used mainly by the multithreaded shells, but it can come in handy in
405 # used mainly by the multithreaded shells, but it can come in handy in
409 # other situations. No need to use a Queue here, since it's a single
406 # other situations. No need to use a Queue here, since it's a single
410 # item which gets cleared once run.
407 # item which gets cleared once run.
411 self.code_to_run = None
408 self.code_to_run = None
412
409
413 # Flag to mark unconditional exit
410 # Flag to mark unconditional exit
414 self.exit_now = False
411 self.exit_now = False
415
412
416 # Temporary files used for various purposes. Deleted at exit.
413 # Temporary files used for various purposes. Deleted at exit.
417 self.tempfiles = []
414 self.tempfiles = []
418
415
419 # Keep track of readline usage (later set by init_readline)
416 # Keep track of readline usage (later set by init_readline)
420 self.has_readline = False
417 self.has_readline = False
421
418
422 # keep track of where we started running (mainly for crash post-mortem)
419 # keep track of where we started running (mainly for crash post-mortem)
423 # This is not being used anywhere currently.
420 # This is not being used anywhere currently.
424 self.starting_dir = os.getcwd()
421 self.starting_dir = os.getcwd()
425
422
426 # Indentation management
423 # Indentation management
427 self.indent_current_nsp = 0
424 self.indent_current_nsp = 0
428
425
429 def init_term_title(self):
426 def init_term_title(self):
430 # Enable or disable the terminal title.
427 # Enable or disable the terminal title.
431 if self.term_title:
428 if self.term_title:
432 toggle_set_term_title(True)
429 toggle_set_term_title(True)
433 set_term_title('IPython: ' + abbrev_cwd())
430 set_term_title('IPython: ' + abbrev_cwd())
434 else:
431 else:
435 toggle_set_term_title(False)
432 toggle_set_term_title(False)
436
433
437 def init_usage(self, usage=None):
434 def init_usage(self, usage=None):
438 if usage is None:
435 if usage is None:
439 self.usage = interactive_usage
436 self.usage = interactive_usage
440 else:
437 else:
441 self.usage = usage
438 self.usage = usage
442
439
443 def init_banner(self, banner1, banner2):
440 def init_banner(self, banner1, banner2):
444 if self.c: # regular python doesn't print the banner with -c
441 if self.c: # regular python doesn't print the banner with -c
445 self.display_banner = False
442 self.display_banner = False
446 if banner1 is not None:
443 if banner1 is not None:
447 self.banner1 = banner1
444 self.banner1 = banner1
448 if banner2 is not None:
445 if banner2 is not None:
449 self.banner2 = banner2
446 self.banner2 = banner2
450 self.compute_banner()
447 self.compute_banner()
451
448
452 def compute_banner(self):
449 def compute_banner(self):
453 self.banner = self.banner1 + '\n'
450 self.banner = self.banner1 + '\n'
454 if self.profile:
451 if self.profile:
455 self.banner += '\nIPython profile: %s\n' % self.profile
452 self.banner += '\nIPython profile: %s\n' % self.profile
456 if self.banner2:
453 if self.banner2:
457 self.banner += '\n' + self.banner2 + '\n'
454 self.banner += '\n' + self.banner2 + '\n'
458
455
459 def init_encoding(self):
456 def init_encoding(self):
460 # Get system encoding at startup time. Certain terminals (like Emacs
457 # Get system encoding at startup time. Certain terminals (like Emacs
461 # under Win32 have it set to None, and we need to have a known valid
458 # under Win32 have it set to None, and we need to have a known valid
462 # encoding to use in the raw_input() method
459 # encoding to use in the raw_input() method
463 try:
460 try:
464 self.stdin_encoding = sys.stdin.encoding or 'ascii'
461 self.stdin_encoding = sys.stdin.encoding or 'ascii'
465 except AttributeError:
462 except AttributeError:
466 self.stdin_encoding = 'ascii'
463 self.stdin_encoding = 'ascii'
467
464
468 def init_syntax_highlighting(self):
465 def init_syntax_highlighting(self):
469 # Python source parser/formatter for syntax highlighting
466 # Python source parser/formatter for syntax highlighting
470 pyformat = PyColorize.Parser().format
467 pyformat = PyColorize.Parser().format
471 self.pycolorize = lambda src: pyformat(src,'str',self.colors)
468 self.pycolorize = lambda src: pyformat(src,'str',self.colors)
472
469
473 def init_pushd_popd_magic(self):
470 def init_pushd_popd_magic(self):
474 # for pushd/popd management
471 # for pushd/popd management
475 try:
472 try:
476 self.home_dir = get_home_dir()
473 self.home_dir = get_home_dir()
477 except HomeDirError, msg:
474 except HomeDirError, msg:
478 fatal(msg)
475 fatal(msg)
479
476
480 self.dir_stack = []
477 self.dir_stack = []
481
478
482 def init_logger(self):
479 def init_logger(self):
483 self.logger = Logger(self, logfname='ipython_log.py', logmode='rotate')
480 self.logger = Logger(self, logfname='ipython_log.py', logmode='rotate')
484 # local shortcut, this is used a LOT
481 # local shortcut, this is used a LOT
485 self.log = self.logger.log
482 self.log = self.logger.log
486 # template for logfile headers. It gets resolved at runtime by the
483 # template for logfile headers. It gets resolved at runtime by the
487 # logstart method.
484 # logstart method.
488 self.loghead_tpl = \
485 self.loghead_tpl = \
489 """#log# Automatic Logger file. *** THIS MUST BE THE FIRST LINE ***
486 """#log# Automatic Logger file. *** THIS MUST BE THE FIRST LINE ***
490 #log# DO NOT CHANGE THIS LINE OR THE TWO BELOW
487 #log# DO NOT CHANGE THIS LINE OR THE TWO BELOW
491 #log# opts = %s
488 #log# opts = %s
492 #log# args = %s
489 #log# args = %s
493 #log# It is safe to make manual edits below here.
490 #log# It is safe to make manual edits below here.
494 #log#-----------------------------------------------------------------------
491 #log#-----------------------------------------------------------------------
495 """
492 """
496
493
497 def init_logstart(self):
494 def init_logstart(self):
498 if self.logplay:
495 if self.logplay:
499 self.magic_logstart(self.logplay + ' append')
496 self.magic_logstart(self.logplay + ' append')
500 elif self.logfile:
497 elif self.logfile:
501 self.magic_logstart(self.logfile)
498 self.magic_logstart(self.logfile)
502 elif self.logstart:
499 elif self.logstart:
503 self.magic_logstart()
500 self.magic_logstart()
504
501
505 def init_builtins(self):
502 def init_builtins(self):
506 self.builtin_trap = BuiltinTrap(self)
503 self.builtin_trap = BuiltinTrap(self)
507
504
508 def init_inspector(self):
505 def init_inspector(self):
509 # Object inspector
506 # Object inspector
510 self.inspector = oinspect.Inspector(oinspect.InspectColors,
507 self.inspector = oinspect.Inspector(oinspect.InspectColors,
511 PyColorize.ANSICodeColors,
508 PyColorize.ANSICodeColors,
512 'NoColor',
509 'NoColor',
513 self.object_info_string_level)
510 self.object_info_string_level)
514
511
515 def init_prompts(self):
512 def init_prompts(self):
516 # Initialize cache, set in/out prompts and printing system
513 # Initialize cache, set in/out prompts and printing system
517 self.outputcache = CachedOutput(self,
514 self.outputcache = CachedOutput(self,
518 self.cache_size,
515 self.cache_size,
519 self.pprint,
516 self.pprint,
520 input_sep = self.separate_in,
517 input_sep = self.separate_in,
521 output_sep = self.separate_out,
518 output_sep = self.separate_out,
522 output_sep2 = self.separate_out2,
519 output_sep2 = self.separate_out2,
523 ps1 = self.prompt_in1,
520 ps1 = self.prompt_in1,
524 ps2 = self.prompt_in2,
521 ps2 = self.prompt_in2,
525 ps_out = self.prompt_out,
522 ps_out = self.prompt_out,
526 pad_left = self.prompts_pad_left)
523 pad_left = self.prompts_pad_left)
527
524
528 # user may have over-ridden the default print hook:
525 # user may have over-ridden the default print hook:
529 try:
526 try:
530 self.outputcache.__class__.display = self.hooks.display
527 self.outputcache.__class__.display = self.hooks.display
531 except AttributeError:
528 except AttributeError:
532 pass
529 pass
533
530
534 def init_displayhook(self):
531 def init_displayhook(self):
535 self.display_trap = DisplayTrap(self, self.outputcache)
532 self.display_trap = DisplayTrap(self, self.outputcache)
536
533
537 def init_reload_doctest(self):
534 def init_reload_doctest(self):
538 # Do a proper resetting of doctest, including the necessary displayhook
535 # Do a proper resetting of doctest, including the necessary displayhook
539 # monkeypatching
536 # monkeypatching
540 try:
537 try:
541 doctest_reload()
538 doctest_reload()
542 except ImportError:
539 except ImportError:
543 warn("doctest module does not exist.")
540 warn("doctest module does not exist.")
544
541
545 #-------------------------------------------------------------------------
542 #-------------------------------------------------------------------------
546 # Things related to injections into the sys module
543 # Things related to injections into the sys module
547 #-------------------------------------------------------------------------
544 #-------------------------------------------------------------------------
548
545
549 def save_sys_module_state(self):
546 def save_sys_module_state(self):
550 """Save the state of hooks in the sys module.
547 """Save the state of hooks in the sys module.
551
548
552 This has to be called after self.user_ns is created.
549 This has to be called after self.user_ns is created.
553 """
550 """
554 self._orig_sys_module_state = {}
551 self._orig_sys_module_state = {}
555 self._orig_sys_module_state['stdin'] = sys.stdin
552 self._orig_sys_module_state['stdin'] = sys.stdin
556 self._orig_sys_module_state['stdout'] = sys.stdout
553 self._orig_sys_module_state['stdout'] = sys.stdout
557 self._orig_sys_module_state['stderr'] = sys.stderr
554 self._orig_sys_module_state['stderr'] = sys.stderr
558 self._orig_sys_module_state['excepthook'] = sys.excepthook
555 self._orig_sys_module_state['excepthook'] = sys.excepthook
559 try:
556 try:
560 self._orig_sys_modules_main_name = self.user_ns['__name__']
557 self._orig_sys_modules_main_name = self.user_ns['__name__']
561 except KeyError:
558 except KeyError:
562 pass
559 pass
563
560
564 def restore_sys_module_state(self):
561 def restore_sys_module_state(self):
565 """Restore the state of the sys module."""
562 """Restore the state of the sys module."""
566 try:
563 try:
567 for k, v in self._orig_sys_module_state.items():
564 for k, v in self._orig_sys_module_state.items():
568 setattr(sys, k, v)
565 setattr(sys, k, v)
569 except AttributeError:
566 except AttributeError:
570 pass
567 pass
571 try:
568 try:
572 delattr(sys, 'ipcompleter')
569 delattr(sys, 'ipcompleter')
573 except AttributeError:
570 except AttributeError:
574 pass
571 pass
575 # Reset what what done in self.init_sys_modules
572 # Reset what what done in self.init_sys_modules
576 try:
573 try:
577 sys.modules[self.user_ns['__name__']] = self._orig_sys_modules_main_name
574 sys.modules[self.user_ns['__name__']] = self._orig_sys_modules_main_name
578 except (AttributeError, KeyError):
575 except (AttributeError, KeyError):
579 pass
576 pass
580
577
581 #-------------------------------------------------------------------------
578 #-------------------------------------------------------------------------
582 # Things related to hooks
579 # Things related to hooks
583 #-------------------------------------------------------------------------
580 #-------------------------------------------------------------------------
584
581
585 def init_hooks(self):
582 def init_hooks(self):
586 # hooks holds pointers used for user-side customizations
583 # hooks holds pointers used for user-side customizations
587 self.hooks = Struct()
584 self.hooks = Struct()
588
585
589 self.strdispatchers = {}
586 self.strdispatchers = {}
590
587
591 # Set all default hooks, defined in the IPython.hooks module.
588 # Set all default hooks, defined in the IPython.hooks module.
592 import IPython.core.hooks
589 import IPython.core.hooks
593 hooks = IPython.core.hooks
590 hooks = IPython.core.hooks
594 for hook_name in hooks.__all__:
591 for hook_name in hooks.__all__:
595 # default hooks have priority 100, i.e. low; user hooks should have
592 # default hooks have priority 100, i.e. low; user hooks should have
596 # 0-100 priority
593 # 0-100 priority
597 self.set_hook(hook_name,getattr(hooks,hook_name), 100)
594 self.set_hook(hook_name,getattr(hooks,hook_name), 100)
598
595
599 def set_hook(self,name,hook, priority = 50, str_key = None, re_key = None):
596 def set_hook(self,name,hook, priority = 50, str_key = None, re_key = None):
600 """set_hook(name,hook) -> sets an internal IPython hook.
597 """set_hook(name,hook) -> sets an internal IPython hook.
601
598
602 IPython exposes some of its internal API as user-modifiable hooks. By
599 IPython exposes some of its internal API as user-modifiable hooks. By
603 adding your function to one of these hooks, you can modify IPython's
600 adding your function to one of these hooks, you can modify IPython's
604 behavior to call at runtime your own routines."""
601 behavior to call at runtime your own routines."""
605
602
606 # At some point in the future, this should validate the hook before it
603 # At some point in the future, this should validate the hook before it
607 # accepts it. Probably at least check that the hook takes the number
604 # accepts it. Probably at least check that the hook takes the number
608 # of args it's supposed to.
605 # of args it's supposed to.
609
606
610 f = new.instancemethod(hook,self,self.__class__)
607 f = new.instancemethod(hook,self,self.__class__)
611
608
612 # check if the hook is for strdispatcher first
609 # check if the hook is for strdispatcher first
613 if str_key is not None:
610 if str_key is not None:
614 sdp = self.strdispatchers.get(name, StrDispatch())
611 sdp = self.strdispatchers.get(name, StrDispatch())
615 sdp.add_s(str_key, f, priority )
612 sdp.add_s(str_key, f, priority )
616 self.strdispatchers[name] = sdp
613 self.strdispatchers[name] = sdp
617 return
614 return
618 if re_key is not None:
615 if re_key is not None:
619 sdp = self.strdispatchers.get(name, StrDispatch())
616 sdp = self.strdispatchers.get(name, StrDispatch())
620 sdp.add_re(re.compile(re_key), f, priority )
617 sdp.add_re(re.compile(re_key), f, priority )
621 self.strdispatchers[name] = sdp
618 self.strdispatchers[name] = sdp
622 return
619 return
623
620
624 dp = getattr(self.hooks, name, None)
621 dp = getattr(self.hooks, name, None)
625 if name not in IPython.core.hooks.__all__:
622 if name not in IPython.core.hooks.__all__:
626 print "Warning! Hook '%s' is not one of %s" % (name, IPython.core.hooks.__all__ )
623 print "Warning! Hook '%s' is not one of %s" % (name, IPython.core.hooks.__all__ )
627 if not dp:
624 if not dp:
628 dp = IPython.core.hooks.CommandChainDispatcher()
625 dp = IPython.core.hooks.CommandChainDispatcher()
629
626
630 try:
627 try:
631 dp.add(f,priority)
628 dp.add(f,priority)
632 except AttributeError:
629 except AttributeError:
633 # it was not commandchain, plain old func - replace
630 # it was not commandchain, plain old func - replace
634 dp = f
631 dp = f
635
632
636 setattr(self.hooks,name, dp)
633 setattr(self.hooks,name, dp)
637
634
638 #-------------------------------------------------------------------------
635 #-------------------------------------------------------------------------
639 # Things related to the "main" module
636 # Things related to the "main" module
640 #-------------------------------------------------------------------------
637 #-------------------------------------------------------------------------
641
638
642 def new_main_mod(self,ns=None):
639 def new_main_mod(self,ns=None):
643 """Return a new 'main' module object for user code execution.
640 """Return a new 'main' module object for user code execution.
644 """
641 """
645 main_mod = self._user_main_module
642 main_mod = self._user_main_module
646 init_fakemod_dict(main_mod,ns)
643 init_fakemod_dict(main_mod,ns)
647 return main_mod
644 return main_mod
648
645
649 def cache_main_mod(self,ns,fname):
646 def cache_main_mod(self,ns,fname):
650 """Cache a main module's namespace.
647 """Cache a main module's namespace.
651
648
652 When scripts are executed via %run, we must keep a reference to the
649 When scripts are executed via %run, we must keep a reference to the
653 namespace of their __main__ module (a FakeModule instance) around so
650 namespace of their __main__ module (a FakeModule instance) around so
654 that Python doesn't clear it, rendering objects defined therein
651 that Python doesn't clear it, rendering objects defined therein
655 useless.
652 useless.
656
653
657 This method keeps said reference in a private dict, keyed by the
654 This method keeps said reference in a private dict, keyed by the
658 absolute path of the module object (which corresponds to the script
655 absolute path of the module object (which corresponds to the script
659 path). This way, for multiple executions of the same script we only
656 path). This way, for multiple executions of the same script we only
660 keep one copy of the namespace (the last one), thus preventing memory
657 keep one copy of the namespace (the last one), thus preventing memory
661 leaks from old references while allowing the objects from the last
658 leaks from old references while allowing the objects from the last
662 execution to be accessible.
659 execution to be accessible.
663
660
664 Note: we can not allow the actual FakeModule instances to be deleted,
661 Note: we can not allow the actual FakeModule instances to be deleted,
665 because of how Python tears down modules (it hard-sets all their
662 because of how Python tears down modules (it hard-sets all their
666 references to None without regard for reference counts). This method
663 references to None without regard for reference counts). This method
667 must therefore make a *copy* of the given namespace, to allow the
664 must therefore make a *copy* of the given namespace, to allow the
668 original module's __dict__ to be cleared and reused.
665 original module's __dict__ to be cleared and reused.
669
666
670
667
671 Parameters
668 Parameters
672 ----------
669 ----------
673 ns : a namespace (a dict, typically)
670 ns : a namespace (a dict, typically)
674
671
675 fname : str
672 fname : str
676 Filename associated with the namespace.
673 Filename associated with the namespace.
677
674
678 Examples
675 Examples
679 --------
676 --------
680
677
681 In [10]: import IPython
678 In [10]: import IPython
682
679
683 In [11]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
680 In [11]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
684
681
685 In [12]: IPython.__file__ in _ip._main_ns_cache
682 In [12]: IPython.__file__ in _ip._main_ns_cache
686 Out[12]: True
683 Out[12]: True
687 """
684 """
688 self._main_ns_cache[os.path.abspath(fname)] = ns.copy()
685 self._main_ns_cache[os.path.abspath(fname)] = ns.copy()
689
686
690 def clear_main_mod_cache(self):
687 def clear_main_mod_cache(self):
691 """Clear the cache of main modules.
688 """Clear the cache of main modules.
692
689
693 Mainly for use by utilities like %reset.
690 Mainly for use by utilities like %reset.
694
691
695 Examples
692 Examples
696 --------
693 --------
697
694
698 In [15]: import IPython
695 In [15]: import IPython
699
696
700 In [16]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
697 In [16]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
701
698
702 In [17]: len(_ip._main_ns_cache) > 0
699 In [17]: len(_ip._main_ns_cache) > 0
703 Out[17]: True
700 Out[17]: True
704
701
705 In [18]: _ip.clear_main_mod_cache()
702 In [18]: _ip.clear_main_mod_cache()
706
703
707 In [19]: len(_ip._main_ns_cache) == 0
704 In [19]: len(_ip._main_ns_cache) == 0
708 Out[19]: True
705 Out[19]: True
709 """
706 """
710 self._main_ns_cache.clear()
707 self._main_ns_cache.clear()
711
708
712 #-------------------------------------------------------------------------
709 #-------------------------------------------------------------------------
713 # Things related to debugging
710 # Things related to debugging
714 #-------------------------------------------------------------------------
711 #-------------------------------------------------------------------------
715
712
716 def init_pdb(self):
713 def init_pdb(self):
717 # Set calling of pdb on exceptions
714 # Set calling of pdb on exceptions
718 # self.call_pdb is a property
715 # self.call_pdb is a property
719 self.call_pdb = self.pdb
716 self.call_pdb = self.pdb
720
717
721 def _get_call_pdb(self):
718 def _get_call_pdb(self):
722 return self._call_pdb
719 return self._call_pdb
723
720
724 def _set_call_pdb(self,val):
721 def _set_call_pdb(self,val):
725
722
726 if val not in (0,1,False,True):
723 if val not in (0,1,False,True):
727 raise ValueError,'new call_pdb value must be boolean'
724 raise ValueError,'new call_pdb value must be boolean'
728
725
729 # store value in instance
726 # store value in instance
730 self._call_pdb = val
727 self._call_pdb = val
731
728
732 # notify the actual exception handlers
729 # notify the actual exception handlers
733 self.InteractiveTB.call_pdb = val
730 self.InteractiveTB.call_pdb = val
734 if self.isthreaded:
731 if self.isthreaded:
735 try:
732 try:
736 self.sys_excepthook.call_pdb = val
733 self.sys_excepthook.call_pdb = val
737 except:
734 except:
738 warn('Failed to activate pdb for threaded exception handler')
735 warn('Failed to activate pdb for threaded exception handler')
739
736
740 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
737 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
741 'Control auto-activation of pdb at exceptions')
738 'Control auto-activation of pdb at exceptions')
742
739
743 def debugger(self,force=False):
740 def debugger(self,force=False):
744 """Call the pydb/pdb debugger.
741 """Call the pydb/pdb debugger.
745
742
746 Keywords:
743 Keywords:
747
744
748 - force(False): by default, this routine checks the instance call_pdb
745 - force(False): by default, this routine checks the instance call_pdb
749 flag and does not actually invoke the debugger if the flag is false.
746 flag and does not actually invoke the debugger if the flag is false.
750 The 'force' option forces the debugger to activate even if the flag
747 The 'force' option forces the debugger to activate even if the flag
751 is false.
748 is false.
752 """
749 """
753
750
754 if not (force or self.call_pdb):
751 if not (force or self.call_pdb):
755 return
752 return
756
753
757 if not hasattr(sys,'last_traceback'):
754 if not hasattr(sys,'last_traceback'):
758 error('No traceback has been produced, nothing to debug.')
755 error('No traceback has been produced, nothing to debug.')
759 return
756 return
760
757
761 # use pydb if available
758 # use pydb if available
762 if debugger.has_pydb:
759 if debugger.has_pydb:
763 from pydb import pm
760 from pydb import pm
764 else:
761 else:
765 # fallback to our internal debugger
762 # fallback to our internal debugger
766 pm = lambda : self.InteractiveTB.debugger(force=True)
763 pm = lambda : self.InteractiveTB.debugger(force=True)
767 self.history_saving_wrapper(pm)()
764 self.history_saving_wrapper(pm)()
768
765
769 #-------------------------------------------------------------------------
766 #-------------------------------------------------------------------------
770 # Things related to IPython's various namespaces
767 # Things related to IPython's various namespaces
771 #-------------------------------------------------------------------------
768 #-------------------------------------------------------------------------
772
769
773 def init_create_namespaces(self, user_ns=None, user_global_ns=None):
770 def init_create_namespaces(self, user_ns=None, user_global_ns=None):
774 # Create the namespace where the user will operate. user_ns is
771 # Create the namespace where the user will operate. user_ns is
775 # normally the only one used, and it is passed to the exec calls as
772 # normally the only one used, and it is passed to the exec calls as
776 # the locals argument. But we do carry a user_global_ns namespace
773 # the locals argument. But we do carry a user_global_ns namespace
777 # given as the exec 'globals' argument, This is useful in embedding
774 # given as the exec 'globals' argument, This is useful in embedding
778 # situations where the ipython shell opens in a context where the
775 # situations where the ipython shell opens in a context where the
779 # distinction between locals and globals is meaningful. For
776 # distinction between locals and globals is meaningful. For
780 # non-embedded contexts, it is just the same object as the user_ns dict.
777 # non-embedded contexts, it is just the same object as the user_ns dict.
781
778
782 # FIXME. For some strange reason, __builtins__ is showing up at user
779 # FIXME. For some strange reason, __builtins__ is showing up at user
783 # level as a dict instead of a module. This is a manual fix, but I
780 # level as a dict instead of a module. This is a manual fix, but I
784 # should really track down where the problem is coming from. Alex
781 # should really track down where the problem is coming from. Alex
785 # Schmolck reported this problem first.
782 # Schmolck reported this problem first.
786
783
787 # A useful post by Alex Martelli on this topic:
784 # A useful post by Alex Martelli on this topic:
788 # Re: inconsistent value from __builtins__
785 # Re: inconsistent value from __builtins__
789 # Von: Alex Martelli <aleaxit@yahoo.com>
786 # Von: Alex Martelli <aleaxit@yahoo.com>
790 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
787 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
791 # Gruppen: comp.lang.python
788 # Gruppen: comp.lang.python
792
789
793 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
790 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
794 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
791 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
795 # > <type 'dict'>
792 # > <type 'dict'>
796 # > >>> print type(__builtins__)
793 # > >>> print type(__builtins__)
797 # > <type 'module'>
794 # > <type 'module'>
798 # > Is this difference in return value intentional?
795 # > Is this difference in return value intentional?
799
796
800 # Well, it's documented that '__builtins__' can be either a dictionary
797 # Well, it's documented that '__builtins__' can be either a dictionary
801 # or a module, and it's been that way for a long time. Whether it's
798 # or a module, and it's been that way for a long time. Whether it's
802 # intentional (or sensible), I don't know. In any case, the idea is
799 # intentional (or sensible), I don't know. In any case, the idea is
803 # that if you need to access the built-in namespace directly, you
800 # that if you need to access the built-in namespace directly, you
804 # should start with "import __builtin__" (note, no 's') which will
801 # should start with "import __builtin__" (note, no 's') which will
805 # definitely give you a module. Yeah, it's somewhat confusing:-(.
802 # definitely give you a module. Yeah, it's somewhat confusing:-(.
806
803
807 # These routines return properly built dicts as needed by the rest of
804 # These routines return properly built dicts as needed by the rest of
808 # the code, and can also be used by extension writers to generate
805 # the code, and can also be used by extension writers to generate
809 # properly initialized namespaces.
806 # properly initialized namespaces.
810 user_ns, user_global_ns = self.make_user_namespaces(user_ns,
807 user_ns, user_global_ns = self.make_user_namespaces(user_ns,
811 user_global_ns)
808 user_global_ns)
812
809
813 # Assign namespaces
810 # Assign namespaces
814 # This is the namespace where all normal user variables live
811 # This is the namespace where all normal user variables live
815 self.user_ns = user_ns
812 self.user_ns = user_ns
816 self.user_global_ns = user_global_ns
813 self.user_global_ns = user_global_ns
817
814
818 # An auxiliary namespace that checks what parts of the user_ns were
815 # An auxiliary namespace that checks what parts of the user_ns were
819 # loaded at startup, so we can list later only variables defined in
816 # loaded at startup, so we can list later only variables defined in
820 # actual interactive use. Since it is always a subset of user_ns, it
817 # actual interactive use. Since it is always a subset of user_ns, it
821 # doesn't need to be seaparately tracked in the ns_table
818 # doesn't need to be seaparately tracked in the ns_table
822 self.user_config_ns = {}
819 self.user_config_ns = {}
823
820
824 # A namespace to keep track of internal data structures to prevent
821 # A namespace to keep track of internal data structures to prevent
825 # them from cluttering user-visible stuff. Will be updated later
822 # them from cluttering user-visible stuff. Will be updated later
826 self.internal_ns = {}
823 self.internal_ns = {}
827
824
828 # Namespace of system aliases. Each entry in the alias
829 # table must be a 2-tuple of the form (N,name), where N is the number
830 # of positional arguments of the alias.
831 self.alias_table = {}
832
833 # Now that FakeModule produces a real module, we've run into a nasty
825 # Now that FakeModule produces a real module, we've run into a nasty
834 # problem: after script execution (via %run), the module where the user
826 # problem: after script execution (via %run), the module where the user
835 # code ran is deleted. Now that this object is a true module (needed
827 # code ran is deleted. Now that this object is a true module (needed
836 # so docetst and other tools work correctly), the Python module
828 # so docetst and other tools work correctly), the Python module
837 # teardown mechanism runs over it, and sets to None every variable
829 # teardown mechanism runs over it, and sets to None every variable
838 # present in that module. Top-level references to objects from the
830 # present in that module. Top-level references to objects from the
839 # script survive, because the user_ns is updated with them. However,
831 # script survive, because the user_ns is updated with them. However,
840 # calling functions defined in the script that use other things from
832 # calling functions defined in the script that use other things from
841 # the script will fail, because the function's closure had references
833 # the script will fail, because the function's closure had references
842 # to the original objects, which are now all None. So we must protect
834 # to the original objects, which are now all None. So we must protect
843 # these modules from deletion by keeping a cache.
835 # these modules from deletion by keeping a cache.
844 #
836 #
845 # To avoid keeping stale modules around (we only need the one from the
837 # To avoid keeping stale modules around (we only need the one from the
846 # last run), we use a dict keyed with the full path to the script, so
838 # last run), we use a dict keyed with the full path to the script, so
847 # only the last version of the module is held in the cache. Note,
839 # only the last version of the module is held in the cache. Note,
848 # however, that we must cache the module *namespace contents* (their
840 # however, that we must cache the module *namespace contents* (their
849 # __dict__). Because if we try to cache the actual modules, old ones
841 # __dict__). Because if we try to cache the actual modules, old ones
850 # (uncached) could be destroyed while still holding references (such as
842 # (uncached) could be destroyed while still holding references (such as
851 # those held by GUI objects that tend to be long-lived)>
843 # those held by GUI objects that tend to be long-lived)>
852 #
844 #
853 # The %reset command will flush this cache. See the cache_main_mod()
845 # The %reset command will flush this cache. See the cache_main_mod()
854 # and clear_main_mod_cache() methods for details on use.
846 # and clear_main_mod_cache() methods for details on use.
855
847
856 # This is the cache used for 'main' namespaces
848 # This is the cache used for 'main' namespaces
857 self._main_ns_cache = {}
849 self._main_ns_cache = {}
858 # And this is the single instance of FakeModule whose __dict__ we keep
850 # And this is the single instance of FakeModule whose __dict__ we keep
859 # copying and clearing for reuse on each %run
851 # copying and clearing for reuse on each %run
860 self._user_main_module = FakeModule()
852 self._user_main_module = FakeModule()
861
853
862 # A table holding all the namespaces IPython deals with, so that
854 # A table holding all the namespaces IPython deals with, so that
863 # introspection facilities can search easily.
855 # introspection facilities can search easily.
864 self.ns_table = {'user':user_ns,
856 self.ns_table = {'user':user_ns,
865 'user_global':user_global_ns,
857 'user_global':user_global_ns,
866 'alias':self.alias_table,
867 'internal':self.internal_ns,
858 'internal':self.internal_ns,
868 'builtin':__builtin__.__dict__
859 'builtin':__builtin__.__dict__
869 }
860 }
870
861
871 # Similarly, track all namespaces where references can be held and that
862 # Similarly, track all namespaces where references can be held and that
872 # we can safely clear (so it can NOT include builtin). This one can be
863 # we can safely clear (so it can NOT include builtin). This one can be
873 # a simple list.
864 # a simple list.
874 self.ns_refs_table = [ user_ns, user_global_ns, self.user_config_ns,
865 self.ns_refs_table = [ user_ns, user_global_ns, self.user_config_ns,
875 self.alias_table, self.internal_ns,
866 self.internal_ns, self._main_ns_cache ]
876 self._main_ns_cache ]
877
867
878 def init_sys_modules(self):
868 def init_sys_modules(self):
879 # We need to insert into sys.modules something that looks like a
869 # We need to insert into sys.modules something that looks like a
880 # module but which accesses the IPython namespace, for shelve and
870 # module but which accesses the IPython namespace, for shelve and
881 # pickle to work interactively. Normally they rely on getting
871 # pickle to work interactively. Normally they rely on getting
882 # everything out of __main__, but for embedding purposes each IPython
872 # everything out of __main__, but for embedding purposes each IPython
883 # instance has its own private namespace, so we can't go shoving
873 # instance has its own private namespace, so we can't go shoving
884 # everything into __main__.
874 # everything into __main__.
885
875
886 # note, however, that we should only do this for non-embedded
876 # note, however, that we should only do this for non-embedded
887 # ipythons, which really mimic the __main__.__dict__ with their own
877 # ipythons, which really mimic the __main__.__dict__ with their own
888 # namespace. Embedded instances, on the other hand, should not do
878 # namespace. Embedded instances, on the other hand, should not do
889 # this because they need to manage the user local/global namespaces
879 # this because they need to manage the user local/global namespaces
890 # only, but they live within a 'normal' __main__ (meaning, they
880 # only, but they live within a 'normal' __main__ (meaning, they
891 # shouldn't overtake the execution environment of the script they're
881 # shouldn't overtake the execution environment of the script they're
892 # embedded in).
882 # embedded in).
893
883
894 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
884 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
895
885
896 try:
886 try:
897 main_name = self.user_ns['__name__']
887 main_name = self.user_ns['__name__']
898 except KeyError:
888 except KeyError:
899 raise KeyError('user_ns dictionary MUST have a "__name__" key')
889 raise KeyError('user_ns dictionary MUST have a "__name__" key')
900 else:
890 else:
901 sys.modules[main_name] = FakeModule(self.user_ns)
891 sys.modules[main_name] = FakeModule(self.user_ns)
902
892
903 def make_user_namespaces(self, user_ns=None, user_global_ns=None):
893 def make_user_namespaces(self, user_ns=None, user_global_ns=None):
904 """Return a valid local and global user interactive namespaces.
894 """Return a valid local and global user interactive namespaces.
905
895
906 This builds a dict with the minimal information needed to operate as a
896 This builds a dict with the minimal information needed to operate as a
907 valid IPython user namespace, which you can pass to the various
897 valid IPython user namespace, which you can pass to the various
908 embedding classes in ipython. The default implementation returns the
898 embedding classes in ipython. The default implementation returns the
909 same dict for both the locals and the globals to allow functions to
899 same dict for both the locals and the globals to allow functions to
910 refer to variables in the namespace. Customized implementations can
900 refer to variables in the namespace. Customized implementations can
911 return different dicts. The locals dictionary can actually be anything
901 return different dicts. The locals dictionary can actually be anything
912 following the basic mapping protocol of a dict, but the globals dict
902 following the basic mapping protocol of a dict, but the globals dict
913 must be a true dict, not even a subclass. It is recommended that any
903 must be a true dict, not even a subclass. It is recommended that any
914 custom object for the locals namespace synchronize with the globals
904 custom object for the locals namespace synchronize with the globals
915 dict somehow.
905 dict somehow.
916
906
917 Raises TypeError if the provided globals namespace is not a true dict.
907 Raises TypeError if the provided globals namespace is not a true dict.
918
908
919 :Parameters:
909 :Parameters:
920 user_ns : dict-like, optional
910 user_ns : dict-like, optional
921 The current user namespace. The items in this namespace should
911 The current user namespace. The items in this namespace should
922 be included in the output. If None, an appropriate blank
912 be included in the output. If None, an appropriate blank
923 namespace should be created.
913 namespace should be created.
924 user_global_ns : dict, optional
914 user_global_ns : dict, optional
925 The current user global namespace. The items in this namespace
915 The current user global namespace. The items in this namespace
926 should be included in the output. If None, an appropriate
916 should be included in the output. If None, an appropriate
927 blank namespace should be created.
917 blank namespace should be created.
928
918
929 :Returns:
919 :Returns:
930 A tuple pair of dictionary-like object to be used as the local namespace
920 A tuple pair of dictionary-like object to be used as the local namespace
931 of the interpreter and a dict to be used as the global namespace.
921 of the interpreter and a dict to be used as the global namespace.
932 """
922 """
933
923
934 if user_ns is None:
924 if user_ns is None:
935 # Set __name__ to __main__ to better match the behavior of the
925 # Set __name__ to __main__ to better match the behavior of the
936 # normal interpreter.
926 # normal interpreter.
937 user_ns = {'__name__' :'__main__',
927 user_ns = {'__name__' :'__main__',
938 '__builtins__' : __builtin__,
928 '__builtins__' : __builtin__,
939 }
929 }
940 else:
930 else:
941 user_ns.setdefault('__name__','__main__')
931 user_ns.setdefault('__name__','__main__')
942 user_ns.setdefault('__builtins__',__builtin__)
932 user_ns.setdefault('__builtins__',__builtin__)
943
933
944 if user_global_ns is None:
934 if user_global_ns is None:
945 user_global_ns = user_ns
935 user_global_ns = user_ns
946 if type(user_global_ns) is not dict:
936 if type(user_global_ns) is not dict:
947 raise TypeError("user_global_ns must be a true dict; got %r"
937 raise TypeError("user_global_ns must be a true dict; got %r"
948 % type(user_global_ns))
938 % type(user_global_ns))
949
939
950 return user_ns, user_global_ns
940 return user_ns, user_global_ns
951
941
952 def init_user_ns(self):
942 def init_user_ns(self):
953 """Initialize all user-visible namespaces to their minimum defaults.
943 """Initialize all user-visible namespaces to their minimum defaults.
954
944
955 Certain history lists are also initialized here, as they effectively
945 Certain history lists are also initialized here, as they effectively
956 act as user namespaces.
946 act as user namespaces.
957
947
958 Notes
948 Notes
959 -----
949 -----
960 All data structures here are only filled in, they are NOT reset by this
950 All data structures here are only filled in, they are NOT reset by this
961 method. If they were not empty before, data will simply be added to
951 method. If they were not empty before, data will simply be added to
962 therm.
952 therm.
963 """
953 """
964 # The user namespace MUST have a pointer to the shell itself.
965 self.user_ns[self.name] = self
966
967 # Store myself as the public api!!!
954 # Store myself as the public api!!!
968 self.user_ns['_ip'] = self
955 self.user_ns['get_ipython'] = self.get_ipython
969
956
970 # make global variables for user access to the histories
957 # make global variables for user access to the histories
971 self.user_ns['_ih'] = self.input_hist
958 self.user_ns['_ih'] = self.input_hist
972 self.user_ns['_oh'] = self.output_hist
959 self.user_ns['_oh'] = self.output_hist
973 self.user_ns['_dh'] = self.dir_hist
960 self.user_ns['_dh'] = self.dir_hist
974
961
975 # user aliases to input and output histories
962 # user aliases to input and output histories
976 self.user_ns['In'] = self.input_hist
963 self.user_ns['In'] = self.input_hist
977 self.user_ns['Out'] = self.output_hist
964 self.user_ns['Out'] = self.output_hist
978
965
979 self.user_ns['_sh'] = shadowns
966 self.user_ns['_sh'] = shadowns
980
967
981 # Put 'help' in the user namespace
968 # Put 'help' in the user namespace
982 try:
969 try:
983 from site import _Helper
970 from site import _Helper
984 self.user_ns['help'] = _Helper()
971 self.user_ns['help'] = _Helper()
985 except ImportError:
972 except ImportError:
986 warn('help() not available - check site.py')
973 warn('help() not available - check site.py')
987
974
988 def reset(self):
975 def reset(self):
989 """Clear all internal namespaces.
976 """Clear all internal namespaces.
990
977
991 Note that this is much more aggressive than %reset, since it clears
978 Note that this is much more aggressive than %reset, since it clears
992 fully all namespaces, as well as all input/output lists.
979 fully all namespaces, as well as all input/output lists.
993 """
980 """
994 for ns in self.ns_refs_table:
981 for ns in self.ns_refs_table:
995 ns.clear()
982 ns.clear()
996
983
984 self.alias_manager.clear_aliases()
985
997 # Clear input and output histories
986 # Clear input and output histories
998 self.input_hist[:] = []
987 self.input_hist[:] = []
999 self.input_hist_raw[:] = []
988 self.input_hist_raw[:] = []
1000 self.output_hist.clear()
989 self.output_hist.clear()
990
1001 # Restore the user namespaces to minimal usability
991 # Restore the user namespaces to minimal usability
1002 self.init_user_ns()
992 self.init_user_ns()
1003
993
994 # Restore the default and user aliases
995 self.alias_manager.init_aliases()
996
1004 def push(self, variables, interactive=True):
997 def push(self, variables, interactive=True):
1005 """Inject a group of variables into the IPython user namespace.
998 """Inject a group of variables into the IPython user namespace.
1006
999
1007 Parameters
1000 Parameters
1008 ----------
1001 ----------
1009 variables : dict, str or list/tuple of str
1002 variables : dict, str or list/tuple of str
1010 The variables to inject into the user's namespace. If a dict,
1003 The variables to inject into the user's namespace. If a dict,
1011 a simple update is done. If a str, the string is assumed to
1004 a simple update is done. If a str, the string is assumed to
1012 have variable names separated by spaces. A list/tuple of str
1005 have variable names separated by spaces. A list/tuple of str
1013 can also be used to give the variable names. If just the variable
1006 can also be used to give the variable names. If just the variable
1014 names are give (list/tuple/str) then the variable values looked
1007 names are give (list/tuple/str) then the variable values looked
1015 up in the callers frame.
1008 up in the callers frame.
1016 interactive : bool
1009 interactive : bool
1017 If True (default), the variables will be listed with the ``who``
1010 If True (default), the variables will be listed with the ``who``
1018 magic.
1011 magic.
1019 """
1012 """
1020 vdict = None
1013 vdict = None
1021
1014
1022 # We need a dict of name/value pairs to do namespace updates.
1015 # We need a dict of name/value pairs to do namespace updates.
1023 if isinstance(variables, dict):
1016 if isinstance(variables, dict):
1024 vdict = variables
1017 vdict = variables
1025 elif isinstance(variables, (basestring, list, tuple)):
1018 elif isinstance(variables, (basestring, list, tuple)):
1026 if isinstance(variables, basestring):
1019 if isinstance(variables, basestring):
1027 vlist = variables.split()
1020 vlist = variables.split()
1028 else:
1021 else:
1029 vlist = variables
1022 vlist = variables
1030 vdict = {}
1023 vdict = {}
1031 cf = sys._getframe(1)
1024 cf = sys._getframe(1)
1032 for name in vlist:
1025 for name in vlist:
1033 try:
1026 try:
1034 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1027 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1035 except:
1028 except:
1036 print ('Could not get variable %s from %s' %
1029 print ('Could not get variable %s from %s' %
1037 (name,cf.f_code.co_name))
1030 (name,cf.f_code.co_name))
1038 else:
1031 else:
1039 raise ValueError('variables must be a dict/str/list/tuple')
1032 raise ValueError('variables must be a dict/str/list/tuple')
1040
1033
1041 # Propagate variables to user namespace
1034 # Propagate variables to user namespace
1042 self.user_ns.update(vdict)
1035 self.user_ns.update(vdict)
1043
1036
1044 # And configure interactive visibility
1037 # And configure interactive visibility
1045 config_ns = self.user_config_ns
1038 config_ns = self.user_config_ns
1046 if interactive:
1039 if interactive:
1047 for name, val in vdict.iteritems():
1040 for name, val in vdict.iteritems():
1048 config_ns.pop(name, None)
1041 config_ns.pop(name, None)
1049 else:
1042 else:
1050 for name,val in vdict.iteritems():
1043 for name,val in vdict.iteritems():
1051 config_ns[name] = val
1044 config_ns[name] = val
1052
1045
1053 #-------------------------------------------------------------------------
1046 #-------------------------------------------------------------------------
1054 # Things related to history management
1047 # Things related to history management
1055 #-------------------------------------------------------------------------
1048 #-------------------------------------------------------------------------
1056
1049
1057 def init_history(self):
1050 def init_history(self):
1058 # List of input with multi-line handling.
1051 # List of input with multi-line handling.
1059 self.input_hist = InputList()
1052 self.input_hist = InputList()
1060 # This one will hold the 'raw' input history, without any
1053 # This one will hold the 'raw' input history, without any
1061 # pre-processing. This will allow users to retrieve the input just as
1054 # pre-processing. This will allow users to retrieve the input just as
1062 # it was exactly typed in by the user, with %hist -r.
1055 # it was exactly typed in by the user, with %hist -r.
1063 self.input_hist_raw = InputList()
1056 self.input_hist_raw = InputList()
1064
1057
1065 # list of visited directories
1058 # list of visited directories
1066 try:
1059 try:
1067 self.dir_hist = [os.getcwd()]
1060 self.dir_hist = [os.getcwd()]
1068 except OSError:
1061 except OSError:
1069 self.dir_hist = []
1062 self.dir_hist = []
1070
1063
1071 # dict of output history
1064 # dict of output history
1072 self.output_hist = {}
1065 self.output_hist = {}
1073
1066
1074 # Now the history file
1067 # Now the history file
1075 try:
1068 try:
1076 histfname = 'history-%s' % self.profile
1069 histfname = 'history-%s' % self.profile
1077 except AttributeError:
1070 except AttributeError:
1078 histfname = 'history'
1071 histfname = 'history'
1079 self.histfile = os.path.join(self.config.IPYTHONDIR, histfname)
1072 self.histfile = os.path.join(self.ipythondir, histfname)
1080
1073
1081 # Fill the history zero entry, user counter starts at 1
1074 # Fill the history zero entry, user counter starts at 1
1082 self.input_hist.append('\n')
1075 self.input_hist.append('\n')
1083 self.input_hist_raw.append('\n')
1076 self.input_hist_raw.append('\n')
1084
1077
1085 def init_shadow_hist(self):
1078 def init_shadow_hist(self):
1086 try:
1079 try:
1087 self.db = pickleshare.PickleShareDB(self.config.IPYTHONDIR + "/db")
1080 self.db = pickleshare.PickleShareDB(self.ipythondir + "/db")
1088 except exceptions.UnicodeDecodeError:
1081 except exceptions.UnicodeDecodeError:
1089 print "Your ipythondir can't be decoded to unicode!"
1082 print "Your ipythondir can't be decoded to unicode!"
1090 print "Please set HOME environment variable to something that"
1083 print "Please set HOME environment variable to something that"
1091 print r"only has ASCII characters, e.g. c:\home"
1084 print r"only has ASCII characters, e.g. c:\home"
1092 print "Now it is", self.config.IPYTHONDIR
1085 print "Now it is", self.ipythondir
1093 sys.exit()
1086 sys.exit()
1094 self.shadowhist = ipcorehist.ShadowHist(self.db)
1087 self.shadowhist = ipcorehist.ShadowHist(self.db)
1095
1088
1096 def savehist(self):
1089 def savehist(self):
1097 """Save input history to a file (via readline library)."""
1090 """Save input history to a file (via readline library)."""
1098
1091
1099 if not self.has_readline:
1092 if not self.has_readline:
1100 return
1093 return
1101
1094
1102 try:
1095 try:
1103 self.readline.write_history_file(self.histfile)
1096 self.readline.write_history_file(self.histfile)
1104 except:
1097 except:
1105 print 'Unable to save IPython command history to file: ' + \
1098 print 'Unable to save IPython command history to file: ' + \
1106 `self.histfile`
1099 `self.histfile`
1107
1100
1108 def reloadhist(self):
1101 def reloadhist(self):
1109 """Reload the input history from disk file."""
1102 """Reload the input history from disk file."""
1110
1103
1111 if self.has_readline:
1104 if self.has_readline:
1112 try:
1105 try:
1113 self.readline.clear_history()
1106 self.readline.clear_history()
1114 self.readline.read_history_file(self.shell.histfile)
1107 self.readline.read_history_file(self.shell.histfile)
1115 except AttributeError:
1108 except AttributeError:
1116 pass
1109 pass
1117
1110
1118 def history_saving_wrapper(self, func):
1111 def history_saving_wrapper(self, func):
1119 """ Wrap func for readline history saving
1112 """ Wrap func for readline history saving
1120
1113
1121 Convert func into callable that saves & restores
1114 Convert func into callable that saves & restores
1122 history around the call """
1115 history around the call """
1123
1116
1124 if not self.has_readline:
1117 if not self.has_readline:
1125 return func
1118 return func
1126
1119
1127 def wrapper():
1120 def wrapper():
1128 self.savehist()
1121 self.savehist()
1129 try:
1122 try:
1130 func()
1123 func()
1131 finally:
1124 finally:
1132 readline.read_history_file(self.histfile)
1125 readline.read_history_file(self.histfile)
1133 return wrapper
1126 return wrapper
1134
1127
1135 #-------------------------------------------------------------------------
1128 #-------------------------------------------------------------------------
1136 # Things related to exception handling and tracebacks (not debugging)
1129 # Things related to exception handling and tracebacks (not debugging)
1137 #-------------------------------------------------------------------------
1130 #-------------------------------------------------------------------------
1138
1131
1139 def init_traceback_handlers(self, custom_exceptions):
1132 def init_traceback_handlers(self, custom_exceptions):
1140 # Syntax error handler.
1133 # Syntax error handler.
1141 self.SyntaxTB = SyntaxTB(color_scheme='NoColor')
1134 self.SyntaxTB = SyntaxTB(color_scheme='NoColor')
1142
1135
1143 # The interactive one is initialized with an offset, meaning we always
1136 # The interactive one is initialized with an offset, meaning we always
1144 # want to remove the topmost item in the traceback, which is our own
1137 # want to remove the topmost item in the traceback, which is our own
1145 # internal code. Valid modes: ['Plain','Context','Verbose']
1138 # internal code. Valid modes: ['Plain','Context','Verbose']
1146 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1139 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1147 color_scheme='NoColor',
1140 color_scheme='NoColor',
1148 tb_offset = 1)
1141 tb_offset = 1)
1149
1142
1150 # IPython itself shouldn't crash. This will produce a detailed
1143 # IPython itself shouldn't crash. This will produce a detailed
1151 # post-mortem if it does. But we only install the crash handler for
1144 # post-mortem if it does. But we only install the crash handler for
1152 # non-threaded shells, the threaded ones use a normal verbose reporter
1145 # non-threaded shells, the threaded ones use a normal verbose reporter
1153 # and lose the crash handler. This is because exceptions in the main
1146 # and lose the crash handler. This is because exceptions in the main
1154 # thread (such as in GUI code) propagate directly to sys.excepthook,
1147 # thread (such as in GUI code) propagate directly to sys.excepthook,
1155 # and there's no point in printing crash dumps for every user exception.
1148 # and there's no point in printing crash dumps for every user exception.
1156 if self.isthreaded:
1149 if self.isthreaded:
1157 ipCrashHandler = ultratb.FormattedTB()
1150 ipCrashHandler = ultratb.FormattedTB()
1158 else:
1151 else:
1159 from IPython.core import crashhandler
1152 from IPython.core import crashhandler
1160 ipCrashHandler = crashhandler.IPythonCrashHandler(self)
1153 ipCrashHandler = crashhandler.IPythonCrashHandler(self)
1161 self.set_crash_handler(ipCrashHandler)
1154 self.set_crash_handler(ipCrashHandler)
1162
1155
1163 # and add any custom exception handlers the user may have specified
1156 # and add any custom exception handlers the user may have specified
1164 self.set_custom_exc(*custom_exceptions)
1157 self.set_custom_exc(*custom_exceptions)
1165
1158
1166 def set_crash_handler(self, crashHandler):
1159 def set_crash_handler(self, crashHandler):
1167 """Set the IPython crash handler.
1160 """Set the IPython crash handler.
1168
1161
1169 This must be a callable with a signature suitable for use as
1162 This must be a callable with a signature suitable for use as
1170 sys.excepthook."""
1163 sys.excepthook."""
1171
1164
1172 # Install the given crash handler as the Python exception hook
1165 # Install the given crash handler as the Python exception hook
1173 sys.excepthook = crashHandler
1166 sys.excepthook = crashHandler
1174
1167
1175 # The instance will store a pointer to this, so that runtime code
1168 # The instance will store a pointer to this, so that runtime code
1176 # (such as magics) can access it. This is because during the
1169 # (such as magics) can access it. This is because during the
1177 # read-eval loop, it gets temporarily overwritten (to deal with GUI
1170 # read-eval loop, it gets temporarily overwritten (to deal with GUI
1178 # frameworks).
1171 # frameworks).
1179 self.sys_excepthook = sys.excepthook
1172 self.sys_excepthook = sys.excepthook
1180
1173
1181 def set_custom_exc(self,exc_tuple,handler):
1174 def set_custom_exc(self,exc_tuple,handler):
1182 """set_custom_exc(exc_tuple,handler)
1175 """set_custom_exc(exc_tuple,handler)
1183
1176
1184 Set a custom exception handler, which will be called if any of the
1177 Set a custom exception handler, which will be called if any of the
1185 exceptions in exc_tuple occur in the mainloop (specifically, in the
1178 exceptions in exc_tuple occur in the mainloop (specifically, in the
1186 runcode() method.
1179 runcode() method.
1187
1180
1188 Inputs:
1181 Inputs:
1189
1182
1190 - exc_tuple: a *tuple* of valid exceptions to call the defined
1183 - exc_tuple: a *tuple* of valid exceptions to call the defined
1191 handler for. It is very important that you use a tuple, and NOT A
1184 handler for. It is very important that you use a tuple, and NOT A
1192 LIST here, because of the way Python's except statement works. If
1185 LIST here, because of the way Python's except statement works. If
1193 you only want to trap a single exception, use a singleton tuple:
1186 you only want to trap a single exception, use a singleton tuple:
1194
1187
1195 exc_tuple == (MyCustomException,)
1188 exc_tuple == (MyCustomException,)
1196
1189
1197 - handler: this must be defined as a function with the following
1190 - handler: this must be defined as a function with the following
1198 basic interface: def my_handler(self,etype,value,tb).
1191 basic interface: def my_handler(self,etype,value,tb).
1199
1192
1200 This will be made into an instance method (via new.instancemethod)
1193 This will be made into an instance method (via new.instancemethod)
1201 of IPython itself, and it will be called if any of the exceptions
1194 of IPython itself, and it will be called if any of the exceptions
1202 listed in the exc_tuple are caught. If the handler is None, an
1195 listed in the exc_tuple are caught. If the handler is None, an
1203 internal basic one is used, which just prints basic info.
1196 internal basic one is used, which just prints basic info.
1204
1197
1205 WARNING: by putting in your own exception handler into IPython's main
1198 WARNING: by putting in your own exception handler into IPython's main
1206 execution loop, you run a very good chance of nasty crashes. This
1199 execution loop, you run a very good chance of nasty crashes. This
1207 facility should only be used if you really know what you are doing."""
1200 facility should only be used if you really know what you are doing."""
1208
1201
1209 assert type(exc_tuple)==type(()) , \
1202 assert type(exc_tuple)==type(()) , \
1210 "The custom exceptions must be given AS A TUPLE."
1203 "The custom exceptions must be given AS A TUPLE."
1211
1204
1212 def dummy_handler(self,etype,value,tb):
1205 def dummy_handler(self,etype,value,tb):
1213 print '*** Simple custom exception handler ***'
1206 print '*** Simple custom exception handler ***'
1214 print 'Exception type :',etype
1207 print 'Exception type :',etype
1215 print 'Exception value:',value
1208 print 'Exception value:',value
1216 print 'Traceback :',tb
1209 print 'Traceback :',tb
1217 print 'Source code :','\n'.join(self.buffer)
1210 print 'Source code :','\n'.join(self.buffer)
1218
1211
1219 if handler is None: handler = dummy_handler
1212 if handler is None: handler = dummy_handler
1220
1213
1221 self.CustomTB = new.instancemethod(handler,self,self.__class__)
1214 self.CustomTB = new.instancemethod(handler,self,self.__class__)
1222 self.custom_exceptions = exc_tuple
1215 self.custom_exceptions = exc_tuple
1223
1216
1224 def excepthook(self, etype, value, tb):
1217 def excepthook(self, etype, value, tb):
1225 """One more defense for GUI apps that call sys.excepthook.
1218 """One more defense for GUI apps that call sys.excepthook.
1226
1219
1227 GUI frameworks like wxPython trap exceptions and call
1220 GUI frameworks like wxPython trap exceptions and call
1228 sys.excepthook themselves. I guess this is a feature that
1221 sys.excepthook themselves. I guess this is a feature that
1229 enables them to keep running after exceptions that would
1222 enables them to keep running after exceptions that would
1230 otherwise kill their mainloop. This is a bother for IPython
1223 otherwise kill their mainloop. This is a bother for IPython
1231 which excepts to catch all of the program exceptions with a try:
1224 which excepts to catch all of the program exceptions with a try:
1232 except: statement.
1225 except: statement.
1233
1226
1234 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1227 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1235 any app directly invokes sys.excepthook, it will look to the user like
1228 any app directly invokes sys.excepthook, it will look to the user like
1236 IPython crashed. In order to work around this, we can disable the
1229 IPython crashed. In order to work around this, we can disable the
1237 CrashHandler and replace it with this excepthook instead, which prints a
1230 CrashHandler and replace it with this excepthook instead, which prints a
1238 regular traceback using our InteractiveTB. In this fashion, apps which
1231 regular traceback using our InteractiveTB. In this fashion, apps which
1239 call sys.excepthook will generate a regular-looking exception from
1232 call sys.excepthook will generate a regular-looking exception from
1240 IPython, and the CrashHandler will only be triggered by real IPython
1233 IPython, and the CrashHandler will only be triggered by real IPython
1241 crashes.
1234 crashes.
1242
1235
1243 This hook should be used sparingly, only in places which are not likely
1236 This hook should be used sparingly, only in places which are not likely
1244 to be true IPython errors.
1237 to be true IPython errors.
1245 """
1238 """
1246 self.showtraceback((etype,value,tb),tb_offset=0)
1239 self.showtraceback((etype,value,tb),tb_offset=0)
1247
1240
1248 def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None):
1241 def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None):
1249 """Display the exception that just occurred.
1242 """Display the exception that just occurred.
1250
1243
1251 If nothing is known about the exception, this is the method which
1244 If nothing is known about the exception, this is the method which
1252 should be used throughout the code for presenting user tracebacks,
1245 should be used throughout the code for presenting user tracebacks,
1253 rather than directly invoking the InteractiveTB object.
1246 rather than directly invoking the InteractiveTB object.
1254
1247
1255 A specific showsyntaxerror() also exists, but this method can take
1248 A specific showsyntaxerror() also exists, but this method can take
1256 care of calling it if needed, so unless you are explicitly catching a
1249 care of calling it if needed, so unless you are explicitly catching a
1257 SyntaxError exception, don't try to analyze the stack manually and
1250 SyntaxError exception, don't try to analyze the stack manually and
1258 simply call this method."""
1251 simply call this method."""
1259
1252
1260
1253
1261 # Though this won't be called by syntax errors in the input line,
1254 # Though this won't be called by syntax errors in the input line,
1262 # there may be SyntaxError cases whith imported code.
1255 # there may be SyntaxError cases whith imported code.
1263
1256
1264 try:
1257 try:
1265 if exc_tuple is None:
1258 if exc_tuple is None:
1266 etype, value, tb = sys.exc_info()
1259 etype, value, tb = sys.exc_info()
1267 else:
1260 else:
1268 etype, value, tb = exc_tuple
1261 etype, value, tb = exc_tuple
1269
1262
1270 if etype is SyntaxError:
1263 if etype is SyntaxError:
1271 self.showsyntaxerror(filename)
1264 self.showsyntaxerror(filename)
1272 elif etype is UsageError:
1265 elif etype is UsageError:
1273 print "UsageError:", value
1266 print "UsageError:", value
1274 else:
1267 else:
1275 # WARNING: these variables are somewhat deprecated and not
1268 # WARNING: these variables are somewhat deprecated and not
1276 # necessarily safe to use in a threaded environment, but tools
1269 # necessarily safe to use in a threaded environment, but tools
1277 # like pdb depend on their existence, so let's set them. If we
1270 # like pdb depend on their existence, so let's set them. If we
1278 # find problems in the field, we'll need to revisit their use.
1271 # find problems in the field, we'll need to revisit their use.
1279 sys.last_type = etype
1272 sys.last_type = etype
1280 sys.last_value = value
1273 sys.last_value = value
1281 sys.last_traceback = tb
1274 sys.last_traceback = tb
1282
1275
1283 if etype in self.custom_exceptions:
1276 if etype in self.custom_exceptions:
1284 self.CustomTB(etype,value,tb)
1277 self.CustomTB(etype,value,tb)
1285 else:
1278 else:
1286 self.InteractiveTB(etype,value,tb,tb_offset=tb_offset)
1279 self.InteractiveTB(etype,value,tb,tb_offset=tb_offset)
1287 if self.InteractiveTB.call_pdb and self.has_readline:
1280 if self.InteractiveTB.call_pdb and self.has_readline:
1288 # pdb mucks up readline, fix it back
1281 # pdb mucks up readline, fix it back
1289 self.set_completer()
1282 self.set_completer()
1290 except KeyboardInterrupt:
1283 except KeyboardInterrupt:
1291 self.write("\nKeyboardInterrupt\n")
1284 self.write("\nKeyboardInterrupt\n")
1292
1285
1293 def showsyntaxerror(self, filename=None):
1286 def showsyntaxerror(self, filename=None):
1294 """Display the syntax error that just occurred.
1287 """Display the syntax error that just occurred.
1295
1288
1296 This doesn't display a stack trace because there isn't one.
1289 This doesn't display a stack trace because there isn't one.
1297
1290
1298 If a filename is given, it is stuffed in the exception instead
1291 If a filename is given, it is stuffed in the exception instead
1299 of what was there before (because Python's parser always uses
1292 of what was there before (because Python's parser always uses
1300 "<string>" when reading from a string).
1293 "<string>" when reading from a string).
1301 """
1294 """
1302 etype, value, last_traceback = sys.exc_info()
1295 etype, value, last_traceback = sys.exc_info()
1303
1296
1304 # See note about these variables in showtraceback() below
1297 # See note about these variables in showtraceback() below
1305 sys.last_type = etype
1298 sys.last_type = etype
1306 sys.last_value = value
1299 sys.last_value = value
1307 sys.last_traceback = last_traceback
1300 sys.last_traceback = last_traceback
1308
1301
1309 if filename and etype is SyntaxError:
1302 if filename and etype is SyntaxError:
1310 # Work hard to stuff the correct filename in the exception
1303 # Work hard to stuff the correct filename in the exception
1311 try:
1304 try:
1312 msg, (dummy_filename, lineno, offset, line) = value
1305 msg, (dummy_filename, lineno, offset, line) = value
1313 except:
1306 except:
1314 # Not the format we expect; leave it alone
1307 # Not the format we expect; leave it alone
1315 pass
1308 pass
1316 else:
1309 else:
1317 # Stuff in the right filename
1310 # Stuff in the right filename
1318 try:
1311 try:
1319 # Assume SyntaxError is a class exception
1312 # Assume SyntaxError is a class exception
1320 value = SyntaxError(msg, (filename, lineno, offset, line))
1313 value = SyntaxError(msg, (filename, lineno, offset, line))
1321 except:
1314 except:
1322 # If that failed, assume SyntaxError is a string
1315 # If that failed, assume SyntaxError is a string
1323 value = msg, (filename, lineno, offset, line)
1316 value = msg, (filename, lineno, offset, line)
1324 self.SyntaxTB(etype,value,[])
1317 self.SyntaxTB(etype,value,[])
1325
1318
1326 def edit_syntax_error(self):
1319 def edit_syntax_error(self):
1327 """The bottom half of the syntax error handler called in the main loop.
1320 """The bottom half of the syntax error handler called in the main loop.
1328
1321
1329 Loop until syntax error is fixed or user cancels.
1322 Loop until syntax error is fixed or user cancels.
1330 """
1323 """
1331
1324
1332 while self.SyntaxTB.last_syntax_error:
1325 while self.SyntaxTB.last_syntax_error:
1333 # copy and clear last_syntax_error
1326 # copy and clear last_syntax_error
1334 err = self.SyntaxTB.clear_err_state()
1327 err = self.SyntaxTB.clear_err_state()
1335 if not self._should_recompile(err):
1328 if not self._should_recompile(err):
1336 return
1329 return
1337 try:
1330 try:
1338 # may set last_syntax_error again if a SyntaxError is raised
1331 # may set last_syntax_error again if a SyntaxError is raised
1339 self.safe_execfile(err.filename,self.user_ns)
1332 self.safe_execfile(err.filename,self.user_ns)
1340 except:
1333 except:
1341 self.showtraceback()
1334 self.showtraceback()
1342 else:
1335 else:
1343 try:
1336 try:
1344 f = file(err.filename)
1337 f = file(err.filename)
1345 try:
1338 try:
1346 # This should be inside a display_trap block and I
1339 # This should be inside a display_trap block and I
1347 # think it is.
1340 # think it is.
1348 sys.displayhook(f.read())
1341 sys.displayhook(f.read())
1349 finally:
1342 finally:
1350 f.close()
1343 f.close()
1351 except:
1344 except:
1352 self.showtraceback()
1345 self.showtraceback()
1353
1346
1354 def _should_recompile(self,e):
1347 def _should_recompile(self,e):
1355 """Utility routine for edit_syntax_error"""
1348 """Utility routine for edit_syntax_error"""
1356
1349
1357 if e.filename in ('<ipython console>','<input>','<string>',
1350 if e.filename in ('<ipython console>','<input>','<string>',
1358 '<console>','<BackgroundJob compilation>',
1351 '<console>','<BackgroundJob compilation>',
1359 None):
1352 None):
1360
1353
1361 return False
1354 return False
1362 try:
1355 try:
1363 if (self.autoedit_syntax and
1356 if (self.autoedit_syntax and
1364 not self.ask_yes_no('Return to editor to correct syntax error? '
1357 not self.ask_yes_no('Return to editor to correct syntax error? '
1365 '[Y/n] ','y')):
1358 '[Y/n] ','y')):
1366 return False
1359 return False
1367 except EOFError:
1360 except EOFError:
1368 return False
1361 return False
1369
1362
1370 def int0(x):
1363 def int0(x):
1371 try:
1364 try:
1372 return int(x)
1365 return int(x)
1373 except TypeError:
1366 except TypeError:
1374 return 0
1367 return 0
1375 # always pass integer line and offset values to editor hook
1368 # always pass integer line and offset values to editor hook
1376 try:
1369 try:
1377 self.hooks.fix_error_editor(e.filename,
1370 self.hooks.fix_error_editor(e.filename,
1378 int0(e.lineno),int0(e.offset),e.msg)
1371 int0(e.lineno),int0(e.offset),e.msg)
1379 except TryNext:
1372 except TryNext:
1380 warn('Could not open editor')
1373 warn('Could not open editor')
1381 return False
1374 return False
1382 return True
1375 return True
1383
1376
1384 #-------------------------------------------------------------------------
1377 #-------------------------------------------------------------------------
1385 # Things related to tab completion
1378 # Things related to tab completion
1386 #-------------------------------------------------------------------------
1379 #-------------------------------------------------------------------------
1387
1380
1388 def complete(self, text):
1381 def complete(self, text):
1389 """Return a sorted list of all possible completions on text.
1382 """Return a sorted list of all possible completions on text.
1390
1383
1391 Inputs:
1384 Inputs:
1392
1385
1393 - text: a string of text to be completed on.
1386 - text: a string of text to be completed on.
1394
1387
1395 This is a wrapper around the completion mechanism, similar to what
1388 This is a wrapper around the completion mechanism, similar to what
1396 readline does at the command line when the TAB key is hit. By
1389 readline does at the command line when the TAB key is hit. By
1397 exposing it as a method, it can be used by other non-readline
1390 exposing it as a method, it can be used by other non-readline
1398 environments (such as GUIs) for text completion.
1391 environments (such as GUIs) for text completion.
1399
1392
1400 Simple usage example:
1393 Simple usage example:
1401
1394
1402 In [7]: x = 'hello'
1395 In [7]: x = 'hello'
1403
1396
1404 In [8]: x
1397 In [8]: x
1405 Out[8]: 'hello'
1398 Out[8]: 'hello'
1406
1399
1407 In [9]: print x
1400 In [9]: print x
1408 hello
1401 hello
1409
1402
1410 In [10]: _ip.complete('x.l')
1403 In [10]: _ip.complete('x.l')
1411 Out[10]: ['x.ljust', 'x.lower', 'x.lstrip']
1404 Out[10]: ['x.ljust', 'x.lower', 'x.lstrip']
1412 """
1405 """
1413
1406
1414 # Inject names into __builtin__ so we can complete on the added names.
1407 # Inject names into __builtin__ so we can complete on the added names.
1415 with self.builtin_trap:
1408 with self.builtin_trap:
1416 complete = self.Completer.complete
1409 complete = self.Completer.complete
1417 state = 0
1410 state = 0
1418 # use a dict so we get unique keys, since ipyhton's multiple
1411 # use a dict so we get unique keys, since ipyhton's multiple
1419 # completers can return duplicates. When we make 2.4 a requirement,
1412 # completers can return duplicates. When we make 2.4 a requirement,
1420 # start using sets instead, which are faster.
1413 # start using sets instead, which are faster.
1421 comps = {}
1414 comps = {}
1422 while True:
1415 while True:
1423 newcomp = complete(text,state,line_buffer=text)
1416 newcomp = complete(text,state,line_buffer=text)
1424 if newcomp is None:
1417 if newcomp is None:
1425 break
1418 break
1426 comps[newcomp] = 1
1419 comps[newcomp] = 1
1427 state += 1
1420 state += 1
1428 outcomps = comps.keys()
1421 outcomps = comps.keys()
1429 outcomps.sort()
1422 outcomps.sort()
1430 #print "T:",text,"OC:",outcomps # dbg
1423 #print "T:",text,"OC:",outcomps # dbg
1431 #print "vars:",self.user_ns.keys()
1424 #print "vars:",self.user_ns.keys()
1432 return outcomps
1425 return outcomps
1433
1426
1434 def set_custom_completer(self,completer,pos=0):
1427 def set_custom_completer(self,completer,pos=0):
1435 """set_custom_completer(completer,pos=0)
1428 """set_custom_completer(completer,pos=0)
1436
1429
1437 Adds a new custom completer function.
1430 Adds a new custom completer function.
1438
1431
1439 The position argument (defaults to 0) is the index in the completers
1432 The position argument (defaults to 0) is the index in the completers
1440 list where you want the completer to be inserted."""
1433 list where you want the completer to be inserted."""
1441
1434
1442 newcomp = new.instancemethod(completer,self.Completer,
1435 newcomp = new.instancemethod(completer,self.Completer,
1443 self.Completer.__class__)
1436 self.Completer.__class__)
1444 self.Completer.matchers.insert(pos,newcomp)
1437 self.Completer.matchers.insert(pos,newcomp)
1445
1438
1446 def set_completer(self):
1439 def set_completer(self):
1447 """reset readline's completer to be our own."""
1440 """reset readline's completer to be our own."""
1448 self.readline.set_completer(self.Completer.complete)
1441 self.readline.set_completer(self.Completer.complete)
1449
1442
1450 #-------------------------------------------------------------------------
1443 #-------------------------------------------------------------------------
1451 # Things related to readline
1444 # Things related to readline
1452 #-------------------------------------------------------------------------
1445 #-------------------------------------------------------------------------
1453
1446
1454 def init_readline(self):
1447 def init_readline(self):
1455 """Command history completion/saving/reloading."""
1448 """Command history completion/saving/reloading."""
1456
1449
1457 self.rl_next_input = None
1450 self.rl_next_input = None
1458 self.rl_do_indent = False
1451 self.rl_do_indent = False
1459
1452
1460 if not self.readline_use:
1453 if not self.readline_use:
1461 return
1454 return
1462
1455
1463 import IPython.utils.rlineimpl as readline
1456 import IPython.utils.rlineimpl as readline
1464
1457
1465 if not readline.have_readline:
1458 if not readline.have_readline:
1466 self.has_readline = 0
1459 self.has_readline = 0
1467 self.readline = None
1460 self.readline = None
1468 # no point in bugging windows users with this every time:
1461 # no point in bugging windows users with this every time:
1469 warn('Readline services not available on this platform.')
1462 warn('Readline services not available on this platform.')
1470 else:
1463 else:
1471 sys.modules['readline'] = readline
1464 sys.modules['readline'] = readline
1472 import atexit
1465 import atexit
1473 from IPython.core.completer import IPCompleter
1466 from IPython.core.completer import IPCompleter
1474 self.Completer = IPCompleter(self,
1467 self.Completer = IPCompleter(self,
1475 self.user_ns,
1468 self.user_ns,
1476 self.user_global_ns,
1469 self.user_global_ns,
1477 self.readline_omit__names,
1470 self.readline_omit__names,
1478 self.alias_table)
1471 self.alias_manager.alias_table)
1479 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
1472 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
1480 self.strdispatchers['complete_command'] = sdisp
1473 self.strdispatchers['complete_command'] = sdisp
1481 self.Completer.custom_completers = sdisp
1474 self.Completer.custom_completers = sdisp
1482 # Platform-specific configuration
1475 # Platform-specific configuration
1483 if os.name == 'nt':
1476 if os.name == 'nt':
1484 self.readline_startup_hook = readline.set_pre_input_hook
1477 self.readline_startup_hook = readline.set_pre_input_hook
1485 else:
1478 else:
1486 self.readline_startup_hook = readline.set_startup_hook
1479 self.readline_startup_hook = readline.set_startup_hook
1487
1480
1488 # Load user's initrc file (readline config)
1481 # Load user's initrc file (readline config)
1489 # Or if libedit is used, load editrc.
1482 # Or if libedit is used, load editrc.
1490 inputrc_name = os.environ.get('INPUTRC')
1483 inputrc_name = os.environ.get('INPUTRC')
1491 if inputrc_name is None:
1484 if inputrc_name is None:
1492 home_dir = get_home_dir()
1485 home_dir = get_home_dir()
1493 if home_dir is not None:
1486 if home_dir is not None:
1494 inputrc_name = '.inputrc'
1487 inputrc_name = '.inputrc'
1495 if readline.uses_libedit:
1488 if readline.uses_libedit:
1496 inputrc_name = '.editrc'
1489 inputrc_name = '.editrc'
1497 inputrc_name = os.path.join(home_dir, inputrc_name)
1490 inputrc_name = os.path.join(home_dir, inputrc_name)
1498 if os.path.isfile(inputrc_name):
1491 if os.path.isfile(inputrc_name):
1499 try:
1492 try:
1500 readline.read_init_file(inputrc_name)
1493 readline.read_init_file(inputrc_name)
1501 except:
1494 except:
1502 warn('Problems reading readline initialization file <%s>'
1495 warn('Problems reading readline initialization file <%s>'
1503 % inputrc_name)
1496 % inputrc_name)
1504
1497
1505 self.has_readline = 1
1498 self.has_readline = 1
1506 self.readline = readline
1499 self.readline = readline
1507 # save this in sys so embedded copies can restore it properly
1500 # save this in sys so embedded copies can restore it properly
1508 sys.ipcompleter = self.Completer.complete
1501 sys.ipcompleter = self.Completer.complete
1509 self.set_completer()
1502 self.set_completer()
1510
1503
1511 # Configure readline according to user's prefs
1504 # Configure readline according to user's prefs
1512 # This is only done if GNU readline is being used. If libedit
1505 # This is only done if GNU readline is being used. If libedit
1513 # is being used (as on Leopard) the readline config is
1506 # is being used (as on Leopard) the readline config is
1514 # not run as the syntax for libedit is different.
1507 # not run as the syntax for libedit is different.
1515 if not readline.uses_libedit:
1508 if not readline.uses_libedit:
1516 for rlcommand in self.readline_parse_and_bind:
1509 for rlcommand in self.readline_parse_and_bind:
1517 #print "loading rl:",rlcommand # dbg
1510 #print "loading rl:",rlcommand # dbg
1518 readline.parse_and_bind(rlcommand)
1511 readline.parse_and_bind(rlcommand)
1519
1512
1520 # Remove some chars from the delimiters list. If we encounter
1513 # Remove some chars from the delimiters list. If we encounter
1521 # unicode chars, discard them.
1514 # unicode chars, discard them.
1522 delims = readline.get_completer_delims().encode("ascii", "ignore")
1515 delims = readline.get_completer_delims().encode("ascii", "ignore")
1523 delims = delims.translate(string._idmap,
1516 delims = delims.translate(string._idmap,
1524 self.readline_remove_delims)
1517 self.readline_remove_delims)
1525 readline.set_completer_delims(delims)
1518 readline.set_completer_delims(delims)
1526 # otherwise we end up with a monster history after a while:
1519 # otherwise we end up with a monster history after a while:
1527 readline.set_history_length(1000)
1520 readline.set_history_length(1000)
1528 try:
1521 try:
1529 #print '*** Reading readline history' # dbg
1522 #print '*** Reading readline history' # dbg
1530 readline.read_history_file(self.histfile)
1523 readline.read_history_file(self.histfile)
1531 except IOError:
1524 except IOError:
1532 pass # It doesn't exist yet.
1525 pass # It doesn't exist yet.
1533
1526
1534 atexit.register(self.atexit_operations)
1527 atexit.register(self.atexit_operations)
1535 del atexit
1528 del atexit
1536
1529
1537 # Configure auto-indent for all platforms
1530 # Configure auto-indent for all platforms
1538 self.set_autoindent(self.autoindent)
1531 self.set_autoindent(self.autoindent)
1539
1532
1540 def set_next_input(self, s):
1533 def set_next_input(self, s):
1541 """ Sets the 'default' input string for the next command line.
1534 """ Sets the 'default' input string for the next command line.
1542
1535
1543 Requires readline.
1536 Requires readline.
1544
1537
1545 Example:
1538 Example:
1546
1539
1547 [D:\ipython]|1> _ip.set_next_input("Hello Word")
1540 [D:\ipython]|1> _ip.set_next_input("Hello Word")
1548 [D:\ipython]|2> Hello Word_ # cursor is here
1541 [D:\ipython]|2> Hello Word_ # cursor is here
1549 """
1542 """
1550
1543
1551 self.rl_next_input = s
1544 self.rl_next_input = s
1552
1545
1553 def pre_readline(self):
1546 def pre_readline(self):
1554 """readline hook to be used at the start of each line.
1547 """readline hook to be used at the start of each line.
1555
1548
1556 Currently it handles auto-indent only."""
1549 Currently it handles auto-indent only."""
1557
1550
1558 #debugx('self.indent_current_nsp','pre_readline:')
1551 #debugx('self.indent_current_nsp','pre_readline:')
1559
1552
1560 if self.rl_do_indent:
1553 if self.rl_do_indent:
1561 self.readline.insert_text(self._indent_current_str())
1554 self.readline.insert_text(self._indent_current_str())
1562 if self.rl_next_input is not None:
1555 if self.rl_next_input is not None:
1563 self.readline.insert_text(self.rl_next_input)
1556 self.readline.insert_text(self.rl_next_input)
1564 self.rl_next_input = None
1557 self.rl_next_input = None
1565
1558
1566 def _indent_current_str(self):
1559 def _indent_current_str(self):
1567 """return the current level of indentation as a string"""
1560 """return the current level of indentation as a string"""
1568 return self.indent_current_nsp * ' '
1561 return self.indent_current_nsp * ' '
1569
1562
1570 #-------------------------------------------------------------------------
1563 #-------------------------------------------------------------------------
1571 # Things related to magics
1564 # Things related to magics
1572 #-------------------------------------------------------------------------
1565 #-------------------------------------------------------------------------
1573
1566
1574 def init_magics(self):
1567 def init_magics(self):
1575 # Set user colors (don't do it in the constructor above so that it
1568 # Set user colors (don't do it in the constructor above so that it
1576 # doesn't crash if colors option is invalid)
1569 # doesn't crash if colors option is invalid)
1577 self.magic_colors(self.colors)
1570 self.magic_colors(self.colors)
1578
1571
1579 def magic(self,arg_s):
1572 def magic(self,arg_s):
1580 """Call a magic function by name.
1573 """Call a magic function by name.
1581
1574
1582 Input: a string containing the name of the magic function to call and any
1575 Input: a string containing the name of the magic function to call and any
1583 additional arguments to be passed to the magic.
1576 additional arguments to be passed to the magic.
1584
1577
1585 magic('name -opt foo bar') is equivalent to typing at the ipython
1578 magic('name -opt foo bar') is equivalent to typing at the ipython
1586 prompt:
1579 prompt:
1587
1580
1588 In[1]: %name -opt foo bar
1581 In[1]: %name -opt foo bar
1589
1582
1590 To call a magic without arguments, simply use magic('name').
1583 To call a magic without arguments, simply use magic('name').
1591
1584
1592 This provides a proper Python function to call IPython's magics in any
1585 This provides a proper Python function to call IPython's magics in any
1593 valid Python code you can type at the interpreter, including loops and
1586 valid Python code you can type at the interpreter, including loops and
1594 compound statements.
1587 compound statements.
1595 """
1588 """
1596
1589
1597 args = arg_s.split(' ',1)
1590 args = arg_s.split(' ',1)
1598 magic_name = args[0]
1591 magic_name = args[0]
1599 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
1592 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
1600
1593
1601 try:
1594 try:
1602 magic_args = args[1]
1595 magic_args = args[1]
1603 except IndexError:
1596 except IndexError:
1604 magic_args = ''
1597 magic_args = ''
1605 fn = getattr(self,'magic_'+magic_name,None)
1598 fn = getattr(self,'magic_'+magic_name,None)
1606 if fn is None:
1599 if fn is None:
1607 error("Magic function `%s` not found." % magic_name)
1600 error("Magic function `%s` not found." % magic_name)
1608 else:
1601 else:
1609 magic_args = self.var_expand(magic_args,1)
1602 magic_args = self.var_expand(magic_args,1)
1610 with nested(self.builtin_trap, self.display_trap):
1603 with nested(self.builtin_trap,):
1611 return fn(magic_args)
1604 result = fn(magic_args)
1605 # Unfortunately, the return statement is what will trigger
1606 # the displayhook, but it is no longer set!
1607 return result
1612
1608
1613 def define_magic(self, magicname, func):
1609 def define_magic(self, magicname, func):
1614 """Expose own function as magic function for ipython
1610 """Expose own function as magic function for ipython
1615
1611
1616 def foo_impl(self,parameter_s=''):
1612 def foo_impl(self,parameter_s=''):
1617 'My very own magic!. (Use docstrings, IPython reads them).'
1613 'My very own magic!. (Use docstrings, IPython reads them).'
1618 print 'Magic function. Passed parameter is between < >:'
1614 print 'Magic function. Passed parameter is between < >:'
1619 print '<%s>' % parameter_s
1615 print '<%s>' % parameter_s
1620 print 'The self object is:',self
1616 print 'The self object is:',self
1621
1617
1622 self.define_magic('foo',foo_impl)
1618 self.define_magic('foo',foo_impl)
1623 """
1619 """
1624
1620
1625 import new
1621 import new
1626 im = new.instancemethod(func,self, self.__class__)
1622 im = new.instancemethod(func,self, self.__class__)
1627 old = getattr(self, "magic_" + magicname, None)
1623 old = getattr(self, "magic_" + magicname, None)
1628 setattr(self, "magic_" + magicname, im)
1624 setattr(self, "magic_" + magicname, im)
1629 return old
1625 return old
1630
1626
1631 #-------------------------------------------------------------------------
1627 #-------------------------------------------------------------------------
1632 # Things related to macros
1628 # Things related to macros
1633 #-------------------------------------------------------------------------
1629 #-------------------------------------------------------------------------
1634
1630
1635 def define_macro(self, name, themacro):
1631 def define_macro(self, name, themacro):
1636 """Define a new macro
1632 """Define a new macro
1637
1633
1638 Parameters
1634 Parameters
1639 ----------
1635 ----------
1640 name : str
1636 name : str
1641 The name of the macro.
1637 The name of the macro.
1642 themacro : str or Macro
1638 themacro : str or Macro
1643 The action to do upon invoking the macro. If a string, a new
1639 The action to do upon invoking the macro. If a string, a new
1644 Macro object is created by passing the string to it.
1640 Macro object is created by passing the string to it.
1645 """
1641 """
1646
1642
1647 from IPython.core import macro
1643 from IPython.core import macro
1648
1644
1649 if isinstance(themacro, basestring):
1645 if isinstance(themacro, basestring):
1650 themacro = macro.Macro(themacro)
1646 themacro = macro.Macro(themacro)
1651 if not isinstance(themacro, macro.Macro):
1647 if not isinstance(themacro, macro.Macro):
1652 raise ValueError('A macro must be a string or a Macro instance.')
1648 raise ValueError('A macro must be a string or a Macro instance.')
1653 self.user_ns[name] = themacro
1649 self.user_ns[name] = themacro
1654
1650
1655 #-------------------------------------------------------------------------
1651 #-------------------------------------------------------------------------
1656 # Things related to the running of system commands
1652 # Things related to the running of system commands
1657 #-------------------------------------------------------------------------
1653 #-------------------------------------------------------------------------
1658
1654
1659 def system(self, cmd):
1655 def system(self, cmd):
1660 """Make a system call, using IPython."""
1656 """Make a system call, using IPython."""
1661 return self.hooks.shell_hook(self.var_expand(cmd, depth=2))
1657 return self.hooks.shell_hook(self.var_expand(cmd, depth=2))
1662
1658
1663 #-------------------------------------------------------------------------
1659 #-------------------------------------------------------------------------
1664 # Things related to aliases
1660 # Things related to aliases
1665 #-------------------------------------------------------------------------
1661 #-------------------------------------------------------------------------
1666
1662
1667 def init_alias(self):
1663 def init_alias(self):
1668 self.alias_manager = AliasManager(self, config=self.config)
1664 self.alias_manager = AliasManager(self, config=self.config)
1665 self.ns_table['alias'] = self.alias_manager.alias_table,
1669
1666
1670 #-------------------------------------------------------------------------
1667 #-------------------------------------------------------------------------
1671 # Things related to the running of code
1668 # Things related to the running of code
1672 #-------------------------------------------------------------------------
1669 #-------------------------------------------------------------------------
1673
1670
1674 def ex(self, cmd):
1671 def ex(self, cmd):
1675 """Execute a normal python statement in user namespace."""
1672 """Execute a normal python statement in user namespace."""
1676 with nested(self.builtin_trap, self.display_trap):
1673 with nested(self.builtin_trap,):
1677 exec cmd in self.user_global_ns, self.user_ns
1674 exec cmd in self.user_global_ns, self.user_ns
1678
1675
1679 def ev(self, expr):
1676 def ev(self, expr):
1680 """Evaluate python expression expr in user namespace.
1677 """Evaluate python expression expr in user namespace.
1681
1678
1682 Returns the result of evaluation
1679 Returns the result of evaluation
1683 """
1680 """
1684 with nested(self.builtin_trap, self.display_trap):
1681 with nested(self.builtin_trap,):
1685 return eval(expr, self.user_global_ns, self.user_ns)
1682 return eval(expr, self.user_global_ns, self.user_ns)
1686
1683
1687 def mainloop(self, banner=None):
1684 def mainloop(self, banner=None):
1688 """Start the mainloop.
1685 """Start the mainloop.
1689
1686
1690 If an optional banner argument is given, it will override the
1687 If an optional banner argument is given, it will override the
1691 internally created default banner.
1688 internally created default banner.
1692 """
1689 """
1693
1690
1694 with nested(self.builtin_trap, self.display_trap):
1691 with nested(self.builtin_trap, self.display_trap):
1695 if self.c: # Emulate Python's -c option
1692 if self.c: # Emulate Python's -c option
1696 self.exec_init_cmd()
1693 self.exec_init_cmd()
1697
1694
1698 if self.display_banner:
1695 if self.display_banner:
1699 if banner is None:
1696 if banner is None:
1700 banner = self.banner
1697 banner = self.banner
1701
1698
1702 # if you run stuff with -c <cmd>, raw hist is not updated
1699 # if you run stuff with -c <cmd>, raw hist is not updated
1703 # ensure that it's in sync
1700 # ensure that it's in sync
1704 if len(self.input_hist) != len (self.input_hist_raw):
1701 if len(self.input_hist) != len (self.input_hist_raw):
1705 self.input_hist_raw = InputList(self.input_hist)
1702 self.input_hist_raw = InputList(self.input_hist)
1706
1703
1707 while 1:
1704 while 1:
1708 try:
1705 try:
1709 self.interact()
1706 self.interact()
1710 #self.interact_with_readline()
1707 #self.interact_with_readline()
1711 # XXX for testing of a readline-decoupled repl loop, call
1708 # XXX for testing of a readline-decoupled repl loop, call
1712 # interact_with_readline above
1709 # interact_with_readline above
1713 break
1710 break
1714 except KeyboardInterrupt:
1711 except KeyboardInterrupt:
1715 # this should not be necessary, but KeyboardInterrupt
1712 # this should not be necessary, but KeyboardInterrupt
1716 # handling seems rather unpredictable...
1713 # handling seems rather unpredictable...
1717 self.write("\nKeyboardInterrupt in interact()\n")
1714 self.write("\nKeyboardInterrupt in interact()\n")
1718
1715
1719 def exec_init_cmd(self):
1716 def exec_init_cmd(self):
1720 """Execute a command given at the command line.
1717 """Execute a command given at the command line.
1721
1718
1722 This emulates Python's -c option."""
1719 This emulates Python's -c option."""
1723
1720
1724 #sys.argv = ['-c']
1721 #sys.argv = ['-c']
1725 self.push_line(self.prefilter_manager.prefilter_lines(self.c, False))
1722 self.push_line(self.prefilter_manager.prefilter_lines(self.c, False))
1726 if not self.interactive:
1723 if not self.interactive:
1727 self.ask_exit()
1724 self.ask_exit()
1728
1725
1729 def interact_prompt(self):
1726 def interact_prompt(self):
1730 """ Print the prompt (in read-eval-print loop)
1727 """ Print the prompt (in read-eval-print loop)
1731
1728
1732 Provided for those who want to implement their own read-eval-print loop (e.g. GUIs), not
1729 Provided for those who want to implement their own read-eval-print loop (e.g. GUIs), not
1733 used in standard IPython flow.
1730 used in standard IPython flow.
1734 """
1731 """
1735 if self.more:
1732 if self.more:
1736 try:
1733 try:
1737 prompt = self.hooks.generate_prompt(True)
1734 prompt = self.hooks.generate_prompt(True)
1738 except:
1735 except:
1739 self.showtraceback()
1736 self.showtraceback()
1740 if self.autoindent:
1737 if self.autoindent:
1741 self.rl_do_indent = True
1738 self.rl_do_indent = True
1742
1739
1743 else:
1740 else:
1744 try:
1741 try:
1745 prompt = self.hooks.generate_prompt(False)
1742 prompt = self.hooks.generate_prompt(False)
1746 except:
1743 except:
1747 self.showtraceback()
1744 self.showtraceback()
1748 self.write(prompt)
1745 self.write(prompt)
1749
1746
1750 def interact_handle_input(self,line):
1747 def interact_handle_input(self,line):
1751 """ Handle the input line (in read-eval-print loop)
1748 """ Handle the input line (in read-eval-print loop)
1752
1749
1753 Provided for those who want to implement their own read-eval-print loop (e.g. GUIs), not
1750 Provided for those who want to implement their own read-eval-print loop (e.g. GUIs), not
1754 used in standard IPython flow.
1751 used in standard IPython flow.
1755 """
1752 """
1756 if line.lstrip() == line:
1753 if line.lstrip() == line:
1757 self.shadowhist.add(line.strip())
1754 self.shadowhist.add(line.strip())
1758 lineout = self.prefilter_manager.prefilter_lines(line,self.more)
1755 lineout = self.prefilter_manager.prefilter_lines(line,self.more)
1759
1756
1760 if line.strip():
1757 if line.strip():
1761 if self.more:
1758 if self.more:
1762 self.input_hist_raw[-1] += '%s\n' % line
1759 self.input_hist_raw[-1] += '%s\n' % line
1763 else:
1760 else:
1764 self.input_hist_raw.append('%s\n' % line)
1761 self.input_hist_raw.append('%s\n' % line)
1765
1762
1766
1763
1767 self.more = self.push_line(lineout)
1764 self.more = self.push_line(lineout)
1768 if (self.SyntaxTB.last_syntax_error and
1765 if (self.SyntaxTB.last_syntax_error and
1769 self.autoedit_syntax):
1766 self.autoedit_syntax):
1770 self.edit_syntax_error()
1767 self.edit_syntax_error()
1771
1768
1772 def interact_with_readline(self):
1769 def interact_with_readline(self):
1773 """ Demo of using interact_handle_input, interact_prompt
1770 """ Demo of using interact_handle_input, interact_prompt
1774
1771
1775 This is the main read-eval-print loop. If you need to implement your own (e.g. for GUI),
1772 This is the main read-eval-print loop. If you need to implement your own (e.g. for GUI),
1776 it should work like this.
1773 it should work like this.
1777 """
1774 """
1778 self.readline_startup_hook(self.pre_readline)
1775 self.readline_startup_hook(self.pre_readline)
1779 while not self.exit_now:
1776 while not self.exit_now:
1780 self.interact_prompt()
1777 self.interact_prompt()
1781 if self.more:
1778 if self.more:
1782 self.rl_do_indent = True
1779 self.rl_do_indent = True
1783 else:
1780 else:
1784 self.rl_do_indent = False
1781 self.rl_do_indent = False
1785 line = raw_input_original().decode(self.stdin_encoding)
1782 line = raw_input_original().decode(self.stdin_encoding)
1786 self.interact_handle_input(line)
1783 self.interact_handle_input(line)
1787
1784
1788 def interact(self, banner=None):
1785 def interact(self, banner=None):
1789 """Closely emulate the interactive Python console."""
1786 """Closely emulate the interactive Python console."""
1790
1787
1791 # batch run -> do not interact
1788 # batch run -> do not interact
1792 if self.exit_now:
1789 if self.exit_now:
1793 return
1790 return
1794
1791
1795 if self.display_banner:
1792 if self.display_banner:
1796 if banner is None:
1793 if banner is None:
1797 banner = self.banner
1794 banner = self.banner
1798 self.write(banner)
1795 self.write(banner)
1799
1796
1800 more = 0
1797 more = 0
1801
1798
1802 # Mark activity in the builtins
1799 # Mark activity in the builtins
1803 __builtin__.__dict__['__IPYTHON__active'] += 1
1800 __builtin__.__dict__['__IPYTHON__active'] += 1
1804
1801
1805 if self.has_readline:
1802 if self.has_readline:
1806 self.readline_startup_hook(self.pre_readline)
1803 self.readline_startup_hook(self.pre_readline)
1807 # exit_now is set by a call to %Exit or %Quit, through the
1804 # exit_now is set by a call to %Exit or %Quit, through the
1808 # ask_exit callback.
1805 # ask_exit callback.
1809
1806
1810 while not self.exit_now:
1807 while not self.exit_now:
1811 self.hooks.pre_prompt_hook()
1808 self.hooks.pre_prompt_hook()
1812 if more:
1809 if more:
1813 try:
1810 try:
1814 prompt = self.hooks.generate_prompt(True)
1811 prompt = self.hooks.generate_prompt(True)
1815 except:
1812 except:
1816 self.showtraceback()
1813 self.showtraceback()
1817 if self.autoindent:
1814 if self.autoindent:
1818 self.rl_do_indent = True
1815 self.rl_do_indent = True
1819
1816
1820 else:
1817 else:
1821 try:
1818 try:
1822 prompt = self.hooks.generate_prompt(False)
1819 prompt = self.hooks.generate_prompt(False)
1823 except:
1820 except:
1824 self.showtraceback()
1821 self.showtraceback()
1825 try:
1822 try:
1826 line = self.raw_input(prompt, more)
1823 line = self.raw_input(prompt, more)
1827 if self.exit_now:
1824 if self.exit_now:
1828 # quick exit on sys.std[in|out] close
1825 # quick exit on sys.std[in|out] close
1829 break
1826 break
1830 if self.autoindent:
1827 if self.autoindent:
1831 self.rl_do_indent = False
1828 self.rl_do_indent = False
1832
1829
1833 except KeyboardInterrupt:
1830 except KeyboardInterrupt:
1834 #double-guard against keyboardinterrupts during kbdint handling
1831 #double-guard against keyboardinterrupts during kbdint handling
1835 try:
1832 try:
1836 self.write('\nKeyboardInterrupt\n')
1833 self.write('\nKeyboardInterrupt\n')
1837 self.resetbuffer()
1834 self.resetbuffer()
1838 # keep cache in sync with the prompt counter:
1835 # keep cache in sync with the prompt counter:
1839 self.outputcache.prompt_count -= 1
1836 self.outputcache.prompt_count -= 1
1840
1837
1841 if self.autoindent:
1838 if self.autoindent:
1842 self.indent_current_nsp = 0
1839 self.indent_current_nsp = 0
1843 more = 0
1840 more = 0
1844 except KeyboardInterrupt:
1841 except KeyboardInterrupt:
1845 pass
1842 pass
1846 except EOFError:
1843 except EOFError:
1847 if self.autoindent:
1844 if self.autoindent:
1848 self.rl_do_indent = False
1845 self.rl_do_indent = False
1849 self.readline_startup_hook(None)
1846 self.readline_startup_hook(None)
1850 self.write('\n')
1847 self.write('\n')
1851 self.exit()
1848 self.exit()
1852 except bdb.BdbQuit:
1849 except bdb.BdbQuit:
1853 warn('The Python debugger has exited with a BdbQuit exception.\n'
1850 warn('The Python debugger has exited with a BdbQuit exception.\n'
1854 'Because of how pdb handles the stack, it is impossible\n'
1851 'Because of how pdb handles the stack, it is impossible\n'
1855 'for IPython to properly format this particular exception.\n'
1852 'for IPython to properly format this particular exception.\n'
1856 'IPython will resume normal operation.')
1853 'IPython will resume normal operation.')
1857 except:
1854 except:
1858 # exceptions here are VERY RARE, but they can be triggered
1855 # exceptions here are VERY RARE, but they can be triggered
1859 # asynchronously by signal handlers, for example.
1856 # asynchronously by signal handlers, for example.
1860 self.showtraceback()
1857 self.showtraceback()
1861 else:
1858 else:
1862 more = self.push_line(line)
1859 more = self.push_line(line)
1863 if (self.SyntaxTB.last_syntax_error and
1860 if (self.SyntaxTB.last_syntax_error and
1864 self.autoedit_syntax):
1861 self.autoedit_syntax):
1865 self.edit_syntax_error()
1862 self.edit_syntax_error()
1866
1863
1867 # We are off again...
1864 # We are off again...
1868 __builtin__.__dict__['__IPYTHON__active'] -= 1
1865 __builtin__.__dict__['__IPYTHON__active'] -= 1
1869
1866
1870 def safe_execfile(self,fname,*where,**kw):
1867 def safe_execfile(self,fname,*where,**kw):
1871 """A safe version of the builtin execfile().
1868 """A safe version of the builtin execfile().
1872
1869
1873 This version will never throw an exception, and knows how to handle
1870 This version will never throw an exception, and knows how to handle
1874 ipython logs as well.
1871 ipython logs as well.
1875
1872
1876 :Parameters:
1873 :Parameters:
1877 fname : string
1874 fname : string
1878 Name of the file to be executed.
1875 Name of the file to be executed.
1879
1876
1880 where : tuple
1877 where : tuple
1881 One or two namespaces, passed to execfile() as (globals,locals).
1878 One or two namespaces, passed to execfile() as (globals,locals).
1882 If only one is given, it is passed as both.
1879 If only one is given, it is passed as both.
1883
1880
1884 :Keywords:
1881 :Keywords:
1885 islog : boolean (False)
1882 islog : boolean (False)
1886
1883
1887 quiet : boolean (True)
1884 quiet : boolean (True)
1888
1885
1889 exit_ignore : boolean (False)
1886 exit_ignore : boolean (False)
1890 """
1887 """
1891
1888
1892 def syspath_cleanup():
1889 def syspath_cleanup():
1893 """Internal cleanup routine for sys.path."""
1890 """Internal cleanup routine for sys.path."""
1894 if add_dname:
1891 if add_dname:
1895 try:
1892 try:
1896 sys.path.remove(dname)
1893 sys.path.remove(dname)
1897 except ValueError:
1894 except ValueError:
1898 # For some reason the user has already removed it, ignore.
1895 # For some reason the user has already removed it, ignore.
1899 pass
1896 pass
1900
1897
1901 fname = os.path.expanduser(fname)
1898 fname = os.path.expanduser(fname)
1902
1899
1903 # Find things also in current directory. This is needed to mimic the
1900 # Find things also in current directory. This is needed to mimic the
1904 # behavior of running a script from the system command line, where
1901 # behavior of running a script from the system command line, where
1905 # Python inserts the script's directory into sys.path
1902 # Python inserts the script's directory into sys.path
1906 dname = os.path.dirname(os.path.abspath(fname))
1903 dname = os.path.dirname(os.path.abspath(fname))
1907 add_dname = False
1904 add_dname = False
1908 if dname not in sys.path:
1905 if dname not in sys.path:
1909 sys.path.insert(0,dname)
1906 sys.path.insert(0,dname)
1910 add_dname = True
1907 add_dname = True
1911
1908
1912 try:
1909 try:
1913 xfile = open(fname)
1910 xfile = open(fname)
1914 except:
1911 except:
1915 print >> Term.cerr, \
1912 print >> Term.cerr, \
1916 'Could not open file <%s> for safe execution.' % fname
1913 'Could not open file <%s> for safe execution.' % fname
1917 syspath_cleanup()
1914 syspath_cleanup()
1918 return None
1915 return None
1919
1916
1920 kw.setdefault('islog',0)
1917 kw.setdefault('islog',0)
1921 kw.setdefault('quiet',1)
1918 kw.setdefault('quiet',1)
1922 kw.setdefault('exit_ignore',0)
1919 kw.setdefault('exit_ignore',0)
1923
1920
1924 first = xfile.readline()
1921 first = xfile.readline()
1925 loghead = str(self.loghead_tpl).split('\n',1)[0].strip()
1922 loghead = str(self.loghead_tpl).split('\n',1)[0].strip()
1926 xfile.close()
1923 xfile.close()
1927 # line by line execution
1924 # line by line execution
1928 if first.startswith(loghead) or kw['islog']:
1925 if first.startswith(loghead) or kw['islog']:
1929 print 'Loading log file <%s> one line at a time...' % fname
1926 print 'Loading log file <%s> one line at a time...' % fname
1930 if kw['quiet']:
1927 if kw['quiet']:
1931 stdout_save = sys.stdout
1928 stdout_save = sys.stdout
1932 sys.stdout = StringIO.StringIO()
1929 sys.stdout = StringIO.StringIO()
1933 try:
1930 try:
1934 globs,locs = where[0:2]
1931 globs,locs = where[0:2]
1935 except:
1932 except:
1936 try:
1933 try:
1937 globs = locs = where[0]
1934 globs = locs = where[0]
1938 except:
1935 except:
1939 globs = locs = globals()
1936 globs = locs = globals()
1940 badblocks = []
1937 badblocks = []
1941
1938
1942 # we also need to identify indented blocks of code when replaying
1939 # we also need to identify indented blocks of code when replaying
1943 # logs and put them together before passing them to an exec
1940 # logs and put them together before passing them to an exec
1944 # statement. This takes a bit of regexp and look-ahead work in the
1941 # statement. This takes a bit of regexp and look-ahead work in the
1945 # file. It's easiest if we swallow the whole thing in memory
1942 # file. It's easiest if we swallow the whole thing in memory
1946 # first, and manually walk through the lines list moving the
1943 # first, and manually walk through the lines list moving the
1947 # counter ourselves.
1944 # counter ourselves.
1948 indent_re = re.compile('\s+\S')
1945 indent_re = re.compile('\s+\S')
1949 xfile = open(fname)
1946 xfile = open(fname)
1950 filelines = xfile.readlines()
1947 filelines = xfile.readlines()
1951 xfile.close()
1948 xfile.close()
1952 nlines = len(filelines)
1949 nlines = len(filelines)
1953 lnum = 0
1950 lnum = 0
1954 while lnum < nlines:
1951 while lnum < nlines:
1955 line = filelines[lnum]
1952 line = filelines[lnum]
1956 lnum += 1
1953 lnum += 1
1957 # don't re-insert logger status info into cache
1954 # don't re-insert logger status info into cache
1958 if line.startswith('#log#'):
1955 if line.startswith('#log#'):
1959 continue
1956 continue
1960 else:
1957 else:
1961 # build a block of code (maybe a single line) for execution
1958 # build a block of code (maybe a single line) for execution
1962 block = line
1959 block = line
1963 try:
1960 try:
1964 next = filelines[lnum] # lnum has already incremented
1961 next = filelines[lnum] # lnum has already incremented
1965 except:
1962 except:
1966 next = None
1963 next = None
1967 while next and indent_re.match(next):
1964 while next and indent_re.match(next):
1968 block += next
1965 block += next
1969 lnum += 1
1966 lnum += 1
1970 try:
1967 try:
1971 next = filelines[lnum]
1968 next = filelines[lnum]
1972 except:
1969 except:
1973 next = None
1970 next = None
1974 # now execute the block of one or more lines
1971 # now execute the block of one or more lines
1975 try:
1972 try:
1976 exec block in globs,locs
1973 exec block in globs,locs
1977 except SystemExit:
1974 except SystemExit:
1978 pass
1975 pass
1979 except:
1976 except:
1980 badblocks.append(block.rstrip())
1977 badblocks.append(block.rstrip())
1981 if kw['quiet']: # restore stdout
1978 if kw['quiet']: # restore stdout
1982 sys.stdout.close()
1979 sys.stdout.close()
1983 sys.stdout = stdout_save
1980 sys.stdout = stdout_save
1984 print 'Finished replaying log file <%s>' % fname
1981 print 'Finished replaying log file <%s>' % fname
1985 if badblocks:
1982 if badblocks:
1986 print >> sys.stderr, ('\nThe following lines/blocks in file '
1983 print >> sys.stderr, ('\nThe following lines/blocks in file '
1987 '<%s> reported errors:' % fname)
1984 '<%s> reported errors:' % fname)
1988
1985
1989 for badline in badblocks:
1986 for badline in badblocks:
1990 print >> sys.stderr, badline
1987 print >> sys.stderr, badline
1991 else: # regular file execution
1988 else: # regular file execution
1992 try:
1989 try:
1993 if sys.platform == 'win32' and sys.version_info < (2,5,1):
1990 if sys.platform == 'win32' and sys.version_info < (2,5,1):
1994 # Work around a bug in Python for Windows. The bug was
1991 # Work around a bug in Python for Windows. The bug was
1995 # fixed in in Python 2.5 r54159 and 54158, but that's still
1992 # fixed in in Python 2.5 r54159 and 54158, but that's still
1996 # SVN Python as of March/07. For details, see:
1993 # SVN Python as of March/07. For details, see:
1997 # http://projects.scipy.org/ipython/ipython/ticket/123
1994 # http://projects.scipy.org/ipython/ipython/ticket/123
1998 try:
1995 try:
1999 globs,locs = where[0:2]
1996 globs,locs = where[0:2]
2000 except:
1997 except:
2001 try:
1998 try:
2002 globs = locs = where[0]
1999 globs = locs = where[0]
2003 except:
2000 except:
2004 globs = locs = globals()
2001 globs = locs = globals()
2005 exec file(fname) in globs,locs
2002 exec file(fname) in globs,locs
2006 else:
2003 else:
2007 execfile(fname,*where)
2004 execfile(fname,*where)
2008 except SyntaxError:
2005 except SyntaxError:
2009 self.showsyntaxerror()
2006 self.showsyntaxerror()
2010 warn('Failure executing file: <%s>' % fname)
2007 warn('Failure executing file: <%s>' % fname)
2011 except SystemExit,status:
2008 except SystemExit,status:
2012 # Code that correctly sets the exit status flag to success (0)
2009 # Code that correctly sets the exit status flag to success (0)
2013 # shouldn't be bothered with a traceback. Note that a plain
2010 # shouldn't be bothered with a traceback. Note that a plain
2014 # sys.exit() does NOT set the message to 0 (it's empty) so that
2011 # sys.exit() does NOT set the message to 0 (it's empty) so that
2015 # will still get a traceback. Note that the structure of the
2012 # will still get a traceback. Note that the structure of the
2016 # SystemExit exception changed between Python 2.4 and 2.5, so
2013 # SystemExit exception changed between Python 2.4 and 2.5, so
2017 # the checks must be done in a version-dependent way.
2014 # the checks must be done in a version-dependent way.
2018 show = False
2015 show = False
2019
2016
2020 if sys.version_info[:2] > (2,5):
2017 if sys.version_info[:2] > (2,5):
2021 if status.message!=0 and not kw['exit_ignore']:
2018 if status.message!=0 and not kw['exit_ignore']:
2022 show = True
2019 show = True
2023 else:
2020 else:
2024 if status.code and not kw['exit_ignore']:
2021 if status.code and not kw['exit_ignore']:
2025 show = True
2022 show = True
2026 if show:
2023 if show:
2027 self.showtraceback()
2024 self.showtraceback()
2028 warn('Failure executing file: <%s>' % fname)
2025 warn('Failure executing file: <%s>' % fname)
2029 except:
2026 except:
2030 self.showtraceback()
2027 self.showtraceback()
2031 warn('Failure executing file: <%s>' % fname)
2028 warn('Failure executing file: <%s>' % fname)
2032
2029
2033 syspath_cleanup()
2030 syspath_cleanup()
2034
2031
2035 def cleanup_ipy_script(self, script):
2032 def cleanup_ipy_script(self, script):
2036 """Make a script safe for self.runlines()
2033 """Make a script safe for self.runlines()
2037
2034
2038 Notes
2035 Notes
2039 -----
2036 -----
2040 This was copied over from the old ipapi and probably can be done
2037 This was copied over from the old ipapi and probably can be done
2041 away with once we move to block based interpreter.
2038 away with once we move to block based interpreter.
2042
2039
2043 - Removes empty lines Suffixes all indented blocks that end with
2040 - Removes empty lines Suffixes all indented blocks that end with
2044 - unindented lines with empty lines
2041 - unindented lines with empty lines
2045 """
2042 """
2046
2043
2047 res = []
2044 res = []
2048 lines = script.splitlines()
2045 lines = script.splitlines()
2049
2046
2050 level = 0
2047 level = 0
2051 for l in lines:
2048 for l in lines:
2052 lstripped = l.lstrip()
2049 lstripped = l.lstrip()
2053 stripped = l.strip()
2050 stripped = l.strip()
2054 if not stripped:
2051 if not stripped:
2055 continue
2052 continue
2056 newlevel = len(l) - len(lstripped)
2053 newlevel = len(l) - len(lstripped)
2057 def is_secondary_block_start(s):
2054 def is_secondary_block_start(s):
2058 if not s.endswith(':'):
2055 if not s.endswith(':'):
2059 return False
2056 return False
2060 if (s.startswith('elif') or
2057 if (s.startswith('elif') or
2061 s.startswith('else') or
2058 s.startswith('else') or
2062 s.startswith('except') or
2059 s.startswith('except') or
2063 s.startswith('finally')):
2060 s.startswith('finally')):
2064 return True
2061 return True
2065
2062
2066 if level > 0 and newlevel == 0 and \
2063 if level > 0 and newlevel == 0 and \
2067 not is_secondary_block_start(stripped):
2064 not is_secondary_block_start(stripped):
2068 # add empty line
2065 # add empty line
2069 res.append('')
2066 res.append('')
2070
2067
2071 res.append(l)
2068 res.append(l)
2072 level = newlevel
2069 level = newlevel
2073 return '\n'.join(res) + '\n'
2070 return '\n'.join(res) + '\n'
2074
2071
2075 def runlines(self, lines, clean=False):
2072 def runlines(self, lines, clean=False):
2076 """Run a string of one or more lines of source.
2073 """Run a string of one or more lines of source.
2077
2074
2078 This method is capable of running a string containing multiple source
2075 This method is capable of running a string containing multiple source
2079 lines, as if they had been entered at the IPython prompt. Since it
2076 lines, as if they had been entered at the IPython prompt. Since it
2080 exposes IPython's processing machinery, the given strings can contain
2077 exposes IPython's processing machinery, the given strings can contain
2081 magic calls (%magic), special shell access (!cmd), etc.
2078 magic calls (%magic), special shell access (!cmd), etc.
2082 """
2079 """
2083
2080
2084 if isinstance(lines, (list, tuple)):
2081 if isinstance(lines, (list, tuple)):
2085 lines = '\n'.join(lines)
2082 lines = '\n'.join(lines)
2086
2083
2087 if clean:
2084 if clean:
2088 lines = self.cleanup_ipy_script(lines)
2085 lines = self.cleanup_ipy_script(lines)
2089
2086
2090 # We must start with a clean buffer, in case this is run from an
2087 # We must start with a clean buffer, in case this is run from an
2091 # interactive IPython session (via a magic, for example).
2088 # interactive IPython session (via a magic, for example).
2092 self.resetbuffer()
2089 self.resetbuffer()
2093 lines = lines.splitlines()
2090 lines = lines.splitlines()
2094 more = 0
2091 more = 0
2095
2092
2096 with nested(self.builtin_trap, self.display_trap):
2093 with nested(self.builtin_trap, self.display_trap):
2097 for line in lines:
2094 for line in lines:
2098 # skip blank lines so we don't mess up the prompt counter, but do
2095 # skip blank lines so we don't mess up the prompt counter, but do
2099 # NOT skip even a blank line if we are in a code block (more is
2096 # NOT skip even a blank line if we are in a code block (more is
2100 # true)
2097 # true)
2101
2098
2102 if line or more:
2099 if line or more:
2103 # push to raw history, so hist line numbers stay in sync
2100 # push to raw history, so hist line numbers stay in sync
2104 self.input_hist_raw.append("# " + line + "\n")
2101 self.input_hist_raw.append("# " + line + "\n")
2105 more = self.push_line(self.prefilter_manager.prefilter_lines(line,more))
2102 more = self.push_line(self.prefilter_manager.prefilter_lines(line,more))
2106 # IPython's runsource returns None if there was an error
2103 # IPython's runsource returns None if there was an error
2107 # compiling the code. This allows us to stop processing right
2104 # compiling the code. This allows us to stop processing right
2108 # away, so the user gets the error message at the right place.
2105 # away, so the user gets the error message at the right place.
2109 if more is None:
2106 if more is None:
2110 break
2107 break
2111 else:
2108 else:
2112 self.input_hist_raw.append("\n")
2109 self.input_hist_raw.append("\n")
2113 # final newline in case the input didn't have it, so that the code
2110 # final newline in case the input didn't have it, so that the code
2114 # actually does get executed
2111 # actually does get executed
2115 if more:
2112 if more:
2116 self.push_line('\n')
2113 self.push_line('\n')
2117
2114
2118 def runsource(self, source, filename='<input>', symbol='single'):
2115 def runsource(self, source, filename='<input>', symbol='single'):
2119 """Compile and run some source in the interpreter.
2116 """Compile and run some source in the interpreter.
2120
2117
2121 Arguments are as for compile_command().
2118 Arguments are as for compile_command().
2122
2119
2123 One several things can happen:
2120 One several things can happen:
2124
2121
2125 1) The input is incorrect; compile_command() raised an
2122 1) The input is incorrect; compile_command() raised an
2126 exception (SyntaxError or OverflowError). A syntax traceback
2123 exception (SyntaxError or OverflowError). A syntax traceback
2127 will be printed by calling the showsyntaxerror() method.
2124 will be printed by calling the showsyntaxerror() method.
2128
2125
2129 2) The input is incomplete, and more input is required;
2126 2) The input is incomplete, and more input is required;
2130 compile_command() returned None. Nothing happens.
2127 compile_command() returned None. Nothing happens.
2131
2128
2132 3) The input is complete; compile_command() returned a code
2129 3) The input is complete; compile_command() returned a code
2133 object. The code is executed by calling self.runcode() (which
2130 object. The code is executed by calling self.runcode() (which
2134 also handles run-time exceptions, except for SystemExit).
2131 also handles run-time exceptions, except for SystemExit).
2135
2132
2136 The return value is:
2133 The return value is:
2137
2134
2138 - True in case 2
2135 - True in case 2
2139
2136
2140 - False in the other cases, unless an exception is raised, where
2137 - False in the other cases, unless an exception is raised, where
2141 None is returned instead. This can be used by external callers to
2138 None is returned instead. This can be used by external callers to
2142 know whether to continue feeding input or not.
2139 know whether to continue feeding input or not.
2143
2140
2144 The return value can be used to decide whether to use sys.ps1 or
2141 The return value can be used to decide whether to use sys.ps1 or
2145 sys.ps2 to prompt the next line."""
2142 sys.ps2 to prompt the next line."""
2146
2143
2147 # if the source code has leading blanks, add 'if 1:\n' to it
2144 # if the source code has leading blanks, add 'if 1:\n' to it
2148 # this allows execution of indented pasted code. It is tempting
2145 # this allows execution of indented pasted code. It is tempting
2149 # to add '\n' at the end of source to run commands like ' a=1'
2146 # to add '\n' at the end of source to run commands like ' a=1'
2150 # directly, but this fails for more complicated scenarios
2147 # directly, but this fails for more complicated scenarios
2151 source=source.encode(self.stdin_encoding)
2148 source=source.encode(self.stdin_encoding)
2152 if source[:1] in [' ', '\t']:
2149 if source[:1] in [' ', '\t']:
2153 source = 'if 1:\n%s' % source
2150 source = 'if 1:\n%s' % source
2154
2151
2155 try:
2152 try:
2156 code = self.compile(source,filename,symbol)
2153 code = self.compile(source,filename,symbol)
2157 except (OverflowError, SyntaxError, ValueError, TypeError, MemoryError):
2154 except (OverflowError, SyntaxError, ValueError, TypeError, MemoryError):
2158 # Case 1
2155 # Case 1
2159 self.showsyntaxerror(filename)
2156 self.showsyntaxerror(filename)
2160 return None
2157 return None
2161
2158
2162 if code is None:
2159 if code is None:
2163 # Case 2
2160 # Case 2
2164 return True
2161 return True
2165
2162
2166 # Case 3
2163 # Case 3
2167 # We store the code object so that threaded shells and
2164 # We store the code object so that threaded shells and
2168 # custom exception handlers can access all this info if needed.
2165 # custom exception handlers can access all this info if needed.
2169 # The source corresponding to this can be obtained from the
2166 # The source corresponding to this can be obtained from the
2170 # buffer attribute as '\n'.join(self.buffer).
2167 # buffer attribute as '\n'.join(self.buffer).
2171 self.code_to_run = code
2168 self.code_to_run = code
2172 # now actually execute the code object
2169 # now actually execute the code object
2173 if self.runcode(code) == 0:
2170 if self.runcode(code) == 0:
2174 return False
2171 return False
2175 else:
2172 else:
2176 return None
2173 return None
2177
2174
2178 def runcode(self,code_obj):
2175 def runcode(self,code_obj):
2179 """Execute a code object.
2176 """Execute a code object.
2180
2177
2181 When an exception occurs, self.showtraceback() is called to display a
2178 When an exception occurs, self.showtraceback() is called to display a
2182 traceback.
2179 traceback.
2183
2180
2184 Return value: a flag indicating whether the code to be run completed
2181 Return value: a flag indicating whether the code to be run completed
2185 successfully:
2182 successfully:
2186
2183
2187 - 0: successful execution.
2184 - 0: successful execution.
2188 - 1: an error occurred.
2185 - 1: an error occurred.
2189 """
2186 """
2190
2187
2191 # Set our own excepthook in case the user code tries to call it
2188 # Set our own excepthook in case the user code tries to call it
2192 # directly, so that the IPython crash handler doesn't get triggered
2189 # directly, so that the IPython crash handler doesn't get triggered
2193 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
2190 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
2194
2191
2195 # we save the original sys.excepthook in the instance, in case config
2192 # we save the original sys.excepthook in the instance, in case config
2196 # code (such as magics) needs access to it.
2193 # code (such as magics) needs access to it.
2197 self.sys_excepthook = old_excepthook
2194 self.sys_excepthook = old_excepthook
2198 outflag = 1 # happens in more places, so it's easier as default
2195 outflag = 1 # happens in more places, so it's easier as default
2199 try:
2196 try:
2200 try:
2197 try:
2201 self.hooks.pre_runcode_hook()
2198 self.hooks.pre_runcode_hook()
2202 exec code_obj in self.user_global_ns, self.user_ns
2199 exec code_obj in self.user_global_ns, self.user_ns
2203 finally:
2200 finally:
2204 # Reset our crash handler in place
2201 # Reset our crash handler in place
2205 sys.excepthook = old_excepthook
2202 sys.excepthook = old_excepthook
2206 except SystemExit:
2203 except SystemExit:
2207 self.resetbuffer()
2204 self.resetbuffer()
2208 self.showtraceback()
2205 self.showtraceback()
2209 warn("Type %exit or %quit to exit IPython "
2206 warn("Type %exit or %quit to exit IPython "
2210 "(%Exit or %Quit do so unconditionally).",level=1)
2207 "(%Exit or %Quit do so unconditionally).",level=1)
2211 except self.custom_exceptions:
2208 except self.custom_exceptions:
2212 etype,value,tb = sys.exc_info()
2209 etype,value,tb = sys.exc_info()
2213 self.CustomTB(etype,value,tb)
2210 self.CustomTB(etype,value,tb)
2214 except:
2211 except:
2215 self.showtraceback()
2212 self.showtraceback()
2216 else:
2213 else:
2217 outflag = 0
2214 outflag = 0
2218 if softspace(sys.stdout, 0):
2215 if softspace(sys.stdout, 0):
2219 print
2216 print
2220 # Flush out code object which has been run (and source)
2217 # Flush out code object which has been run (and source)
2221 self.code_to_run = None
2218 self.code_to_run = None
2222 return outflag
2219 return outflag
2223
2220
2224 def push_line(self, line):
2221 def push_line(self, line):
2225 """Push a line to the interpreter.
2222 """Push a line to the interpreter.
2226
2223
2227 The line should not have a trailing newline; it may have
2224 The line should not have a trailing newline; it may have
2228 internal newlines. The line is appended to a buffer and the
2225 internal newlines. The line is appended to a buffer and the
2229 interpreter's runsource() method is called with the
2226 interpreter's runsource() method is called with the
2230 concatenated contents of the buffer as source. If this
2227 concatenated contents of the buffer as source. If this
2231 indicates that the command was executed or invalid, the buffer
2228 indicates that the command was executed or invalid, the buffer
2232 is reset; otherwise, the command is incomplete, and the buffer
2229 is reset; otherwise, the command is incomplete, and the buffer
2233 is left as it was after the line was appended. The return
2230 is left as it was after the line was appended. The return
2234 value is 1 if more input is required, 0 if the line was dealt
2231 value is 1 if more input is required, 0 if the line was dealt
2235 with in some way (this is the same as runsource()).
2232 with in some way (this is the same as runsource()).
2236 """
2233 """
2237
2234
2238 # autoindent management should be done here, and not in the
2235 # autoindent management should be done here, and not in the
2239 # interactive loop, since that one is only seen by keyboard input. We
2236 # interactive loop, since that one is only seen by keyboard input. We
2240 # need this done correctly even for code run via runlines (which uses
2237 # need this done correctly even for code run via runlines (which uses
2241 # push).
2238 # push).
2242
2239
2243 #print 'push line: <%s>' % line # dbg
2240 #print 'push line: <%s>' % line # dbg
2244 for subline in line.splitlines():
2241 for subline in line.splitlines():
2245 self._autoindent_update(subline)
2242 self._autoindent_update(subline)
2246 self.buffer.append(line)
2243 self.buffer.append(line)
2247 more = self.runsource('\n'.join(self.buffer), self.filename)
2244 more = self.runsource('\n'.join(self.buffer), self.filename)
2248 if not more:
2245 if not more:
2249 self.resetbuffer()
2246 self.resetbuffer()
2250 return more
2247 return more
2251
2248
2252 def _autoindent_update(self,line):
2249 def _autoindent_update(self,line):
2253 """Keep track of the indent level."""
2250 """Keep track of the indent level."""
2254
2251
2255 #debugx('line')
2252 #debugx('line')
2256 #debugx('self.indent_current_nsp')
2253 #debugx('self.indent_current_nsp')
2257 if self.autoindent:
2254 if self.autoindent:
2258 if line:
2255 if line:
2259 inisp = num_ini_spaces(line)
2256 inisp = num_ini_spaces(line)
2260 if inisp < self.indent_current_nsp:
2257 if inisp < self.indent_current_nsp:
2261 self.indent_current_nsp = inisp
2258 self.indent_current_nsp = inisp
2262
2259
2263 if line[-1] == ':':
2260 if line[-1] == ':':
2264 self.indent_current_nsp += 4
2261 self.indent_current_nsp += 4
2265 elif dedent_re.match(line):
2262 elif dedent_re.match(line):
2266 self.indent_current_nsp -= 4
2263 self.indent_current_nsp -= 4
2267 else:
2264 else:
2268 self.indent_current_nsp = 0
2265 self.indent_current_nsp = 0
2269
2266
2270 def resetbuffer(self):
2267 def resetbuffer(self):
2271 """Reset the input buffer."""
2268 """Reset the input buffer."""
2272 self.buffer[:] = []
2269 self.buffer[:] = []
2273
2270
2274 def raw_input(self,prompt='',continue_prompt=False):
2271 def raw_input(self,prompt='',continue_prompt=False):
2275 """Write a prompt and read a line.
2272 """Write a prompt and read a line.
2276
2273
2277 The returned line does not include the trailing newline.
2274 The returned line does not include the trailing newline.
2278 When the user enters the EOF key sequence, EOFError is raised.
2275 When the user enters the EOF key sequence, EOFError is raised.
2279
2276
2280 Optional inputs:
2277 Optional inputs:
2281
2278
2282 - prompt(''): a string to be printed to prompt the user.
2279 - prompt(''): a string to be printed to prompt the user.
2283
2280
2284 - continue_prompt(False): whether this line is the first one or a
2281 - continue_prompt(False): whether this line is the first one or a
2285 continuation in a sequence of inputs.
2282 continuation in a sequence of inputs.
2286 """
2283 """
2287 # growl.notify("raw_input: ", "prompt = %r\ncontinue_prompt = %s" % (prompt, continue_prompt))
2284 # growl.notify("raw_input: ", "prompt = %r\ncontinue_prompt = %s" % (prompt, continue_prompt))
2288
2285
2289 # Code run by the user may have modified the readline completer state.
2286 # Code run by the user may have modified the readline completer state.
2290 # We must ensure that our completer is back in place.
2287 # We must ensure that our completer is back in place.
2291
2288
2292 if self.has_readline:
2289 if self.has_readline:
2293 self.set_completer()
2290 self.set_completer()
2294
2291
2295 try:
2292 try:
2296 line = raw_input_original(prompt).decode(self.stdin_encoding)
2293 line = raw_input_original(prompt).decode(self.stdin_encoding)
2297 except ValueError:
2294 except ValueError:
2298 warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
2295 warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
2299 " or sys.stdout.close()!\nExiting IPython!")
2296 " or sys.stdout.close()!\nExiting IPython!")
2300 self.ask_exit()
2297 self.ask_exit()
2301 return ""
2298 return ""
2302
2299
2303 # Try to be reasonably smart about not re-indenting pasted input more
2300 # Try to be reasonably smart about not re-indenting pasted input more
2304 # than necessary. We do this by trimming out the auto-indent initial
2301 # than necessary. We do this by trimming out the auto-indent initial
2305 # spaces, if the user's actual input started itself with whitespace.
2302 # spaces, if the user's actual input started itself with whitespace.
2306 #debugx('self.buffer[-1]')
2303 #debugx('self.buffer[-1]')
2307
2304
2308 if self.autoindent:
2305 if self.autoindent:
2309 if num_ini_spaces(line) > self.indent_current_nsp:
2306 if num_ini_spaces(line) > self.indent_current_nsp:
2310 line = line[self.indent_current_nsp:]
2307 line = line[self.indent_current_nsp:]
2311 self.indent_current_nsp = 0
2308 self.indent_current_nsp = 0
2312
2309
2313 # store the unfiltered input before the user has any chance to modify
2310 # store the unfiltered input before the user has any chance to modify
2314 # it.
2311 # it.
2315 if line.strip():
2312 if line.strip():
2316 if continue_prompt:
2313 if continue_prompt:
2317 self.input_hist_raw[-1] += '%s\n' % line
2314 self.input_hist_raw[-1] += '%s\n' % line
2318 if self.has_readline: # and some config option is set?
2315 if self.has_readline: # and some config option is set?
2319 try:
2316 try:
2320 histlen = self.readline.get_current_history_length()
2317 histlen = self.readline.get_current_history_length()
2321 if histlen > 1:
2318 if histlen > 1:
2322 newhist = self.input_hist_raw[-1].rstrip()
2319 newhist = self.input_hist_raw[-1].rstrip()
2323 self.readline.remove_history_item(histlen-1)
2320 self.readline.remove_history_item(histlen-1)
2324 self.readline.replace_history_item(histlen-2,
2321 self.readline.replace_history_item(histlen-2,
2325 newhist.encode(self.stdin_encoding))
2322 newhist.encode(self.stdin_encoding))
2326 except AttributeError:
2323 except AttributeError:
2327 pass # re{move,place}_history_item are new in 2.4.
2324 pass # re{move,place}_history_item are new in 2.4.
2328 else:
2325 else:
2329 self.input_hist_raw.append('%s\n' % line)
2326 self.input_hist_raw.append('%s\n' % line)
2330 # only entries starting at first column go to shadow history
2327 # only entries starting at first column go to shadow history
2331 if line.lstrip() == line:
2328 if line.lstrip() == line:
2332 self.shadowhist.add(line.strip())
2329 self.shadowhist.add(line.strip())
2333 elif not continue_prompt:
2330 elif not continue_prompt:
2334 self.input_hist_raw.append('\n')
2331 self.input_hist_raw.append('\n')
2335 try:
2332 try:
2336 lineout = self.prefilter_manager.prefilter_lines(line,continue_prompt)
2333 lineout = self.prefilter_manager.prefilter_lines(line,continue_prompt)
2337 except:
2334 except:
2338 # blanket except, in case a user-defined prefilter crashes, so it
2335 # blanket except, in case a user-defined prefilter crashes, so it
2339 # can't take all of ipython with it.
2336 # can't take all of ipython with it.
2340 self.showtraceback()
2337 self.showtraceback()
2341 return ''
2338 return ''
2342 else:
2339 else:
2343 return lineout
2340 return lineout
2344
2341
2345 # def init_exec_commands(self):
2342 # def init_exec_commands(self):
2346 # for cmd in self.config.EXECUTE:
2343 # for cmd in self.config.EXECUTE:
2347 # print "execute:", cmd
2344 # print "execute:", cmd
2348 # self.api.runlines(cmd)
2345 # self.api.runlines(cmd)
2349 #
2346 #
2350 # batchrun = False
2347 # batchrun = False
2351 # if self.config.has_key('EXECFILE'):
2348 # if self.config.has_key('EXECFILE'):
2352 # for batchfile in [path(arg) for arg in self.config.EXECFILE
2349 # for batchfile in [path(arg) for arg in self.config.EXECFILE
2353 # if arg.lower().endswith('.ipy')]:
2350 # if arg.lower().endswith('.ipy')]:
2354 # if not batchfile.isfile():
2351 # if not batchfile.isfile():
2355 # print "No such batch file:", batchfile
2352 # print "No such batch file:", batchfile
2356 # continue
2353 # continue
2357 # self.api.runlines(batchfile.text())
2354 # self.api.runlines(batchfile.text())
2358 # batchrun = True
2355 # batchrun = True
2359 # # without -i option, exit after running the batch file
2356 # # without -i option, exit after running the batch file
2360 # if batchrun and not self.interactive:
2357 # if batchrun and not self.interactive:
2361 # self.ask_exit()
2358 # self.ask_exit()
2362
2359
2363 # def load(self, mod):
2360 # def load(self, mod):
2364 # """ Load an extension.
2361 # """ Load an extension.
2365 #
2362 #
2366 # Some modules should (or must) be 'load()':ed, rather than just imported.
2363 # Some modules should (or must) be 'load()':ed, rather than just imported.
2367 #
2364 #
2368 # Loading will do:
2365 # Loading will do:
2369 #
2366 #
2370 # - run init_ipython(ip)
2367 # - run init_ipython(ip)
2371 # - run ipython_firstrun(ip)
2368 # - run ipython_firstrun(ip)
2372 # """
2369 # """
2373 #
2370 #
2374 # if mod in self.extensions:
2371 # if mod in self.extensions:
2375 # # just to make sure we don't init it twice
2372 # # just to make sure we don't init it twice
2376 # # note that if you 'load' a module that has already been
2373 # # note that if you 'load' a module that has already been
2377 # # imported, init_ipython gets run anyway
2374 # # imported, init_ipython gets run anyway
2378 #
2375 #
2379 # return self.extensions[mod]
2376 # return self.extensions[mod]
2380 # __import__(mod)
2377 # __import__(mod)
2381 # m = sys.modules[mod]
2378 # m = sys.modules[mod]
2382 # if hasattr(m,'init_ipython'):
2379 # if hasattr(m,'init_ipython'):
2383 # m.init_ipython(self)
2380 # m.init_ipython(self)
2384 #
2381 #
2385 # if hasattr(m,'ipython_firstrun'):
2382 # if hasattr(m,'ipython_firstrun'):
2386 # already_loaded = self.db.get('firstrun_done', set())
2383 # already_loaded = self.db.get('firstrun_done', set())
2387 # if mod not in already_loaded:
2384 # if mod not in already_loaded:
2388 # m.ipython_firstrun(self)
2385 # m.ipython_firstrun(self)
2389 # already_loaded.add(mod)
2386 # already_loaded.add(mod)
2390 # self.db['firstrun_done'] = already_loaded
2387 # self.db['firstrun_done'] = already_loaded
2391 #
2388 #
2392 # self.extensions[mod] = m
2389 # self.extensions[mod] = m
2393 # return m
2390 # return m
2394
2391
2395 #-------------------------------------------------------------------------
2392 #-------------------------------------------------------------------------
2396 # Things related to the prefilter
2393 # Things related to the prefilter
2397 #-------------------------------------------------------------------------
2394 #-------------------------------------------------------------------------
2398
2395
2399 def init_prefilter(self):
2396 def init_prefilter(self):
2400 self.prefilter_manager = PrefilterManager(self, config=self.config)
2397 self.prefilter_manager = PrefilterManager(self, config=self.config)
2401
2398
2402 #-------------------------------------------------------------------------
2399 #-------------------------------------------------------------------------
2403 # Utilities
2400 # Utilities
2404 #-------------------------------------------------------------------------
2401 #-------------------------------------------------------------------------
2405
2402
2406 def getoutput(self, cmd):
2403 def getoutput(self, cmd):
2407 return getoutput(self.var_expand(cmd,depth=2),
2404 return getoutput(self.var_expand(cmd,depth=2),
2408 header=self.system_header,
2405 header=self.system_header,
2409 verbose=self.system_verbose)
2406 verbose=self.system_verbose)
2410
2407
2411 def getoutputerror(self, cmd):
2408 def getoutputerror(self, cmd):
2412 return getoutputerror(self.var_expand(cmd,depth=2),
2409 return getoutputerror(self.var_expand(cmd,depth=2),
2413 header=self.system_header,
2410 header=self.system_header,
2414 verbose=self.system_verbose)
2411 verbose=self.system_verbose)
2415
2412
2416 def var_expand(self,cmd,depth=0):
2413 def var_expand(self,cmd,depth=0):
2417 """Expand python variables in a string.
2414 """Expand python variables in a string.
2418
2415
2419 The depth argument indicates how many frames above the caller should
2416 The depth argument indicates how many frames above the caller should
2420 be walked to look for the local namespace where to expand variables.
2417 be walked to look for the local namespace where to expand variables.
2421
2418
2422 The global namespace for expansion is always the user's interactive
2419 The global namespace for expansion is always the user's interactive
2423 namespace.
2420 namespace.
2424 """
2421 """
2425
2422
2426 return str(ItplNS(cmd,
2423 return str(ItplNS(cmd,
2427 self.user_ns, # globals
2424 self.user_ns, # globals
2428 # Skip our own frame in searching for locals:
2425 # Skip our own frame in searching for locals:
2429 sys._getframe(depth+1).f_locals # locals
2426 sys._getframe(depth+1).f_locals # locals
2430 ))
2427 ))
2431
2428
2432 def mktempfile(self,data=None):
2429 def mktempfile(self,data=None):
2433 """Make a new tempfile and return its filename.
2430 """Make a new tempfile and return its filename.
2434
2431
2435 This makes a call to tempfile.mktemp, but it registers the created
2432 This makes a call to tempfile.mktemp, but it registers the created
2436 filename internally so ipython cleans it up at exit time.
2433 filename internally so ipython cleans it up at exit time.
2437
2434
2438 Optional inputs:
2435 Optional inputs:
2439
2436
2440 - data(None): if data is given, it gets written out to the temp file
2437 - data(None): if data is given, it gets written out to the temp file
2441 immediately, and the file is closed again."""
2438 immediately, and the file is closed again."""
2442
2439
2443 filename = tempfile.mktemp('.py','ipython_edit_')
2440 filename = tempfile.mktemp('.py','ipython_edit_')
2444 self.tempfiles.append(filename)
2441 self.tempfiles.append(filename)
2445
2442
2446 if data:
2443 if data:
2447 tmp_file = open(filename,'w')
2444 tmp_file = open(filename,'w')
2448 tmp_file.write(data)
2445 tmp_file.write(data)
2449 tmp_file.close()
2446 tmp_file.close()
2450 return filename
2447 return filename
2451
2448
2452 def write(self,data):
2449 def write(self,data):
2453 """Write a string to the default output"""
2450 """Write a string to the default output"""
2454 Term.cout.write(data)
2451 Term.cout.write(data)
2455
2452
2456 def write_err(self,data):
2453 def write_err(self,data):
2457 """Write a string to the default error output"""
2454 """Write a string to the default error output"""
2458 Term.cerr.write(data)
2455 Term.cerr.write(data)
2459
2456
2460 def ask_yes_no(self,prompt,default=True):
2457 def ask_yes_no(self,prompt,default=True):
2461 if self.quiet:
2458 if self.quiet:
2462 return True
2459 return True
2463 return ask_yes_no(prompt,default)
2460 return ask_yes_no(prompt,default)
2464
2461
2465 #-------------------------------------------------------------------------
2462 #-------------------------------------------------------------------------
2466 # Things related to IPython exiting
2463 # Things related to IPython exiting
2467 #-------------------------------------------------------------------------
2464 #-------------------------------------------------------------------------
2468
2465
2469 def ask_exit(self):
2466 def ask_exit(self):
2470 """ Call for exiting. Can be overiden and used as a callback. """
2467 """ Call for exiting. Can be overiden and used as a callback. """
2471 self.exit_now = True
2468 self.exit_now = True
2472
2469
2473 def exit(self):
2470 def exit(self):
2474 """Handle interactive exit.
2471 """Handle interactive exit.
2475
2472
2476 This method calls the ask_exit callback."""
2473 This method calls the ask_exit callback."""
2477 if self.confirm_exit:
2474 if self.confirm_exit:
2478 if self.ask_yes_no('Do you really want to exit ([y]/n)?','y'):
2475 if self.ask_yes_no('Do you really want to exit ([y]/n)?','y'):
2479 self.ask_exit()
2476 self.ask_exit()
2480 else:
2477 else:
2481 self.ask_exit()
2478 self.ask_exit()
2482
2479
2483 def atexit_operations(self):
2480 def atexit_operations(self):
2484 """This will be executed at the time of exit.
2481 """This will be executed at the time of exit.
2485
2482
2486 Saving of persistent data should be performed here.
2483 Saving of persistent data should be performed here.
2487 """
2484 """
2488 self.savehist()
2485 self.savehist()
2489
2486
2490 # Cleanup all tempfiles left around
2487 # Cleanup all tempfiles left around
2491 for tfile in self.tempfiles:
2488 for tfile in self.tempfiles:
2492 try:
2489 try:
2493 os.unlink(tfile)
2490 os.unlink(tfile)
2494 except OSError:
2491 except OSError:
2495 pass
2492 pass
2496
2493
2497 # Clear all user namespaces to release all references cleanly.
2494 # Clear all user namespaces to release all references cleanly.
2498 self.reset()
2495 self.reset()
2499
2496
2500 # Run user hooks
2497 # Run user hooks
2501 self.hooks.shutdown_hook()
2498 self.hooks.shutdown_hook()
2502
2499
2503 def cleanup(self):
2500 def cleanup(self):
2504 self.restore_sys_module_state()
2501 self.restore_sys_module_state()
2505
2502
2506
2503
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
@@ -1,777 +1,777 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 """
3 """
4 Prefiltering components.
4 Prefiltering components.
5
5
6 Authors:
6 Authors:
7
7
8 * Brian Granger
8 * Brian Granger
9 * Fernando Perez
9 * Fernando Perez
10 * Dan Milstein
10 * Dan Milstein
11 """
11 """
12
12
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Copyright (C) 2008-2009 The IPython Development Team
14 # Copyright (C) 2008-2009 The IPython Development Team
15 #
15 #
16 # Distributed under the terms of the BSD License. The full license is in
16 # Distributed under the terms of the BSD License. The full license is in
17 # the file COPYING, distributed as part of this software.
17 # the file COPYING, distributed as part of this software.
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19
19
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21 # Imports
21 # Imports
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23
23
24 import __builtin__
24 import __builtin__
25 import codeop
25 import codeop
26 import keyword
26 import keyword
27 import os
27 import os
28 import re
28 import re
29 import sys
29 import sys
30
30
31 from IPython.core.alias import AliasManager
31 from IPython.core.alias import AliasManager
32 from IPython.core.autocall import IPyAutocall
32 from IPython.core.autocall import IPyAutocall
33 from IPython.core.component import Component
33 from IPython.core.component import Component
34 from IPython.core.splitinput import split_user_input
34 from IPython.core.splitinput import split_user_input
35
35
36 from IPython.utils.traitlets import List, Int, Any, Str, CBool
36 from IPython.utils.traitlets import List, Int, Any, Str, CBool
37 from IPython.utils.genutils import make_quoted_expr
37 from IPython.utils.genutils import make_quoted_expr
38 from IPython.utils.autoattr import auto_attr
38 from IPython.utils.autoattr import auto_attr
39
39
40 #-----------------------------------------------------------------------------
40 #-----------------------------------------------------------------------------
41 # Global utilities, errors and constants
41 # Global utilities, errors and constants
42 #-----------------------------------------------------------------------------
42 #-----------------------------------------------------------------------------
43
43
44
44
45 ESC_SHELL = '!'
45 ESC_SHELL = '!'
46 ESC_SH_CAP = '!!'
46 ESC_SH_CAP = '!!'
47 ESC_HELP = '?'
47 ESC_HELP = '?'
48 ESC_MAGIC = '%'
48 ESC_MAGIC = '%'
49 ESC_QUOTE = ','
49 ESC_QUOTE = ','
50 ESC_QUOTE2 = ';'
50 ESC_QUOTE2 = ';'
51 ESC_PAREN = '/'
51 ESC_PAREN = '/'
52
52
53
53
54 class PrefilterError(Exception):
54 class PrefilterError(Exception):
55 pass
55 pass
56
56
57
57
58 # RegExp to identify potential function names
58 # RegExp to identify potential function names
59 re_fun_name = re.compile(r'[a-zA-Z_]([a-zA-Z0-9_.]*) *$')
59 re_fun_name = re.compile(r'[a-zA-Z_]([a-zA-Z0-9_.]*) *$')
60
60
61 # RegExp to exclude strings with this start from autocalling. In
61 # RegExp to exclude strings with this start from autocalling. In
62 # particular, all binary operators should be excluded, so that if foo is
62 # particular, all binary operators should be excluded, so that if foo is
63 # callable, foo OP bar doesn't become foo(OP bar), which is invalid. The
63 # callable, foo OP bar doesn't become foo(OP bar), which is invalid. The
64 # characters '!=()' don't need to be checked for, as the checkPythonChars
64 # characters '!=()' don't need to be checked for, as the checkPythonChars
65 # routine explicitely does so, to catch direct calls and rebindings of
65 # routine explicitely does so, to catch direct calls and rebindings of
66 # existing names.
66 # existing names.
67
67
68 # Warning: the '-' HAS TO BE AT THE END of the first group, otherwise
68 # Warning: the '-' HAS TO BE AT THE END of the first group, otherwise
69 # it affects the rest of the group in square brackets.
69 # it affects the rest of the group in square brackets.
70 re_exclude_auto = re.compile(r'^[,&^\|\*/\+-]'
70 re_exclude_auto = re.compile(r'^[,&^\|\*/\+-]'
71 r'|^is |^not |^in |^and |^or ')
71 r'|^is |^not |^in |^and |^or ')
72
72
73 # try to catch also methods for stuff in lists/tuples/dicts: off
73 # try to catch also methods for stuff in lists/tuples/dicts: off
74 # (experimental). For this to work, the line_split regexp would need
74 # (experimental). For this to work, the line_split regexp would need
75 # to be modified so it wouldn't break things at '['. That line is
75 # to be modified so it wouldn't break things at '['. That line is
76 # nasty enough that I shouldn't change it until I can test it _well_.
76 # nasty enough that I shouldn't change it until I can test it _well_.
77 #self.re_fun_name = re.compile (r'[a-zA-Z_]([a-zA-Z0-9_.\[\]]*) ?$')
77 #self.re_fun_name = re.compile (r'[a-zA-Z_]([a-zA-Z0-9_.\[\]]*) ?$')
78
78
79
79
80 # Handler Check Utilities
80 # Handler Check Utilities
81 def is_shadowed(identifier, ip):
81 def is_shadowed(identifier, ip):
82 """Is the given identifier defined in one of the namespaces which shadow
82 """Is the given identifier defined in one of the namespaces which shadow
83 the alias and magic namespaces? Note that an identifier is different
83 the alias and magic namespaces? Note that an identifier is different
84 than ifun, because it can not contain a '.' character."""
84 than ifun, because it can not contain a '.' character."""
85 # This is much safer than calling ofind, which can change state
85 # This is much safer than calling ofind, which can change state
86 return (identifier in ip.user_ns \
86 return (identifier in ip.user_ns \
87 or identifier in ip.internal_ns \
87 or identifier in ip.internal_ns \
88 or identifier in ip.ns_table['builtin'])
88 or identifier in ip.ns_table['builtin'])
89
89
90
90
91 #-----------------------------------------------------------------------------
91 #-----------------------------------------------------------------------------
92 # The LineInfo class used throughout
92 # The LineInfo class used throughout
93 #-----------------------------------------------------------------------------
93 #-----------------------------------------------------------------------------
94
94
95
95
96 class LineInfo(object):
96 class LineInfo(object):
97 """A single line of input and associated info.
97 """A single line of input and associated info.
98
98
99 Includes the following as properties:
99 Includes the following as properties:
100
100
101 line
101 line
102 The original, raw line
102 The original, raw line
103
103
104 continue_prompt
104 continue_prompt
105 Is this line a continuation in a sequence of multiline input?
105 Is this line a continuation in a sequence of multiline input?
106
106
107 pre
107 pre
108 The initial esc character or whitespace.
108 The initial esc character or whitespace.
109
109
110 pre_char
110 pre_char
111 The escape character(s) in pre or the empty string if there isn't one.
111 The escape character(s) in pre or the empty string if there isn't one.
112 Note that '!!' is a possible value for pre_char. Otherwise it will
112 Note that '!!' is a possible value for pre_char. Otherwise it will
113 always be a single character.
113 always be a single character.
114
114
115 pre_whitespace
115 pre_whitespace
116 The leading whitespace from pre if it exists. If there is a pre_char,
116 The leading whitespace from pre if it exists. If there is a pre_char,
117 this is just ''.
117 this is just ''.
118
118
119 ifun
119 ifun
120 The 'function part', which is basically the maximal initial sequence
120 The 'function part', which is basically the maximal initial sequence
121 of valid python identifiers and the '.' character. This is what is
121 of valid python identifiers and the '.' character. This is what is
122 checked for alias and magic transformations, used for auto-calling,
122 checked for alias and magic transformations, used for auto-calling,
123 etc.
123 etc.
124
124
125 the_rest
125 the_rest
126 Everything else on the line.
126 Everything else on the line.
127 """
127 """
128 def __init__(self, line, continue_prompt):
128 def __init__(self, line, continue_prompt):
129 self.line = line
129 self.line = line
130 self.continue_prompt = continue_prompt
130 self.continue_prompt = continue_prompt
131 self.pre, self.ifun, self.the_rest = split_user_input(line)
131 self.pre, self.ifun, self.the_rest = split_user_input(line)
132
132
133 self.pre_char = self.pre.strip()
133 self.pre_char = self.pre.strip()
134 if self.pre_char:
134 if self.pre_char:
135 self.pre_whitespace = '' # No whitespace allowd before esc chars
135 self.pre_whitespace = '' # No whitespace allowd before esc chars
136 else:
136 else:
137 self.pre_whitespace = self.pre
137 self.pre_whitespace = self.pre
138
138
139 self._oinfo = None
139 self._oinfo = None
140
140
141 def ofind(self, ip):
141 def ofind(self, ip):
142 """Do a full, attribute-walking lookup of the ifun in the various
142 """Do a full, attribute-walking lookup of the ifun in the various
143 namespaces for the given IPython InteractiveShell instance.
143 namespaces for the given IPython InteractiveShell instance.
144
144
145 Return a dict with keys: found,obj,ospace,ismagic
145 Return a dict with keys: found,obj,ospace,ismagic
146
146
147 Note: can cause state changes because of calling getattr, but should
147 Note: can cause state changes because of calling getattr, but should
148 only be run if autocall is on and if the line hasn't matched any
148 only be run if autocall is on and if the line hasn't matched any
149 other, less dangerous handlers.
149 other, less dangerous handlers.
150
150
151 Does cache the results of the call, so can be called multiple times
151 Does cache the results of the call, so can be called multiple times
152 without worrying about *further* damaging state.
152 without worrying about *further* damaging state.
153 """
153 """
154 if not self._oinfo:
154 if not self._oinfo:
155 self._oinfo = ip._ofind(self.ifun)
155 self._oinfo = ip._ofind(self.ifun)
156 return self._oinfo
156 return self._oinfo
157
157
158 def __str__(self):
158 def __str__(self):
159 return "Lineinfo [%s|%s|%s]" %(self.pre,self.ifun,self.the_rest)
159 return "Lineinfo [%s|%s|%s]" %(self.pre,self.ifun,self.the_rest)
160
160
161
161
162 #-----------------------------------------------------------------------------
162 #-----------------------------------------------------------------------------
163 # Main Prefilter manager
163 # Main Prefilter manager
164 #-----------------------------------------------------------------------------
164 #-----------------------------------------------------------------------------
165
165
166
166
167 class PrefilterManager(Component):
167 class PrefilterManager(Component):
168 """Main prefilter component.
168 """Main prefilter component.
169
169
170 The IPython prefilter is run on all user input before it is run. The
170 The IPython prefilter is run on all user input before it is run. The
171 prefilter consumes lines of input and produces transformed lines of
171 prefilter consumes lines of input and produces transformed lines of
172 input. The implementation consists of checkers and handlers. The
172 input. The implementation consists of checkers and handlers. The
173 checkers inspect the input line and select which handler will be used
173 checkers inspect the input line and select which handler will be used
174 to transform the input line.
174 to transform the input line.
175 """
175 """
176
176
177 multi_line_specials = CBool(True, config_key='MULTI_LINE_SPECIALS')
177 multi_line_specials = CBool(True, config=True)
178
178
179 def __init__(self, parent, config=None):
179 def __init__(self, parent, config=None):
180 super(PrefilterManager, self).__init__(parent, config=config)
180 super(PrefilterManager, self).__init__(parent, config=config)
181 self.init_handlers()
181 self.init_handlers()
182 self.init_checkers()
182 self.init_checkers()
183
183
184 @auto_attr
184 @auto_attr
185 def shell(self):
185 def shell(self):
186 shell = Component.get_instances(
186 shell = Component.get_instances(
187 root=self.root,
187 root=self.root,
188 klass='IPython.core.iplib.InteractiveShell'
188 klass='IPython.core.iplib.InteractiveShell'
189 )[0]
189 )[0]
190 return shell
190 return shell
191
191
192 def init_checkers(self):
192 def init_checkers(self):
193 self._checkers = []
193 self._checkers = []
194 for checker in _default_checkers:
194 for checker in _default_checkers:
195 self._checkers.append(checker(self, config=self.config))
195 self._checkers.append(checker(self, config=self.config))
196
196
197 def init_handlers(self):
197 def init_handlers(self):
198 self._handlers = {}
198 self._handlers = {}
199 self._esc_handlers = {}
199 self._esc_handlers = {}
200 for handler in _default_handlers:
200 for handler in _default_handlers:
201 handler(self, config=self.config)
201 handler(self, config=self.config)
202
202
203 @property
203 @property
204 def sorted_checkers(self):
204 def sorted_checkers(self):
205 """Return a list of checkers, sorted by priority."""
205 """Return a list of checkers, sorted by priority."""
206 return sorted(self._checkers, cmp=lambda x,y: x.priority-y.priority)
206 return sorted(self._checkers, cmp=lambda x,y: x.priority-y.priority)
207
207
208 def register_handler(self, name, handler, esc_strings):
208 def register_handler(self, name, handler, esc_strings):
209 """Register a handler instance by name with esc_strings."""
209 """Register a handler instance by name with esc_strings."""
210 self._handlers[name] = handler
210 self._handlers[name] = handler
211 for esc_str in esc_strings:
211 for esc_str in esc_strings:
212 self._esc_handlers[esc_str] = handler
212 self._esc_handlers[esc_str] = handler
213
213
214 def unregister_handler(self, name, handler, esc_strings):
214 def unregister_handler(self, name, handler, esc_strings):
215 """Unregister a handler instance by name with esc_strings."""
215 """Unregister a handler instance by name with esc_strings."""
216 try:
216 try:
217 del self._handlers[name]
217 del self._handlers[name]
218 except KeyError:
218 except KeyError:
219 pass
219 pass
220 for esc_str in esc_strings:
220 for esc_str in esc_strings:
221 h = self._esc_handlers.get(esc_str)
221 h = self._esc_handlers.get(esc_str)
222 if h is handler:
222 if h is handler:
223 del self._esc_handlers[esc_str]
223 del self._esc_handlers[esc_str]
224
224
225 def get_handler_by_name(self, name):
225 def get_handler_by_name(self, name):
226 """Get a handler by its name."""
226 """Get a handler by its name."""
227 return self._handlers.get(name)
227 return self._handlers.get(name)
228
228
229 def get_handler_by_esc(self, esc_str):
229 def get_handler_by_esc(self, esc_str):
230 """Get a handler by its escape string."""
230 """Get a handler by its escape string."""
231 return self._esc_handlers.get(esc_str)
231 return self._esc_handlers.get(esc_str)
232
232
233 def prefilter_line_info(self, line_info):
233 def prefilter_line_info(self, line_info):
234 """Prefilter a line that has been converted to a LineInfo object."""
234 """Prefilter a line that has been converted to a LineInfo object."""
235 handler = self.find_handler(line_info)
235 handler = self.find_handler(line_info)
236 return handler.handle(line_info)
236 return handler.handle(line_info)
237
237
238 def find_handler(self, line_info):
238 def find_handler(self, line_info):
239 """Find a handler for the line_info by trying checkers."""
239 """Find a handler for the line_info by trying checkers."""
240 for checker in self.sorted_checkers:
240 for checker in self.sorted_checkers:
241 handler = checker.check(line_info)
241 handler = checker.check(line_info)
242 if handler:
242 if handler:
243 return handler
243 return handler
244 return self.get_handler_by_name('normal')
244 return self.get_handler_by_name('normal')
245
245
246 def prefilter_line(self, line, continue_prompt):
246 def prefilter_line(self, line, continue_prompt):
247 """Prefilter a single input line as text."""
247 """Prefilter a single input line as text."""
248
248
249 # All handlers *must* return a value, even if it's blank ('').
249 # All handlers *must* return a value, even if it's blank ('').
250
250
251 # Lines are NOT logged here. Handlers should process the line as
251 # Lines are NOT logged here. Handlers should process the line as
252 # needed, update the cache AND log it (so that the input cache array
252 # needed, update the cache AND log it (so that the input cache array
253 # stays synced).
253 # stays synced).
254
254
255 # growl.notify("_prefilter: ", "line = %s\ncontinue_prompt = %s" % (line, continue_prompt))
255 # growl.notify("_prefilter: ", "line = %s\ncontinue_prompt = %s" % (line, continue_prompt))
256
256
257 # save the line away in case we crash, so the post-mortem handler can
257 # save the line away in case we crash, so the post-mortem handler can
258 # record it
258 # record it
259 self.shell._last_input_line = line
259 self.shell._last_input_line = line
260
260
261 if not line:
261 if not line:
262 # Return immediately on purely empty lines, so that if the user
262 # Return immediately on purely empty lines, so that if the user
263 # previously typed some whitespace that started a continuation
263 # previously typed some whitespace that started a continuation
264 # prompt, he can break out of that loop with just an empty line.
264 # prompt, he can break out of that loop with just an empty line.
265 # This is how the default python prompt works.
265 # This is how the default python prompt works.
266
266
267 # Only return if the accumulated input buffer was just whitespace!
267 # Only return if the accumulated input buffer was just whitespace!
268 if ''.join(self.shell.buffer).isspace():
268 if ''.join(self.shell.buffer).isspace():
269 self.shell.buffer[:] = []
269 self.shell.buffer[:] = []
270 return ''
270 return ''
271
271
272 line_info = LineInfo(line, continue_prompt)
272 line_info = LineInfo(line, continue_prompt)
273
273
274 # the input history needs to track even empty lines
274 # the input history needs to track even empty lines
275 stripped = line.strip()
275 stripped = line.strip()
276
276
277 handle_normal = self.get_handler_by_name('normal')
277 normal_handler = self.get_handler_by_name('normal')
278 if not stripped:
278 if not stripped:
279 if not continue_prompt:
279 if not continue_prompt:
280 self.shell.outputcache.prompt_count -= 1
280 self.shell.outputcache.prompt_count -= 1
281
281
282 return handle_normal(line_info)
282 return normal_handler.handle(line_info)
283
283
284 # special handlers are only allowed for single line statements
284 # special handlers are only allowed for single line statements
285 if continue_prompt and not self.multi_line_specials:
285 if continue_prompt and not self.multi_line_specials:
286 return handle_normal(line_info)
286 return normal_handler.handle(line_info)
287
287
288 return self.prefilter_line_info(line_info)
288 return self.prefilter_line_info(line_info)
289
289
290 def prefilter_lines(self, lines, continue_prompt):
290 def prefilter_lines(self, lines, continue_prompt):
291 """Prefilter multiple input lines of text.
291 """Prefilter multiple input lines of text.
292
292
293 Covers cases where there are multiple lines in the user entry,
293 Covers cases where there are multiple lines in the user entry,
294 which is the case when the user goes back to a multiline history
294 which is the case when the user goes back to a multiline history
295 entry and presses enter.
295 entry and presses enter.
296 """
296 """
297 # growl.notify("multiline_prefilter: ", "%s\n%s" % (line, continue_prompt))
297 # growl.notify("multiline_prefilter: ", "%s\n%s" % (line, continue_prompt))
298 out = []
298 out = []
299 for line in lines.rstrip('\n').split('\n'):
299 for line in lines.rstrip('\n').split('\n'):
300 out.append(self.prefilter_line(line, continue_prompt))
300 out.append(self.prefilter_line(line, continue_prompt))
301 # growl.notify("multiline_prefilter return: ", '\n'.join(out))
301 # growl.notify("multiline_prefilter return: ", '\n'.join(out))
302 return '\n'.join(out)
302 return '\n'.join(out)
303
303
304
304
305 #-----------------------------------------------------------------------------
305 #-----------------------------------------------------------------------------
306 # Prefilter checkers
306 # Prefilter checkers
307 #-----------------------------------------------------------------------------
307 #-----------------------------------------------------------------------------
308
308
309
309
310 class PrefilterChecker(Component):
310 class PrefilterChecker(Component):
311 """Inspect an input line and return a handler for that line."""
311 """Inspect an input line and return a handler for that line."""
312
312
313 priority = Int(100)
313 priority = Int(100, config=True)
314 shell = Any
314 shell = Any
315 prefilter_manager = Any
315 prefilter_manager = Any
316
316
317 def __init__(self, parent, config=None):
317 def __init__(self, parent, config=None):
318 super(PrefilterChecker, self).__init__(parent, config=config)
318 super(PrefilterChecker, self).__init__(parent, config=config)
319
319
320 @auto_attr
320 @auto_attr
321 def shell(self):
321 def shell(self):
322 shell = Component.get_instances(
322 shell = Component.get_instances(
323 root=self.root,
323 root=self.root,
324 klass='IPython.core.iplib.InteractiveShell'
324 klass='IPython.core.iplib.InteractiveShell'
325 )[0]
325 )[0]
326 return shell
326 return shell
327
327
328 @auto_attr
328 @auto_attr
329 def prefilter_manager(self):
329 def prefilter_manager(self):
330 return PrefilterManager.get_instances(root=self.root)[0]
330 return PrefilterManager.get_instances(root=self.root)[0]
331
331
332 def check(self, line_info):
332 def check(self, line_info):
333 """Inspect line_info and return a handler or None."""
333 """Inspect line_info and return a handler or None."""
334 return None
334 return None
335
335
336
336
337 class EmacsChecker(PrefilterChecker):
337 class EmacsChecker(PrefilterChecker):
338
338
339 priority = Int(100)
339 priority = Int(100, config=True)
340
340
341 def check(self, line_info):
341 def check(self, line_info):
342 "Emacs ipython-mode tags certain input lines."
342 "Emacs ipython-mode tags certain input lines."
343 if line_info.line.endswith('# PYTHON-MODE'):
343 if line_info.line.endswith('# PYTHON-MODE'):
344 return self.prefilter_manager.get_handler_by_name('emacs')
344 return self.prefilter_manager.get_handler_by_name('emacs')
345 else:
345 else:
346 return None
346 return None
347
347
348
348
349 class ShellEscapeChecker(PrefilterChecker):
349 class ShellEscapeChecker(PrefilterChecker):
350
350
351 priority = Int(200)
351 priority = Int(200, config=True)
352
352
353 def check(self, line_info):
353 def check(self, line_info):
354 if line_info.line.lstrip().startswith(ESC_SHELL):
354 if line_info.line.lstrip().startswith(ESC_SHELL):
355 return self.prefilter_manager.get_handler_by_name('shell')
355 return self.prefilter_manager.get_handler_by_name('shell')
356
356
357
357
358 class IPyAutocallChecker(PrefilterChecker):
358 class IPyAutocallChecker(PrefilterChecker):
359
359
360 priority = Int(300)
360 priority = Int(300, config=True)
361
361
362 def check(self, line_info):
362 def check(self, line_info):
363 "Instances of IPyAutocall in user_ns get autocalled immediately"
363 "Instances of IPyAutocall in user_ns get autocalled immediately"
364 obj = self.shell.user_ns.get(line_info.ifun, None)
364 obj = self.shell.user_ns.get(line_info.ifun, None)
365 if isinstance(obj, IPyAutocall):
365 if isinstance(obj, IPyAutocall):
366 obj.set_ip(self.shell)
366 obj.set_ip(self.shell)
367 return self.prefilter_manager.get_handler_by_name('auto')
367 return self.prefilter_manager.get_handler_by_name('auto')
368 else:
368 else:
369 return None
369 return None
370
370
371
371
372 class MultiLineMagicChecker(PrefilterChecker):
372 class MultiLineMagicChecker(PrefilterChecker):
373
373
374 priority = Int(400)
374 priority = Int(400, config=True)
375
375
376 def check(self, line_info):
376 def check(self, line_info):
377 "Allow ! and !! in multi-line statements if multi_line_specials is on"
377 "Allow ! and !! in multi-line statements if multi_line_specials is on"
378 # Note that this one of the only places we check the first character of
378 # Note that this one of the only places we check the first character of
379 # ifun and *not* the pre_char. Also note that the below test matches
379 # ifun and *not* the pre_char. Also note that the below test matches
380 # both ! and !!.
380 # both ! and !!.
381 if line_info.continue_prompt \
381 if line_info.continue_prompt \
382 and self.prefilter_manager.multi_line_specials:
382 and self.prefilter_manager.multi_line_specials:
383 if line_info.ifun.startswith(ESC_MAGIC):
383 if line_info.ifun.startswith(ESC_MAGIC):
384 return self.prefilter_manager.get_handler_by_name('magic')
384 return self.prefilter_manager.get_handler_by_name('magic')
385 else:
385 else:
386 return None
386 return None
387
387
388
388
389 class EscCharsChecker(PrefilterChecker):
389 class EscCharsChecker(PrefilterChecker):
390
390
391 priority = Int(500)
391 priority = Int(500, config=True)
392
392
393 def check(self, line_info):
393 def check(self, line_info):
394 """Check for escape character and return either a handler to handle it,
394 """Check for escape character and return either a handler to handle it,
395 or None if there is no escape char."""
395 or None if there is no escape char."""
396 if line_info.line[-1] == ESC_HELP \
396 if line_info.line[-1] == ESC_HELP \
397 and line_info.pre_char != ESC_SHELL \
397 and line_info.pre_char != ESC_SHELL \
398 and line_info.pre_char != ESC_SH_CAP:
398 and line_info.pre_char != ESC_SH_CAP:
399 # the ? can be at the end, but *not* for either kind of shell escape,
399 # the ? can be at the end, but *not* for either kind of shell escape,
400 # because a ? can be a vaild final char in a shell cmd
400 # because a ? can be a vaild final char in a shell cmd
401 return self.prefilter_manager.get_handler_by_name('help')
401 return self.prefilter_manager.get_handler_by_name('help')
402 else:
402 else:
403 # This returns None like it should if no handler exists
403 # This returns None like it should if no handler exists
404 return self.prefilter_manager.get_handler_by_esc(line_info.pre_char)
404 return self.prefilter_manager.get_handler_by_esc(line_info.pre_char)
405
405
406
406
407 class AssignmentChecker(PrefilterChecker):
407 class AssignmentChecker(PrefilterChecker):
408
408
409 priority = Int(600)
409 priority = Int(600, config=True)
410
410
411 def check(self, line_info):
411 def check(self, line_info):
412 """Check to see if user is assigning to a var for the first time, in
412 """Check to see if user is assigning to a var for the first time, in
413 which case we want to avoid any sort of automagic / autocall games.
413 which case we want to avoid any sort of automagic / autocall games.
414
414
415 This allows users to assign to either alias or magic names true python
415 This allows users to assign to either alias or magic names true python
416 variables (the magic/alias systems always take second seat to true
416 variables (the magic/alias systems always take second seat to true
417 python code). E.g. ls='hi', or ls,that=1,2"""
417 python code). E.g. ls='hi', or ls,that=1,2"""
418 if line_info.the_rest and line_info.the_rest[0] in '=,':
418 if line_info.the_rest and line_info.the_rest[0] in '=,':
419 return self.prefilter_manager.get_handler_by_name('normal')
419 return self.prefilter_manager.get_handler_by_name('normal')
420 else:
420 else:
421 return None
421 return None
422
422
423
423
424 class AutoMagicChecker(PrefilterChecker):
424 class AutoMagicChecker(PrefilterChecker):
425
425
426 priority = Int(700)
426 priority = Int(700, config=True)
427
427
428 def check(self, line_info):
428 def check(self, line_info):
429 """If the ifun is magic, and automagic is on, run it. Note: normal,
429 """If the ifun is magic, and automagic is on, run it. Note: normal,
430 non-auto magic would already have been triggered via '%' in
430 non-auto magic would already have been triggered via '%' in
431 check_esc_chars. This just checks for automagic. Also, before
431 check_esc_chars. This just checks for automagic. Also, before
432 triggering the magic handler, make sure that there is nothing in the
432 triggering the magic handler, make sure that there is nothing in the
433 user namespace which could shadow it."""
433 user namespace which could shadow it."""
434 if not self.shell.automagic or not hasattr(self.shell,'magic_'+line_info.ifun):
434 if not self.shell.automagic or not hasattr(self.shell,'magic_'+line_info.ifun):
435 return None
435 return None
436
436
437 # We have a likely magic method. Make sure we should actually call it.
437 # We have a likely magic method. Make sure we should actually call it.
438 if line_info.continue_prompt and not self.shell.multi_line_specials:
438 if line_info.continue_prompt and not self.shell.multi_line_specials:
439 return None
439 return None
440
440
441 head = line_info.ifun.split('.',1)[0]
441 head = line_info.ifun.split('.',1)[0]
442 if is_shadowed(head, self.shell):
442 if is_shadowed(head, self.shell):
443 return None
443 return None
444
444
445 return self.prefilter_manager.get_handler_by_name('magic')
445 return self.prefilter_manager.get_handler_by_name('magic')
446
446
447
447
448 class AliasChecker(PrefilterChecker):
448 class AliasChecker(PrefilterChecker):
449
449
450 priority = Int(800)
450 priority = Int(800, config=True)
451
451
452 @auto_attr
452 @auto_attr
453 def alias_manager(self):
453 def alias_manager(self):
454 return AliasManager.get_instances(root=self.root)[0]
454 return AliasManager.get_instances(root=self.root)[0]
455
455
456 def check(self, line_info):
456 def check(self, line_info):
457 "Check if the initital identifier on the line is an alias."
457 "Check if the initital identifier on the line is an alias."
458 # Note: aliases can not contain '.'
458 # Note: aliases can not contain '.'
459 head = line_info.ifun.split('.',1)[0]
459 head = line_info.ifun.split('.',1)[0]
460 if line_info.ifun not in self.alias_manager \
460 if line_info.ifun not in self.alias_manager \
461 or head not in self.alias_manager \
461 or head not in self.alias_manager \
462 or is_shadowed(head, self.shell):
462 or is_shadowed(head, self.shell):
463 return None
463 return None
464
464
465 return self.prefilter_manager.get_handler_by_name('alias')
465 return self.prefilter_manager.get_handler_by_name('alias')
466
466
467
467
468 class PythonOpsChecker(PrefilterChecker):
468 class PythonOpsChecker(PrefilterChecker):
469
469
470 priority = Int(900)
470 priority = Int(900, config=True)
471
471
472 def check(self, line_info):
472 def check(self, line_info):
473 """If the 'rest' of the line begins with a function call or pretty much
473 """If the 'rest' of the line begins with a function call or pretty much
474 any python operator, we should simply execute the line (regardless of
474 any python operator, we should simply execute the line (regardless of
475 whether or not there's a possible autocall expansion). This avoids
475 whether or not there's a possible autocall expansion). This avoids
476 spurious (and very confusing) geattr() accesses."""
476 spurious (and very confusing) geattr() accesses."""
477 if line_info.the_rest and line_info.the_rest[0] in '!=()<>,+*/%^&|':
477 if line_info.the_rest and line_info.the_rest[0] in '!=()<>,+*/%^&|':
478 return self.prefilter_manager.get_handler_by_name('normal')
478 return self.prefilter_manager.get_handler_by_name('normal')
479 else:
479 else:
480 return None
480 return None
481
481
482
482
483 class AutocallChecker(PrefilterChecker):
483 class AutocallChecker(PrefilterChecker):
484
484
485 priority = Int(1000)
485 priority = Int(1000, config=True)
486
486
487 def check(self, line_info):
487 def check(self, line_info):
488 "Check if the initial word/function is callable and autocall is on."
488 "Check if the initial word/function is callable and autocall is on."
489 if not self.shell.autocall:
489 if not self.shell.autocall:
490 return None
490 return None
491
491
492 oinfo = line_info.ofind(self.shell) # This can mutate state via getattr
492 oinfo = line_info.ofind(self.shell) # This can mutate state via getattr
493 if not oinfo['found']:
493 if not oinfo['found']:
494 return None
494 return None
495
495
496 if callable(oinfo['obj']) \
496 if callable(oinfo['obj']) \
497 and (not re_exclude_auto.match(line_info.the_rest)) \
497 and (not re_exclude_auto.match(line_info.the_rest)) \
498 and re_fun_name.match(line_info.ifun):
498 and re_fun_name.match(line_info.ifun):
499 return self.prefilter_manager.get_handler_by_name('auto')
499 return self.prefilter_manager.get_handler_by_name('auto')
500 else:
500 else:
501 return None
501 return None
502
502
503
503
504 #-----------------------------------------------------------------------------
504 #-----------------------------------------------------------------------------
505 # Prefilter handlers
505 # Prefilter handlers
506 #-----------------------------------------------------------------------------
506 #-----------------------------------------------------------------------------
507
507
508
508
509 class PrefilterHandler(Component):
509 class PrefilterHandler(Component):
510
510
511 handler_name = Str('normal')
511 handler_name = Str('normal')
512 esc_strings = List([])
512 esc_strings = List([])
513 shell = Any
513 shell = Any
514 prefilter_manager = Any
514 prefilter_manager = Any
515
515
516 def __init__(self, parent, config=None):
516 def __init__(self, parent, config=None):
517 super(PrefilterHandler, self).__init__(parent, config=config)
517 super(PrefilterHandler, self).__init__(parent, config=config)
518 self.prefilter_manager.register_handler(
518 self.prefilter_manager.register_handler(
519 self.handler_name,
519 self.handler_name,
520 self,
520 self,
521 self.esc_strings
521 self.esc_strings
522 )
522 )
523
523
524 @auto_attr
524 @auto_attr
525 def shell(self):
525 def shell(self):
526 shell = Component.get_instances(
526 shell = Component.get_instances(
527 root=self.root,
527 root=self.root,
528 klass='IPython.core.iplib.InteractiveShell'
528 klass='IPython.core.iplib.InteractiveShell'
529 )[0]
529 )[0]
530 return shell
530 return shell
531
531
532 @auto_attr
532 @auto_attr
533 def prefilter_manager(self):
533 def prefilter_manager(self):
534 return PrefilterManager.get_instances(root=self.root)[0]
534 return PrefilterManager.get_instances(root=self.root)[0]
535
535
536 def handle(self, line_info):
536 def handle(self, line_info):
537 """Handle normal input lines. Use as a template for handlers."""
537 """Handle normal input lines. Use as a template for handlers."""
538
538
539 # With autoindent on, we need some way to exit the input loop, and I
539 # With autoindent on, we need some way to exit the input loop, and I
540 # don't want to force the user to have to backspace all the way to
540 # don't want to force the user to have to backspace all the way to
541 # clear the line. The rule will be in this case, that either two
541 # clear the line. The rule will be in this case, that either two
542 # lines of pure whitespace in a row, or a line of pure whitespace but
542 # lines of pure whitespace in a row, or a line of pure whitespace but
543 # of a size different to the indent level, will exit the input loop.
543 # of a size different to the indent level, will exit the input loop.
544 line = line_info.line
544 line = line_info.line
545 continue_prompt = line_info.continue_prompt
545 continue_prompt = line_info.continue_prompt
546
546
547 if (continue_prompt and self.shell.autoindent and line.isspace() and
547 if (continue_prompt and self.shell.autoindent and line.isspace() and
548 (0 < abs(len(line) - self.shell.indent_current_nsp) <= 2 or
548 (0 < abs(len(line) - self.shell.indent_current_nsp) <= 2 or
549 (self.shell.buffer[-1]).isspace() )):
549 (self.shell.buffer[-1]).isspace() )):
550 line = ''
550 line = ''
551
551
552 self.shell.log(line, line, continue_prompt)
552 self.shell.log(line, line, continue_prompt)
553 return line
553 return line
554
554
555
555
556 class AliasHandler(PrefilterHandler):
556 class AliasHandler(PrefilterHandler):
557
557
558 handler_name = Str('alias')
558 handler_name = Str('alias')
559 esc_strings = List([])
559 esc_strings = List([])
560
560
561 @auto_attr
561 @auto_attr
562 def alias_manager(self):
562 def alias_manager(self):
563 return AliasManager.get_instances(root=self.root)[0]
563 return AliasManager.get_instances(root=self.root)[0]
564
564
565 def handle(self, line_info):
565 def handle(self, line_info):
566 """Handle alias input lines. """
566 """Handle alias input lines. """
567 transformed = self.alias_manager.expand_aliases(line_info.ifun,line_info.the_rest)
567 transformed = self.alias_manager.expand_aliases(line_info.ifun,line_info.the_rest)
568 # pre is needed, because it carries the leading whitespace. Otherwise
568 # pre is needed, because it carries the leading whitespace. Otherwise
569 # aliases won't work in indented sections.
569 # aliases won't work in indented sections.
570 line_out = '%s_ip.system(%s)' % (line_info.pre_whitespace,
570 line_out = '%sget_ipython().system(%s)' % (line_info.pre_whitespace,
571 make_quoted_expr(transformed))
571 make_quoted_expr(transformed))
572
572
573 self.shell.log(line_info.line, line_out, line_info.continue_prompt)
573 self.shell.log(line_info.line, line_out, line_info.continue_prompt)
574 return line_out
574 return line_out
575
575
576
576
577 class ShellEscapeHandler(PrefilterHandler):
577 class ShellEscapeHandler(PrefilterHandler):
578
578
579 handler_name = Str('shell')
579 handler_name = Str('shell')
580 esc_strings = List([ESC_SHELL, ESC_SH_CAP])
580 esc_strings = List([ESC_SHELL, ESC_SH_CAP])
581
581
582 def handle(self, line_info):
582 def handle(self, line_info):
583 """Execute the line in a shell, empty return value"""
583 """Execute the line in a shell, empty return value"""
584 magic_handler = self.prefilter_manager.get_handler_by_name('magic')
584 magic_handler = self.prefilter_manager.get_handler_by_name('magic')
585
585
586 line = line_info.line
586 line = line_info.line
587 if line.lstrip().startswith(ESC_SH_CAP):
587 if line.lstrip().startswith(ESC_SH_CAP):
588 # rewrite LineInfo's line, ifun and the_rest to properly hold the
588 # rewrite LineInfo's line, ifun and the_rest to properly hold the
589 # call to %sx and the actual command to be executed, so
589 # call to %sx and the actual command to be executed, so
590 # handle_magic can work correctly. Note that this works even if
590 # handle_magic can work correctly. Note that this works even if
591 # the line is indented, so it handles multi_line_specials
591 # the line is indented, so it handles multi_line_specials
592 # properly.
592 # properly.
593 new_rest = line.lstrip()[2:]
593 new_rest = line.lstrip()[2:]
594 line_info.line = '%ssx %s' % (ESC_MAGIC, new_rest)
594 line_info.line = '%ssx %s' % (ESC_MAGIC, new_rest)
595 line_info.ifun = 'sx'
595 line_info.ifun = 'sx'
596 line_info.the_rest = new_rest
596 line_info.the_rest = new_rest
597 return magic_handler.handle(line_info)
597 return magic_handler.handle(line_info)
598 else:
598 else:
599 cmd = line.lstrip().lstrip(ESC_SHELL)
599 cmd = line.lstrip().lstrip(ESC_SHELL)
600 line_out = '%s_ip.system(%s)' % (line_info.pre_whitespace,
600 line_out = '%sget_ipython().system(%s)' % (line_info.pre_whitespace,
601 make_quoted_expr(cmd))
601 make_quoted_expr(cmd))
602 # update cache/log and return
602 # update cache/log and return
603 self.shell.log(line, line_out, line_info.continue_prompt)
603 self.shell.log(line, line_out, line_info.continue_prompt)
604 return line_out
604 return line_out
605
605
606
606
607 class MagicHandler(PrefilterHandler):
607 class MagicHandler(PrefilterHandler):
608
608
609 handler_name = Str('magic')
609 handler_name = Str('magic')
610 esc_strings = List(['%'])
610 esc_strings = List([ESC_MAGIC])
611
611
612 def handle(self, line_info):
612 def handle(self, line_info):
613 """Execute magic functions."""
613 """Execute magic functions."""
614 ifun = line_info.ifun
614 ifun = line_info.ifun
615 the_rest = line_info.the_rest
615 the_rest = line_info.the_rest
616 cmd = '%s_ip.magic(%s)' % (line_info.pre_whitespace,
616 cmd = '%sget_ipython().magic(%s)' % (line_info.pre_whitespace,
617 make_quoted_expr(ifun + " " + the_rest))
617 make_quoted_expr(ifun + " " + the_rest))
618 self.shell.log(line_info.line, cmd, line_info.continue_prompt)
618 self.shell.log(line_info.line, cmd, line_info.continue_prompt)
619 return cmd
619 return cmd
620
620
621
621
622 class AutoHandler(PrefilterHandler):
622 class AutoHandler(PrefilterHandler):
623
623
624 handler_name = Str('auto')
624 handler_name = Str('auto')
625 esc_strings = List([ESC_PAREN, ESC_QUOTE, ESC_QUOTE2])
625 esc_strings = List([ESC_PAREN, ESC_QUOTE, ESC_QUOTE2])
626
626
627 def handle(self, line_info):
627 def handle(self, line_info):
628 """Hande lines which can be auto-executed, quoting if requested."""
628 """Hande lines which can be auto-executed, quoting if requested."""
629 line = line_info.line
629 line = line_info.line
630 ifun = line_info.ifun
630 ifun = line_info.ifun
631 the_rest = line_info.the_rest
631 the_rest = line_info.the_rest
632 pre = line_info.pre
632 pre = line_info.pre
633 continue_prompt = line_info.continue_prompt
633 continue_prompt = line_info.continue_prompt
634 obj = line_info.ofind(self)['obj']
634 obj = line_info.ofind(self)['obj']
635
635
636 #print 'pre <%s> ifun <%s> rest <%s>' % (pre,ifun,the_rest) # dbg
636 #print 'pre <%s> ifun <%s> rest <%s>' % (pre,ifun,the_rest) # dbg
637
637
638 # This should only be active for single-line input!
638 # This should only be active for single-line input!
639 if continue_prompt:
639 if continue_prompt:
640 self.log(line,line,continue_prompt)
640 self.log(line,line,continue_prompt)
641 return line
641 return line
642
642
643 force_auto = isinstance(obj, IPyAutocall)
643 force_auto = isinstance(obj, IPyAutocall)
644 auto_rewrite = True
644 auto_rewrite = True
645
645
646 if pre == ESC_QUOTE:
646 if pre == ESC_QUOTE:
647 # Auto-quote splitting on whitespace
647 # Auto-quote splitting on whitespace
648 newcmd = '%s("%s")' % (ifun,'", "'.join(the_rest.split()) )
648 newcmd = '%s("%s")' % (ifun,'", "'.join(the_rest.split()) )
649 elif pre == ESC_QUOTE2:
649 elif pre == ESC_QUOTE2:
650 # Auto-quote whole string
650 # Auto-quote whole string
651 newcmd = '%s("%s")' % (ifun,the_rest)
651 newcmd = '%s("%s")' % (ifun,the_rest)
652 elif pre == ESC_PAREN:
652 elif pre == ESC_PAREN:
653 newcmd = '%s(%s)' % (ifun,",".join(the_rest.split()))
653 newcmd = '%s(%s)' % (ifun,",".join(the_rest.split()))
654 else:
654 else:
655 # Auto-paren.
655 # Auto-paren.
656 # We only apply it to argument-less calls if the autocall
656 # We only apply it to argument-less calls if the autocall
657 # parameter is set to 2. We only need to check that autocall is <
657 # parameter is set to 2. We only need to check that autocall is <
658 # 2, since this function isn't called unless it's at least 1.
658 # 2, since this function isn't called unless it's at least 1.
659 if not the_rest and (self.autocall < 2) and not force_auto:
659 if not the_rest and (self.shell.autocall < 2) and not force_auto:
660 newcmd = '%s %s' % (ifun,the_rest)
660 newcmd = '%s %s' % (ifun,the_rest)
661 auto_rewrite = False
661 auto_rewrite = False
662 else:
662 else:
663 if not force_auto and the_rest.startswith('['):
663 if not force_auto and the_rest.startswith('['):
664 if hasattr(obj,'__getitem__'):
664 if hasattr(obj,'__getitem__'):
665 # Don't autocall in this case: item access for an object
665 # Don't autocall in this case: item access for an object
666 # which is BOTH callable and implements __getitem__.
666 # which is BOTH callable and implements __getitem__.
667 newcmd = '%s %s' % (ifun,the_rest)
667 newcmd = '%s %s' % (ifun,the_rest)
668 auto_rewrite = False
668 auto_rewrite = False
669 else:
669 else:
670 # if the object doesn't support [] access, go ahead and
670 # if the object doesn't support [] access, go ahead and
671 # autocall
671 # autocall
672 newcmd = '%s(%s)' % (ifun.rstrip(),the_rest)
672 newcmd = '%s(%s)' % (ifun.rstrip(),the_rest)
673 elif the_rest.endswith(';'):
673 elif the_rest.endswith(';'):
674 newcmd = '%s(%s);' % (ifun.rstrip(),the_rest[:-1])
674 newcmd = '%s(%s);' % (ifun.rstrip(),the_rest[:-1])
675 else:
675 else:
676 newcmd = '%s(%s)' % (ifun.rstrip(), the_rest)
676 newcmd = '%s(%s)' % (ifun.rstrip(), the_rest)
677
677
678 if auto_rewrite:
678 if auto_rewrite:
679 rw = self.shell.outputcache.prompt1.auto_rewrite() + newcmd
679 rw = self.shell.outputcache.prompt1.auto_rewrite() + newcmd
680
680
681 try:
681 try:
682 # plain ascii works better w/ pyreadline, on some machines, so
682 # plain ascii works better w/ pyreadline, on some machines, so
683 # we use it and only print uncolored rewrite if we have unicode
683 # we use it and only print uncolored rewrite if we have unicode
684 rw = str(rw)
684 rw = str(rw)
685 print >>Term.cout, rw
685 print >>Term.cout, rw
686 except UnicodeEncodeError:
686 except UnicodeEncodeError:
687 print "-------------->" + newcmd
687 print "-------------->" + newcmd
688
688
689 # log what is now valid Python, not the actual user input (without the
689 # log what is now valid Python, not the actual user input (without the
690 # final newline)
690 # final newline)
691 self.shell.log(line,newcmd,continue_prompt)
691 self.shell.log(line,newcmd,continue_prompt)
692 return newcmd
692 return newcmd
693
693
694
694
695 class HelpHandler(PrefilterHandler):
695 class HelpHandler(PrefilterHandler):
696
696
697 handler_name = Str('help')
697 handler_name = Str('help')
698 esc_strings = List([ESC_HELP])
698 esc_strings = List([ESC_HELP])
699
699
700 def handle(self, line_info):
700 def handle(self, line_info):
701 """Try to get some help for the object.
701 """Try to get some help for the object.
702
702
703 obj? or ?obj -> basic information.
703 obj? or ?obj -> basic information.
704 obj?? or ??obj -> more details.
704 obj?? or ??obj -> more details.
705 """
705 """
706 normal_handler = self.prefilter_manager.get_handler_by_name('normal')
706 normal_handler = self.prefilter_manager.get_handler_by_name('normal')
707 line = line_info.line
707 line = line_info.line
708 # We need to make sure that we don't process lines which would be
708 # We need to make sure that we don't process lines which would be
709 # otherwise valid python, such as "x=1 # what?"
709 # otherwise valid python, such as "x=1 # what?"
710 try:
710 try:
711 codeop.compile_command(line)
711 codeop.compile_command(line)
712 except SyntaxError:
712 except SyntaxError:
713 # We should only handle as help stuff which is NOT valid syntax
713 # We should only handle as help stuff which is NOT valid syntax
714 if line[0]==ESC_HELP:
714 if line[0]==ESC_HELP:
715 line = line[1:]
715 line = line[1:]
716 elif line[-1]==ESC_HELP:
716 elif line[-1]==ESC_HELP:
717 line = line[:-1]
717 line = line[:-1]
718 self.shell.log(line, '#?'+line, line_info.continue_prompt)
718 self.shell.log(line, '#?'+line, line_info.continue_prompt)
719 if line:
719 if line:
720 #print 'line:<%r>' % line # dbg
720 #print 'line:<%r>' % line # dbg
721 self.shell.magic_pinfo(line)
721 self.shell.magic_pinfo(line)
722 else:
722 else:
723 page(self.shell.usage, screen_lines=self.shell.usable_screen_length)
723 page(self.shell.usage, screen_lines=self.shell.usable_screen_length)
724 return '' # Empty string is needed here!
724 return '' # Empty string is needed here!
725 except:
725 except:
726 raise
726 raise
727 # Pass any other exceptions through to the normal handler
727 # Pass any other exceptions through to the normal handler
728 return normal_handler.handle(line_info)
728 return normal_handler.handle(line_info)
729 else:
729 else:
730 raise
730 raise
731 # If the code compiles ok, we should handle it normally
731 # If the code compiles ok, we should handle it normally
732 return normal_handler.handle(line_info)
732 return normal_handler.handle(line_info)
733
733
734
734
735 class EmacsHandler(PrefilterHandler):
735 class EmacsHandler(PrefilterHandler):
736
736
737 handler_name = Str('emacs')
737 handler_name = Str('emacs')
738 esc_strings = List([])
738 esc_strings = List([])
739
739
740 def handle(self, line_info):
740 def handle(self, line_info):
741 """Handle input lines marked by python-mode."""
741 """Handle input lines marked by python-mode."""
742
742
743 # Currently, nothing is done. Later more functionality can be added
743 # Currently, nothing is done. Later more functionality can be added
744 # here if needed.
744 # here if needed.
745
745
746 # The input cache shouldn't be updated
746 # The input cache shouldn't be updated
747 return line_info.line
747 return line_info.line
748
748
749
749
750 #-----------------------------------------------------------------------------
750 #-----------------------------------------------------------------------------
751 # Defaults
751 # Defaults
752 #-----------------------------------------------------------------------------
752 #-----------------------------------------------------------------------------
753
753
754
754
755 _default_checkers = [
755 _default_checkers = [
756 EmacsChecker,
756 EmacsChecker,
757 ShellEscapeChecker,
757 ShellEscapeChecker,
758 IPyAutocallChecker,
758 IPyAutocallChecker,
759 MultiLineMagicChecker,
759 MultiLineMagicChecker,
760 EscCharsChecker,
760 EscCharsChecker,
761 AssignmentChecker,
761 AssignmentChecker,
762 AutoMagicChecker,
762 AutoMagicChecker,
763 AliasChecker,
763 AliasChecker,
764 PythonOpsChecker,
764 PythonOpsChecker,
765 AutocallChecker
765 AutocallChecker
766 ]
766 ]
767
767
768 _default_handlers = [
768 _default_handlers = [
769 PrefilterHandler,
769 PrefilterHandler,
770 AliasHandler,
770 AliasHandler,
771 ShellEscapeHandler,
771 ShellEscapeHandler,
772 MagicHandler,
772 MagicHandler,
773 AutoHandler,
773 AutoHandler,
774 HelpHandler,
774 HelpHandler,
775 EmacsHandler
775 EmacsHandler
776 ]
776 ]
777
777
@@ -1,627 +1,630 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 Classes for handling input/output prompts.
3 Classes for handling input/output prompts.
4 """
4 """
5
5
6 #*****************************************************************************
6 #*****************************************************************************
7 # Copyright (C) 2008-2009 The IPython Development Team
7 # Copyright (C) 2008-2009 The IPython Development Team
8 # Copyright (C) 2001-2007 Fernando Perez <fperez@colorado.edu>
8 # Copyright (C) 2001-2007 Fernando Perez <fperez@colorado.edu>
9 #
9 #
10 # Distributed under the terms of the BSD License. The full license is in
10 # Distributed under the terms of the BSD License. The full license is in
11 # the file COPYING, distributed as part of this software.
11 # the file COPYING, distributed as part of this software.
12 #*****************************************************************************
12 #*****************************************************************************
13
13
14 #****************************************************************************
14 #****************************************************************************
15 # Required modules
15 # Required modules
16 import __builtin__
16 import __builtin__
17 import os
17 import os
18 import socket
18 import socket
19 import sys
19 import sys
20 import time
20 import time
21
21
22 # IPython's own
22 # IPython's own
23 from IPython.utils import coloransi
23 from IPython.utils import coloransi
24 from IPython.core import release
24 from IPython.core import release
25 from IPython.external.Itpl import ItplNS
25 from IPython.external.Itpl import ItplNS
26 from IPython.core.error import TryNext
26 from IPython.core.error import TryNext
27 from IPython.utils.ipstruct import Struct
27 from IPython.utils.ipstruct import Struct
28 from IPython.core.macro import Macro
28 from IPython.core.macro import Macro
29 import IPython.utils.generics
29 import IPython.utils.generics
30
30
31 from IPython.utils.genutils import *
31 from IPython.utils.genutils import *
32
32
33 #****************************************************************************
33 #****************************************************************************
34 #Color schemes for Prompts.
34 #Color schemes for Prompts.
35
35
36 PromptColors = coloransi.ColorSchemeTable()
36 PromptColors = coloransi.ColorSchemeTable()
37 InputColors = coloransi.InputTermColors # just a shorthand
37 InputColors = coloransi.InputTermColors # just a shorthand
38 Colors = coloransi.TermColors # just a shorthand
38 Colors = coloransi.TermColors # just a shorthand
39
39
40 PromptColors.add_scheme(coloransi.ColorScheme(
40 PromptColors.add_scheme(coloransi.ColorScheme(
41 'NoColor',
41 'NoColor',
42 in_prompt = InputColors.NoColor, # Input prompt
42 in_prompt = InputColors.NoColor, # Input prompt
43 in_number = InputColors.NoColor, # Input prompt number
43 in_number = InputColors.NoColor, # Input prompt number
44 in_prompt2 = InputColors.NoColor, # Continuation prompt
44 in_prompt2 = InputColors.NoColor, # Continuation prompt
45 in_normal = InputColors.NoColor, # color off (usu. Colors.Normal)
45 in_normal = InputColors.NoColor, # color off (usu. Colors.Normal)
46
46
47 out_prompt = Colors.NoColor, # Output prompt
47 out_prompt = Colors.NoColor, # Output prompt
48 out_number = Colors.NoColor, # Output prompt number
48 out_number = Colors.NoColor, # Output prompt number
49
49
50 normal = Colors.NoColor # color off (usu. Colors.Normal)
50 normal = Colors.NoColor # color off (usu. Colors.Normal)
51 ))
51 ))
52
52
53 # make some schemes as instances so we can copy them for modification easily:
53 # make some schemes as instances so we can copy them for modification easily:
54 __PColLinux = coloransi.ColorScheme(
54 __PColLinux = coloransi.ColorScheme(
55 'Linux',
55 'Linux',
56 in_prompt = InputColors.Green,
56 in_prompt = InputColors.Green,
57 in_number = InputColors.LightGreen,
57 in_number = InputColors.LightGreen,
58 in_prompt2 = InputColors.Green,
58 in_prompt2 = InputColors.Green,
59 in_normal = InputColors.Normal, # color off (usu. Colors.Normal)
59 in_normal = InputColors.Normal, # color off (usu. Colors.Normal)
60
60
61 out_prompt = Colors.Red,
61 out_prompt = Colors.Red,
62 out_number = Colors.LightRed,
62 out_number = Colors.LightRed,
63
63
64 normal = Colors.Normal
64 normal = Colors.Normal
65 )
65 )
66 # Don't forget to enter it into the table!
66 # Don't forget to enter it into the table!
67 PromptColors.add_scheme(__PColLinux)
67 PromptColors.add_scheme(__PColLinux)
68
68
69 # Slightly modified Linux for light backgrounds
69 # Slightly modified Linux for light backgrounds
70 __PColLightBG = __PColLinux.copy('LightBG')
70 __PColLightBG = __PColLinux.copy('LightBG')
71
71
72 __PColLightBG.colors.update(
72 __PColLightBG.colors.update(
73 in_prompt = InputColors.Blue,
73 in_prompt = InputColors.Blue,
74 in_number = InputColors.LightBlue,
74 in_number = InputColors.LightBlue,
75 in_prompt2 = InputColors.Blue
75 in_prompt2 = InputColors.Blue
76 )
76 )
77 PromptColors.add_scheme(__PColLightBG)
77 PromptColors.add_scheme(__PColLightBG)
78
78
79 del Colors,InputColors
79 del Colors,InputColors
80
80
81 #-----------------------------------------------------------------------------
81 #-----------------------------------------------------------------------------
82 def multiple_replace(dict, text):
82 def multiple_replace(dict, text):
83 """ Replace in 'text' all occurences of any key in the given
83 """ Replace in 'text' all occurences of any key in the given
84 dictionary by its corresponding value. Returns the new string."""
84 dictionary by its corresponding value. Returns the new string."""
85
85
86 # Function by Xavier Defrang, originally found at:
86 # Function by Xavier Defrang, originally found at:
87 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/81330
87 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/81330
88
88
89 # Create a regular expression from the dictionary keys
89 # Create a regular expression from the dictionary keys
90 regex = re.compile("(%s)" % "|".join(map(re.escape, dict.keys())))
90 regex = re.compile("(%s)" % "|".join(map(re.escape, dict.keys())))
91 # For each match, look-up corresponding value in dictionary
91 # For each match, look-up corresponding value in dictionary
92 return regex.sub(lambda mo: dict[mo.string[mo.start():mo.end()]], text)
92 return regex.sub(lambda mo: dict[mo.string[mo.start():mo.end()]], text)
93
93
94 #-----------------------------------------------------------------------------
94 #-----------------------------------------------------------------------------
95 # Special characters that can be used in prompt templates, mainly bash-like
95 # Special characters that can be used in prompt templates, mainly bash-like
96
96
97 # If $HOME isn't defined (Windows), make it an absurd string so that it can
97 # If $HOME isn't defined (Windows), make it an absurd string so that it can
98 # never be expanded out into '~'. Basically anything which can never be a
98 # never be expanded out into '~'. Basically anything which can never be a
99 # reasonable directory name will do, we just want the $HOME -> '~' operation
99 # reasonable directory name will do, we just want the $HOME -> '~' operation
100 # to become a no-op. We pre-compute $HOME here so it's not done on every
100 # to become a no-op. We pre-compute $HOME here so it's not done on every
101 # prompt call.
101 # prompt call.
102
102
103 # FIXME:
103 # FIXME:
104
104
105 # - This should be turned into a class which does proper namespace management,
105 # - This should be turned into a class which does proper namespace management,
106 # since the prompt specials need to be evaluated in a certain namespace.
106 # since the prompt specials need to be evaluated in a certain namespace.
107 # Currently it's just globals, which need to be managed manually by code
107 # Currently it's just globals, which need to be managed manually by code
108 # below.
108 # below.
109
109
110 # - I also need to split up the color schemes from the prompt specials
110 # - I also need to split up the color schemes from the prompt specials
111 # somehow. I don't have a clean design for that quite yet.
111 # somehow. I don't have a clean design for that quite yet.
112
112
113 HOME = os.environ.get("HOME","//////:::::ZZZZZ,,,~~~")
113 HOME = os.environ.get("HOME","//////:::::ZZZZZ,,,~~~")
114
114
115 # We precompute a few more strings here for the prompt_specials, which are
115 # We precompute a few more strings here for the prompt_specials, which are
116 # fixed once ipython starts. This reduces the runtime overhead of computing
116 # fixed once ipython starts. This reduces the runtime overhead of computing
117 # prompt strings.
117 # prompt strings.
118 USER = os.environ.get("USER")
118 USER = os.environ.get("USER")
119 HOSTNAME = socket.gethostname()
119 HOSTNAME = socket.gethostname()
120 HOSTNAME_SHORT = HOSTNAME.split(".")[0]
120 HOSTNAME_SHORT = HOSTNAME.split(".")[0]
121 ROOT_SYMBOL = "$#"[os.name=='nt' or os.getuid()==0]
121 ROOT_SYMBOL = "$#"[os.name=='nt' or os.getuid()==0]
122
122
123 prompt_specials_color = {
123 prompt_specials_color = {
124 # Prompt/history count
124 # Prompt/history count
125 '%n' : '${self.col_num}' '${self.cache.prompt_count}' '${self.col_p}',
125 '%n' : '${self.col_num}' '${self.cache.prompt_count}' '${self.col_p}',
126 r'\#': '${self.col_num}' '${self.cache.prompt_count}' '${self.col_p}',
126 r'\#': '${self.col_num}' '${self.cache.prompt_count}' '${self.col_p}',
127 # Just the prompt counter number, WITHOUT any coloring wrappers, so users
127 # Just the prompt counter number, WITHOUT any coloring wrappers, so users
128 # can get numbers displayed in whatever color they want.
128 # can get numbers displayed in whatever color they want.
129 r'\N': '${self.cache.prompt_count}',
129 r'\N': '${self.cache.prompt_count}',
130
130
131 # Prompt/history count, with the actual digits replaced by dots. Used
131 # Prompt/history count, with the actual digits replaced by dots. Used
132 # mainly in continuation prompts (prompt_in2)
132 # mainly in continuation prompts (prompt_in2)
133 #r'\D': '${"."*len(str(self.cache.prompt_count))}',
133 #r'\D': '${"."*len(str(self.cache.prompt_count))}',
134 # More robust form of the above expression, that uses __builtins__
134 # More robust form of the above expression, that uses __builtins__
135 r'\D': '${"."*__builtins__.len(__builtins__.str(self.cache.prompt_count))}',
135 r'\D': '${"."*__builtins__.len(__builtins__.str(self.cache.prompt_count))}',
136
136
137 # Current working directory
137 # Current working directory
138 r'\w': '${os.getcwd()}',
138 r'\w': '${os.getcwd()}',
139 # Current time
139 # Current time
140 r'\t' : '${time.strftime("%H:%M:%S")}',
140 r'\t' : '${time.strftime("%H:%M:%S")}',
141 # Basename of current working directory.
141 # Basename of current working directory.
142 # (use os.sep to make this portable across OSes)
142 # (use os.sep to make this portable across OSes)
143 r'\W' : '${os.getcwd().split("%s")[-1]}' % os.sep,
143 r'\W' : '${os.getcwd().split("%s")[-1]}' % os.sep,
144 # These X<N> are an extension to the normal bash prompts. They return
144 # These X<N> are an extension to the normal bash prompts. They return
145 # N terms of the path, after replacing $HOME with '~'
145 # N terms of the path, after replacing $HOME with '~'
146 r'\X0': '${os.getcwd().replace("%s","~")}' % HOME,
146 r'\X0': '${os.getcwd().replace("%s","~")}' % HOME,
147 r'\X1': '${self.cwd_filt(1)}',
147 r'\X1': '${self.cwd_filt(1)}',
148 r'\X2': '${self.cwd_filt(2)}',
148 r'\X2': '${self.cwd_filt(2)}',
149 r'\X3': '${self.cwd_filt(3)}',
149 r'\X3': '${self.cwd_filt(3)}',
150 r'\X4': '${self.cwd_filt(4)}',
150 r'\X4': '${self.cwd_filt(4)}',
151 r'\X5': '${self.cwd_filt(5)}',
151 r'\X5': '${self.cwd_filt(5)}',
152 # Y<N> are similar to X<N>, but they show '~' if it's the directory
152 # Y<N> are similar to X<N>, but they show '~' if it's the directory
153 # N+1 in the list. Somewhat like %cN in tcsh.
153 # N+1 in the list. Somewhat like %cN in tcsh.
154 r'\Y0': '${self.cwd_filt2(0)}',
154 r'\Y0': '${self.cwd_filt2(0)}',
155 r'\Y1': '${self.cwd_filt2(1)}',
155 r'\Y1': '${self.cwd_filt2(1)}',
156 r'\Y2': '${self.cwd_filt2(2)}',
156 r'\Y2': '${self.cwd_filt2(2)}',
157 r'\Y3': '${self.cwd_filt2(3)}',
157 r'\Y3': '${self.cwd_filt2(3)}',
158 r'\Y4': '${self.cwd_filt2(4)}',
158 r'\Y4': '${self.cwd_filt2(4)}',
159 r'\Y5': '${self.cwd_filt2(5)}',
159 r'\Y5': '${self.cwd_filt2(5)}',
160 # Hostname up to first .
160 # Hostname up to first .
161 r'\h': HOSTNAME_SHORT,
161 r'\h': HOSTNAME_SHORT,
162 # Full hostname
162 # Full hostname
163 r'\H': HOSTNAME,
163 r'\H': HOSTNAME,
164 # Username of current user
164 # Username of current user
165 r'\u': USER,
165 r'\u': USER,
166 # Escaped '\'
166 # Escaped '\'
167 '\\\\': '\\',
167 '\\\\': '\\',
168 # Newline
168 # Newline
169 r'\n': '\n',
169 r'\n': '\n',
170 # Carriage return
170 # Carriage return
171 r'\r': '\r',
171 r'\r': '\r',
172 # Release version
172 # Release version
173 r'\v': release.version,
173 r'\v': release.version,
174 # Root symbol ($ or #)
174 # Root symbol ($ or #)
175 r'\$': ROOT_SYMBOL,
175 r'\$': ROOT_SYMBOL,
176 }
176 }
177
177
178 # A copy of the prompt_specials dictionary but with all color escapes removed,
178 # A copy of the prompt_specials dictionary but with all color escapes removed,
179 # so we can correctly compute the prompt length for the auto_rewrite method.
179 # so we can correctly compute the prompt length for the auto_rewrite method.
180 prompt_specials_nocolor = prompt_specials_color.copy()
180 prompt_specials_nocolor = prompt_specials_color.copy()
181 prompt_specials_nocolor['%n'] = '${self.cache.prompt_count}'
181 prompt_specials_nocolor['%n'] = '${self.cache.prompt_count}'
182 prompt_specials_nocolor[r'\#'] = '${self.cache.prompt_count}'
182 prompt_specials_nocolor[r'\#'] = '${self.cache.prompt_count}'
183
183
184 # Add in all the InputTermColors color escapes as valid prompt characters.
184 # Add in all the InputTermColors color escapes as valid prompt characters.
185 # They all get added as \\C_COLORNAME, so that we don't have any conflicts
185 # They all get added as \\C_COLORNAME, so that we don't have any conflicts
186 # with a color name which may begin with a letter used by any other of the
186 # with a color name which may begin with a letter used by any other of the
187 # allowed specials. This of course means that \\C will never be allowed for
187 # allowed specials. This of course means that \\C will never be allowed for
188 # anything else.
188 # anything else.
189 input_colors = coloransi.InputTermColors
189 input_colors = coloransi.InputTermColors
190 for _color in dir(input_colors):
190 for _color in dir(input_colors):
191 if _color[0] != '_':
191 if _color[0] != '_':
192 c_name = r'\C_'+_color
192 c_name = r'\C_'+_color
193 prompt_specials_color[c_name] = getattr(input_colors,_color)
193 prompt_specials_color[c_name] = getattr(input_colors,_color)
194 prompt_specials_nocolor[c_name] = ''
194 prompt_specials_nocolor[c_name] = ''
195
195
196 # we default to no color for safety. Note that prompt_specials is a global
196 # we default to no color for safety. Note that prompt_specials is a global
197 # variable used by all prompt objects.
197 # variable used by all prompt objects.
198 prompt_specials = prompt_specials_nocolor
198 prompt_specials = prompt_specials_nocolor
199
199
200 #-----------------------------------------------------------------------------
200 #-----------------------------------------------------------------------------
201 def str_safe(arg):
201 def str_safe(arg):
202 """Convert to a string, without ever raising an exception.
202 """Convert to a string, without ever raising an exception.
203
203
204 If str(arg) fails, <ERROR: ... > is returned, where ... is the exception
204 If str(arg) fails, <ERROR: ... > is returned, where ... is the exception
205 error message."""
205 error message."""
206
206
207 try:
207 try:
208 out = str(arg)
208 out = str(arg)
209 except UnicodeError:
209 except UnicodeError:
210 try:
210 try:
211 out = arg.encode('utf_8','replace')
211 out = arg.encode('utf_8','replace')
212 except Exception,msg:
212 except Exception,msg:
213 # let's keep this little duplication here, so that the most common
213 # let's keep this little duplication here, so that the most common
214 # case doesn't suffer from a double try wrapping.
214 # case doesn't suffer from a double try wrapping.
215 out = '<ERROR: %s>' % msg
215 out = '<ERROR: %s>' % msg
216 except Exception,msg:
216 except Exception,msg:
217 out = '<ERROR: %s>' % msg
217 out = '<ERROR: %s>' % msg
218 return out
218 return out
219
219
220 class BasePrompt(object):
220 class BasePrompt(object):
221 """Interactive prompt similar to Mathematica's."""
221 """Interactive prompt similar to Mathematica's."""
222
222
223 def _get_p_template(self):
223 def _get_p_template(self):
224 return self._p_template
224 return self._p_template
225
225
226 def _set_p_template(self,val):
226 def _set_p_template(self,val):
227 self._p_template = val
227 self._p_template = val
228 self.set_p_str()
228 self.set_p_str()
229
229
230 p_template = property(_get_p_template,_set_p_template,
230 p_template = property(_get_p_template,_set_p_template,
231 doc='Template for prompt string creation')
231 doc='Template for prompt string creation')
232
232
233 def __init__(self,cache,sep,prompt,pad_left=False):
233 def __init__(self,cache,sep,prompt,pad_left=False):
234
234
235 # Hack: we access information about the primary prompt through the
235 # Hack: we access information about the primary prompt through the
236 # cache argument. We need this, because we want the secondary prompt
236 # cache argument. We need this, because we want the secondary prompt
237 # to be aligned with the primary one. Color table info is also shared
237 # to be aligned with the primary one. Color table info is also shared
238 # by all prompt classes through the cache. Nice OO spaghetti code!
238 # by all prompt classes through the cache. Nice OO spaghetti code!
239 self.cache = cache
239 self.cache = cache
240 self.sep = sep
240 self.sep = sep
241
241
242 # regexp to count the number of spaces at the end of a prompt
242 # regexp to count the number of spaces at the end of a prompt
243 # expression, useful for prompt auto-rewriting
243 # expression, useful for prompt auto-rewriting
244 self.rspace = re.compile(r'(\s*)$')
244 self.rspace = re.compile(r'(\s*)$')
245 # Flag to left-pad prompt strings to match the length of the primary
245 # Flag to left-pad prompt strings to match the length of the primary
246 # prompt
246 # prompt
247 self.pad_left = pad_left
247 self.pad_left = pad_left
248
248
249 # Set template to create each actual prompt (where numbers change).
249 # Set template to create each actual prompt (where numbers change).
250 # Use a property
250 # Use a property
251 self.p_template = prompt
251 self.p_template = prompt
252 self.set_p_str()
252 self.set_p_str()
253
253
254 def set_p_str(self):
254 def set_p_str(self):
255 """ Set the interpolating prompt strings.
255 """ Set the interpolating prompt strings.
256
256
257 This must be called every time the color settings change, because the
257 This must be called every time the color settings change, because the
258 prompt_specials global may have changed."""
258 prompt_specials global may have changed."""
259
259
260 import os,time # needed in locals for prompt string handling
260 import os,time # needed in locals for prompt string handling
261 loc = locals()
261 loc = locals()
262 try:
262 try:
263 self.p_str = ItplNS('%s%s%s' %
263 self.p_str = ItplNS('%s%s%s' %
264 ('${self.sep}${self.col_p}',
264 ('${self.sep}${self.col_p}',
265 multiple_replace(prompt_specials, self.p_template),
265 multiple_replace(prompt_specials, self.p_template),
266 '${self.col_norm}'),self.cache.user_ns,loc)
266 '${self.col_norm}'),self.cache.user_ns,loc)
267
267
268 self.p_str_nocolor = ItplNS(multiple_replace(prompt_specials_nocolor,
268 self.p_str_nocolor = ItplNS(multiple_replace(prompt_specials_nocolor,
269 self.p_template),
269 self.p_template),
270 self.cache.user_ns,loc)
270 self.cache.user_ns,loc)
271 except:
271 except:
272 print "Illegal prompt template (check $ usage!):",self.p_template
272 print "Illegal prompt template (check $ usage!):",self.p_template
273 self.p_str = self.p_template
273 self.p_str = self.p_template
274 self.p_str_nocolor = self.p_template
274 self.p_str_nocolor = self.p_template
275
275
276 def write(self,msg): # dbg
276 def write(self,msg): # dbg
277 sys.stdout.write(msg)
277 sys.stdout.write(msg)
278 return ''
278 return ''
279
279
280 def __str__(self):
280 def __str__(self):
281 """Return a string form of the prompt.
281 """Return a string form of the prompt.
282
282
283 This for is useful for continuation and output prompts, since it is
283 This for is useful for continuation and output prompts, since it is
284 left-padded to match lengths with the primary one (if the
284 left-padded to match lengths with the primary one (if the
285 self.pad_left attribute is set)."""
285 self.pad_left attribute is set)."""
286
286
287 out_str = str_safe(self.p_str)
287 out_str = str_safe(self.p_str)
288 if self.pad_left:
288 if self.pad_left:
289 # We must find the amount of padding required to match lengths,
289 # We must find the amount of padding required to match lengths,
290 # taking the color escapes (which are invisible on-screen) into
290 # taking the color escapes (which are invisible on-screen) into
291 # account.
291 # account.
292 esc_pad = len(out_str) - len(str_safe(self.p_str_nocolor))
292 esc_pad = len(out_str) - len(str_safe(self.p_str_nocolor))
293 format = '%%%ss' % (len(str(self.cache.last_prompt))+esc_pad)
293 format = '%%%ss' % (len(str(self.cache.last_prompt))+esc_pad)
294 return format % out_str
294 return format % out_str
295 else:
295 else:
296 return out_str
296 return out_str
297
297
298 # these path filters are put in as methods so that we can control the
298 # these path filters are put in as methods so that we can control the
299 # namespace where the prompt strings get evaluated
299 # namespace where the prompt strings get evaluated
300 def cwd_filt(self,depth):
300 def cwd_filt(self,depth):
301 """Return the last depth elements of the current working directory.
301 """Return the last depth elements of the current working directory.
302
302
303 $HOME is always replaced with '~'.
303 $HOME is always replaced with '~'.
304 If depth==0, the full path is returned."""
304 If depth==0, the full path is returned."""
305
305
306 cwd = os.getcwd().replace(HOME,"~")
306 cwd = os.getcwd().replace(HOME,"~")
307 out = os.sep.join(cwd.split(os.sep)[-depth:])
307 out = os.sep.join(cwd.split(os.sep)[-depth:])
308 if out:
308 if out:
309 return out
309 return out
310 else:
310 else:
311 return os.sep
311 return os.sep
312
312
313 def cwd_filt2(self,depth):
313 def cwd_filt2(self,depth):
314 """Return the last depth elements of the current working directory.
314 """Return the last depth elements of the current working directory.
315
315
316 $HOME is always replaced with '~'.
316 $HOME is always replaced with '~'.
317 If depth==0, the full path is returned."""
317 If depth==0, the full path is returned."""
318
318
319 full_cwd = os.getcwd()
319 full_cwd = os.getcwd()
320 cwd = full_cwd.replace(HOME,"~").split(os.sep)
320 cwd = full_cwd.replace(HOME,"~").split(os.sep)
321 if '~' in cwd and len(cwd) == depth+1:
321 if '~' in cwd and len(cwd) == depth+1:
322 depth += 1
322 depth += 1
323 drivepart = ''
323 drivepart = ''
324 if sys.platform == 'win32' and len(cwd) > depth:
324 if sys.platform == 'win32' and len(cwd) > depth:
325 drivepart = os.path.splitdrive(full_cwd)[0]
325 drivepart = os.path.splitdrive(full_cwd)[0]
326 out = drivepart + '/'.join(cwd[-depth:])
326 out = drivepart + '/'.join(cwd[-depth:])
327
327
328 if out:
328 if out:
329 return out
329 return out
330 else:
330 else:
331 return os.sep
331 return os.sep
332
332
333 def __nonzero__(self):
333 def __nonzero__(self):
334 """Implement boolean behavior.
334 """Implement boolean behavior.
335
335
336 Checks whether the p_str attribute is non-empty"""
336 Checks whether the p_str attribute is non-empty"""
337
337
338 return bool(self.p_template)
338 return bool(self.p_template)
339
339
340 class Prompt1(BasePrompt):
340 class Prompt1(BasePrompt):
341 """Input interactive prompt similar to Mathematica's."""
341 """Input interactive prompt similar to Mathematica's."""
342
342
343 def __init__(self,cache,sep='\n',prompt='In [\\#]: ',pad_left=True):
343 def __init__(self,cache,sep='\n',prompt='In [\\#]: ',pad_left=True):
344 BasePrompt.__init__(self,cache,sep,prompt,pad_left)
344 BasePrompt.__init__(self,cache,sep,prompt,pad_left)
345
345
346 def set_colors(self):
346 def set_colors(self):
347 self.set_p_str()
347 self.set_p_str()
348 Colors = self.cache.color_table.active_colors # shorthand
348 Colors = self.cache.color_table.active_colors # shorthand
349 self.col_p = Colors.in_prompt
349 self.col_p = Colors.in_prompt
350 self.col_num = Colors.in_number
350 self.col_num = Colors.in_number
351 self.col_norm = Colors.in_normal
351 self.col_norm = Colors.in_normal
352 # We need a non-input version of these escapes for the '--->'
352 # We need a non-input version of these escapes for the '--->'
353 # auto-call prompts used in the auto_rewrite() method.
353 # auto-call prompts used in the auto_rewrite() method.
354 self.col_p_ni = self.col_p.replace('\001','').replace('\002','')
354 self.col_p_ni = self.col_p.replace('\001','').replace('\002','')
355 self.col_norm_ni = Colors.normal
355 self.col_norm_ni = Colors.normal
356
356
357 def __str__(self):
357 def __str__(self):
358 self.cache.prompt_count += 1
358 self.cache.prompt_count += 1
359 self.cache.last_prompt = str_safe(self.p_str_nocolor).split('\n')[-1]
359 self.cache.last_prompt = str_safe(self.p_str_nocolor).split('\n')[-1]
360 return str_safe(self.p_str)
360 return str_safe(self.p_str)
361
361
362 def auto_rewrite(self):
362 def auto_rewrite(self):
363 """Print a string of the form '--->' which lines up with the previous
363 """Print a string of the form '--->' which lines up with the previous
364 input string. Useful for systems which re-write the user input when
364 input string. Useful for systems which re-write the user input when
365 handling automatically special syntaxes."""
365 handling automatically special syntaxes."""
366
366
367 curr = str(self.cache.last_prompt)
367 curr = str(self.cache.last_prompt)
368 nrspaces = len(self.rspace.search(curr).group())
368 nrspaces = len(self.rspace.search(curr).group())
369 return '%s%s>%s%s' % (self.col_p_ni,'-'*(len(curr)-nrspaces-1),
369 return '%s%s>%s%s' % (self.col_p_ni,'-'*(len(curr)-nrspaces-1),
370 ' '*nrspaces,self.col_norm_ni)
370 ' '*nrspaces,self.col_norm_ni)
371
371
372 class PromptOut(BasePrompt):
372 class PromptOut(BasePrompt):
373 """Output interactive prompt similar to Mathematica's."""
373 """Output interactive prompt similar to Mathematica's."""
374
374
375 def __init__(self,cache,sep='',prompt='Out[\\#]: ',pad_left=True):
375 def __init__(self,cache,sep='',prompt='Out[\\#]: ',pad_left=True):
376 BasePrompt.__init__(self,cache,sep,prompt,pad_left)
376 BasePrompt.__init__(self,cache,sep,prompt,pad_left)
377 if not self.p_template:
377 if not self.p_template:
378 self.__str__ = lambda: ''
378 self.__str__ = lambda: ''
379
379
380 def set_colors(self):
380 def set_colors(self):
381 self.set_p_str()
381 self.set_p_str()
382 Colors = self.cache.color_table.active_colors # shorthand
382 Colors = self.cache.color_table.active_colors # shorthand
383 self.col_p = Colors.out_prompt
383 self.col_p = Colors.out_prompt
384 self.col_num = Colors.out_number
384 self.col_num = Colors.out_number
385 self.col_norm = Colors.normal
385 self.col_norm = Colors.normal
386
386
387 class Prompt2(BasePrompt):
387 class Prompt2(BasePrompt):
388 """Interactive continuation prompt."""
388 """Interactive continuation prompt."""
389
389
390 def __init__(self,cache,prompt=' .\\D.: ',pad_left=True):
390 def __init__(self,cache,prompt=' .\\D.: ',pad_left=True):
391 self.cache = cache
391 self.cache = cache
392 self.p_template = prompt
392 self.p_template = prompt
393 self.pad_left = pad_left
393 self.pad_left = pad_left
394 self.set_p_str()
394 self.set_p_str()
395
395
396 def set_p_str(self):
396 def set_p_str(self):
397 import os,time # needed in locals for prompt string handling
397 import os,time # needed in locals for prompt string handling
398 loc = locals()
398 loc = locals()
399 self.p_str = ItplNS('%s%s%s' %
399 self.p_str = ItplNS('%s%s%s' %
400 ('${self.col_p2}',
400 ('${self.col_p2}',
401 multiple_replace(prompt_specials, self.p_template),
401 multiple_replace(prompt_specials, self.p_template),
402 '$self.col_norm'),
402 '$self.col_norm'),
403 self.cache.user_ns,loc)
403 self.cache.user_ns,loc)
404 self.p_str_nocolor = ItplNS(multiple_replace(prompt_specials_nocolor,
404 self.p_str_nocolor = ItplNS(multiple_replace(prompt_specials_nocolor,
405 self.p_template),
405 self.p_template),
406 self.cache.user_ns,loc)
406 self.cache.user_ns,loc)
407
407
408 def set_colors(self):
408 def set_colors(self):
409 self.set_p_str()
409 self.set_p_str()
410 Colors = self.cache.color_table.active_colors
410 Colors = self.cache.color_table.active_colors
411 self.col_p2 = Colors.in_prompt2
411 self.col_p2 = Colors.in_prompt2
412 self.col_norm = Colors.in_normal
412 self.col_norm = Colors.in_normal
413 # FIXME (2004-06-16) HACK: prevent crashes for users who haven't
413 # FIXME (2004-06-16) HACK: prevent crashes for users who haven't
414 # updated their prompt_in2 definitions. Remove eventually.
414 # updated their prompt_in2 definitions. Remove eventually.
415 self.col_p = Colors.out_prompt
415 self.col_p = Colors.out_prompt
416 self.col_num = Colors.out_number
416 self.col_num = Colors.out_number
417
417
418
418
419 #-----------------------------------------------------------------------------
419 #-----------------------------------------------------------------------------
420 class CachedOutput:
420 class CachedOutput:
421 """Class for printing output from calculations while keeping a cache of
421 """Class for printing output from calculations while keeping a cache of
422 reults. It dynamically creates global variables prefixed with _ which
422 reults. It dynamically creates global variables prefixed with _ which
423 contain these results.
423 contain these results.
424
424
425 Meant to be used as a sys.displayhook replacement, providing numbered
425 Meant to be used as a sys.displayhook replacement, providing numbered
426 prompts and cache services.
426 prompts and cache services.
427
427
428 Initialize with initial and final values for cache counter (this defines
428 Initialize with initial and final values for cache counter (this defines
429 the maximum size of the cache."""
429 the maximum size of the cache."""
430
430
431 def __init__(self,shell,cache_size,Pprint,
431 def __init__(self,shell,cache_size,Pprint,
432 colors='NoColor',input_sep='\n',
432 colors='NoColor',input_sep='\n',
433 output_sep='\n',output_sep2='',
433 output_sep='\n',output_sep2='',
434 ps1 = None, ps2 = None,ps_out = None,pad_left=True):
434 ps1 = None, ps2 = None,ps_out = None,pad_left=True):
435
435
436 cache_size_min = 3
436 cache_size_min = 3
437 if cache_size <= 0:
437 if cache_size <= 0:
438 self.do_full_cache = 0
438 self.do_full_cache = 0
439 cache_size = 0
439 cache_size = 0
440 elif cache_size < cache_size_min:
440 elif cache_size < cache_size_min:
441 self.do_full_cache = 0
441 self.do_full_cache = 0
442 cache_size = 0
442 cache_size = 0
443 warn('caching was disabled (min value for cache size is %s).' %
443 warn('caching was disabled (min value for cache size is %s).' %
444 cache_size_min,level=3)
444 cache_size_min,level=3)
445 else:
445 else:
446 self.do_full_cache = 1
446 self.do_full_cache = 1
447
447
448 self.cache_size = cache_size
448 self.cache_size = cache_size
449 self.input_sep = input_sep
449 self.input_sep = input_sep
450
450
451 # we need a reference to the user-level namespace
451 # we need a reference to the user-level namespace
452 self.shell = shell
452 self.shell = shell
453 self.user_ns = shell.user_ns
453 self.user_ns = shell.user_ns
454 # and to the user's input
454 # and to the user's input
455 self.input_hist = shell.input_hist
455 self.input_hist = shell.input_hist
456 # and to the user's logger, for logging output
456 # and to the user's logger, for logging output
457 self.logger = shell.logger
457 self.logger = shell.logger
458
458
459 # Set input prompt strings and colors
459 # Set input prompt strings and colors
460 if cache_size == 0:
460 if cache_size == 0:
461 if ps1.find('%n') > -1 or ps1.find(r'\#') > -1 \
461 if ps1.find('%n') > -1 or ps1.find(r'\#') > -1 \
462 or ps1.find(r'\N') > -1:
462 or ps1.find(r'\N') > -1:
463 ps1 = '>>> '
463 ps1 = '>>> '
464 if ps2.find('%n') > -1 or ps2.find(r'\#') > -1 \
464 if ps2.find('%n') > -1 or ps2.find(r'\#') > -1 \
465 or ps2.find(r'\N') > -1:
465 or ps2.find(r'\N') > -1:
466 ps2 = '... '
466 ps2 = '... '
467 self.ps1_str = self._set_prompt_str(ps1,'In [\\#]: ','>>> ')
467 self.ps1_str = self._set_prompt_str(ps1,'In [\\#]: ','>>> ')
468 self.ps2_str = self._set_prompt_str(ps2,' .\\D.: ','... ')
468 self.ps2_str = self._set_prompt_str(ps2,' .\\D.: ','... ')
469 self.ps_out_str = self._set_prompt_str(ps_out,'Out[\\#]: ','')
469 self.ps_out_str = self._set_prompt_str(ps_out,'Out[\\#]: ','')
470
470
471 self.color_table = PromptColors
471 self.color_table = PromptColors
472 self.prompt1 = Prompt1(self,sep=input_sep,prompt=self.ps1_str,
472 self.prompt1 = Prompt1(self,sep=input_sep,prompt=self.ps1_str,
473 pad_left=pad_left)
473 pad_left=pad_left)
474 self.prompt2 = Prompt2(self,prompt=self.ps2_str,pad_left=pad_left)
474 self.prompt2 = Prompt2(self,prompt=self.ps2_str,pad_left=pad_left)
475 self.prompt_out = PromptOut(self,sep='',prompt=self.ps_out_str,
475 self.prompt_out = PromptOut(self,sep='',prompt=self.ps_out_str,
476 pad_left=pad_left)
476 pad_left=pad_left)
477 self.set_colors(colors)
477 self.set_colors(colors)
478
478
479 # other more normal stuff
479 # other more normal stuff
480 # b/c each call to the In[] prompt raises it by 1, even the first.
480 # b/c each call to the In[] prompt raises it by 1, even the first.
481 self.prompt_count = 0
481 self.prompt_count = 0
482 # Store the last prompt string each time, we need it for aligning
482 # Store the last prompt string each time, we need it for aligning
483 # continuation and auto-rewrite prompts
483 # continuation and auto-rewrite prompts
484 self.last_prompt = ''
484 self.last_prompt = ''
485 self.Pprint = Pprint
485 self.Pprint = Pprint
486 self.output_sep = output_sep
486 self.output_sep = output_sep
487 self.output_sep2 = output_sep2
487 self.output_sep2 = output_sep2
488 self._,self.__,self.___ = '','',''
488 self._,self.__,self.___ = '','',''
489 self.pprint_types = map(type,[(),[],{}])
489 self.pprint_types = map(type,[(),[],{}])
490
490
491 # these are deliberately global:
491 # these are deliberately global:
492 to_user_ns = {'_':self._,'__':self.__,'___':self.___}
492 to_user_ns = {'_':self._,'__':self.__,'___':self.___}
493 self.user_ns.update(to_user_ns)
493 self.user_ns.update(to_user_ns)
494
494
495 def _set_prompt_str(self,p_str,cache_def,no_cache_def):
495 def _set_prompt_str(self,p_str,cache_def,no_cache_def):
496 if p_str is None:
496 if p_str is None:
497 if self.do_full_cache:
497 if self.do_full_cache:
498 return cache_def
498 return cache_def
499 else:
499 else:
500 return no_cache_def
500 return no_cache_def
501 else:
501 else:
502 return p_str
502 return p_str
503
503
504 def set_colors(self,colors):
504 def set_colors(self,colors):
505 """Set the active color scheme and configure colors for the three
505 """Set the active color scheme and configure colors for the three
506 prompt subsystems."""
506 prompt subsystems."""
507
507
508 # FIXME: the prompt_specials global should be gobbled inside this
508 # FIXME: the prompt_specials global should be gobbled inside this
509 # class instead. Do it when cleaning up the whole 3-prompt system.
509 # class instead. Do it when cleaning up the whole 3-prompt system.
510 global prompt_specials
510 global prompt_specials
511 if colors.lower()=='nocolor':
511 if colors.lower()=='nocolor':
512 prompt_specials = prompt_specials_nocolor
512 prompt_specials = prompt_specials_nocolor
513 else:
513 else:
514 prompt_specials = prompt_specials_color
514 prompt_specials = prompt_specials_color
515
515
516 self.color_table.set_active_scheme(colors)
516 self.color_table.set_active_scheme(colors)
517 self.prompt1.set_colors()
517 self.prompt1.set_colors()
518 self.prompt2.set_colors()
518 self.prompt2.set_colors()
519 self.prompt_out.set_colors()
519 self.prompt_out.set_colors()
520
520
521 def __call__(self,arg=None):
521 def __call__(self,arg=None):
522 """Printing with history cache management.
522 """Printing with history cache management.
523
523
524 This is invoked everytime the interpreter needs to print, and is
524 This is invoked everytime the interpreter needs to print, and is
525 activated by setting the variable sys.displayhook to it."""
525 activated by setting the variable sys.displayhook to it."""
526
526
527 # If something injected a '_' variable in __builtin__, delete
527 # If something injected a '_' variable in __builtin__, delete
528 # ipython's automatic one so we don't clobber that. gettext() in
528 # ipython's automatic one so we don't clobber that. gettext() in
529 # particular uses _, so we need to stay away from it.
529 # particular uses _, so we need to stay away from it.
530 if '_' in __builtin__.__dict__:
530 if '_' in __builtin__.__dict__:
531 try:
531 try:
532 del self.user_ns['_']
532 del self.user_ns['_']
533 except KeyError:
533 except KeyError:
534 pass
534 pass
535 if arg is not None:
535 if arg is not None:
536 cout_write = Term.cout.write # fast lookup
536 cout_write = Term.cout.write # fast lookup
537 # first handle the cache and counters
537 # first handle the cache and counters
538
538
539 # do not print output if input ends in ';'
539 # do not print output if input ends in ';'
540 try:
540 try:
541 if self.input_hist[self.prompt_count].endswith(';\n'):
541 if self.input_hist[self.prompt_count].endswith(';\n'):
542 return
542 return
543 except IndexError:
543 except IndexError:
544 # some uses of ipshellembed may fail here
544 # some uses of ipshellembed may fail here
545 pass
545 pass
546 # don't use print, puts an extra space
546 # don't use print, puts an extra space
547 cout_write(self.output_sep)
547 cout_write(self.output_sep)
548 outprompt = self.shell.hooks.generate_output_prompt()
548 outprompt = self.shell.hooks.generate_output_prompt()
549 # print "Got prompt: ", outprompt
549 if self.do_full_cache:
550 if self.do_full_cache:
550 cout_write(outprompt)
551 cout_write(outprompt)
552 else:
553 print "self.do_full_cache = False"
551
554
552 # and now call a possibly user-defined print mechanism
555 # and now call a possibly user-defined print mechanism
553 manipulated_val = self.display(arg)
556 manipulated_val = self.display(arg)
554
557
555 # user display hooks can change the variable to be stored in
558 # user display hooks can change the variable to be stored in
556 # output history
559 # output history
557
560
558 if manipulated_val is not None:
561 if manipulated_val is not None:
559 arg = manipulated_val
562 arg = manipulated_val
560
563
561 # avoid recursive reference when displaying _oh/Out
564 # avoid recursive reference when displaying _oh/Out
562 if arg is not self.user_ns['_oh']:
565 if arg is not self.user_ns['_oh']:
563 self.update(arg)
566 self.update(arg)
564
567
565 if self.logger.log_output:
568 if self.logger.log_output:
566 self.logger.log_write(repr(arg),'output')
569 self.logger.log_write(repr(arg),'output')
567 cout_write(self.output_sep2)
570 cout_write(self.output_sep2)
568 Term.cout.flush()
571 Term.cout.flush()
569
572
570 def _display(self,arg):
573 def _display(self,arg):
571 """Default printer method, uses pprint.
574 """Default printer method, uses pprint.
572
575
573 Do ip.set_hook("result_display", my_displayhook) for custom result
576 Do ip.set_hook("result_display", my_displayhook) for custom result
574 display, e.g. when your own objects need special formatting.
577 display, e.g. when your own objects need special formatting.
575 """
578 """
576 try:
579 try:
577 return IPython.utils.generics.result_display(arg)
580 return IPython.utils.generics.result_display(arg)
578 except TryNext:
581 except TryNext:
579 return self.shell.hooks.result_display(arg)
582 return self.shell.hooks.result_display(arg)
580
583
581 # Assign the default display method:
584 # Assign the default display method:
582 display = _display
585 display = _display
583
586
584 def update(self,arg):
587 def update(self,arg):
585 #print '***cache_count', self.cache_count # dbg
588 #print '***cache_count', self.cache_count # dbg
586 if len(self.user_ns['_oh']) >= self.cache_size and self.do_full_cache:
589 if len(self.user_ns['_oh']) >= self.cache_size and self.do_full_cache:
587 warn('Output cache limit (currently '+
590 warn('Output cache limit (currently '+
588 `self.cache_size`+' entries) hit.\n'
591 `self.cache_size`+' entries) hit.\n'
589 'Flushing cache and resetting history counter...\n'
592 'Flushing cache and resetting history counter...\n'
590 'The only history variables available will be _,__,___ and _1\n'
593 'The only history variables available will be _,__,___ and _1\n'
591 'with the current result.')
594 'with the current result.')
592
595
593 self.flush()
596 self.flush()
594 # Don't overwrite '_' and friends if '_' is in __builtin__ (otherwise
597 # Don't overwrite '_' and friends if '_' is in __builtin__ (otherwise
595 # we cause buggy behavior for things like gettext).
598 # we cause buggy behavior for things like gettext).
596 if '_' not in __builtin__.__dict__:
599 if '_' not in __builtin__.__dict__:
597 self.___ = self.__
600 self.___ = self.__
598 self.__ = self._
601 self.__ = self._
599 self._ = arg
602 self._ = arg
600 self.user_ns.update({'_':self._,'__':self.__,'___':self.___})
603 self.user_ns.update({'_':self._,'__':self.__,'___':self.___})
601
604
602 # hackish access to top-level namespace to create _1,_2... dynamically
605 # hackish access to top-level namespace to create _1,_2... dynamically
603 to_main = {}
606 to_main = {}
604 if self.do_full_cache:
607 if self.do_full_cache:
605 new_result = '_'+`self.prompt_count`
608 new_result = '_'+`self.prompt_count`
606 to_main[new_result] = arg
609 to_main[new_result] = arg
607 self.user_ns.update(to_main)
610 self.user_ns.update(to_main)
608 self.user_ns['_oh'][self.prompt_count] = arg
611 self.user_ns['_oh'][self.prompt_count] = arg
609
612
610 def flush(self):
613 def flush(self):
611 if not self.do_full_cache:
614 if not self.do_full_cache:
612 raise ValueError,"You shouldn't have reached the cache flush "\
615 raise ValueError,"You shouldn't have reached the cache flush "\
613 "if full caching is not enabled!"
616 "if full caching is not enabled!"
614 # delete auto-generated vars from global namespace
617 # delete auto-generated vars from global namespace
615
618
616 for n in range(1,self.prompt_count + 1):
619 for n in range(1,self.prompt_count + 1):
617 key = '_'+`n`
620 key = '_'+`n`
618 try:
621 try:
619 del self.user_ns[key]
622 del self.user_ns[key]
620 except: pass
623 except: pass
621 self.user_ns['_oh'].clear()
624 self.user_ns['_oh'].clear()
622
625
623 if '_' not in __builtin__.__dict__:
626 if '_' not in __builtin__.__dict__:
624 self.user_ns.update({'_':None,'__':None, '___':None})
627 self.user_ns.update({'_':None,'__':None, '___':None})
625 import gc
628 import gc
626 gc.collect() # xxx needed?
629 gc.collect() # xxx needed?
627
630
@@ -1,34 +1,35 b''
1 """Test code for https://bugs.launchpad.net/ipython/+bug/239054
1 """Test code for https://bugs.launchpad.net/ipython/+bug/239054
2
2
3 WARNING: this script exits IPython! It MUST be run in a subprocess.
3 WARNING: this script exits IPython! It MUST be run in a subprocess.
4
4
5 When you run the following script from CPython it prints:
5 When you run the following script from CPython it prints:
6 __init__ is here
6 __init__ is here
7 __del__ is here
7 __del__ is here
8
8
9 and creates the __del__.txt file
9 and creates the __del__.txt file
10
10
11 When you run it from IPython it prints:
11 When you run it from IPython it prints:
12 __init__ is here
12 __init__ is here
13
13
14 When you exit() or Exit from IPython neothing is printed and no file is created
14 When you exit() or Exit from IPython neothing is printed and no file is created
15 (the file thing is to make sure __del__ is really never called and not that
15 (the file thing is to make sure __del__ is really never called and not that
16 just the output is eaten).
16 just the output is eaten).
17
17
18 Note that if you call %reset in IPython then everything is Ok.
18 Note that if you call %reset in IPython then everything is Ok.
19
19
20 IPython should do the equivalent of %reset and release all the references it
20 IPython should do the equivalent of %reset and release all the references it
21 holds before exit. This behavior is important when working with binding objects
21 holds before exit. This behavior is important when working with binding objects
22 that rely on __del__. If the current behavior has some use case then I suggest
22 that rely on __del__. If the current behavior has some use case then I suggest
23 to add a configuration option to IPython to control it.
23 to add a configuration option to IPython to control it.
24 """
24 """
25 import sys
25 import sys
26
26
27 class A(object):
27 class A(object):
28 def __del__(self):
28 def __del__(self):
29 print 'obj_del.py: object A deleted'
29 print 'obj_del.py: object A deleted'
30
30
31 a = A()
31 a = A()
32
32
33 # Now, we force an exit, the caller will check that the del printout was given
33 # Now, we force an exit, the caller will check that the del printout was given
34 _ip = get_ipython()
34 _ip.ask_exit()
35 _ip.ask_exit()
@@ -1,194 +1,194 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 """
3 """
4 Tests for IPython.core.component
4 Tests for IPython.core.component
5
5
6 Authors:
6 Authors:
7
7
8 * Brian Granger
8 * Brian Granger
9 * Fernando Perez (design help)
9 * Fernando Perez (design help)
10 """
10 """
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Copyright (C) 2008-2009 The IPython Development Team
13 # Copyright (C) 2008-2009 The IPython Development Team
14 #
14 #
15 # Distributed under the terms of the BSD License. The full license is in
15 # Distributed under the terms of the BSD License. The full license is in
16 # the file COPYING, distributed as part of this software.
16 # the file COPYING, distributed as part of this software.
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Imports
20 # Imports
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22
22
23 from unittest import TestCase
23 from unittest import TestCase
24
24
25 from IPython.core.component import Component, ComponentError
25 from IPython.core.component import Component, ComponentError
26 from IPython.utils.traitlets import (
26 from IPython.utils.traitlets import (
27 TraitletError, Int, Float, Str
27 TraitletError, Int, Float, Str
28 )
28 )
29 from IPython.utils.ipstruct import Struct
29 from IPython.config.loader import Config
30
30
31
31
32 #-----------------------------------------------------------------------------
32 #-----------------------------------------------------------------------------
33 # Test cases
33 # Test cases
34 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
35
35
36
36
37 class TestComponentMeta(TestCase):
37 class TestComponentMeta(TestCase):
38
38
39 def test_get_instances(self):
39 def test_get_instances(self):
40 class BaseComponent(Component):
40 class BaseComponent(Component):
41 pass
41 pass
42 c1 = BaseComponent(None)
42 c1 = BaseComponent(None)
43 c2 = BaseComponent(c1)
43 c2 = BaseComponent(c1)
44 self.assertEquals(BaseComponent.get_instances(),[c1,c2])
44 self.assertEquals(BaseComponent.get_instances(),[c1,c2])
45
45
46 def test_get_instances_subclass(self):
46 def test_get_instances_subclass(self):
47 class MyComponent(Component):
47 class MyComponent(Component):
48 pass
48 pass
49 class MyOtherComponent(MyComponent):
49 class MyOtherComponent(MyComponent):
50 pass
50 pass
51 c1 = MyComponent(None)
51 c1 = MyComponent(None)
52 c2 = MyOtherComponent(c1)
52 c2 = MyOtherComponent(c1)
53 c3 = MyOtherComponent(c2)
53 c3 = MyOtherComponent(c2)
54 self.assertEquals(MyComponent.get_instances(), [c1, c2, c3])
54 self.assertEquals(MyComponent.get_instances(), [c1, c2, c3])
55 self.assertEquals(MyOtherComponent.get_instances(), [c2, c3])
55 self.assertEquals(MyOtherComponent.get_instances(), [c2, c3])
56
56
57 def test_get_instances_root(self):
57 def test_get_instances_root(self):
58 class MyComponent(Component):
58 class MyComponent(Component):
59 pass
59 pass
60 class MyOtherComponent(MyComponent):
60 class MyOtherComponent(MyComponent):
61 pass
61 pass
62 c1 = MyComponent(None)
62 c1 = MyComponent(None)
63 c2 = MyOtherComponent(c1)
63 c2 = MyOtherComponent(c1)
64 c3 = MyOtherComponent(c2)
64 c3 = MyOtherComponent(c2)
65 c4 = MyComponent(None)
65 c4 = MyComponent(None)
66 c5 = MyComponent(c4)
66 c5 = MyComponent(c4)
67 self.assertEquals(MyComponent.get_instances(root=c1), [c1, c2, c3])
67 self.assertEquals(MyComponent.get_instances(root=c1), [c1, c2, c3])
68 self.assertEquals(MyComponent.get_instances(root=c4), [c4, c5])
68 self.assertEquals(MyComponent.get_instances(root=c4), [c4, c5])
69
69
70
70
71 class TestComponent(TestCase):
71 class TestComponent(TestCase):
72
72
73 def test_parent_child(self):
73 def test_parent_child(self):
74 c1 = Component(None)
74 c1 = Component(None)
75 c2 = Component(c1)
75 c2 = Component(c1)
76 c3 = Component(c1)
76 c3 = Component(c1)
77 c4 = Component(c3)
77 c4 = Component(c3)
78 self.assertEquals(c1.parent, None)
78 self.assertEquals(c1.parent, None)
79 self.assertEquals(c2.parent, c1)
79 self.assertEquals(c2.parent, c1)
80 self.assertEquals(c3.parent, c1)
80 self.assertEquals(c3.parent, c1)
81 self.assertEquals(c4.parent, c3)
81 self.assertEquals(c4.parent, c3)
82 self.assertEquals(c1.children, [c2, c3])
82 self.assertEquals(c1.children, [c2, c3])
83 self.assertEquals(c2.children, [])
83 self.assertEquals(c2.children, [])
84 self.assertEquals(c3.children, [c4])
84 self.assertEquals(c3.children, [c4])
85 self.assertEquals(c4.children, [])
85 self.assertEquals(c4.children, [])
86
86
87 def test_root(self):
87 def test_root(self):
88 c1 = Component(None)
88 c1 = Component(None)
89 c2 = Component(c1)
89 c2 = Component(c1)
90 c3 = Component(c1)
90 c3 = Component(c1)
91 c4 = Component(c3)
91 c4 = Component(c3)
92 self.assertEquals(c1.root, c1.root)
92 self.assertEquals(c1.root, c1.root)
93 self.assertEquals(c2.root, c1)
93 self.assertEquals(c2.root, c1)
94 self.assertEquals(c3.root, c1)
94 self.assertEquals(c3.root, c1)
95 self.assertEquals(c4.root, c1)
95 self.assertEquals(c4.root, c1)
96
96
97 def test_change_parent(self):
97 def test_change_parent(self):
98 c1 = Component(None)
98 c1 = Component(None)
99 c2 = Component(None)
99 c2 = Component(None)
100 c3 = Component(c1)
100 c3 = Component(c1)
101 self.assertEquals(c3.root, c1)
101 self.assertEquals(c3.root, c1)
102 self.assertEquals(c3.parent, c1)
102 self.assertEquals(c3.parent, c1)
103 self.assertEquals(c1.children,[c3])
103 self.assertEquals(c1.children,[c3])
104 c3.parent = c2
104 c3.parent = c2
105 self.assertEquals(c3.root, c2)
105 self.assertEquals(c3.root, c2)
106 self.assertEquals(c3.parent, c2)
106 self.assertEquals(c3.parent, c2)
107 self.assertEquals(c2.children,[c3])
107 self.assertEquals(c2.children,[c3])
108 self.assertEquals(c1.children,[])
108 self.assertEquals(c1.children,[])
109
109
110 def test_subclass_parent(self):
110 def test_subclass_parent(self):
111 c1 = Component(None)
111 c1 = Component(None)
112 self.assertRaises(TraitletError, setattr, c1, 'parent', 10)
112 self.assertRaises(TraitletError, setattr, c1, 'parent', 10)
113
113
114 class MyComponent(Component):
114 class MyComponent(Component):
115 pass
115 pass
116 c1 = Component(None)
116 c1 = Component(None)
117 c2 = MyComponent(c1)
117 c2 = MyComponent(c1)
118 self.assertEquals(MyComponent.parent.this_class, Component)
118 self.assertEquals(MyComponent.parent.this_class, Component)
119 self.assertEquals(c2.parent, c1)
119 self.assertEquals(c2.parent, c1)
120
120
121 def test_bad_root(self):
121 def test_bad_root(self):
122 c1 = Component(None)
122 c1 = Component(None)
123 c2 = Component(None)
123 c2 = Component(None)
124 c3 = Component(None)
124 c3 = Component(None)
125 self.assertRaises(ComponentError, setattr, c1, 'root', c2)
125 self.assertRaises(ComponentError, setattr, c1, 'root', c2)
126 c1.parent = c2
126 c1.parent = c2
127 self.assertEquals(c1.root, c2)
127 self.assertEquals(c1.root, c2)
128 self.assertRaises(ComponentError, setattr, c1, 'root', c3)
128 self.assertRaises(ComponentError, setattr, c1, 'root', c3)
129
129
130
130
131 class TestComponentConfig(TestCase):
131 class TestComponentConfig(TestCase):
132
132
133 def test_default(self):
133 def test_default(self):
134 c1 = Component(None)
134 c1 = Component(None)
135 c2 = Component(c1)
135 c2 = Component(c1)
136 c3 = Component(c2)
136 c3 = Component(c2)
137 self.assertEquals(c1.config, c2.config)
137 self.assertEquals(c1.config, c2.config)
138 self.assertEquals(c2.config, c3.config)
138 self.assertEquals(c2.config, c3.config)
139
139
140 def test_custom(self):
140 def test_custom(self):
141 config = Struct()
141 config = Config()
142 config.FOO = 'foo'
142 config.foo = 'foo'
143 config.BAR = 'bar'
143 config.bar = 'bar'
144 c1 = Component(None, config=config)
144 c1 = Component(None, config=config)
145 c2 = Component(c1)
145 c2 = Component(c1)
146 c3 = Component(c2)
146 c3 = Component(c2)
147 self.assertEquals(c1.config, config)
147 self.assertEquals(c1.config, config)
148 self.assertEquals(c2.config, config)
148 self.assertEquals(c2.config, config)
149 self.assertEquals(c3.config, config)
149 self.assertEquals(c3.config, config)
150 # Test that we always make copies
150 # Test that we always make copies
151 self.assert_(c1.config is not config)
151 self.assert_(c1.config is not config)
152 self.assert_(c2.config is not config)
152 self.assert_(c2.config is not config)
153 self.assert_(c3.config is not config)
153 self.assert_(c3.config is not config)
154 self.assert_(c1.config is not c2.config)
154 self.assert_(c1.config is not c2.config)
155 self.assert_(c2.config is not c3.config)
155 self.assert_(c2.config is not c3.config)
156
156
157 def test_inheritance(self):
157 def test_inheritance(self):
158 class MyComponent(Component):
158 class MyComponent(Component):
159 a = Int(1, config_key='A')
159 a = Int(1, config=True)
160 b = Float(1.0, config_key='B')
160 b = Float(1.0, config=True)
161 c = Str('no config')
161 c = Str('no config')
162 config = Struct()
162 config = Config()
163 config.A = 2
163 config.MyComponent.a = 2
164 config.B = 2.0
164 config.MyComponent.b = 2.0
165 c1 = MyComponent(None, config=config)
165 c1 = MyComponent(None, config=config)
166 c2 = MyComponent(c1)
166 c2 = MyComponent(c1)
167 self.assertEquals(c1.a, config.A)
167 self.assertEquals(c1.a, config.MyComponent.a)
168 self.assertEquals(c1.b, config.B)
168 self.assertEquals(c1.b, config.MyComponent.b)
169 self.assertEquals(c2.a, config.A)
169 self.assertEquals(c2.a, config.MyComponent.a)
170 self.assertEquals(c2.b, config.B)
170 self.assertEquals(c2.b, config.MyComponent.b)
171 c4 = MyComponent(c2, config=Struct())
171 c4 = MyComponent(c2, config=Config())
172 self.assertEquals(c4.a, 1)
172 self.assertEquals(c4.a, 1)
173 self.assertEquals(c4.b, 1.0)
173 self.assertEquals(c4.b, 1.0)
174
174
175 class TestComponentName(TestCase):
175 class TestComponentName(TestCase):
176
176
177 def test_default(self):
177 def test_default(self):
178 class MyComponent(Component):
178 class MyComponent(Component):
179 pass
179 pass
180 c1 = Component(None)
180 c1 = Component(None)
181 c2 = MyComponent(None)
181 c2 = MyComponent(None)
182 c3 = Component(c2)
182 c3 = Component(c2)
183 self.assertNotEquals(c1.name, c2.name)
183 self.assertNotEquals(c1.name, c2.name)
184 self.assertNotEquals(c1.name, c3.name)
184 self.assertNotEquals(c1.name, c3.name)
185
185
186 def test_manual(self):
186 def test_manual(self):
187 class MyComponent(Component):
187 class MyComponent(Component):
188 pass
188 pass
189 c1 = Component(None, name='foo')
189 c1 = Component(None, name='foo')
190 c2 = MyComponent(None, name='bar')
190 c2 = MyComponent(None, name='bar')
191 c3 = Component(c2, name='bah')
191 c3 = Component(c2, name='bah')
192 self.assertEquals(c1.name, 'foo')
192 self.assertEquals(c1.name, 'foo')
193 self.assertEquals(c2.name, 'bar')
193 self.assertEquals(c2.name, 'bar')
194 self.assertEquals(c3.name, 'bah')
194 self.assertEquals(c3.name, 'bah')
@@ -1,326 +1,331 b''
1 """Tests for various magic functions.
1 """Tests for various magic functions.
2
2
3 Needs to be run by nose (to make ipython session available).
3 Needs to be run by nose (to make ipython session available).
4 """
4 """
5
5
6 import os
6 import os
7 import sys
7 import sys
8 import tempfile
8 import tempfile
9 import types
9 import types
10 from cStringIO import StringIO
10 from cStringIO import StringIO
11
11
12 import nose.tools as nt
12 import nose.tools as nt
13
13
14 from IPython.utils.platutils import find_cmd, get_long_path_name
14 from IPython.utils.platutils import find_cmd, get_long_path_name
15 from IPython.testing import decorators as dec
15 from IPython.testing import decorators as dec
16 from IPython.testing import tools as tt
16 from IPython.testing import tools as tt
17
17
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19 # Test functions begin
19 # Test functions begin
20
20
21 def test_rehashx():
21 def test_rehashx():
22 # clear up everything
22 # clear up everything
23 _ip.alias_table.clear()
23 _ip = get_ipython()
24 _ip.alias_manager.alias_table.clear()
24 del _ip.db['syscmdlist']
25 del _ip.db['syscmdlist']
25
26
26 _ip.magic('rehashx')
27 _ip.magic('rehashx')
27 # Practically ALL ipython development systems will have more than 10 aliases
28 # Practically ALL ipython development systems will have more than 10 aliases
28
29
29 yield (nt.assert_true, len(_ip.alias_table) > 10)
30 yield (nt.assert_true, len(_ip.alias_manager.alias_table) > 10)
30 for key, val in _ip.alias_table.items():
31 for key, val in _ip.alias_manager.alias_table.items():
31 # we must strip dots from alias names
32 # we must strip dots from alias names
32 nt.assert_true('.' not in key)
33 nt.assert_true('.' not in key)
33
34
34 # rehashx must fill up syscmdlist
35 # rehashx must fill up syscmdlist
35 scoms = _ip.db['syscmdlist']
36 scoms = _ip.db['syscmdlist']
36 yield (nt.assert_true, len(scoms) > 10)
37 yield (nt.assert_true, len(scoms) > 10)
37
38
38
39
39 def doctest_hist_f():
40 def doctest_hist_f():
40 """Test %hist -f with temporary filename.
41 """Test %hist -f with temporary filename.
41
42
42 In [9]: import tempfile
43 In [9]: import tempfile
43
44
44 In [10]: tfile = tempfile.mktemp('.py','tmp-ipython-')
45 In [10]: tfile = tempfile.mktemp('.py','tmp-ipython-')
45
46
46 In [11]: %hist -n -f $tfile 3
47 In [11]: %hist -n -f $tfile 3
47 """
48 """
48
49
49
50
50 def doctest_hist_r():
51 def doctest_hist_r():
51 """Test %hist -r
52 """Test %hist -r
52
53
53 XXX - This test is not recording the output correctly. Not sure why...
54 XXX - This test is not recording the output correctly. Not sure why...
54
55
55 In [20]: 'hist' in _ip.lsmagic()
56 In [20]: 'hist' in _ip.lsmagic()
56 Out[20]: True
57 Out[20]: True
57
58
58 In [6]: x=1
59 In [6]: x=1
59
60
60 In [7]: %hist -n -r 2
61 In [7]: %hist -n -r 2
61 x=1 # random
62 x=1 # random
62 hist -n -r 2 # random
63 hist -n -r 2 # random
63 """
64 """
64
65
65 # This test is known to fail on win32.
66 # This test is known to fail on win32.
66 # See ticket https://bugs.launchpad.net/bugs/366334
67 # See ticket https://bugs.launchpad.net/bugs/366334
67 def test_obj_del():
68 def test_obj_del():
69 _ip = get_ipython()
68 """Test that object's __del__ methods are called on exit."""
70 """Test that object's __del__ methods are called on exit."""
69 test_dir = os.path.dirname(__file__)
71 test_dir = os.path.dirname(__file__)
70 del_file = os.path.join(test_dir,'obj_del.py')
72 del_file = os.path.join(test_dir,'obj_del.py')
71 ipython_cmd = find_cmd('ipython')
73 ipython_cmd = find_cmd('ipython')
72 out = _ip.getoutput('%s %s' % (ipython_cmd, del_file))
74 out = _ip.getoutput('%s %s' % (ipython_cmd, del_file))
73 nt.assert_equals(out,'obj_del.py: object A deleted')
75 nt.assert_equals(out,'obj_del.py: object A deleted')
74
76
75
77
76 def test_shist():
78 def test_shist():
77 # Simple tests of ShadowHist class - test generator.
79 # Simple tests of ShadowHist class - test generator.
78 import os, shutil, tempfile
80 import os, shutil, tempfile
79
81
80 from IPython.extensions import pickleshare
82 from IPython.extensions import pickleshare
81 from IPython.core.history import ShadowHist
83 from IPython.core.history import ShadowHist
82
84
83 tfile = tempfile.mktemp('','tmp-ipython-')
85 tfile = tempfile.mktemp('','tmp-ipython-')
84
86
85 db = pickleshare.PickleShareDB(tfile)
87 db = pickleshare.PickleShareDB(tfile)
86 s = ShadowHist(db)
88 s = ShadowHist(db)
87 s.add('hello')
89 s.add('hello')
88 s.add('world')
90 s.add('world')
89 s.add('hello')
91 s.add('hello')
90 s.add('hello')
92 s.add('hello')
91 s.add('karhu')
93 s.add('karhu')
92
94
93 yield nt.assert_equals,s.all(),[(1, 'hello'), (2, 'world'), (3, 'karhu')]
95 yield nt.assert_equals,s.all(),[(1, 'hello'), (2, 'world'), (3, 'karhu')]
94
96
95 yield nt.assert_equal,s.get(2),'world'
97 yield nt.assert_equal,s.get(2),'world'
96
98
97 shutil.rmtree(tfile)
99 shutil.rmtree(tfile)
98
100
99 @dec.skipif_not_numpy
101 @dec.skipif_not_numpy
100 def test_numpy_clear_array_undec():
102 def test_numpy_clear_array_undec():
101 from IPython.extensions import clearcmd
103 from IPython.extensions import clearcmd
102
104
103 _ip.ex('import numpy as np')
105 _ip.ex('import numpy as np')
104 _ip.ex('a = np.empty(2)')
106 _ip.ex('a = np.empty(2)')
105 yield (nt.assert_true, 'a' in _ip.user_ns)
107 yield (nt.assert_true, 'a' in _ip.user_ns)
106 _ip.magic('clear array')
108 _ip.magic('clear array')
107 yield (nt.assert_false, 'a' in _ip.user_ns)
109 yield (nt.assert_false, 'a' in _ip.user_ns)
108
110
109
111
110 @dec.skip()
112 @dec.skip()
111 def test_fail_dec(*a,**k):
113 def test_fail_dec(*a,**k):
112 yield nt.assert_true, False
114 yield nt.assert_true, False
113
115
114 @dec.skip('This one shouldn not run')
116 @dec.skip('This one shouldn not run')
115 def test_fail_dec2(*a,**k):
117 def test_fail_dec2(*a,**k):
116 yield nt.assert_true, False
118 yield nt.assert_true, False
117
119
118 @dec.skipknownfailure
120 @dec.skipknownfailure
119 def test_fail_dec3(*a,**k):
121 def test_fail_dec3(*a,**k):
120 yield nt.assert_true, False
122 yield nt.assert_true, False
121
123
122
124
123 def doctest_refbug():
125 def doctest_refbug():
124 """Very nasty problem with references held by multiple runs of a script.
126 """Very nasty problem with references held by multiple runs of a script.
125 See: https://bugs.launchpad.net/ipython/+bug/269966
127 See: https://bugs.launchpad.net/ipython/+bug/269966
126
128
127 In [1]: _ip.clear_main_mod_cache()
129 In [1]: _ip.clear_main_mod_cache()
128
130
129 In [2]: run refbug
131 In [2]: run refbug
130
132
131 In [3]: call_f()
133 In [3]: call_f()
132 lowercased: hello
134 lowercased: hello
133
135
134 In [4]: run refbug
136 In [4]: run refbug
135
137
136 In [5]: call_f()
138 In [5]: call_f()
137 lowercased: hello
139 lowercased: hello
138 lowercased: hello
140 lowercased: hello
139 """
141 """
140
142
141 #-----------------------------------------------------------------------------
143 #-----------------------------------------------------------------------------
142 # Tests for %run
144 # Tests for %run
143 #-----------------------------------------------------------------------------
145 #-----------------------------------------------------------------------------
144
146
145 # %run is critical enough that it's a good idea to have a solid collection of
147 # %run is critical enough that it's a good idea to have a solid collection of
146 # tests for it, some as doctests and some as normal tests.
148 # tests for it, some as doctests and some as normal tests.
147
149
148 def doctest_run_ns():
150 def doctest_run_ns():
149 """Classes declared %run scripts must be instantiable afterwards.
151 """Classes declared %run scripts must be instantiable afterwards.
150
152
151 In [11]: run tclass foo
153 In [11]: run tclass foo
152
154
153 In [12]: isinstance(f(),foo)
155 In [12]: isinstance(f(),foo)
154 Out[12]: True
156 Out[12]: True
155 """
157 """
156
158
157
159
158 def doctest_run_ns2():
160 def doctest_run_ns2():
159 """Classes declared %run scripts must be instantiable afterwards.
161 """Classes declared %run scripts must be instantiable afterwards.
160
162
161 In [4]: run tclass C-first_pass
163 In [4]: run tclass C-first_pass
162
164
163 In [5]: run tclass C-second_pass
165 In [5]: run tclass C-second_pass
164 tclass.py: deleting object: C-first_pass
166 tclass.py: deleting object: C-first_pass
165 """
167 """
166
168
167 def doctest_run_builtins():
169 def doctest_run_builtins():
168 """Check that %run doesn't damage __builtins__ via a doctest.
170 """Check that %run doesn't damage __builtins__ via a doctest.
169
171
170 This is similar to the test_run_builtins, but I want *both* forms of the
172 This is similar to the test_run_builtins, but I want *both* forms of the
171 test to catch any possible glitches in our testing machinery, since that
173 test to catch any possible glitches in our testing machinery, since that
172 modifies %run somewhat. So for this, we have both a normal test (below)
174 modifies %run somewhat. So for this, we have both a normal test (below)
173 and a doctest (this one).
175 and a doctest (this one).
174
176
175 In [1]: import tempfile
177 In [1]: import tempfile
176
178
177 In [2]: bid1 = id(__builtins__)
179 In [2]: bid1 = id(__builtins__)
178
180
179 In [3]: fname = tempfile.mkstemp()[1]
181 In [3]: fname = tempfile.mkstemp()[1]
180
182
181 In [3]: f = open(fname,'w')
183 In [3]: f = open(fname,'w')
182
184
183 In [4]: f.write('pass\\n')
185 In [4]: f.write('pass\\n')
184
186
185 In [5]: f.flush()
187 In [5]: f.flush()
186
188
187 In [6]: print type(__builtins__)
189 In [6]: print type(__builtins__)
188 <type 'module'>
190 <type 'module'>
189
191
190 In [7]: %run "$fname"
192 In [7]: %run "$fname"
191
193
192 In [7]: f.close()
194 In [7]: f.close()
193
195
194 In [8]: bid2 = id(__builtins__)
196 In [8]: bid2 = id(__builtins__)
195
197
196 In [9]: print type(__builtins__)
198 In [9]: print type(__builtins__)
197 <type 'module'>
199 <type 'module'>
198
200
199 In [10]: bid1 == bid2
201 In [10]: bid1 == bid2
200 Out[10]: True
202 Out[10]: True
201
203
202 In [12]: try:
204 In [12]: try:
203 ....: os.unlink(fname)
205 ....: os.unlink(fname)
204 ....: except:
206 ....: except:
205 ....: pass
207 ....: pass
206 ....:
208 ....:
207 """
209 """
208
210
209 # For some tests, it will be handy to organize them in a class with a common
211 # For some tests, it will be handy to organize them in a class with a common
210 # setup that makes a temp file
212 # setup that makes a temp file
211
213
212 class TestMagicRun(object):
214 class TestMagicRun(object):
213
215
214 def setup(self):
216 def setup(self):
215 """Make a valid python temp file."""
217 """Make a valid python temp file."""
216 fname = tempfile.mkstemp()[1]
218 fname = tempfile.mkstemp()[1]
217 f = open(fname,'w')
219 f = open(fname,'w')
218 f.write('pass\n')
220 f.write('pass\n')
219 f.flush()
221 f.flush()
220 self.tmpfile = f
222 self.tmpfile = f
221 self.fname = fname
223 self.fname = fname
222
224
223 def run_tmpfile(self):
225 def run_tmpfile(self):
226 _ip = get_ipython()
224 # This fails on Windows if self.tmpfile.name has spaces or "~" in it.
227 # This fails on Windows if self.tmpfile.name has spaces or "~" in it.
225 # See below and ticket https://bugs.launchpad.net/bugs/366353
228 # See below and ticket https://bugs.launchpad.net/bugs/366353
226 _ip.magic('run "%s"' % self.fname)
229 _ip.magic('run "%s"' % self.fname)
227
230
228 def test_builtins_id(self):
231 def test_builtins_id(self):
229 """Check that %run doesn't damage __builtins__ """
232 """Check that %run doesn't damage __builtins__ """
230
233 _ip = get_ipython()
231 # Test that the id of __builtins__ is not modified by %run
234 # Test that the id of __builtins__ is not modified by %run
232 bid1 = id(_ip.user_ns['__builtins__'])
235 bid1 = id(_ip.user_ns['__builtins__'])
233 self.run_tmpfile()
236 self.run_tmpfile()
234 bid2 = id(_ip.user_ns['__builtins__'])
237 bid2 = id(_ip.user_ns['__builtins__'])
235 tt.assert_equals(bid1, bid2)
238 tt.assert_equals(bid1, bid2)
236
239
237 def test_builtins_type(self):
240 def test_builtins_type(self):
238 """Check that the type of __builtins__ doesn't change with %run.
241 """Check that the type of __builtins__ doesn't change with %run.
239
242
240 However, the above could pass if __builtins__ was already modified to
243 However, the above could pass if __builtins__ was already modified to
241 be a dict (it should be a module) by a previous use of %run. So we
244 be a dict (it should be a module) by a previous use of %run. So we
242 also check explicitly that it really is a module:
245 also check explicitly that it really is a module:
243 """
246 """
247 _ip = get_ipython()
244 self.run_tmpfile()
248 self.run_tmpfile()
245 tt.assert_equals(type(_ip.user_ns['__builtins__']),type(sys))
249 tt.assert_equals(type(_ip.user_ns['__builtins__']),type(sys))
246
250
247 def test_prompts(self):
251 def test_prompts(self):
248 """Test that prompts correctly generate after %run"""
252 """Test that prompts correctly generate after %run"""
249 self.run_tmpfile()
253 self.run_tmpfile()
254 _ip = get_ipython()
250 p2 = str(_ip.outputcache.prompt2).strip()
255 p2 = str(_ip.outputcache.prompt2).strip()
251 nt.assert_equals(p2[:3], '...')
256 nt.assert_equals(p2[:3], '...')
252
257
253 def teardown(self):
258 def teardown(self):
254 self.tmpfile.close()
259 self.tmpfile.close()
255 try:
260 try:
256 os.unlink(self.fname)
261 os.unlink(self.fname)
257 except:
262 except:
258 # On Windows, even though we close the file, we still can't delete
263 # On Windows, even though we close the file, we still can't delete
259 # it. I have no clue why
264 # it. I have no clue why
260 pass
265 pass
261
266
262 # Multiple tests for clipboard pasting
267 # Multiple tests for clipboard pasting
263 def test_paste():
268 def test_paste():
264
269 _ip = get_ipython()
265 def paste(txt, flags='-q'):
270 def paste(txt, flags='-q'):
266 """Paste input text, by default in quiet mode"""
271 """Paste input text, by default in quiet mode"""
267 hooks.clipboard_get = lambda : txt
272 hooks.clipboard_get = lambda : txt
268 _ip.magic('paste '+flags)
273 _ip.magic('paste '+flags)
269
274
270 # Inject fake clipboard hook but save original so we can restore it later
275 # Inject fake clipboard hook but save original so we can restore it later
271 hooks = _ip.hooks
276 hooks = _ip.hooks
272 user_ns = _ip.user_ns
277 user_ns = _ip.user_ns
273 original_clip = hooks.clipboard_get
278 original_clip = hooks.clipboard_get
274
279
275 try:
280 try:
276 # This try/except with an emtpy except clause is here only because
281 # This try/except with an emtpy except clause is here only because
277 # try/yield/finally is invalid syntax in Python 2.4. This will be
282 # try/yield/finally is invalid syntax in Python 2.4. This will be
278 # removed when we drop 2.4-compatibility, and the emtpy except below
283 # removed when we drop 2.4-compatibility, and the emtpy except below
279 # will be changed to a finally.
284 # will be changed to a finally.
280
285
281 # Run tests with fake clipboard function
286 # Run tests with fake clipboard function
282 user_ns.pop('x', None)
287 user_ns.pop('x', None)
283 paste('x=1')
288 paste('x=1')
284 yield (nt.assert_equal, user_ns['x'], 1)
289 yield (nt.assert_equal, user_ns['x'], 1)
285
290
286 user_ns.pop('x', None)
291 user_ns.pop('x', None)
287 paste('>>> x=2')
292 paste('>>> x=2')
288 yield (nt.assert_equal, user_ns['x'], 2)
293 yield (nt.assert_equal, user_ns['x'], 2)
289
294
290 paste("""
295 paste("""
291 >>> x = [1,2,3]
296 >>> x = [1,2,3]
292 >>> y = []
297 >>> y = []
293 >>> for i in x:
298 >>> for i in x:
294 ... y.append(i**2)
299 ... y.append(i**2)
295 ...
300 ...
296 """)
301 """)
297 yield (nt.assert_equal, user_ns['x'], [1,2,3])
302 yield (nt.assert_equal, user_ns['x'], [1,2,3])
298 yield (nt.assert_equal, user_ns['y'], [1,4,9])
303 yield (nt.assert_equal, user_ns['y'], [1,4,9])
299
304
300 # Now, test that paste -r works
305 # Now, test that paste -r works
301 user_ns.pop('x', None)
306 user_ns.pop('x', None)
302 yield (nt.assert_false, 'x' in user_ns)
307 yield (nt.assert_false, 'x' in user_ns)
303 _ip.magic('paste -r')
308 _ip.magic('paste -r')
304 yield (nt.assert_equal, user_ns['x'], [1,2,3])
309 yield (nt.assert_equal, user_ns['x'], [1,2,3])
305
310
306 # Also test paste echoing, by temporarily faking the writer
311 # Also test paste echoing, by temporarily faking the writer
307 w = StringIO()
312 w = StringIO()
308 writer = _ip.write
313 writer = _ip.write
309 _ip.write = w.write
314 _ip.write = w.write
310 code = """
315 code = """
311 a = 100
316 a = 100
312 b = 200"""
317 b = 200"""
313 try:
318 try:
314 paste(code,'')
319 paste(code,'')
315 out = w.getvalue()
320 out = w.getvalue()
316 finally:
321 finally:
317 _ip.write = writer
322 _ip.write = writer
318 yield (nt.assert_equal, user_ns['a'], 100)
323 yield (nt.assert_equal, user_ns['a'], 100)
319 yield (nt.assert_equal, user_ns['b'], 200)
324 yield (nt.assert_equal, user_ns['b'], 200)
320 yield (nt.assert_equal, out, code+"\n## -- End pasted text --\n")
325 yield (nt.assert_equal, out, code+"\n## -- End pasted text --\n")
321
326
322 finally:
327 finally:
323 # This should be in a finally clause, instead of the bare except above.
328 # This should be in a finally clause, instead of the bare except above.
324 # Restore original hook
329 # Restore original hook
325 hooks.clipboard_get = original_clip
330 hooks.clipboard_get = original_clip
326
331
@@ -1,58 +1,58 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """ IPython extension: new prefilters for output grabbing
2 """ IPython extension: new prefilters for output grabbing
3
3
4 Provides
4 Provides
5
5
6 var = %magic blah blah
6 var = %magic blah blah
7
7
8 var = !ls
8 var = !ls
9 """
9 """
10
10
11 from IPython.core import ipapi
11 from IPython.core import ipapi
12 from IPython.core.error import TryNext
12 from IPython.core.error import TryNext
13 from IPython.utils.genutils import *
13 from IPython.utils.genutils import *
14
14
15 ip = ipapi.get()
15 ip = ipapi.get()
16
16
17 import re
17 import re
18
18
19 def hnd_magic(line,mo):
19 def hnd_magic(line,mo):
20 """ Handle a = %mymagic blah blah """
20 """ Handle a = %mymagic blah blah """
21 var = mo.group('varname')
21 var = mo.group('varname')
22 cmd = mo.group('cmd')
22 cmd = mo.group('cmd')
23 expr = make_quoted_expr(cmd)
23 expr = make_quoted_expr(cmd)
24 return itpl('$var = _ip.magic($expr)')
24 return itpl('$var = get_ipython().magic($expr)')
25
25
26 def hnd_syscmd(line,mo):
26 def hnd_syscmd(line,mo):
27 """ Handle a = !ls """
27 """ Handle a = !ls """
28 var = mo.group('varname')
28 var = mo.group('varname')
29 cmd = mo.group('cmd')
29 cmd = mo.group('cmd')
30 expr = make_quoted_expr(itpl("sc -l =$cmd"))
30 expr = make_quoted_expr(itpl("sc -l =$cmd"))
31 return itpl('$var = _ip.magic($expr)')
31 return itpl('$var = get_ipython().magic($expr)')
32
32
33 def install_re_handler(pat, hnd):
33 def install_re_handler(pat, hnd):
34 ip.meta.re_prefilters.append((re.compile(pat), hnd))
34 ip.meta.re_prefilters.append((re.compile(pat), hnd))
35
35
36 def init_handlers():
36 def init_handlers():
37
37
38 ip.meta.re_prefilters = []
38 ip.meta.re_prefilters = []
39
39
40 install_re_handler('(?P<varname>[\w\.]+)\s*=\s*%(?P<cmd>.*)',
40 install_re_handler('(?P<varname>[\w\.]+)\s*=\s*%(?P<cmd>.*)',
41 hnd_magic
41 hnd_magic
42 )
42 )
43
43
44 install_re_handler('(?P<varname>[\w\.]+)\s*=\s*!(?P<cmd>.*)',
44 install_re_handler('(?P<varname>[\w\.]+)\s*=\s*!(?P<cmd>.*)',
45 hnd_syscmd
45 hnd_syscmd
46 )
46 )
47
47
48 init_handlers()
48 init_handlers()
49
49
50 def regex_prefilter_f(self,line):
50 def regex_prefilter_f(self,line):
51 for pat, handler in ip.meta.re_prefilters:
51 for pat, handler in ip.meta.re_prefilters:
52 mo = pat.match(line)
52 mo = pat.match(line)
53 if mo:
53 if mo:
54 return handler(line,mo)
54 return handler(line,mo)
55
55
56 raise TryNext
56 raise TryNext
57
57
58 ip.set_hook('input_prefilter', regex_prefilter_f)
58 ip.set_hook('input_prefilter', regex_prefilter_f)
@@ -1,2328 +1,2328 b''
1 # -*- coding: iso-8859-1 -*-
1 # -*- coding: iso-8859-1 -*-
2
2
3 """
3 """
4 ``ipipe`` provides classes to be used in an interactive Python session. Doing a
4 ``ipipe`` provides classes to be used in an interactive Python session. Doing a
5 ``from ipipe import *`` is the preferred way to do this. The name of all
5 ``from ipipe import *`` is the preferred way to do this. The name of all
6 objects imported this way starts with ``i`` to minimize collisions.
6 objects imported this way starts with ``i`` to minimize collisions.
7
7
8 ``ipipe`` supports "pipeline expressions", which is something resembling Unix
8 ``ipipe`` supports "pipeline expressions", which is something resembling Unix
9 pipes. An example is::
9 pipes. An example is::
10
10
11 >>> ienv | isort("key.lower()")
11 >>> ienv | isort("key.lower()")
12
12
13 This gives a listing of all environment variables sorted by name.
13 This gives a listing of all environment variables sorted by name.
14
14
15
15
16 There are three types of objects in a pipeline expression:
16 There are three types of objects in a pipeline expression:
17
17
18 * ``Table``s: These objects produce items. Examples are ``ils`` (listing the
18 * ``Table``s: These objects produce items. Examples are ``ils`` (listing the
19 current directory, ``ienv`` (listing environment variables), ``ipwd`` (listing
19 current directory, ``ienv`` (listing environment variables), ``ipwd`` (listing
20 user accounts) and ``igrp`` (listing user groups). A ``Table`` must be the
20 user accounts) and ``igrp`` (listing user groups). A ``Table`` must be the
21 first object in a pipe expression.
21 first object in a pipe expression.
22
22
23 * ``Pipe``s: These objects sit in the middle of a pipe expression. They
23 * ``Pipe``s: These objects sit in the middle of a pipe expression. They
24 transform the input in some way (e.g. filtering or sorting it). Examples are:
24 transform the input in some way (e.g. filtering or sorting it). Examples are:
25 ``ifilter`` (which filters the input pipe), ``isort`` (which sorts the input
25 ``ifilter`` (which filters the input pipe), ``isort`` (which sorts the input
26 pipe) and ``ieval`` (which evaluates a function or expression for each object
26 pipe) and ``ieval`` (which evaluates a function or expression for each object
27 in the input pipe).
27 in the input pipe).
28
28
29 * ``Display``s: These objects can be put as the last object in a pipeline
29 * ``Display``s: These objects can be put as the last object in a pipeline
30 expression. There are responsible for displaying the result of the pipeline
30 expression. There are responsible for displaying the result of the pipeline
31 expression. If a pipeline expression doesn't end in a display object a default
31 expression. If a pipeline expression doesn't end in a display object a default
32 display objects will be used. One example is ``ibrowse`` which is a ``curses``
32 display objects will be used. One example is ``ibrowse`` which is a ``curses``
33 based browser.
33 based browser.
34
34
35
35
36 Adding support for pipeline expressions to your own objects can be done through
36 Adding support for pipeline expressions to your own objects can be done through
37 three extensions points (all of them optional):
37 three extensions points (all of them optional):
38
38
39 * An object that will be displayed as a row by a ``Display`` object should
39 * An object that will be displayed as a row by a ``Display`` object should
40 implement the method ``__xattrs__(self, mode)`` method or register an
40 implement the method ``__xattrs__(self, mode)`` method or register an
41 implementation of the generic function ``xattrs``. For more info see ``xattrs``.
41 implementation of the generic function ``xattrs``. For more info see ``xattrs``.
42
42
43 * When an object ``foo`` is displayed by a ``Display`` object, the generic
43 * When an object ``foo`` is displayed by a ``Display`` object, the generic
44 function ``xrepr`` is used.
44 function ``xrepr`` is used.
45
45
46 * Objects that can be iterated by ``Pipe``s must iterable. For special cases,
46 * Objects that can be iterated by ``Pipe``s must iterable. For special cases,
47 where iteration for display is different than the normal iteration a special
47 where iteration for display is different than the normal iteration a special
48 implementation can be registered with the generic function ``xiter``. This
48 implementation can be registered with the generic function ``xiter``. This
49 makes it possible to use dictionaries and modules in pipeline expressions,
49 makes it possible to use dictionaries and modules in pipeline expressions,
50 for example::
50 for example::
51
51
52 >>> import sys
52 >>> import sys
53 >>> sys | ifilter("isinstance(value, int)") | idump
53 >>> sys | ifilter("isinstance(value, int)") | idump
54 key |value
54 key |value
55 api_version| 1012
55 api_version| 1012
56 dllhandle | 503316480
56 dllhandle | 503316480
57 hexversion | 33817328
57 hexversion | 33817328
58 maxint |2147483647
58 maxint |2147483647
59 maxunicode | 65535
59 maxunicode | 65535
60 >>> sys.modules | ifilter("_.value is not None") | isort("_.key.lower()")
60 >>> sys.modules | ifilter("_.value is not None") | isort("_.key.lower()")
61 ...
61 ...
62
62
63 Note: The expression strings passed to ``ifilter()`` and ``isort()`` can
63 Note: The expression strings passed to ``ifilter()`` and ``isort()`` can
64 refer to the object to be filtered or sorted via the variable ``_`` and to any
64 refer to the object to be filtered or sorted via the variable ``_`` and to any
65 of the attributes of the object, i.e.::
65 of the attributes of the object, i.e.::
66
66
67 >>> sys.modules | ifilter("_.value is not None") | isort("_.key.lower()")
67 >>> sys.modules | ifilter("_.value is not None") | isort("_.key.lower()")
68
68
69 does the same as::
69 does the same as::
70
70
71 >>> sys.modules | ifilter("value is not None") | isort("key.lower()")
71 >>> sys.modules | ifilter("value is not None") | isort("key.lower()")
72
72
73 In addition to expression strings, it's possible to pass callables (taking
73 In addition to expression strings, it's possible to pass callables (taking
74 the object as an argument) to ``ifilter()``, ``isort()`` and ``ieval()``::
74 the object as an argument) to ``ifilter()``, ``isort()`` and ``ieval()``::
75
75
76 >>> sys | ifilter(lambda _:isinstance(_.value, int)) \
76 >>> sys | ifilter(lambda _:isinstance(_.value, int)) \
77 ... | ieval(lambda _: (_.key, hex(_.value))) | idump
77 ... | ieval(lambda _: (_.key, hex(_.value))) | idump
78 0 |1
78 0 |1
79 api_version|0x3f4
79 api_version|0x3f4
80 dllhandle |0x1e000000
80 dllhandle |0x1e000000
81 hexversion |0x20402f0
81 hexversion |0x20402f0
82 maxint |0x7fffffff
82 maxint |0x7fffffff
83 maxunicode |0xffff
83 maxunicode |0xffff
84 """
84 """
85
85
86 skip_doctest = True # ignore top-level docstring as a doctest.
86 skip_doctest = True # ignore top-level docstring as a doctest.
87
87
88 import sys, os, os.path, stat, glob, new, csv, datetime, types
88 import sys, os, os.path, stat, glob, new, csv, datetime, types
89 import itertools, mimetypes, StringIO
89 import itertools, mimetypes, StringIO
90
90
91 try: # Python 2.3 compatibility
91 try: # Python 2.3 compatibility
92 import collections
92 import collections
93 except ImportError:
93 except ImportError:
94 deque = list
94 deque = list
95 else:
95 else:
96 deque = collections.deque
96 deque = collections.deque
97
97
98 try: # Python 2.3 compatibility
98 try: # Python 2.3 compatibility
99 set
99 set
100 except NameError:
100 except NameError:
101 import sets
101 import sets
102 set = sets.Set
102 set = sets.Set
103
103
104 try: # Python 2.3 compatibility
104 try: # Python 2.3 compatibility
105 sorted
105 sorted
106 except NameError:
106 except NameError:
107 def sorted(iterator, key=None, reverse=False):
107 def sorted(iterator, key=None, reverse=False):
108 items = list(iterator)
108 items = list(iterator)
109 if key is not None:
109 if key is not None:
110 items.sort(lambda i1, i2: cmp(key(i1), key(i2)))
110 items.sort(lambda i1, i2: cmp(key(i1), key(i2)))
111 else:
111 else:
112 items.sort()
112 items.sort()
113 if reverse:
113 if reverse:
114 items.reverse()
114 items.reverse()
115 return items
115 return items
116
116
117 try: # Python 2.4 compatibility
117 try: # Python 2.4 compatibility
118 GeneratorExit
118 GeneratorExit
119 except NameError:
119 except NameError:
120 GeneratorExit = SystemExit
120 GeneratorExit = SystemExit
121
121
122 try:
122 try:
123 import pwd
123 import pwd
124 except ImportError:
124 except ImportError:
125 pwd = None
125 pwd = None
126
126
127 try:
127 try:
128 import grp
128 import grp
129 except ImportError:
129 except ImportError:
130 grp = None
130 grp = None
131
131
132 from IPython.external import simplegeneric
132 from IPython.external import simplegeneric
133 from IPython.external import path
133 from IPython.external import path
134
134
135 try:
135 try:
136 from IPython.utils import genutils
136 from IPython.utils import genutils
137 from IPython.utils import generics
137 from IPython.utils import generics
138 except ImportError:
138 except ImportError:
139 genutils = None
139 genutils = None
140 generics = None
140 generics = None
141
141
142 from IPython.core import ipapi
142 from IPython.core import ipapi
143
143
144
144
145 __all__ = [
145 __all__ = [
146 "ifile", "ils", "iglob", "iwalk", "ipwdentry", "ipwd", "igrpentry", "igrp",
146 "ifile", "ils", "iglob", "iwalk", "ipwdentry", "ipwd", "igrpentry", "igrp",
147 "icsv", "ix", "ichain", "isort", "ifilter", "ieval", "ienum",
147 "icsv", "ix", "ichain", "isort", "ifilter", "ieval", "ienum",
148 "ienv", "ihist", "ialias", "icap", "idump", "iless"
148 "ienv", "ihist", "ialias", "icap", "idump", "iless"
149 ]
149 ]
150
150
151
151
152 os.stat_float_times(True) # enable microseconds
152 os.stat_float_times(True) # enable microseconds
153
153
154
154
155 class AttrNamespace(object):
155 class AttrNamespace(object):
156 """
156 """
157 Helper class that is used for providing a namespace for evaluating
157 Helper class that is used for providing a namespace for evaluating
158 expressions containing attribute names of an object.
158 expressions containing attribute names of an object.
159 """
159 """
160 def __init__(self, wrapped):
160 def __init__(self, wrapped):
161 self.wrapped = wrapped
161 self.wrapped = wrapped
162
162
163 def __getitem__(self, name):
163 def __getitem__(self, name):
164 if name == "_":
164 if name == "_":
165 return self.wrapped
165 return self.wrapped
166 try:
166 try:
167 return getattr(self.wrapped, name)
167 return getattr(self.wrapped, name)
168 except AttributeError:
168 except AttributeError:
169 raise KeyError(name)
169 raise KeyError(name)
170
170
171 # Python 2.3 compatibility
171 # Python 2.3 compatibility
172 # use eval workaround to find out which names are used in the
172 # use eval workaround to find out which names are used in the
173 # eval string and put them into the locals. This works for most
173 # eval string and put them into the locals. This works for most
174 # normal uses case, bizarre ones like accessing the locals()
174 # normal uses case, bizarre ones like accessing the locals()
175 # will fail
175 # will fail
176 try:
176 try:
177 eval("_", None, AttrNamespace(None))
177 eval("_", None, AttrNamespace(None))
178 except TypeError:
178 except TypeError:
179 real_eval = eval
179 real_eval = eval
180 def eval(codestring, _globals, _locals):
180 def eval(codestring, _globals, _locals):
181 """
181 """
182 eval(source[, globals[, locals]]) -> value
182 eval(source[, globals[, locals]]) -> value
183
183
184 Evaluate the source in the context of globals and locals.
184 Evaluate the source in the context of globals and locals.
185 The source may be a string representing a Python expression
185 The source may be a string representing a Python expression
186 or a code object as returned by compile().
186 or a code object as returned by compile().
187 The globals must be a dictionary and locals can be any mappping.
187 The globals must be a dictionary and locals can be any mappping.
188
188
189 This function is a workaround for the shortcomings of
189 This function is a workaround for the shortcomings of
190 Python 2.3's eval.
190 Python 2.3's eval.
191 """
191 """
192
192
193 if isinstance(codestring, basestring):
193 if isinstance(codestring, basestring):
194 code = compile(codestring, "_eval", "eval")
194 code = compile(codestring, "_eval", "eval")
195 else:
195 else:
196 code = codestring
196 code = codestring
197 newlocals = {}
197 newlocals = {}
198 for name in code.co_names:
198 for name in code.co_names:
199 try:
199 try:
200 newlocals[name] = _locals[name]
200 newlocals[name] = _locals[name]
201 except KeyError:
201 except KeyError:
202 pass
202 pass
203 return real_eval(code, _globals, newlocals)
203 return real_eval(code, _globals, newlocals)
204
204
205
205
206 noitem = object()
206 noitem = object()
207
207
208
208
209 def item(iterator, index, default=noitem):
209 def item(iterator, index, default=noitem):
210 """
210 """
211 Return the ``index``th item from the iterator ``iterator``.
211 Return the ``index``th item from the iterator ``iterator``.
212 ``index`` must be an integer (negative integers are relative to the
212 ``index`` must be an integer (negative integers are relative to the
213 end (i.e. the last items produced by the iterator)).
213 end (i.e. the last items produced by the iterator)).
214
214
215 If ``default`` is given, this will be the default value when
215 If ``default`` is given, this will be the default value when
216 the iterator doesn't contain an item at this position. Otherwise an
216 the iterator doesn't contain an item at this position. Otherwise an
217 ``IndexError`` will be raised.
217 ``IndexError`` will be raised.
218
218
219 Note that using this function will partially or totally exhaust the
219 Note that using this function will partially or totally exhaust the
220 iterator.
220 iterator.
221 """
221 """
222 i = index
222 i = index
223 if i>=0:
223 if i>=0:
224 for item in iterator:
224 for item in iterator:
225 if not i:
225 if not i:
226 return item
226 return item
227 i -= 1
227 i -= 1
228 else:
228 else:
229 i = -index
229 i = -index
230 cache = deque()
230 cache = deque()
231 for item in iterator:
231 for item in iterator:
232 cache.append(item)
232 cache.append(item)
233 if len(cache)>i:
233 if len(cache)>i:
234 cache.popleft()
234 cache.popleft()
235 if len(cache)==i:
235 if len(cache)==i:
236 return cache.popleft()
236 return cache.popleft()
237 if default is noitem:
237 if default is noitem:
238 raise IndexError(index)
238 raise IndexError(index)
239 else:
239 else:
240 return default
240 return default
241
241
242
242
243 def getglobals(g):
243 def getglobals(g):
244 """
244 """
245 Return the global namespace that is used for expression strings in
245 Return the global namespace that is used for expression strings in
246 ``ifilter`` and others. This is ``g`` or (if ``g`` is ``None``) IPython's
246 ``ifilter`` and others. This is ``g`` or (if ``g`` is ``None``) IPython's
247 user namespace.
247 user namespace.
248 """
248 """
249 if g is None:
249 if g is None:
250 if ipapi is not None:
250 if ipapi is not None:
251 api = ipapi.get()
251 api = ipapi.get()
252 if api is not None:
252 if api is not None:
253 return api.user_ns
253 return api.user_ns
254 return globals()
254 return globals()
255 return g
255 return g
256
256
257
257
258 class Descriptor(object):
258 class Descriptor(object):
259 """
259 """
260 A ``Descriptor`` object is used for describing the attributes of objects.
260 A ``Descriptor`` object is used for describing the attributes of objects.
261 """
261 """
262 def __hash__(self):
262 def __hash__(self):
263 return hash(self.__class__) ^ hash(self.key())
263 return hash(self.__class__) ^ hash(self.key())
264
264
265 def __eq__(self, other):
265 def __eq__(self, other):
266 return self.__class__ is other.__class__ and self.key() == other.key()
266 return self.__class__ is other.__class__ and self.key() == other.key()
267
267
268 def __ne__(self, other):
268 def __ne__(self, other):
269 return self.__class__ is not other.__class__ or self.key() != other.key()
269 return self.__class__ is not other.__class__ or self.key() != other.key()
270
270
271 def key(self):
271 def key(self):
272 pass
272 pass
273
273
274 def name(self):
274 def name(self):
275 """
275 """
276 Return the name of this attribute for display by a ``Display`` object
276 Return the name of this attribute for display by a ``Display`` object
277 (e.g. as a column title).
277 (e.g. as a column title).
278 """
278 """
279 key = self.key()
279 key = self.key()
280 if key is None:
280 if key is None:
281 return "_"
281 return "_"
282 return str(key)
282 return str(key)
283
283
284 def attrtype(self, obj):
284 def attrtype(self, obj):
285 """
285 """
286 Return the type of this attribute (i.e. something like "attribute" or
286 Return the type of this attribute (i.e. something like "attribute" or
287 "method").
287 "method").
288 """
288 """
289
289
290 def valuetype(self, obj):
290 def valuetype(self, obj):
291 """
291 """
292 Return the type of this attribute value of the object ``obj``.
292 Return the type of this attribute value of the object ``obj``.
293 """
293 """
294
294
295 def value(self, obj):
295 def value(self, obj):
296 """
296 """
297 Return the value of this attribute of the object ``obj``.
297 Return the value of this attribute of the object ``obj``.
298 """
298 """
299
299
300 def doc(self, obj):
300 def doc(self, obj):
301 """
301 """
302 Return the documentation for this attribute.
302 Return the documentation for this attribute.
303 """
303 """
304
304
305 def shortdoc(self, obj):
305 def shortdoc(self, obj):
306 """
306 """
307 Return a short documentation for this attribute (defaulting to the
307 Return a short documentation for this attribute (defaulting to the
308 first line).
308 first line).
309 """
309 """
310 doc = self.doc(obj)
310 doc = self.doc(obj)
311 if doc is not None:
311 if doc is not None:
312 doc = doc.strip().splitlines()[0].strip()
312 doc = doc.strip().splitlines()[0].strip()
313 return doc
313 return doc
314
314
315 def iter(self, obj):
315 def iter(self, obj):
316 """
316 """
317 Return an iterator for this attribute of the object ``obj``.
317 Return an iterator for this attribute of the object ``obj``.
318 """
318 """
319 return xiter(self.value(obj))
319 return xiter(self.value(obj))
320
320
321
321
322 class SelfDescriptor(Descriptor):
322 class SelfDescriptor(Descriptor):
323 """
323 """
324 A ``SelfDescriptor`` describes the object itself.
324 A ``SelfDescriptor`` describes the object itself.
325 """
325 """
326 def key(self):
326 def key(self):
327 return None
327 return None
328
328
329 def attrtype(self, obj):
329 def attrtype(self, obj):
330 return "self"
330 return "self"
331
331
332 def valuetype(self, obj):
332 def valuetype(self, obj):
333 return type(obj)
333 return type(obj)
334
334
335 def value(self, obj):
335 def value(self, obj):
336 return obj
336 return obj
337
337
338 def __repr__(self):
338 def __repr__(self):
339 return "Self"
339 return "Self"
340
340
341 selfdescriptor = SelfDescriptor() # there's no need for more than one
341 selfdescriptor = SelfDescriptor() # there's no need for more than one
342
342
343
343
344 class AttributeDescriptor(Descriptor):
344 class AttributeDescriptor(Descriptor):
345 """
345 """
346 An ``AttributeDescriptor`` describes a simple attribute of an object.
346 An ``AttributeDescriptor`` describes a simple attribute of an object.
347 """
347 """
348 __slots__ = ("_name", "_doc")
348 __slots__ = ("_name", "_doc")
349
349
350 def __init__(self, name, doc=None):
350 def __init__(self, name, doc=None):
351 self._name = name
351 self._name = name
352 self._doc = doc
352 self._doc = doc
353
353
354 def key(self):
354 def key(self):
355 return self._name
355 return self._name
356
356
357 def doc(self, obj):
357 def doc(self, obj):
358 return self._doc
358 return self._doc
359
359
360 def attrtype(self, obj):
360 def attrtype(self, obj):
361 return "attr"
361 return "attr"
362
362
363 def valuetype(self, obj):
363 def valuetype(self, obj):
364 return type(getattr(obj, self._name))
364 return type(getattr(obj, self._name))
365
365
366 def value(self, obj):
366 def value(self, obj):
367 return getattr(obj, self._name)
367 return getattr(obj, self._name)
368
368
369 def __repr__(self):
369 def __repr__(self):
370 if self._doc is None:
370 if self._doc is None:
371 return "Attribute(%r)" % self._name
371 return "Attribute(%r)" % self._name
372 else:
372 else:
373 return "Attribute(%r, %r)" % (self._name, self._doc)
373 return "Attribute(%r, %r)" % (self._name, self._doc)
374
374
375
375
376 class IndexDescriptor(Descriptor):
376 class IndexDescriptor(Descriptor):
377 """
377 """
378 An ``IndexDescriptor`` describes an "attribute" of an object that is fetched
378 An ``IndexDescriptor`` describes an "attribute" of an object that is fetched
379 via ``__getitem__``.
379 via ``__getitem__``.
380 """
380 """
381 __slots__ = ("_index",)
381 __slots__ = ("_index",)
382
382
383 def __init__(self, index):
383 def __init__(self, index):
384 self._index = index
384 self._index = index
385
385
386 def key(self):
386 def key(self):
387 return self._index
387 return self._index
388
388
389 def attrtype(self, obj):
389 def attrtype(self, obj):
390 return "item"
390 return "item"
391
391
392 def valuetype(self, obj):
392 def valuetype(self, obj):
393 return type(obj[self._index])
393 return type(obj[self._index])
394
394
395 def value(self, obj):
395 def value(self, obj):
396 return obj[self._index]
396 return obj[self._index]
397
397
398 def __repr__(self):
398 def __repr__(self):
399 return "Index(%r)" % self._index
399 return "Index(%r)" % self._index
400
400
401
401
402 class MethodDescriptor(Descriptor):
402 class MethodDescriptor(Descriptor):
403 """
403 """
404 A ``MethodDescriptor`` describes a method of an object that can be called
404 A ``MethodDescriptor`` describes a method of an object that can be called
405 without argument. Note that this method shouldn't change the object.
405 without argument. Note that this method shouldn't change the object.
406 """
406 """
407 __slots__ = ("_name", "_doc")
407 __slots__ = ("_name", "_doc")
408
408
409 def __init__(self, name, doc=None):
409 def __init__(self, name, doc=None):
410 self._name = name
410 self._name = name
411 self._doc = doc
411 self._doc = doc
412
412
413 def key(self):
413 def key(self):
414 return self._name
414 return self._name
415
415
416 def doc(self, obj):
416 def doc(self, obj):
417 if self._doc is None:
417 if self._doc is None:
418 return getattr(obj, self._name).__doc__
418 return getattr(obj, self._name).__doc__
419 return self._doc
419 return self._doc
420
420
421 def attrtype(self, obj):
421 def attrtype(self, obj):
422 return "method"
422 return "method"
423
423
424 def valuetype(self, obj):
424 def valuetype(self, obj):
425 return type(self.value(obj))
425 return type(self.value(obj))
426
426
427 def value(self, obj):
427 def value(self, obj):
428 return getattr(obj, self._name)()
428 return getattr(obj, self._name)()
429
429
430 def __repr__(self):
430 def __repr__(self):
431 if self._doc is None:
431 if self._doc is None:
432 return "Method(%r)" % self._name
432 return "Method(%r)" % self._name
433 else:
433 else:
434 return "Method(%r, %r)" % (self._name, self._doc)
434 return "Method(%r, %r)" % (self._name, self._doc)
435
435
436
436
437 class IterAttributeDescriptor(Descriptor):
437 class IterAttributeDescriptor(Descriptor):
438 """
438 """
439 An ``IterAttributeDescriptor`` works like an ``AttributeDescriptor`` but
439 An ``IterAttributeDescriptor`` works like an ``AttributeDescriptor`` but
440 doesn't return an attribute values (because this value might be e.g. a large
440 doesn't return an attribute values (because this value might be e.g. a large
441 list).
441 list).
442 """
442 """
443 __slots__ = ("_name", "_doc")
443 __slots__ = ("_name", "_doc")
444
444
445 def __init__(self, name, doc=None):
445 def __init__(self, name, doc=None):
446 self._name = name
446 self._name = name
447 self._doc = doc
447 self._doc = doc
448
448
449 def key(self):
449 def key(self):
450 return self._name
450 return self._name
451
451
452 def doc(self, obj):
452 def doc(self, obj):
453 return self._doc
453 return self._doc
454
454
455 def attrtype(self, obj):
455 def attrtype(self, obj):
456 return "iter"
456 return "iter"
457
457
458 def valuetype(self, obj):
458 def valuetype(self, obj):
459 return noitem
459 return noitem
460
460
461 def value(self, obj):
461 def value(self, obj):
462 return noitem
462 return noitem
463
463
464 def iter(self, obj):
464 def iter(self, obj):
465 return xiter(getattr(obj, self._name))
465 return xiter(getattr(obj, self._name))
466
466
467 def __repr__(self):
467 def __repr__(self):
468 if self._doc is None:
468 if self._doc is None:
469 return "IterAttribute(%r)" % self._name
469 return "IterAttribute(%r)" % self._name
470 else:
470 else:
471 return "IterAttribute(%r, %r)" % (self._name, self._doc)
471 return "IterAttribute(%r, %r)" % (self._name, self._doc)
472
472
473
473
474 class IterMethodDescriptor(Descriptor):
474 class IterMethodDescriptor(Descriptor):
475 """
475 """
476 An ``IterMethodDescriptor`` works like an ``MethodDescriptor`` but doesn't
476 An ``IterMethodDescriptor`` works like an ``MethodDescriptor`` but doesn't
477 return an attribute values (because this value might be e.g. a large list).
477 return an attribute values (because this value might be e.g. a large list).
478 """
478 """
479 __slots__ = ("_name", "_doc")
479 __slots__ = ("_name", "_doc")
480
480
481 def __init__(self, name, doc=None):
481 def __init__(self, name, doc=None):
482 self._name = name
482 self._name = name
483 self._doc = doc
483 self._doc = doc
484
484
485 def key(self):
485 def key(self):
486 return self._name
486 return self._name
487
487
488 def doc(self, obj):
488 def doc(self, obj):
489 if self._doc is None:
489 if self._doc is None:
490 return getattr(obj, self._name).__doc__
490 return getattr(obj, self._name).__doc__
491 return self._doc
491 return self._doc
492
492
493 def attrtype(self, obj):
493 def attrtype(self, obj):
494 return "itermethod"
494 return "itermethod"
495
495
496 def valuetype(self, obj):
496 def valuetype(self, obj):
497 return noitem
497 return noitem
498
498
499 def value(self, obj):
499 def value(self, obj):
500 return noitem
500 return noitem
501
501
502 def iter(self, obj):
502 def iter(self, obj):
503 return xiter(getattr(obj, self._name)())
503 return xiter(getattr(obj, self._name)())
504
504
505 def __repr__(self):
505 def __repr__(self):
506 if self._doc is None:
506 if self._doc is None:
507 return "IterMethod(%r)" % self._name
507 return "IterMethod(%r)" % self._name
508 else:
508 else:
509 return "IterMethod(%r, %r)" % (self._name, self._doc)
509 return "IterMethod(%r, %r)" % (self._name, self._doc)
510
510
511
511
512 class FunctionDescriptor(Descriptor):
512 class FunctionDescriptor(Descriptor):
513 """
513 """
514 A ``FunctionDescriptor`` turns a function into a descriptor. The function
514 A ``FunctionDescriptor`` turns a function into a descriptor. The function
515 will be called with the object to get the type and value of the attribute.
515 will be called with the object to get the type and value of the attribute.
516 """
516 """
517 __slots__ = ("_function", "_name", "_doc")
517 __slots__ = ("_function", "_name", "_doc")
518
518
519 def __init__(self, function, name=None, doc=None):
519 def __init__(self, function, name=None, doc=None):
520 self._function = function
520 self._function = function
521 self._name = name
521 self._name = name
522 self._doc = doc
522 self._doc = doc
523
523
524 def key(self):
524 def key(self):
525 return self._function
525 return self._function
526
526
527 def name(self):
527 def name(self):
528 if self._name is not None:
528 if self._name is not None:
529 return self._name
529 return self._name
530 return getattr(self._function, "__xname__", self._function.__name__)
530 return getattr(self._function, "__xname__", self._function.__name__)
531
531
532 def doc(self, obj):
532 def doc(self, obj):
533 if self._doc is None:
533 if self._doc is None:
534 return self._function.__doc__
534 return self._function.__doc__
535 return self._doc
535 return self._doc
536
536
537 def attrtype(self, obj):
537 def attrtype(self, obj):
538 return "function"
538 return "function"
539
539
540 def valuetype(self, obj):
540 def valuetype(self, obj):
541 return type(self._function(obj))
541 return type(self._function(obj))
542
542
543 def value(self, obj):
543 def value(self, obj):
544 return self._function(obj)
544 return self._function(obj)
545
545
546 def __repr__(self):
546 def __repr__(self):
547 if self._doc is None:
547 if self._doc is None:
548 return "Function(%r)" % self._name
548 return "Function(%r)" % self._name
549 else:
549 else:
550 return "Function(%r, %r)" % (self._name, self._doc)
550 return "Function(%r, %r)" % (self._name, self._doc)
551
551
552
552
553 class Table(object):
553 class Table(object):
554 """
554 """
555 A ``Table`` is an object that produces items (just like a normal Python
555 A ``Table`` is an object that produces items (just like a normal Python
556 iterator/generator does) and can be used as the first object in a pipeline
556 iterator/generator does) and can be used as the first object in a pipeline
557 expression. The displayhook will open the default browser for such an object
557 expression. The displayhook will open the default browser for such an object
558 (instead of simply printing the ``repr()`` result).
558 (instead of simply printing the ``repr()`` result).
559 """
559 """
560
560
561 # We want to support ``foo`` and ``foo()`` in pipeline expression:
561 # We want to support ``foo`` and ``foo()`` in pipeline expression:
562 # So we implement the required operators (``|`` and ``+``) in the metaclass,
562 # So we implement the required operators (``|`` and ``+``) in the metaclass,
563 # instantiate the class and forward the operator to the instance
563 # instantiate the class and forward the operator to the instance
564 class __metaclass__(type):
564 class __metaclass__(type):
565 def __iter__(self):
565 def __iter__(self):
566 return iter(self())
566 return iter(self())
567
567
568 def __or__(self, other):
568 def __or__(self, other):
569 return self() | other
569 return self() | other
570
570
571 def __add__(self, other):
571 def __add__(self, other):
572 return self() + other
572 return self() + other
573
573
574 def __radd__(self, other):
574 def __radd__(self, other):
575 return other + self()
575 return other + self()
576
576
577 def __getitem__(self, index):
577 def __getitem__(self, index):
578 return self()[index]
578 return self()[index]
579
579
580 def __getitem__(self, index):
580 def __getitem__(self, index):
581 return item(self, index)
581 return item(self, index)
582
582
583 def __contains__(self, item):
583 def __contains__(self, item):
584 for haveitem in self:
584 for haveitem in self:
585 if item == haveitem:
585 if item == haveitem:
586 return True
586 return True
587 return False
587 return False
588
588
589 def __or__(self, other):
589 def __or__(self, other):
590 # autoinstantiate right hand side
590 # autoinstantiate right hand side
591 if isinstance(other, type) and issubclass(other, (Table, Display)):
591 if isinstance(other, type) and issubclass(other, (Table, Display)):
592 other = other()
592 other = other()
593 # treat simple strings and functions as ``ieval`` instances
593 # treat simple strings and functions as ``ieval`` instances
594 elif not isinstance(other, Display) and not isinstance(other, Table):
594 elif not isinstance(other, Display) and not isinstance(other, Table):
595 other = ieval(other)
595 other = ieval(other)
596 # forward operations to the right hand side
596 # forward operations to the right hand side
597 return other.__ror__(self)
597 return other.__ror__(self)
598
598
599 def __add__(self, other):
599 def __add__(self, other):
600 # autoinstantiate right hand side
600 # autoinstantiate right hand side
601 if isinstance(other, type) and issubclass(other, Table):
601 if isinstance(other, type) and issubclass(other, Table):
602 other = other()
602 other = other()
603 return ichain(self, other)
603 return ichain(self, other)
604
604
605 def __radd__(self, other):
605 def __radd__(self, other):
606 # autoinstantiate left hand side
606 # autoinstantiate left hand side
607 if isinstance(other, type) and issubclass(other, Table):
607 if isinstance(other, type) and issubclass(other, Table):
608 other = other()
608 other = other()
609 return ichain(other, self)
609 return ichain(other, self)
610
610
611
611
612 class Pipe(Table):
612 class Pipe(Table):
613 """
613 """
614 A ``Pipe`` is an object that can be used in a pipeline expression. It
614 A ``Pipe`` is an object that can be used in a pipeline expression. It
615 processes the objects it gets from its input ``Table``/``Pipe``. Note that
615 processes the objects it gets from its input ``Table``/``Pipe``. Note that
616 a ``Pipe`` object can't be used as the first object in a pipeline
616 a ``Pipe`` object can't be used as the first object in a pipeline
617 expression, as it doesn't produces items itself.
617 expression, as it doesn't produces items itself.
618 """
618 """
619 class __metaclass__(Table.__metaclass__):
619 class __metaclass__(Table.__metaclass__):
620 def __ror__(self, input):
620 def __ror__(self, input):
621 return input | self()
621 return input | self()
622
622
623 def __ror__(self, input):
623 def __ror__(self, input):
624 # autoinstantiate left hand side
624 # autoinstantiate left hand side
625 if isinstance(input, type) and issubclass(input, Table):
625 if isinstance(input, type) and issubclass(input, Table):
626 input = input()
626 input = input()
627 self.input = input
627 self.input = input
628 return self
628 return self
629
629
630
630
631 def xrepr(item, mode="default"):
631 def xrepr(item, mode="default"):
632 """
632 """
633 Generic function that adds color output and different display modes to ``repr``.
633 Generic function that adds color output and different display modes to ``repr``.
634
634
635 The result of an ``xrepr`` call is iterable and consists of ``(style, string)``
635 The result of an ``xrepr`` call is iterable and consists of ``(style, string)``
636 tuples. The ``style`` in this tuple must be a ``Style`` object from the
636 tuples. The ``style`` in this tuple must be a ``Style`` object from the
637 ``astring`` module. To reconfigure the output the first yielded tuple can be
637 ``astring`` module. To reconfigure the output the first yielded tuple can be
638 a ``(aligment, full)`` tuple instead of a ``(style, string)`` tuple.
638 a ``(aligment, full)`` tuple instead of a ``(style, string)`` tuple.
639 ``alignment`` can be -1 for left aligned, 0 for centered and 1 for right
639 ``alignment`` can be -1 for left aligned, 0 for centered and 1 for right
640 aligned (the default is left alignment). ``full`` is a boolean that specifies
640 aligned (the default is left alignment). ``full`` is a boolean that specifies
641 whether the complete output must be displayed or the ``Display`` object is
641 whether the complete output must be displayed or the ``Display`` object is
642 allowed to stop output after enough text has been produced (e.g. a syntax
642 allowed to stop output after enough text has been produced (e.g. a syntax
643 highlighted text line would use ``True``, but for a large data structure
643 highlighted text line would use ``True``, but for a large data structure
644 (i.e. a nested list, tuple or dictionary) ``False`` would be used).
644 (i.e. a nested list, tuple or dictionary) ``False`` would be used).
645 The default is full output.
645 The default is full output.
646
646
647 There are four different possible values for ``mode`` depending on where
647 There are four different possible values for ``mode`` depending on where
648 the ``Display`` object will display ``item``:
648 the ``Display`` object will display ``item``:
649
649
650 ``"header"``
650 ``"header"``
651 ``item`` will be displayed in a header line (this is used by ``ibrowse``).
651 ``item`` will be displayed in a header line (this is used by ``ibrowse``).
652
652
653 ``"footer"``
653 ``"footer"``
654 ``item`` will be displayed in a footer line (this is used by ``ibrowse``).
654 ``item`` will be displayed in a footer line (this is used by ``ibrowse``).
655
655
656 ``"cell"``
656 ``"cell"``
657 ``item`` will be displayed in a table cell/list.
657 ``item`` will be displayed in a table cell/list.
658
658
659 ``"default"``
659 ``"default"``
660 default mode. If an ``xrepr`` implementation recursively outputs objects,
660 default mode. If an ``xrepr`` implementation recursively outputs objects,
661 ``"default"`` must be passed in the recursive calls to ``xrepr``.
661 ``"default"`` must be passed in the recursive calls to ``xrepr``.
662
662
663 If no implementation is registered for ``item``, ``xrepr`` will try the
663 If no implementation is registered for ``item``, ``xrepr`` will try the
664 ``__xrepr__`` method on ``item``. If ``item`` doesn't have an ``__xrepr__``
664 ``__xrepr__`` method on ``item``. If ``item`` doesn't have an ``__xrepr__``
665 method it falls back to ``repr``/``__repr__`` for all modes.
665 method it falls back to ``repr``/``__repr__`` for all modes.
666 """
666 """
667 try:
667 try:
668 func = item.__xrepr__
668 func = item.__xrepr__
669 except AttributeError:
669 except AttributeError:
670 yield (astyle.style_default, repr(item))
670 yield (astyle.style_default, repr(item))
671 else:
671 else:
672 try:
672 try:
673 for x in func(mode):
673 for x in func(mode):
674 yield x
674 yield x
675 except (KeyboardInterrupt, SystemExit, GeneratorExit):
675 except (KeyboardInterrupt, SystemExit, GeneratorExit):
676 raise
676 raise
677 except Exception:
677 except Exception:
678 yield (astyle.style_default, repr(item))
678 yield (astyle.style_default, repr(item))
679 xrepr = simplegeneric.generic(xrepr)
679 xrepr = simplegeneric.generic(xrepr)
680
680
681
681
682 def xrepr_none(self, mode="default"):
682 def xrepr_none(self, mode="default"):
683 yield (astyle.style_type_none, repr(self))
683 yield (astyle.style_type_none, repr(self))
684 xrepr.when_object(None)(xrepr_none)
684 xrepr.when_object(None)(xrepr_none)
685
685
686
686
687 def xrepr_noitem(self, mode="default"):
687 def xrepr_noitem(self, mode="default"):
688 yield (2, True)
688 yield (2, True)
689 yield (astyle.style_nodata, "<?>")
689 yield (astyle.style_nodata, "<?>")
690 xrepr.when_object(noitem)(xrepr_noitem)
690 xrepr.when_object(noitem)(xrepr_noitem)
691
691
692
692
693 def xrepr_bool(self, mode="default"):
693 def xrepr_bool(self, mode="default"):
694 yield (astyle.style_type_bool, repr(self))
694 yield (astyle.style_type_bool, repr(self))
695 xrepr.when_type(bool)(xrepr_bool)
695 xrepr.when_type(bool)(xrepr_bool)
696
696
697
697
698 def xrepr_str(self, mode="default"):
698 def xrepr_str(self, mode="default"):
699 if mode == "cell":
699 if mode == "cell":
700 yield (astyle.style_default, repr(self.expandtabs(tab))[1:-1])
700 yield (astyle.style_default, repr(self.expandtabs(tab))[1:-1])
701 else:
701 else:
702 yield (astyle.style_default, repr(self))
702 yield (astyle.style_default, repr(self))
703 xrepr.when_type(str)(xrepr_str)
703 xrepr.when_type(str)(xrepr_str)
704
704
705
705
706 def xrepr_unicode(self, mode="default"):
706 def xrepr_unicode(self, mode="default"):
707 if mode == "cell":
707 if mode == "cell":
708 yield (astyle.style_default, repr(self.expandtabs(tab))[2:-1])
708 yield (astyle.style_default, repr(self.expandtabs(tab))[2:-1])
709 else:
709 else:
710 yield (astyle.style_default, repr(self))
710 yield (astyle.style_default, repr(self))
711 xrepr.when_type(unicode)(xrepr_unicode)
711 xrepr.when_type(unicode)(xrepr_unicode)
712
712
713
713
714 def xrepr_number(self, mode="default"):
714 def xrepr_number(self, mode="default"):
715 yield (1, True)
715 yield (1, True)
716 yield (astyle.style_type_number, repr(self))
716 yield (astyle.style_type_number, repr(self))
717 xrepr.when_type(int)(xrepr_number)
717 xrepr.when_type(int)(xrepr_number)
718 xrepr.when_type(long)(xrepr_number)
718 xrepr.when_type(long)(xrepr_number)
719 xrepr.when_type(float)(xrepr_number)
719 xrepr.when_type(float)(xrepr_number)
720
720
721
721
722 def xrepr_complex(self, mode="default"):
722 def xrepr_complex(self, mode="default"):
723 yield (astyle.style_type_number, repr(self))
723 yield (astyle.style_type_number, repr(self))
724 xrepr.when_type(complex)(xrepr_number)
724 xrepr.when_type(complex)(xrepr_number)
725
725
726
726
727 def xrepr_datetime(self, mode="default"):
727 def xrepr_datetime(self, mode="default"):
728 if mode == "cell":
728 if mode == "cell":
729 # Don't use strftime() here, as this requires year >= 1900
729 # Don't use strftime() here, as this requires year >= 1900
730 yield (astyle.style_type_datetime,
730 yield (astyle.style_type_datetime,
731 "%04d-%02d-%02d %02d:%02d:%02d.%06d" % \
731 "%04d-%02d-%02d %02d:%02d:%02d.%06d" % \
732 (self.year, self.month, self.day,
732 (self.year, self.month, self.day,
733 self.hour, self.minute, self.second,
733 self.hour, self.minute, self.second,
734 self.microsecond),
734 self.microsecond),
735 )
735 )
736 else:
736 else:
737 yield (astyle.style_type_datetime, repr(self))
737 yield (astyle.style_type_datetime, repr(self))
738 xrepr.when_type(datetime.datetime)(xrepr_datetime)
738 xrepr.when_type(datetime.datetime)(xrepr_datetime)
739
739
740
740
741 def xrepr_date(self, mode="default"):
741 def xrepr_date(self, mode="default"):
742 if mode == "cell":
742 if mode == "cell":
743 yield (astyle.style_type_datetime,
743 yield (astyle.style_type_datetime,
744 "%04d-%02d-%02d" % (self.year, self.month, self.day))
744 "%04d-%02d-%02d" % (self.year, self.month, self.day))
745 else:
745 else:
746 yield (astyle.style_type_datetime, repr(self))
746 yield (astyle.style_type_datetime, repr(self))
747 xrepr.when_type(datetime.date)(xrepr_date)
747 xrepr.when_type(datetime.date)(xrepr_date)
748
748
749
749
750 def xrepr_time(self, mode="default"):
750 def xrepr_time(self, mode="default"):
751 if mode == "cell":
751 if mode == "cell":
752 yield (astyle.style_type_datetime,
752 yield (astyle.style_type_datetime,
753 "%02d:%02d:%02d.%06d" % \
753 "%02d:%02d:%02d.%06d" % \
754 (self.hour, self.minute, self.second, self.microsecond))
754 (self.hour, self.minute, self.second, self.microsecond))
755 else:
755 else:
756 yield (astyle.style_type_datetime, repr(self))
756 yield (astyle.style_type_datetime, repr(self))
757 xrepr.when_type(datetime.time)(xrepr_time)
757 xrepr.when_type(datetime.time)(xrepr_time)
758
758
759
759
760 def xrepr_timedelta(self, mode="default"):
760 def xrepr_timedelta(self, mode="default"):
761 yield (astyle.style_type_datetime, repr(self))
761 yield (astyle.style_type_datetime, repr(self))
762 xrepr.when_type(datetime.timedelta)(xrepr_timedelta)
762 xrepr.when_type(datetime.timedelta)(xrepr_timedelta)
763
763
764
764
765 def xrepr_type(self, mode="default"):
765 def xrepr_type(self, mode="default"):
766 if self.__module__ == "__builtin__":
766 if self.__module__ == "__builtin__":
767 yield (astyle.style_type_type, self.__name__)
767 yield (astyle.style_type_type, self.__name__)
768 else:
768 else:
769 yield (astyle.style_type_type, "%s.%s" % (self.__module__, self.__name__))
769 yield (astyle.style_type_type, "%s.%s" % (self.__module__, self.__name__))
770 xrepr.when_type(type)(xrepr_type)
770 xrepr.when_type(type)(xrepr_type)
771
771
772
772
773 def xrepr_exception(self, mode="default"):
773 def xrepr_exception(self, mode="default"):
774 if self.__class__.__module__ == "exceptions":
774 if self.__class__.__module__ == "exceptions":
775 classname = self.__class__.__name__
775 classname = self.__class__.__name__
776 else:
776 else:
777 classname = "%s.%s" % \
777 classname = "%s.%s" % \
778 (self.__class__.__module__, self.__class__.__name__)
778 (self.__class__.__module__, self.__class__.__name__)
779 if mode == "header" or mode == "footer":
779 if mode == "header" or mode == "footer":
780 yield (astyle.style_error, "%s: %s" % (classname, self))
780 yield (astyle.style_error, "%s: %s" % (classname, self))
781 else:
781 else:
782 yield (astyle.style_error, classname)
782 yield (astyle.style_error, classname)
783 xrepr.when_type(Exception)(xrepr_exception)
783 xrepr.when_type(Exception)(xrepr_exception)
784
784
785
785
786 def xrepr_listtuple(self, mode="default"):
786 def xrepr_listtuple(self, mode="default"):
787 if mode == "header" or mode == "footer":
787 if mode == "header" or mode == "footer":
788 if self.__class__.__module__ == "__builtin__":
788 if self.__class__.__module__ == "__builtin__":
789 classname = self.__class__.__name__
789 classname = self.__class__.__name__
790 else:
790 else:
791 classname = "%s.%s" % \
791 classname = "%s.%s" % \
792 (self.__class__.__module__,self.__class__.__name__)
792 (self.__class__.__module__,self.__class__.__name__)
793 yield (astyle.style_default,
793 yield (astyle.style_default,
794 "<%s object with %d items at 0x%x>" % \
794 "<%s object with %d items at 0x%x>" % \
795 (classname, len(self), id(self)))
795 (classname, len(self), id(self)))
796 else:
796 else:
797 yield (-1, False)
797 yield (-1, False)
798 if isinstance(self, list):
798 if isinstance(self, list):
799 yield (astyle.style_default, "[")
799 yield (astyle.style_default, "[")
800 end = "]"
800 end = "]"
801 else:
801 else:
802 yield (astyle.style_default, "(")
802 yield (astyle.style_default, "(")
803 end = ")"
803 end = ")"
804 for (i, subself) in enumerate(self):
804 for (i, subself) in enumerate(self):
805 if i:
805 if i:
806 yield (astyle.style_default, ", ")
806 yield (astyle.style_default, ", ")
807 for part in xrepr(subself, "default"):
807 for part in xrepr(subself, "default"):
808 yield part
808 yield part
809 yield (astyle.style_default, end)
809 yield (astyle.style_default, end)
810 xrepr.when_type(list)(xrepr_listtuple)
810 xrepr.when_type(list)(xrepr_listtuple)
811 xrepr.when_type(tuple)(xrepr_listtuple)
811 xrepr.when_type(tuple)(xrepr_listtuple)
812
812
813
813
814 def xrepr_dict(self, mode="default"):
814 def xrepr_dict(self, mode="default"):
815 if mode == "header" or mode == "footer":
815 if mode == "header" or mode == "footer":
816 if self.__class__.__module__ == "__builtin__":
816 if self.__class__.__module__ == "__builtin__":
817 classname = self.__class__.__name__
817 classname = self.__class__.__name__
818 else:
818 else:
819 classname = "%s.%s" % \
819 classname = "%s.%s" % \
820 (self.__class__.__module__,self.__class__.__name__)
820 (self.__class__.__module__,self.__class__.__name__)
821 yield (astyle.style_default,
821 yield (astyle.style_default,
822 "<%s object with %d items at 0x%x>" % \
822 "<%s object with %d items at 0x%x>" % \
823 (classname, len(self), id(self)))
823 (classname, len(self), id(self)))
824 else:
824 else:
825 yield (-1, False)
825 yield (-1, False)
826 if isinstance(self, dict):
826 if isinstance(self, dict):
827 yield (astyle.style_default, "{")
827 yield (astyle.style_default, "{")
828 end = "}"
828 end = "}"
829 else:
829 else:
830 yield (astyle.style_default, "dictproxy((")
830 yield (astyle.style_default, "dictproxy((")
831 end = "})"
831 end = "})"
832 for (i, (key, value)) in enumerate(self.iteritems()):
832 for (i, (key, value)) in enumerate(self.iteritems()):
833 if i:
833 if i:
834 yield (astyle.style_default, ", ")
834 yield (astyle.style_default, ", ")
835 for part in xrepr(key, "default"):
835 for part in xrepr(key, "default"):
836 yield part
836 yield part
837 yield (astyle.style_default, ": ")
837 yield (astyle.style_default, ": ")
838 for part in xrepr(value, "default"):
838 for part in xrepr(value, "default"):
839 yield part
839 yield part
840 yield (astyle.style_default, end)
840 yield (astyle.style_default, end)
841 xrepr.when_type(dict)(xrepr_dict)
841 xrepr.when_type(dict)(xrepr_dict)
842 xrepr.when_type(types.DictProxyType)(xrepr_dict)
842 xrepr.when_type(types.DictProxyType)(xrepr_dict)
843
843
844
844
845 def upgradexattr(attr):
845 def upgradexattr(attr):
846 """
846 """
847 Convert an attribute descriptor string to a real descriptor object.
847 Convert an attribute descriptor string to a real descriptor object.
848
848
849 If attr already is a descriptor object return it unmodified. A
849 If attr already is a descriptor object return it unmodified. A
850 ``SelfDescriptor`` will be returned if ``attr`` is ``None``. ``"foo"``
850 ``SelfDescriptor`` will be returned if ``attr`` is ``None``. ``"foo"``
851 returns an ``AttributeDescriptor`` for the attribute named ``"foo"``.
851 returns an ``AttributeDescriptor`` for the attribute named ``"foo"``.
852 ``"foo()"`` returns a ``MethodDescriptor`` for the method named ``"foo"``.
852 ``"foo()"`` returns a ``MethodDescriptor`` for the method named ``"foo"``.
853 ``"-foo"`` will return an ``IterAttributeDescriptor`` for the attribute
853 ``"-foo"`` will return an ``IterAttributeDescriptor`` for the attribute
854 named ``"foo"`` and ``"-foo()"`` will return an ``IterMethodDescriptor``
854 named ``"foo"`` and ``"-foo()"`` will return an ``IterMethodDescriptor``
855 for the method named ``"foo"``. Furthermore integers will return the appropriate
855 for the method named ``"foo"``. Furthermore integers will return the appropriate
856 ``IndexDescriptor`` and callables will return a ``FunctionDescriptor``.
856 ``IndexDescriptor`` and callables will return a ``FunctionDescriptor``.
857 """
857 """
858 if attr is None:
858 if attr is None:
859 return selfdescriptor
859 return selfdescriptor
860 elif isinstance(attr, Descriptor):
860 elif isinstance(attr, Descriptor):
861 return attr
861 return attr
862 elif isinstance(attr, basestring):
862 elif isinstance(attr, basestring):
863 if attr.endswith("()"):
863 if attr.endswith("()"):
864 if attr.startswith("-"):
864 if attr.startswith("-"):
865 return IterMethodDescriptor(attr[1:-2])
865 return IterMethodDescriptor(attr[1:-2])
866 else:
866 else:
867 return MethodDescriptor(attr[:-2])
867 return MethodDescriptor(attr[:-2])
868 else:
868 else:
869 if attr.startswith("-"):
869 if attr.startswith("-"):
870 return IterAttributeDescriptor(attr[1:])
870 return IterAttributeDescriptor(attr[1:])
871 else:
871 else:
872 return AttributeDescriptor(attr)
872 return AttributeDescriptor(attr)
873 elif isinstance(attr, (int, long)):
873 elif isinstance(attr, (int, long)):
874 return IndexDescriptor(attr)
874 return IndexDescriptor(attr)
875 elif callable(attr):
875 elif callable(attr):
876 return FunctionDescriptor(attr)
876 return FunctionDescriptor(attr)
877 else:
877 else:
878 raise TypeError("can't handle descriptor %r" % attr)
878 raise TypeError("can't handle descriptor %r" % attr)
879
879
880
880
881 def xattrs(item, mode="default"):
881 def xattrs(item, mode="default"):
882 """
882 """
883 Generic function that returns an iterable of attribute descriptors
883 Generic function that returns an iterable of attribute descriptors
884 to be used for displaying the attributes ob the object ``item`` in display
884 to be used for displaying the attributes ob the object ``item`` in display
885 mode ``mode``.
885 mode ``mode``.
886
886
887 There are two possible modes:
887 There are two possible modes:
888
888
889 ``"detail"``
889 ``"detail"``
890 The ``Display`` object wants to display a detailed list of the object
890 The ``Display`` object wants to display a detailed list of the object
891 attributes.
891 attributes.
892
892
893 ``"default"``
893 ``"default"``
894 The ``Display`` object wants to display the object in a list view.
894 The ``Display`` object wants to display the object in a list view.
895
895
896 If no implementation is registered for the object ``item`` ``xattrs`` falls
896 If no implementation is registered for the object ``item`` ``xattrs`` falls
897 back to trying the ``__xattrs__`` method of the object. If this doesn't
897 back to trying the ``__xattrs__`` method of the object. If this doesn't
898 exist either, ``dir(item)`` is used for ``"detail"`` mode and ``(None,)``
898 exist either, ``dir(item)`` is used for ``"detail"`` mode and ``(None,)``
899 for ``"default"`` mode.
899 for ``"default"`` mode.
900
900
901 The implementation must yield attribute descriptors (see the class
901 The implementation must yield attribute descriptors (see the class
902 ``Descriptor`` for more info). The ``__xattrs__`` method may also return
902 ``Descriptor`` for more info). The ``__xattrs__`` method may also return
903 attribute descriptor strings (and ``None``) which will be converted to real
903 attribute descriptor strings (and ``None``) which will be converted to real
904 descriptors by ``upgradexattr()``.
904 descriptors by ``upgradexattr()``.
905 """
905 """
906 try:
906 try:
907 func = item.__xattrs__
907 func = item.__xattrs__
908 except AttributeError:
908 except AttributeError:
909 if mode == "detail":
909 if mode == "detail":
910 for attrname in dir(item):
910 for attrname in dir(item):
911 yield AttributeDescriptor(attrname)
911 yield AttributeDescriptor(attrname)
912 else:
912 else:
913 yield selfdescriptor
913 yield selfdescriptor
914 else:
914 else:
915 for attr in func(mode):
915 for attr in func(mode):
916 yield upgradexattr(attr)
916 yield upgradexattr(attr)
917 xattrs = simplegeneric.generic(xattrs)
917 xattrs = simplegeneric.generic(xattrs)
918
918
919
919
920 def xattrs_complex(self, mode="default"):
920 def xattrs_complex(self, mode="default"):
921 if mode == "detail":
921 if mode == "detail":
922 return (AttributeDescriptor("real"), AttributeDescriptor("imag"))
922 return (AttributeDescriptor("real"), AttributeDescriptor("imag"))
923 return (selfdescriptor,)
923 return (selfdescriptor,)
924 xattrs.when_type(complex)(xattrs_complex)
924 xattrs.when_type(complex)(xattrs_complex)
925
925
926
926
927 def _isdict(item):
927 def _isdict(item):
928 try:
928 try:
929 itermeth = item.__class__.__iter__
929 itermeth = item.__class__.__iter__
930 except (AttributeError, TypeError):
930 except (AttributeError, TypeError):
931 return False
931 return False
932 return itermeth is dict.__iter__ or itermeth is types.DictProxyType.__iter__
932 return itermeth is dict.__iter__ or itermeth is types.DictProxyType.__iter__
933
933
934
934
935 def _isstr(item):
935 def _isstr(item):
936 if not isinstance(item, basestring):
936 if not isinstance(item, basestring):
937 return False
937 return False
938 try:
938 try:
939 itermeth = item.__class__.__iter__
939 itermeth = item.__class__.__iter__
940 except AttributeError:
940 except AttributeError:
941 return True
941 return True
942 return False # ``__iter__`` has been redefined
942 return False # ``__iter__`` has been redefined
943
943
944
944
945 def xiter(item):
945 def xiter(item):
946 """
946 """
947 Generic function that implements iteration for pipeline expression. If no
947 Generic function that implements iteration for pipeline expression. If no
948 implementation is registered for ``item`` ``xiter`` falls back to ``iter``.
948 implementation is registered for ``item`` ``xiter`` falls back to ``iter``.
949 """
949 """
950 try:
950 try:
951 func = item.__xiter__
951 func = item.__xiter__
952 except AttributeError:
952 except AttributeError:
953 if _isdict(item):
953 if _isdict(item):
954 def items(item):
954 def items(item):
955 fields = ("key", "value")
955 fields = ("key", "value")
956 for (key, value) in item.iteritems():
956 for (key, value) in item.iteritems():
957 yield Fields(fields, key=key, value=value)
957 yield Fields(fields, key=key, value=value)
958 return items(item)
958 return items(item)
959 elif isinstance(item, new.module):
959 elif isinstance(item, new.module):
960 def items(item):
960 def items(item):
961 fields = ("key", "value")
961 fields = ("key", "value")
962 for key in sorted(item.__dict__):
962 for key in sorted(item.__dict__):
963 yield Fields(fields, key=key, value=getattr(item, key))
963 yield Fields(fields, key=key, value=getattr(item, key))
964 return items(item)
964 return items(item)
965 elif _isstr(item):
965 elif _isstr(item):
966 if not item:
966 if not item:
967 raise ValueError("can't enter empty string")
967 raise ValueError("can't enter empty string")
968 lines = item.splitlines()
968 lines = item.splitlines()
969 if len(lines) == 1:
969 if len(lines) == 1:
970 def iterone(item):
970 def iterone(item):
971 yield item
971 yield item
972 return iterone(item)
972 return iterone(item)
973 else:
973 else:
974 return iter(lines)
974 return iter(lines)
975 return iter(item)
975 return iter(item)
976 else:
976 else:
977 return iter(func()) # iter() just to be safe
977 return iter(func()) # iter() just to be safe
978 xiter = simplegeneric.generic(xiter)
978 xiter = simplegeneric.generic(xiter)
979
979
980
980
981 class ichain(Pipe):
981 class ichain(Pipe):
982 """
982 """
983 Chains multiple ``Table``s into one.
983 Chains multiple ``Table``s into one.
984 """
984 """
985
985
986 def __init__(self, *iters):
986 def __init__(self, *iters):
987 self.iters = iters
987 self.iters = iters
988
988
989 def __iter__(self):
989 def __iter__(self):
990 return itertools.chain(*self.iters)
990 return itertools.chain(*self.iters)
991
991
992 def __xrepr__(self, mode="default"):
992 def __xrepr__(self, mode="default"):
993 if mode == "header" or mode == "footer":
993 if mode == "header" or mode == "footer":
994 for (i, item) in enumerate(self.iters):
994 for (i, item) in enumerate(self.iters):
995 if i:
995 if i:
996 yield (astyle.style_default, "+")
996 yield (astyle.style_default, "+")
997 if isinstance(item, Pipe):
997 if isinstance(item, Pipe):
998 yield (astyle.style_default, "(")
998 yield (astyle.style_default, "(")
999 for part in xrepr(item, mode):
999 for part in xrepr(item, mode):
1000 yield part
1000 yield part
1001 if isinstance(item, Pipe):
1001 if isinstance(item, Pipe):
1002 yield (astyle.style_default, ")")
1002 yield (astyle.style_default, ")")
1003 else:
1003 else:
1004 yield (astyle.style_default, repr(self))
1004 yield (astyle.style_default, repr(self))
1005
1005
1006 def __repr__(self):
1006 def __repr__(self):
1007 args = ", ".join([repr(it) for it in self.iters])
1007 args = ", ".join([repr(it) for it in self.iters])
1008 return "%s.%s(%s)" % \
1008 return "%s.%s(%s)" % \
1009 (self.__class__.__module__, self.__class__.__name__, args)
1009 (self.__class__.__module__, self.__class__.__name__, args)
1010
1010
1011
1011
1012 class ifile(path.path):
1012 class ifile(path.path):
1013 """
1013 """
1014 file (or directory) object.
1014 file (or directory) object.
1015 """
1015 """
1016
1016
1017 def getmode(self):
1017 def getmode(self):
1018 return self.stat().st_mode
1018 return self.stat().st_mode
1019 mode = property(getmode, None, None, "Access mode")
1019 mode = property(getmode, None, None, "Access mode")
1020
1020
1021 def gettype(self):
1021 def gettype(self):
1022 data = [
1022 data = [
1023 (stat.S_ISREG, "file"),
1023 (stat.S_ISREG, "file"),
1024 (stat.S_ISDIR, "dir"),
1024 (stat.S_ISDIR, "dir"),
1025 (stat.S_ISCHR, "chardev"),
1025 (stat.S_ISCHR, "chardev"),
1026 (stat.S_ISBLK, "blockdev"),
1026 (stat.S_ISBLK, "blockdev"),
1027 (stat.S_ISFIFO, "fifo"),
1027 (stat.S_ISFIFO, "fifo"),
1028 (stat.S_ISLNK, "symlink"),
1028 (stat.S_ISLNK, "symlink"),
1029 (stat.S_ISSOCK,"socket"),
1029 (stat.S_ISSOCK,"socket"),
1030 ]
1030 ]
1031 lstat = self.lstat()
1031 lstat = self.lstat()
1032 if lstat is not None:
1032 if lstat is not None:
1033 types = set([text for (func, text) in data if func(lstat.st_mode)])
1033 types = set([text for (func, text) in data if func(lstat.st_mode)])
1034 else:
1034 else:
1035 types = set()
1035 types = set()
1036 m = self.mode
1036 m = self.mode
1037 types.update([text for (func, text) in data if func(m)])
1037 types.update([text for (func, text) in data if func(m)])
1038 return ", ".join(types)
1038 return ", ".join(types)
1039 type = property(gettype, None, None, "file type (file, directory, link, etc.)")
1039 type = property(gettype, None, None, "file type (file, directory, link, etc.)")
1040
1040
1041 def getmodestr(self):
1041 def getmodestr(self):
1042 m = self.mode
1042 m = self.mode
1043 data = [
1043 data = [
1044 (stat.S_IRUSR, "-r"),
1044 (stat.S_IRUSR, "-r"),
1045 (stat.S_IWUSR, "-w"),
1045 (stat.S_IWUSR, "-w"),
1046 (stat.S_IXUSR, "-x"),
1046 (stat.S_IXUSR, "-x"),
1047 (stat.S_IRGRP, "-r"),
1047 (stat.S_IRGRP, "-r"),
1048 (stat.S_IWGRP, "-w"),
1048 (stat.S_IWGRP, "-w"),
1049 (stat.S_IXGRP, "-x"),
1049 (stat.S_IXGRP, "-x"),
1050 (stat.S_IROTH, "-r"),
1050 (stat.S_IROTH, "-r"),
1051 (stat.S_IWOTH, "-w"),
1051 (stat.S_IWOTH, "-w"),
1052 (stat.S_IXOTH, "-x"),
1052 (stat.S_IXOTH, "-x"),
1053 ]
1053 ]
1054 return "".join([text[bool(m&bit)] for (bit, text) in data])
1054 return "".join([text[bool(m&bit)] for (bit, text) in data])
1055
1055
1056 modestr = property(getmodestr, None, None, "Access mode as string")
1056 modestr = property(getmodestr, None, None, "Access mode as string")
1057
1057
1058 def getblocks(self):
1058 def getblocks(self):
1059 return self.stat().st_blocks
1059 return self.stat().st_blocks
1060 blocks = property(getblocks, None, None, "File size in blocks")
1060 blocks = property(getblocks, None, None, "File size in blocks")
1061
1061
1062 def getblksize(self):
1062 def getblksize(self):
1063 return self.stat().st_blksize
1063 return self.stat().st_blksize
1064 blksize = property(getblksize, None, None, "Filesystem block size")
1064 blksize = property(getblksize, None, None, "Filesystem block size")
1065
1065
1066 def getdev(self):
1066 def getdev(self):
1067 return self.stat().st_dev
1067 return self.stat().st_dev
1068 dev = property(getdev)
1068 dev = property(getdev)
1069
1069
1070 def getnlink(self):
1070 def getnlink(self):
1071 return self.stat().st_nlink
1071 return self.stat().st_nlink
1072 nlink = property(getnlink, None, None, "Number of links")
1072 nlink = property(getnlink, None, None, "Number of links")
1073
1073
1074 def getuid(self):
1074 def getuid(self):
1075 return self.stat().st_uid
1075 return self.stat().st_uid
1076 uid = property(getuid, None, None, "User id of file owner")
1076 uid = property(getuid, None, None, "User id of file owner")
1077
1077
1078 def getgid(self):
1078 def getgid(self):
1079 return self.stat().st_gid
1079 return self.stat().st_gid
1080 gid = property(getgid, None, None, "Group id of file owner")
1080 gid = property(getgid, None, None, "Group id of file owner")
1081
1081
1082 def getowner(self):
1082 def getowner(self):
1083 stat = self.stat()
1083 stat = self.stat()
1084 try:
1084 try:
1085 return pwd.getpwuid(stat.st_uid).pw_name
1085 return pwd.getpwuid(stat.st_uid).pw_name
1086 except KeyError:
1086 except KeyError:
1087 return stat.st_uid
1087 return stat.st_uid
1088 owner = property(getowner, None, None, "Owner name (or id)")
1088 owner = property(getowner, None, None, "Owner name (or id)")
1089
1089
1090 def getgroup(self):
1090 def getgroup(self):
1091 stat = self.stat()
1091 stat = self.stat()
1092 try:
1092 try:
1093 return grp.getgrgid(stat.st_gid).gr_name
1093 return grp.getgrgid(stat.st_gid).gr_name
1094 except KeyError:
1094 except KeyError:
1095 return stat.st_gid
1095 return stat.st_gid
1096 group = property(getgroup, None, None, "Group name (or id)")
1096 group = property(getgroup, None, None, "Group name (or id)")
1097
1097
1098 def getadate(self):
1098 def getadate(self):
1099 return datetime.datetime.utcfromtimestamp(self.atime)
1099 return datetime.datetime.utcfromtimestamp(self.atime)
1100 adate = property(getadate, None, None, "Access date")
1100 adate = property(getadate, None, None, "Access date")
1101
1101
1102 def getcdate(self):
1102 def getcdate(self):
1103 return datetime.datetime.utcfromtimestamp(self.ctime)
1103 return datetime.datetime.utcfromtimestamp(self.ctime)
1104 cdate = property(getcdate, None, None, "Creation date")
1104 cdate = property(getcdate, None, None, "Creation date")
1105
1105
1106 def getmdate(self):
1106 def getmdate(self):
1107 return datetime.datetime.utcfromtimestamp(self.mtime)
1107 return datetime.datetime.utcfromtimestamp(self.mtime)
1108 mdate = property(getmdate, None, None, "Modification date")
1108 mdate = property(getmdate, None, None, "Modification date")
1109
1109
1110 def mimetype(self):
1110 def mimetype(self):
1111 """
1111 """
1112 Return MIME type guessed from the extension.
1112 Return MIME type guessed from the extension.
1113 """
1113 """
1114 return mimetypes.guess_type(self.basename())[0]
1114 return mimetypes.guess_type(self.basename())[0]
1115
1115
1116 def encoding(self):
1116 def encoding(self):
1117 """
1117 """
1118 Return guessed compression (like "compress" or "gzip").
1118 Return guessed compression (like "compress" or "gzip").
1119 """
1119 """
1120 return mimetypes.guess_type(self.basename())[1]
1120 return mimetypes.guess_type(self.basename())[1]
1121
1121
1122 def __repr__(self):
1122 def __repr__(self):
1123 return "ifile(%s)" % path._base.__repr__(self)
1123 return "ifile(%s)" % path._base.__repr__(self)
1124
1124
1125 if sys.platform == "win32":
1125 if sys.platform == "win32":
1126 defaultattrs = (None, "type", "size", "modestr", "mdate")
1126 defaultattrs = (None, "type", "size", "modestr", "mdate")
1127 else:
1127 else:
1128 defaultattrs = (None, "type", "size", "modestr", "owner", "group", "mdate")
1128 defaultattrs = (None, "type", "size", "modestr", "owner", "group", "mdate")
1129
1129
1130 def __xattrs__(self, mode="default"):
1130 def __xattrs__(self, mode="default"):
1131 if mode == "detail":
1131 if mode == "detail":
1132 return (
1132 return (
1133 "name",
1133 "name",
1134 "basename()",
1134 "basename()",
1135 "abspath()",
1135 "abspath()",
1136 "realpath()",
1136 "realpath()",
1137 "type",
1137 "type",
1138 "mode",
1138 "mode",
1139 "modestr",
1139 "modestr",
1140 "stat()",
1140 "stat()",
1141 "lstat()",
1141 "lstat()",
1142 "uid",
1142 "uid",
1143 "gid",
1143 "gid",
1144 "owner",
1144 "owner",
1145 "group",
1145 "group",
1146 "dev",
1146 "dev",
1147 "nlink",
1147 "nlink",
1148 "ctime",
1148 "ctime",
1149 "mtime",
1149 "mtime",
1150 "atime",
1150 "atime",
1151 "cdate",
1151 "cdate",
1152 "mdate",
1152 "mdate",
1153 "adate",
1153 "adate",
1154 "size",
1154 "size",
1155 "blocks",
1155 "blocks",
1156 "blksize",
1156 "blksize",
1157 "isdir()",
1157 "isdir()",
1158 "islink()",
1158 "islink()",
1159 "mimetype()",
1159 "mimetype()",
1160 "encoding()",
1160 "encoding()",
1161 "-listdir()",
1161 "-listdir()",
1162 "-dirs()",
1162 "-dirs()",
1163 "-files()",
1163 "-files()",
1164 "-walk()",
1164 "-walk()",
1165 "-walkdirs()",
1165 "-walkdirs()",
1166 "-walkfiles()",
1166 "-walkfiles()",
1167 )
1167 )
1168 else:
1168 else:
1169 return self.defaultattrs
1169 return self.defaultattrs
1170
1170
1171
1171
1172 def xiter_ifile(self):
1172 def xiter_ifile(self):
1173 if self.isdir():
1173 if self.isdir():
1174 yield (self / os.pardir).abspath()
1174 yield (self / os.pardir).abspath()
1175 for child in sorted(self.listdir()):
1175 for child in sorted(self.listdir()):
1176 yield child
1176 yield child
1177 else:
1177 else:
1178 f = self.open("rb")
1178 f = self.open("rb")
1179 for line in f:
1179 for line in f:
1180 yield line
1180 yield line
1181 f.close()
1181 f.close()
1182 xiter.when_type(ifile)(xiter_ifile)
1182 xiter.when_type(ifile)(xiter_ifile)
1183
1183
1184
1184
1185 # We need to implement ``xrepr`` for ``ifile`` as a generic function, because
1185 # We need to implement ``xrepr`` for ``ifile`` as a generic function, because
1186 # otherwise ``xrepr_str`` would kick in.
1186 # otherwise ``xrepr_str`` would kick in.
1187 def xrepr_ifile(self, mode="default"):
1187 def xrepr_ifile(self, mode="default"):
1188 try:
1188 try:
1189 if self.isdir():
1189 if self.isdir():
1190 name = "idir"
1190 name = "idir"
1191 style = astyle.style_dir
1191 style = astyle.style_dir
1192 else:
1192 else:
1193 name = "ifile"
1193 name = "ifile"
1194 style = astyle.style_file
1194 style = astyle.style_file
1195 except IOError:
1195 except IOError:
1196 name = "ifile"
1196 name = "ifile"
1197 style = astyle.style_default
1197 style = astyle.style_default
1198 if mode in ("cell", "header", "footer"):
1198 if mode in ("cell", "header", "footer"):
1199 abspath = repr(path._base(self.normpath()))
1199 abspath = repr(path._base(self.normpath()))
1200 if abspath.startswith("u"):
1200 if abspath.startswith("u"):
1201 abspath = abspath[2:-1]
1201 abspath = abspath[2:-1]
1202 else:
1202 else:
1203 abspath = abspath[1:-1]
1203 abspath = abspath[1:-1]
1204 if mode == "cell":
1204 if mode == "cell":
1205 yield (style, abspath)
1205 yield (style, abspath)
1206 else:
1206 else:
1207 yield (style, "%s(%s)" % (name, abspath))
1207 yield (style, "%s(%s)" % (name, abspath))
1208 else:
1208 else:
1209 yield (style, repr(self))
1209 yield (style, repr(self))
1210 xrepr.when_type(ifile)(xrepr_ifile)
1210 xrepr.when_type(ifile)(xrepr_ifile)
1211
1211
1212
1212
1213 class ils(Table):
1213 class ils(Table):
1214 """
1214 """
1215 List the current (or a specified) directory.
1215 List the current (or a specified) directory.
1216
1216
1217 Examples::
1217 Examples::
1218
1218
1219 >>> ils
1219 >>> ils
1220 <class 'IPython.extensions.ipipe.ils'>
1220 <class 'IPython.extensions.ipipe.ils'>
1221 >>> ils("/usr/local/lib/python2.4")
1221 >>> ils("/usr/local/lib/python2.4")
1222 IPython.extensions.ipipe.ils('/usr/local/lib/python2.4')
1222 IPython.extensions.ipipe.ils('/usr/local/lib/python2.4')
1223 >>> ils("~")
1223 >>> ils("~")
1224 IPython.extensions.ipipe.ils('/home/fperez')
1224 IPython.extensions.ipipe.ils('/home/fperez')
1225 # all-random
1225 # all-random
1226 """
1226 """
1227 def __init__(self, base=os.curdir, dirs=True, files=True):
1227 def __init__(self, base=os.curdir, dirs=True, files=True):
1228 self.base = os.path.expanduser(base)
1228 self.base = os.path.expanduser(base)
1229 self.dirs = dirs
1229 self.dirs = dirs
1230 self.files = files
1230 self.files = files
1231
1231
1232 def __iter__(self):
1232 def __iter__(self):
1233 base = ifile(self.base)
1233 base = ifile(self.base)
1234 yield (base / os.pardir).abspath()
1234 yield (base / os.pardir).abspath()
1235 for child in sorted(base.listdir()):
1235 for child in sorted(base.listdir()):
1236 if self.dirs:
1236 if self.dirs:
1237 if self.files:
1237 if self.files:
1238 yield child
1238 yield child
1239 else:
1239 else:
1240 if child.isdir():
1240 if child.isdir():
1241 yield child
1241 yield child
1242 elif self.files:
1242 elif self.files:
1243 if not child.isdir():
1243 if not child.isdir():
1244 yield child
1244 yield child
1245
1245
1246 def __xrepr__(self, mode="default"):
1246 def __xrepr__(self, mode="default"):
1247 return xrepr(ifile(self.base), mode)
1247 return xrepr(ifile(self.base), mode)
1248
1248
1249 def __repr__(self):
1249 def __repr__(self):
1250 return "%s.%s(%r)" % \
1250 return "%s.%s(%r)" % \
1251 (self.__class__.__module__, self.__class__.__name__, self.base)
1251 (self.__class__.__module__, self.__class__.__name__, self.base)
1252
1252
1253
1253
1254 class iglob(Table):
1254 class iglob(Table):
1255 """
1255 """
1256 List all files and directories matching a specified pattern.
1256 List all files and directories matching a specified pattern.
1257 (See ``glob.glob()`` for more info.).
1257 (See ``glob.glob()`` for more info.).
1258
1258
1259 Examples::
1259 Examples::
1260
1260
1261 >>> iglob("*.py")
1261 >>> iglob("*.py")
1262 IPython.extensions.ipipe.iglob('*.py')
1262 IPython.extensions.ipipe.iglob('*.py')
1263 """
1263 """
1264 def __init__(self, glob):
1264 def __init__(self, glob):
1265 self.glob = glob
1265 self.glob = glob
1266
1266
1267 def __iter__(self):
1267 def __iter__(self):
1268 for name in glob.glob(self.glob):
1268 for name in glob.glob(self.glob):
1269 yield ifile(name)
1269 yield ifile(name)
1270
1270
1271 def __xrepr__(self, mode="default"):
1271 def __xrepr__(self, mode="default"):
1272 if mode == "header" or mode == "footer" or mode == "cell":
1272 if mode == "header" or mode == "footer" or mode == "cell":
1273 yield (astyle.style_default,
1273 yield (astyle.style_default,
1274 "%s(%r)" % (self.__class__.__name__, self.glob))
1274 "%s(%r)" % (self.__class__.__name__, self.glob))
1275 else:
1275 else:
1276 yield (astyle.style_default, repr(self))
1276 yield (astyle.style_default, repr(self))
1277
1277
1278 def __repr__(self):
1278 def __repr__(self):
1279 return "%s.%s(%r)" % \
1279 return "%s.%s(%r)" % \
1280 (self.__class__.__module__, self.__class__.__name__, self.glob)
1280 (self.__class__.__module__, self.__class__.__name__, self.glob)
1281
1281
1282
1282
1283 class iwalk(Table):
1283 class iwalk(Table):
1284 """
1284 """
1285 List all files and directories in a directory and it's subdirectory::
1285 List all files and directories in a directory and it's subdirectory::
1286
1286
1287 >>> iwalk
1287 >>> iwalk
1288 <class 'IPython.extensions.ipipe.iwalk'>
1288 <class 'IPython.extensions.ipipe.iwalk'>
1289 >>> iwalk("/usr/lib")
1289 >>> iwalk("/usr/lib")
1290 IPython.extensions.ipipe.iwalk('/usr/lib')
1290 IPython.extensions.ipipe.iwalk('/usr/lib')
1291 >>> iwalk("~")
1291 >>> iwalk("~")
1292 IPython.extensions.ipipe.iwalk('/home/fperez') # random
1292 IPython.extensions.ipipe.iwalk('/home/fperez') # random
1293
1293
1294 """
1294 """
1295 def __init__(self, base=os.curdir, dirs=True, files=True):
1295 def __init__(self, base=os.curdir, dirs=True, files=True):
1296 self.base = os.path.expanduser(base)
1296 self.base = os.path.expanduser(base)
1297 self.dirs = dirs
1297 self.dirs = dirs
1298 self.files = files
1298 self.files = files
1299
1299
1300 def __iter__(self):
1300 def __iter__(self):
1301 for (dirpath, dirnames, filenames) in os.walk(self.base):
1301 for (dirpath, dirnames, filenames) in os.walk(self.base):
1302 if self.dirs:
1302 if self.dirs:
1303 for name in sorted(dirnames):
1303 for name in sorted(dirnames):
1304 yield ifile(os.path.join(dirpath, name))
1304 yield ifile(os.path.join(dirpath, name))
1305 if self.files:
1305 if self.files:
1306 for name in sorted(filenames):
1306 for name in sorted(filenames):
1307 yield ifile(os.path.join(dirpath, name))
1307 yield ifile(os.path.join(dirpath, name))
1308
1308
1309 def __xrepr__(self, mode="default"):
1309 def __xrepr__(self, mode="default"):
1310 if mode == "header" or mode == "footer" or mode == "cell":
1310 if mode == "header" or mode == "footer" or mode == "cell":
1311 yield (astyle.style_default,
1311 yield (astyle.style_default,
1312 "%s(%r)" % (self.__class__.__name__, self.base))
1312 "%s(%r)" % (self.__class__.__name__, self.base))
1313 else:
1313 else:
1314 yield (astyle.style_default, repr(self))
1314 yield (astyle.style_default, repr(self))
1315
1315
1316 def __repr__(self):
1316 def __repr__(self):
1317 return "%s.%s(%r)" % \
1317 return "%s.%s(%r)" % \
1318 (self.__class__.__module__, self.__class__.__name__, self.base)
1318 (self.__class__.__module__, self.__class__.__name__, self.base)
1319
1319
1320
1320
1321 class ipwdentry(object):
1321 class ipwdentry(object):
1322 """
1322 """
1323 ``ipwdentry`` objects encapsulate entries in the Unix user account and
1323 ``ipwdentry`` objects encapsulate entries in the Unix user account and
1324 password database.
1324 password database.
1325 """
1325 """
1326 def __init__(self, id):
1326 def __init__(self, id):
1327 self._id = id
1327 self._id = id
1328 self._entry = None
1328 self._entry = None
1329
1329
1330 def __eq__(self, other):
1330 def __eq__(self, other):
1331 return self.__class__ is other.__class__ and self._id == other._id
1331 return self.__class__ is other.__class__ and self._id == other._id
1332
1332
1333 def __ne__(self, other):
1333 def __ne__(self, other):
1334 return self.__class__ is not other.__class__ or self._id != other._id
1334 return self.__class__ is not other.__class__ or self._id != other._id
1335
1335
1336 def _getentry(self):
1336 def _getentry(self):
1337 if self._entry is None:
1337 if self._entry is None:
1338 if isinstance(self._id, basestring):
1338 if isinstance(self._id, basestring):
1339 self._entry = pwd.getpwnam(self._id)
1339 self._entry = pwd.getpwnam(self._id)
1340 else:
1340 else:
1341 self._entry = pwd.getpwuid(self._id)
1341 self._entry = pwd.getpwuid(self._id)
1342 return self._entry
1342 return self._entry
1343
1343
1344 def getname(self):
1344 def getname(self):
1345 if isinstance(self._id, basestring):
1345 if isinstance(self._id, basestring):
1346 return self._id
1346 return self._id
1347 else:
1347 else:
1348 return self._getentry().pw_name
1348 return self._getentry().pw_name
1349 name = property(getname, None, None, "User name")
1349 name = property(getname, None, None, "User name")
1350
1350
1351 def getpasswd(self):
1351 def getpasswd(self):
1352 return self._getentry().pw_passwd
1352 return self._getentry().pw_passwd
1353 passwd = property(getpasswd, None, None, "Password")
1353 passwd = property(getpasswd, None, None, "Password")
1354
1354
1355 def getuid(self):
1355 def getuid(self):
1356 if isinstance(self._id, basestring):
1356 if isinstance(self._id, basestring):
1357 return self._getentry().pw_uid
1357 return self._getentry().pw_uid
1358 else:
1358 else:
1359 return self._id
1359 return self._id
1360 uid = property(getuid, None, None, "User id")
1360 uid = property(getuid, None, None, "User id")
1361
1361
1362 def getgid(self):
1362 def getgid(self):
1363 return self._getentry().pw_gid
1363 return self._getentry().pw_gid
1364 gid = property(getgid, None, None, "Primary group id")
1364 gid = property(getgid, None, None, "Primary group id")
1365
1365
1366 def getgroup(self):
1366 def getgroup(self):
1367 return igrpentry(self.gid)
1367 return igrpentry(self.gid)
1368 group = property(getgroup, None, None, "Group")
1368 group = property(getgroup, None, None, "Group")
1369
1369
1370 def getgecos(self):
1370 def getgecos(self):
1371 return self._getentry().pw_gecos
1371 return self._getentry().pw_gecos
1372 gecos = property(getgecos, None, None, "Information (e.g. full user name)")
1372 gecos = property(getgecos, None, None, "Information (e.g. full user name)")
1373
1373
1374 def getdir(self):
1374 def getdir(self):
1375 return self._getentry().pw_dir
1375 return self._getentry().pw_dir
1376 dir = property(getdir, None, None, "$HOME directory")
1376 dir = property(getdir, None, None, "$HOME directory")
1377
1377
1378 def getshell(self):
1378 def getshell(self):
1379 return self._getentry().pw_shell
1379 return self._getentry().pw_shell
1380 shell = property(getshell, None, None, "Login shell")
1380 shell = property(getshell, None, None, "Login shell")
1381
1381
1382 def __xattrs__(self, mode="default"):
1382 def __xattrs__(self, mode="default"):
1383 return ("name", "passwd", "uid", "gid", "gecos", "dir", "shell")
1383 return ("name", "passwd", "uid", "gid", "gecos", "dir", "shell")
1384
1384
1385 def __repr__(self):
1385 def __repr__(self):
1386 return "%s.%s(%r)" % \
1386 return "%s.%s(%r)" % \
1387 (self.__class__.__module__, self.__class__.__name__, self._id)
1387 (self.__class__.__module__, self.__class__.__name__, self._id)
1388
1388
1389
1389
1390 class ipwd(Table):
1390 class ipwd(Table):
1391 """
1391 """
1392 List all entries in the Unix user account and password database.
1392 List all entries in the Unix user account and password database.
1393
1393
1394 Example::
1394 Example::
1395
1395
1396 >>> ipwd | isort("uid")
1396 >>> ipwd | isort("uid")
1397 <IPython.extensions.ipipe.isort key='uid' reverse=False at 0x849efec>
1397 <IPython.extensions.ipipe.isort key='uid' reverse=False at 0x849efec>
1398 # random
1398 # random
1399 """
1399 """
1400 def __iter__(self):
1400 def __iter__(self):
1401 for entry in pwd.getpwall():
1401 for entry in pwd.getpwall():
1402 yield ipwdentry(entry.pw_name)
1402 yield ipwdentry(entry.pw_name)
1403
1403
1404 def __xrepr__(self, mode="default"):
1404 def __xrepr__(self, mode="default"):
1405 if mode == "header" or mode == "footer" or mode == "cell":
1405 if mode == "header" or mode == "footer" or mode == "cell":
1406 yield (astyle.style_default, "%s()" % self.__class__.__name__)
1406 yield (astyle.style_default, "%s()" % self.__class__.__name__)
1407 else:
1407 else:
1408 yield (astyle.style_default, repr(self))
1408 yield (astyle.style_default, repr(self))
1409
1409
1410
1410
1411 class igrpentry(object):
1411 class igrpentry(object):
1412 """
1412 """
1413 ``igrpentry`` objects encapsulate entries in the Unix group database.
1413 ``igrpentry`` objects encapsulate entries in the Unix group database.
1414 """
1414 """
1415 def __init__(self, id):
1415 def __init__(self, id):
1416 self._id = id
1416 self._id = id
1417 self._entry = None
1417 self._entry = None
1418
1418
1419 def __eq__(self, other):
1419 def __eq__(self, other):
1420 return self.__class__ is other.__class__ and self._id == other._id
1420 return self.__class__ is other.__class__ and self._id == other._id
1421
1421
1422 def __ne__(self, other):
1422 def __ne__(self, other):
1423 return self.__class__ is not other.__class__ or self._id != other._id
1423 return self.__class__ is not other.__class__ or self._id != other._id
1424
1424
1425 def _getentry(self):
1425 def _getentry(self):
1426 if self._entry is None:
1426 if self._entry is None:
1427 if isinstance(self._id, basestring):
1427 if isinstance(self._id, basestring):
1428 self._entry = grp.getgrnam(self._id)
1428 self._entry = grp.getgrnam(self._id)
1429 else:
1429 else:
1430 self._entry = grp.getgrgid(self._id)
1430 self._entry = grp.getgrgid(self._id)
1431 return self._entry
1431 return self._entry
1432
1432
1433 def getname(self):
1433 def getname(self):
1434 if isinstance(self._id, basestring):
1434 if isinstance(self._id, basestring):
1435 return self._id
1435 return self._id
1436 else:
1436 else:
1437 return self._getentry().gr_name
1437 return self._getentry().gr_name
1438 name = property(getname, None, None, "Group name")
1438 name = property(getname, None, None, "Group name")
1439
1439
1440 def getpasswd(self):
1440 def getpasswd(self):
1441 return self._getentry().gr_passwd
1441 return self._getentry().gr_passwd
1442 passwd = property(getpasswd, None, None, "Password")
1442 passwd = property(getpasswd, None, None, "Password")
1443
1443
1444 def getgid(self):
1444 def getgid(self):
1445 if isinstance(self._id, basestring):
1445 if isinstance(self._id, basestring):
1446 return self._getentry().gr_gid
1446 return self._getentry().gr_gid
1447 else:
1447 else:
1448 return self._id
1448 return self._id
1449 gid = property(getgid, None, None, "Group id")
1449 gid = property(getgid, None, None, "Group id")
1450
1450
1451 def getmem(self):
1451 def getmem(self):
1452 return self._getentry().gr_mem
1452 return self._getentry().gr_mem
1453 mem = property(getmem, None, None, "Members")
1453 mem = property(getmem, None, None, "Members")
1454
1454
1455 def __xattrs__(self, mode="default"):
1455 def __xattrs__(self, mode="default"):
1456 return ("name", "passwd", "gid", "mem")
1456 return ("name", "passwd", "gid", "mem")
1457
1457
1458 def __xrepr__(self, mode="default"):
1458 def __xrepr__(self, mode="default"):
1459 if mode == "header" or mode == "footer" or mode == "cell":
1459 if mode == "header" or mode == "footer" or mode == "cell":
1460 yield (astyle.style_default, "group ")
1460 yield (astyle.style_default, "group ")
1461 try:
1461 try:
1462 yield (astyle.style_default, self.name)
1462 yield (astyle.style_default, self.name)
1463 except KeyError:
1463 except KeyError:
1464 if isinstance(self._id, basestring):
1464 if isinstance(self._id, basestring):
1465 yield (astyle.style_default, self.name_id)
1465 yield (astyle.style_default, self.name_id)
1466 else:
1466 else:
1467 yield (astyle.style_type_number, str(self._id))
1467 yield (astyle.style_type_number, str(self._id))
1468 else:
1468 else:
1469 yield (astyle.style_default, repr(self))
1469 yield (astyle.style_default, repr(self))
1470
1470
1471 def __iter__(self):
1471 def __iter__(self):
1472 for member in self.mem:
1472 for member in self.mem:
1473 yield ipwdentry(member)
1473 yield ipwdentry(member)
1474
1474
1475 def __repr__(self):
1475 def __repr__(self):
1476 return "%s.%s(%r)" % \
1476 return "%s.%s(%r)" % \
1477 (self.__class__.__module__, self.__class__.__name__, self._id)
1477 (self.__class__.__module__, self.__class__.__name__, self._id)
1478
1478
1479
1479
1480 class igrp(Table):
1480 class igrp(Table):
1481 """
1481 """
1482 This ``Table`` lists all entries in the Unix group database.
1482 This ``Table`` lists all entries in the Unix group database.
1483 """
1483 """
1484 def __iter__(self):
1484 def __iter__(self):
1485 for entry in grp.getgrall():
1485 for entry in grp.getgrall():
1486 yield igrpentry(entry.gr_name)
1486 yield igrpentry(entry.gr_name)
1487
1487
1488 def __xrepr__(self, mode="default"):
1488 def __xrepr__(self, mode="default"):
1489 if mode == "header" or mode == "footer":
1489 if mode == "header" or mode == "footer":
1490 yield (astyle.style_default, "%s()" % self.__class__.__name__)
1490 yield (astyle.style_default, "%s()" % self.__class__.__name__)
1491 else:
1491 else:
1492 yield (astyle.style_default, repr(self))
1492 yield (astyle.style_default, repr(self))
1493
1493
1494
1494
1495 class Fields(object):
1495 class Fields(object):
1496 def __init__(self, fieldnames, **fields):
1496 def __init__(self, fieldnames, **fields):
1497 self.__fieldnames = [upgradexattr(fieldname) for fieldname in fieldnames]
1497 self.__fieldnames = [upgradexattr(fieldname) for fieldname in fieldnames]
1498 for (key, value) in fields.iteritems():
1498 for (key, value) in fields.iteritems():
1499 setattr(self, key, value)
1499 setattr(self, key, value)
1500
1500
1501 def __xattrs__(self, mode="default"):
1501 def __xattrs__(self, mode="default"):
1502 return self.__fieldnames
1502 return self.__fieldnames
1503
1503
1504 def __xrepr__(self, mode="default"):
1504 def __xrepr__(self, mode="default"):
1505 yield (-1, False)
1505 yield (-1, False)
1506 if mode == "header" or mode == "cell":
1506 if mode == "header" or mode == "cell":
1507 yield (astyle.style_default, self.__class__.__name__)
1507 yield (astyle.style_default, self.__class__.__name__)
1508 yield (astyle.style_default, "(")
1508 yield (astyle.style_default, "(")
1509 for (i, f) in enumerate(self.__fieldnames):
1509 for (i, f) in enumerate(self.__fieldnames):
1510 if i:
1510 if i:
1511 yield (astyle.style_default, ", ")
1511 yield (astyle.style_default, ", ")
1512 yield (astyle.style_default, f.name())
1512 yield (astyle.style_default, f.name())
1513 yield (astyle.style_default, "=")
1513 yield (astyle.style_default, "=")
1514 for part in xrepr(getattr(self, f), "default"):
1514 for part in xrepr(getattr(self, f), "default"):
1515 yield part
1515 yield part
1516 yield (astyle.style_default, ")")
1516 yield (astyle.style_default, ")")
1517 elif mode == "footer":
1517 elif mode == "footer":
1518 yield (astyle.style_default, self.__class__.__name__)
1518 yield (astyle.style_default, self.__class__.__name__)
1519 yield (astyle.style_default, "(")
1519 yield (astyle.style_default, "(")
1520 for (i, f) in enumerate(self.__fieldnames):
1520 for (i, f) in enumerate(self.__fieldnames):
1521 if i:
1521 if i:
1522 yield (astyle.style_default, ", ")
1522 yield (astyle.style_default, ", ")
1523 yield (astyle.style_default, f.name())
1523 yield (astyle.style_default, f.name())
1524 yield (astyle.style_default, ")")
1524 yield (astyle.style_default, ")")
1525 else:
1525 else:
1526 yield (astyle.style_default, repr(self))
1526 yield (astyle.style_default, repr(self))
1527
1527
1528
1528
1529 class FieldTable(Table, list):
1529 class FieldTable(Table, list):
1530 def __init__(self, *fields):
1530 def __init__(self, *fields):
1531 Table.__init__(self)
1531 Table.__init__(self)
1532 list.__init__(self)
1532 list.__init__(self)
1533 self.fields = fields
1533 self.fields = fields
1534
1534
1535 def add(self, **fields):
1535 def add(self, **fields):
1536 self.append(Fields(self.fields, **fields))
1536 self.append(Fields(self.fields, **fields))
1537
1537
1538 def __xrepr__(self, mode="default"):
1538 def __xrepr__(self, mode="default"):
1539 yield (-1, False)
1539 yield (-1, False)
1540 if mode == "header" or mode == "footer":
1540 if mode == "header" or mode == "footer":
1541 yield (astyle.style_default, self.__class__.__name__)
1541 yield (astyle.style_default, self.__class__.__name__)
1542 yield (astyle.style_default, "(")
1542 yield (astyle.style_default, "(")
1543 for (i, f) in enumerate(self.__fieldnames):
1543 for (i, f) in enumerate(self.__fieldnames):
1544 if i:
1544 if i:
1545 yield (astyle.style_default, ", ")
1545 yield (astyle.style_default, ", ")
1546 yield (astyle.style_default, f)
1546 yield (astyle.style_default, f)
1547 yield (astyle.style_default, ")")
1547 yield (astyle.style_default, ")")
1548 else:
1548 else:
1549 yield (astyle.style_default, repr(self))
1549 yield (astyle.style_default, repr(self))
1550
1550
1551 def __repr__(self):
1551 def __repr__(self):
1552 return "<%s.%s object with fields=%r at 0x%x>" % \
1552 return "<%s.%s object with fields=%r at 0x%x>" % \
1553 (self.__class__.__module__, self.__class__.__name__,
1553 (self.__class__.__module__, self.__class__.__name__,
1554 ", ".join(map(repr, self.fields)), id(self))
1554 ", ".join(map(repr, self.fields)), id(self))
1555
1555
1556
1556
1557 class List(list):
1557 class List(list):
1558 def __xattrs__(self, mode="default"):
1558 def __xattrs__(self, mode="default"):
1559 return xrange(len(self))
1559 return xrange(len(self))
1560
1560
1561 def __xrepr__(self, mode="default"):
1561 def __xrepr__(self, mode="default"):
1562 yield (-1, False)
1562 yield (-1, False)
1563 if mode == "header" or mode == "cell" or mode == "footer" or mode == "default":
1563 if mode == "header" or mode == "cell" or mode == "footer" or mode == "default":
1564 yield (astyle.style_default, self.__class__.__name__)
1564 yield (astyle.style_default, self.__class__.__name__)
1565 yield (astyle.style_default, "(")
1565 yield (astyle.style_default, "(")
1566 for (i, item) in enumerate(self):
1566 for (i, item) in enumerate(self):
1567 if i:
1567 if i:
1568 yield (astyle.style_default, ", ")
1568 yield (astyle.style_default, ", ")
1569 for part in xrepr(item, "default"):
1569 for part in xrepr(item, "default"):
1570 yield part
1570 yield part
1571 yield (astyle.style_default, ")")
1571 yield (astyle.style_default, ")")
1572 else:
1572 else:
1573 yield (astyle.style_default, repr(self))
1573 yield (astyle.style_default, repr(self))
1574
1574
1575
1575
1576 class ienv(Table):
1576 class ienv(Table):
1577 """
1577 """
1578 List environment variables.
1578 List environment variables.
1579
1579
1580 Example::
1580 Example::
1581
1581
1582 >>> ienv
1582 >>> ienv
1583 <class 'IPython.extensions.ipipe.ienv'>
1583 <class 'IPython.extensions.ipipe.ienv'>
1584 """
1584 """
1585
1585
1586 def __iter__(self):
1586 def __iter__(self):
1587 fields = ("key", "value")
1587 fields = ("key", "value")
1588 for (key, value) in os.environ.iteritems():
1588 for (key, value) in os.environ.iteritems():
1589 yield Fields(fields, key=key, value=value)
1589 yield Fields(fields, key=key, value=value)
1590
1590
1591 def __xrepr__(self, mode="default"):
1591 def __xrepr__(self, mode="default"):
1592 if mode == "header" or mode == "cell":
1592 if mode == "header" or mode == "cell":
1593 yield (astyle.style_default, "%s()" % self.__class__.__name__)
1593 yield (astyle.style_default, "%s()" % self.__class__.__name__)
1594 else:
1594 else:
1595 yield (astyle.style_default, repr(self))
1595 yield (astyle.style_default, repr(self))
1596
1596
1597
1597
1598 class ihist(Table):
1598 class ihist(Table):
1599 """
1599 """
1600 IPython input history
1600 IPython input history
1601
1601
1602 Example::
1602 Example::
1603
1603
1604 >>> ihist
1604 >>> ihist
1605 <class 'IPython.extensions.ipipe.ihist'>
1605 <class 'IPython.extensions.ipipe.ihist'>
1606 >>> ihist(True) # raw mode
1606 >>> ihist(True) # raw mode
1607 <IPython.extensions.ipipe.ihist object at 0x849602c> # random
1607 <IPython.extensions.ipipe.ihist object at 0x849602c> # random
1608 """
1608 """
1609 def __init__(self, raw=True):
1609 def __init__(self, raw=True):
1610 self.raw = raw
1610 self.raw = raw
1611
1611
1612 def __iter__(self):
1612 def __iter__(self):
1613 api = ipapi.get()
1613 api = ipapi.get()
1614 if self.raw:
1614 if self.raw:
1615 for line in api.input_hist_raw:
1615 for line in api.input_hist_raw:
1616 yield line.rstrip("\n")
1616 yield line.rstrip("\n")
1617 else:
1617 else:
1618 for line in api.input_hist:
1618 for line in api.input_hist:
1619 yield line.rstrip("\n")
1619 yield line.rstrip("\n")
1620
1620
1621
1621
1622 class Alias(object):
1622 class Alias(object):
1623 """
1623 """
1624 Entry in the alias table
1624 Entry in the alias table
1625 """
1625 """
1626 def __init__(self, name, args, command):
1626 def __init__(self, name, args, command):
1627 self.name = name
1627 self.name = name
1628 self.args = args
1628 self.args = args
1629 self.command = command
1629 self.command = command
1630
1630
1631 def __xattrs__(self, mode="default"):
1631 def __xattrs__(self, mode="default"):
1632 return ("name", "args", "command")
1632 return ("name", "args", "command")
1633
1633
1634
1634
1635 class ialias(Table):
1635 class ialias(Table):
1636 """
1636 """
1637 IPython alias list
1637 IPython alias list
1638
1638
1639 Example::
1639 Example::
1640
1640
1641 >>> ialias
1641 >>> ialias
1642 <class 'IPython.extensions.ipipe.ialias'>
1642 <class 'IPython.extensions.ipipe.ialias'>
1643 """
1643 """
1644 def __iter__(self):
1644 def __iter__(self):
1645 api = ipapi.get()
1645 api = ipapi.get()
1646
1646
1647 for (name, (args, command)) in api.alias_table.iteritems():
1647 for (name, (args, command)) in api.alias_manager.alias_table.iteritems():
1648 yield Alias(name, args, command)
1648 yield Alias(name, args, command)
1649
1649
1650
1650
1651 class icsv(Pipe):
1651 class icsv(Pipe):
1652 """
1652 """
1653 This ``Pipe`` turns the input (with must be a pipe outputting lines
1653 This ``Pipe`` turns the input (with must be a pipe outputting lines
1654 or an ``ifile``) into lines of CVS columns.
1654 or an ``ifile``) into lines of CVS columns.
1655 """
1655 """
1656 def __init__(self, **csvargs):
1656 def __init__(self, **csvargs):
1657 """
1657 """
1658 Create an ``icsv`` object. ``cvsargs`` will be passed through as
1658 Create an ``icsv`` object. ``cvsargs`` will be passed through as
1659 keyword arguments to ``cvs.reader()``.
1659 keyword arguments to ``cvs.reader()``.
1660 """
1660 """
1661 self.csvargs = csvargs
1661 self.csvargs = csvargs
1662
1662
1663 def __iter__(self):
1663 def __iter__(self):
1664 input = self.input
1664 input = self.input
1665 if isinstance(input, ifile):
1665 if isinstance(input, ifile):
1666 input = input.open("rb")
1666 input = input.open("rb")
1667 reader = csv.reader(input, **self.csvargs)
1667 reader = csv.reader(input, **self.csvargs)
1668 for line in reader:
1668 for line in reader:
1669 yield List(line)
1669 yield List(line)
1670
1670
1671 def __xrepr__(self, mode="default"):
1671 def __xrepr__(self, mode="default"):
1672 yield (-1, False)
1672 yield (-1, False)
1673 if mode == "header" or mode == "footer":
1673 if mode == "header" or mode == "footer":
1674 input = getattr(self, "input", None)
1674 input = getattr(self, "input", None)
1675 if input is not None:
1675 if input is not None:
1676 for part in xrepr(input, mode):
1676 for part in xrepr(input, mode):
1677 yield part
1677 yield part
1678 yield (astyle.style_default, " | ")
1678 yield (astyle.style_default, " | ")
1679 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1679 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1680 for (i, (name, value)) in enumerate(self.csvargs.iteritems()):
1680 for (i, (name, value)) in enumerate(self.csvargs.iteritems()):
1681 if i:
1681 if i:
1682 yield (astyle.style_default, ", ")
1682 yield (astyle.style_default, ", ")
1683 yield (astyle.style_default, name)
1683 yield (astyle.style_default, name)
1684 yield (astyle.style_default, "=")
1684 yield (astyle.style_default, "=")
1685 for part in xrepr(value, "default"):
1685 for part in xrepr(value, "default"):
1686 yield part
1686 yield part
1687 yield (astyle.style_default, ")")
1687 yield (astyle.style_default, ")")
1688 else:
1688 else:
1689 yield (astyle.style_default, repr(self))
1689 yield (astyle.style_default, repr(self))
1690
1690
1691 def __repr__(self):
1691 def __repr__(self):
1692 args = ", ".join(["%s=%r" % item for item in self.csvargs.iteritems()])
1692 args = ", ".join(["%s=%r" % item for item in self.csvargs.iteritems()])
1693 return "<%s.%s %s at 0x%x>" % \
1693 return "<%s.%s %s at 0x%x>" % \
1694 (self.__class__.__module__, self.__class__.__name__, args, id(self))
1694 (self.__class__.__module__, self.__class__.__name__, args, id(self))
1695
1695
1696
1696
1697 class ix(Table):
1697 class ix(Table):
1698 """
1698 """
1699 Execute a system command and list its output as lines
1699 Execute a system command and list its output as lines
1700 (similar to ``os.popen()``).
1700 (similar to ``os.popen()``).
1701
1701
1702 Examples::
1702 Examples::
1703
1703
1704 >>> ix("ps x")
1704 >>> ix("ps x")
1705 IPython.extensions.ipipe.ix('ps x')
1705 IPython.extensions.ipipe.ix('ps x')
1706
1706
1707 >>> ix("find .") | ifile
1707 >>> ix("find .") | ifile
1708 <IPython.extensions.ipipe.ieval expr=<class 'IPython.extensions.ipipe.ifile'> at 0x8509d2c>
1708 <IPython.extensions.ipipe.ieval expr=<class 'IPython.extensions.ipipe.ifile'> at 0x8509d2c>
1709 # random
1709 # random
1710 """
1710 """
1711 def __init__(self, cmd):
1711 def __init__(self, cmd):
1712 self.cmd = cmd
1712 self.cmd = cmd
1713 self._pipeout = None
1713 self._pipeout = None
1714
1714
1715 def __iter__(self):
1715 def __iter__(self):
1716 (_pipein, self._pipeout) = os.popen4(self.cmd)
1716 (_pipein, self._pipeout) = os.popen4(self.cmd)
1717 _pipein.close()
1717 _pipein.close()
1718 for l in self._pipeout:
1718 for l in self._pipeout:
1719 yield l.rstrip("\r\n")
1719 yield l.rstrip("\r\n")
1720 self._pipeout.close()
1720 self._pipeout.close()
1721 self._pipeout = None
1721 self._pipeout = None
1722
1722
1723 def __del__(self):
1723 def __del__(self):
1724 if self._pipeout is not None and not self._pipeout.closed:
1724 if self._pipeout is not None and not self._pipeout.closed:
1725 self._pipeout.close()
1725 self._pipeout.close()
1726 self._pipeout = None
1726 self._pipeout = None
1727
1727
1728 def __xrepr__(self, mode="default"):
1728 def __xrepr__(self, mode="default"):
1729 if mode == "header" or mode == "footer":
1729 if mode == "header" or mode == "footer":
1730 yield (astyle.style_default,
1730 yield (astyle.style_default,
1731 "%s(%r)" % (self.__class__.__name__, self.cmd))
1731 "%s(%r)" % (self.__class__.__name__, self.cmd))
1732 else:
1732 else:
1733 yield (astyle.style_default, repr(self))
1733 yield (astyle.style_default, repr(self))
1734
1734
1735 def __repr__(self):
1735 def __repr__(self):
1736 return "%s.%s(%r)" % \
1736 return "%s.%s(%r)" % \
1737 (self.__class__.__module__, self.__class__.__name__, self.cmd)
1737 (self.__class__.__module__, self.__class__.__name__, self.cmd)
1738
1738
1739
1739
1740 class ifilter(Pipe):
1740 class ifilter(Pipe):
1741 """
1741 """
1742 Filter an input pipe. Only objects where an expression evaluates to true
1742 Filter an input pipe. Only objects where an expression evaluates to true
1743 (and doesn't raise an exception) are listed.
1743 (and doesn't raise an exception) are listed.
1744
1744
1745 Examples::
1745 Examples::
1746
1746
1747 >>> ils | ifilter("_.isfile() and size>1000")
1747 >>> ils | ifilter("_.isfile() and size>1000")
1748 >>> igrp | ifilter("len(mem)")
1748 >>> igrp | ifilter("len(mem)")
1749 >>> sys.modules | ifilter(lambda _:_.value is not None)
1749 >>> sys.modules | ifilter(lambda _:_.value is not None)
1750 # all-random
1750 # all-random
1751 """
1751 """
1752
1752
1753 def __init__(self, expr, globals=None, errors="raiseifallfail"):
1753 def __init__(self, expr, globals=None, errors="raiseifallfail"):
1754 """
1754 """
1755 Create an ``ifilter`` object. ``expr`` can be a callable or a string
1755 Create an ``ifilter`` object. ``expr`` can be a callable or a string
1756 containing an expression. ``globals`` will be used as the global
1756 containing an expression. ``globals`` will be used as the global
1757 namespace for calling string expressions (defaulting to IPython's
1757 namespace for calling string expressions (defaulting to IPython's
1758 user namespace). ``errors`` specifies how exception during evaluation
1758 user namespace). ``errors`` specifies how exception during evaluation
1759 of ``expr`` are handled:
1759 of ``expr`` are handled:
1760
1760
1761 ``"drop"``
1761 ``"drop"``
1762 drop all items that have errors;
1762 drop all items that have errors;
1763
1763
1764 ``"keep"``
1764 ``"keep"``
1765 keep all items that have errors;
1765 keep all items that have errors;
1766
1766
1767 ``"keeperror"``
1767 ``"keeperror"``
1768 keep the exception of all items that have errors;
1768 keep the exception of all items that have errors;
1769
1769
1770 ``"raise"``
1770 ``"raise"``
1771 raise the exception;
1771 raise the exception;
1772
1772
1773 ``"raiseifallfail"``
1773 ``"raiseifallfail"``
1774 raise the first exception if all items have errors; otherwise drop
1774 raise the first exception if all items have errors; otherwise drop
1775 those with errors (this is the default).
1775 those with errors (this is the default).
1776 """
1776 """
1777 self.expr = expr
1777 self.expr = expr
1778 self.globals = globals
1778 self.globals = globals
1779 self.errors = errors
1779 self.errors = errors
1780
1780
1781 def __iter__(self):
1781 def __iter__(self):
1782 if callable(self.expr):
1782 if callable(self.expr):
1783 test = self.expr
1783 test = self.expr
1784 else:
1784 else:
1785 g = getglobals(self.globals)
1785 g = getglobals(self.globals)
1786 expr = compile(self.expr, "ipipe-expression", "eval")
1786 expr = compile(self.expr, "ipipe-expression", "eval")
1787 def test(item):
1787 def test(item):
1788 return eval(expr, g, AttrNamespace(item))
1788 return eval(expr, g, AttrNamespace(item))
1789
1789
1790 ok = 0
1790 ok = 0
1791 exc_info = None
1791 exc_info = None
1792 for item in xiter(self.input):
1792 for item in xiter(self.input):
1793 try:
1793 try:
1794 if test(item):
1794 if test(item):
1795 yield item
1795 yield item
1796 ok += 1
1796 ok += 1
1797 except (KeyboardInterrupt, SystemExit):
1797 except (KeyboardInterrupt, SystemExit):
1798 raise
1798 raise
1799 except Exception, exc:
1799 except Exception, exc:
1800 if self.errors == "drop":
1800 if self.errors == "drop":
1801 pass # Ignore errors
1801 pass # Ignore errors
1802 elif self.errors == "keep":
1802 elif self.errors == "keep":
1803 yield item
1803 yield item
1804 elif self.errors == "keeperror":
1804 elif self.errors == "keeperror":
1805 yield exc
1805 yield exc
1806 elif self.errors == "raise":
1806 elif self.errors == "raise":
1807 raise
1807 raise
1808 elif self.errors == "raiseifallfail":
1808 elif self.errors == "raiseifallfail":
1809 if exc_info is None:
1809 if exc_info is None:
1810 exc_info = sys.exc_info()
1810 exc_info = sys.exc_info()
1811 if not ok and exc_info is not None:
1811 if not ok and exc_info is not None:
1812 raise exc_info[0], exc_info[1], exc_info[2]
1812 raise exc_info[0], exc_info[1], exc_info[2]
1813
1813
1814 def __xrepr__(self, mode="default"):
1814 def __xrepr__(self, mode="default"):
1815 if mode == "header" or mode == "footer":
1815 if mode == "header" or mode == "footer":
1816 input = getattr(self, "input", None)
1816 input = getattr(self, "input", None)
1817 if input is not None:
1817 if input is not None:
1818 for part in xrepr(input, mode):
1818 for part in xrepr(input, mode):
1819 yield part
1819 yield part
1820 yield (astyle.style_default, " | ")
1820 yield (astyle.style_default, " | ")
1821 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1821 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1822 for part in xrepr(self.expr, "default"):
1822 for part in xrepr(self.expr, "default"):
1823 yield part
1823 yield part
1824 yield (astyle.style_default, ")")
1824 yield (astyle.style_default, ")")
1825 else:
1825 else:
1826 yield (astyle.style_default, repr(self))
1826 yield (astyle.style_default, repr(self))
1827
1827
1828 def __repr__(self):
1828 def __repr__(self):
1829 return "<%s.%s expr=%r at 0x%x>" % \
1829 return "<%s.%s expr=%r at 0x%x>" % \
1830 (self.__class__.__module__, self.__class__.__name__,
1830 (self.__class__.__module__, self.__class__.__name__,
1831 self.expr, id(self))
1831 self.expr, id(self))
1832
1832
1833
1833
1834 class ieval(Pipe):
1834 class ieval(Pipe):
1835 """
1835 """
1836 Evaluate an expression for each object in the input pipe.
1836 Evaluate an expression for each object in the input pipe.
1837
1837
1838 Examples::
1838 Examples::
1839
1839
1840 >>> ils | ieval("_.abspath()")
1840 >>> ils | ieval("_.abspath()")
1841 # random
1841 # random
1842 >>> sys.path | ieval(ifile)
1842 >>> sys.path | ieval(ifile)
1843 # random
1843 # random
1844 """
1844 """
1845
1845
1846 def __init__(self, expr, globals=None, errors="raiseifallfail"):
1846 def __init__(self, expr, globals=None, errors="raiseifallfail"):
1847 """
1847 """
1848 Create an ``ieval`` object. ``expr`` can be a callable or a string
1848 Create an ``ieval`` object. ``expr`` can be a callable or a string
1849 containing an expression. For the meaning of ``globals`` and
1849 containing an expression. For the meaning of ``globals`` and
1850 ``errors`` see ``ifilter``.
1850 ``errors`` see ``ifilter``.
1851 """
1851 """
1852 self.expr = expr
1852 self.expr = expr
1853 self.globals = globals
1853 self.globals = globals
1854 self.errors = errors
1854 self.errors = errors
1855
1855
1856 def __iter__(self):
1856 def __iter__(self):
1857 if callable(self.expr):
1857 if callable(self.expr):
1858 do = self.expr
1858 do = self.expr
1859 else:
1859 else:
1860 g = getglobals(self.globals)
1860 g = getglobals(self.globals)
1861 expr = compile(self.expr, "ipipe-expression", "eval")
1861 expr = compile(self.expr, "ipipe-expression", "eval")
1862 def do(item):
1862 def do(item):
1863 return eval(expr, g, AttrNamespace(item))
1863 return eval(expr, g, AttrNamespace(item))
1864
1864
1865 ok = 0
1865 ok = 0
1866 exc_info = None
1866 exc_info = None
1867 for item in xiter(self.input):
1867 for item in xiter(self.input):
1868 try:
1868 try:
1869 yield do(item)
1869 yield do(item)
1870 except (KeyboardInterrupt, SystemExit):
1870 except (KeyboardInterrupt, SystemExit):
1871 raise
1871 raise
1872 except Exception, exc:
1872 except Exception, exc:
1873 if self.errors == "drop":
1873 if self.errors == "drop":
1874 pass # Ignore errors
1874 pass # Ignore errors
1875 elif self.errors == "keep":
1875 elif self.errors == "keep":
1876 yield item
1876 yield item
1877 elif self.errors == "keeperror":
1877 elif self.errors == "keeperror":
1878 yield exc
1878 yield exc
1879 elif self.errors == "raise":
1879 elif self.errors == "raise":
1880 raise
1880 raise
1881 elif self.errors == "raiseifallfail":
1881 elif self.errors == "raiseifallfail":
1882 if exc_info is None:
1882 if exc_info is None:
1883 exc_info = sys.exc_info()
1883 exc_info = sys.exc_info()
1884 if not ok and exc_info is not None:
1884 if not ok and exc_info is not None:
1885 raise exc_info[0], exc_info[1], exc_info[2]
1885 raise exc_info[0], exc_info[1], exc_info[2]
1886
1886
1887 def __xrepr__(self, mode="default"):
1887 def __xrepr__(self, mode="default"):
1888 if mode == "header" or mode == "footer":
1888 if mode == "header" or mode == "footer":
1889 input = getattr(self, "input", None)
1889 input = getattr(self, "input", None)
1890 if input is not None:
1890 if input is not None:
1891 for part in xrepr(input, mode):
1891 for part in xrepr(input, mode):
1892 yield part
1892 yield part
1893 yield (astyle.style_default, " | ")
1893 yield (astyle.style_default, " | ")
1894 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1894 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1895 for part in xrepr(self.expr, "default"):
1895 for part in xrepr(self.expr, "default"):
1896 yield part
1896 yield part
1897 yield (astyle.style_default, ")")
1897 yield (astyle.style_default, ")")
1898 else:
1898 else:
1899 yield (astyle.style_default, repr(self))
1899 yield (astyle.style_default, repr(self))
1900
1900
1901 def __repr__(self):
1901 def __repr__(self):
1902 return "<%s.%s expr=%r at 0x%x>" % \
1902 return "<%s.%s expr=%r at 0x%x>" % \
1903 (self.__class__.__module__, self.__class__.__name__,
1903 (self.__class__.__module__, self.__class__.__name__,
1904 self.expr, id(self))
1904 self.expr, id(self))
1905
1905
1906
1906
1907 class ienum(Pipe):
1907 class ienum(Pipe):
1908 """
1908 """
1909 Enumerate the input pipe (i.e. wrap each input object in an object
1909 Enumerate the input pipe (i.e. wrap each input object in an object
1910 with ``index`` and ``object`` attributes).
1910 with ``index`` and ``object`` attributes).
1911
1911
1912 Examples::
1912 Examples::
1913
1913
1914 >>> xrange(20) | ieval("_,_*_") | ienum | ifilter("index % 2 == 0") | ieval("object")
1914 >>> xrange(20) | ieval("_,_*_") | ienum | ifilter("index % 2 == 0") | ieval("object")
1915 """
1915 """
1916 skip_doctest = True
1916 skip_doctest = True
1917
1917
1918 def __iter__(self):
1918 def __iter__(self):
1919 fields = ("index", "object")
1919 fields = ("index", "object")
1920 for (index, object) in enumerate(xiter(self.input)):
1920 for (index, object) in enumerate(xiter(self.input)):
1921 yield Fields(fields, index=index, object=object)
1921 yield Fields(fields, index=index, object=object)
1922
1922
1923
1923
1924 class isort(Pipe):
1924 class isort(Pipe):
1925 """
1925 """
1926 Sorts the input pipe.
1926 Sorts the input pipe.
1927
1927
1928 Examples::
1928 Examples::
1929
1929
1930 >>> ils | isort("size")
1930 >>> ils | isort("size")
1931 <IPython.extensions.ipipe.isort key='size' reverse=False at 0x849ec2c>
1931 <IPython.extensions.ipipe.isort key='size' reverse=False at 0x849ec2c>
1932 >>> ils | isort("_.isdir(), _.lower()", reverse=True)
1932 >>> ils | isort("_.isdir(), _.lower()", reverse=True)
1933 <IPython.extensions.ipipe.isort key='_.isdir(), _.lower()' reverse=True at 0x849eacc>
1933 <IPython.extensions.ipipe.isort key='_.isdir(), _.lower()' reverse=True at 0x849eacc>
1934 # all-random
1934 # all-random
1935 """
1935 """
1936
1936
1937 def __init__(self, key=None, globals=None, reverse=False):
1937 def __init__(self, key=None, globals=None, reverse=False):
1938 """
1938 """
1939 Create an ``isort`` object. ``key`` can be a callable or a string
1939 Create an ``isort`` object. ``key`` can be a callable or a string
1940 containing an expression (or ``None`` in which case the items
1940 containing an expression (or ``None`` in which case the items
1941 themselves will be sorted). If ``reverse`` is true the sort order
1941 themselves will be sorted). If ``reverse`` is true the sort order
1942 will be reversed. For the meaning of ``globals`` see ``ifilter``.
1942 will be reversed. For the meaning of ``globals`` see ``ifilter``.
1943 """
1943 """
1944 self.key = key
1944 self.key = key
1945 self.globals = globals
1945 self.globals = globals
1946 self.reverse = reverse
1946 self.reverse = reverse
1947
1947
1948 def __iter__(self):
1948 def __iter__(self):
1949 if self.key is None:
1949 if self.key is None:
1950 items = sorted(xiter(self.input), reverse=self.reverse)
1950 items = sorted(xiter(self.input), reverse=self.reverse)
1951 elif callable(self.key):
1951 elif callable(self.key):
1952 items = sorted(xiter(self.input), key=self.key, reverse=self.reverse)
1952 items = sorted(xiter(self.input), key=self.key, reverse=self.reverse)
1953 else:
1953 else:
1954 g = getglobals(self.globals)
1954 g = getglobals(self.globals)
1955 key = compile(self.key, "ipipe-expression", "eval")
1955 key = compile(self.key, "ipipe-expression", "eval")
1956 def realkey(item):
1956 def realkey(item):
1957 return eval(key, g, AttrNamespace(item))
1957 return eval(key, g, AttrNamespace(item))
1958 items = sorted(xiter(self.input), key=realkey, reverse=self.reverse)
1958 items = sorted(xiter(self.input), key=realkey, reverse=self.reverse)
1959 for item in items:
1959 for item in items:
1960 yield item
1960 yield item
1961
1961
1962 def __xrepr__(self, mode="default"):
1962 def __xrepr__(self, mode="default"):
1963 if mode == "header" or mode == "footer":
1963 if mode == "header" or mode == "footer":
1964 input = getattr(self, "input", None)
1964 input = getattr(self, "input", None)
1965 if input is not None:
1965 if input is not None:
1966 for part in xrepr(input, mode):
1966 for part in xrepr(input, mode):
1967 yield part
1967 yield part
1968 yield (astyle.style_default, " | ")
1968 yield (astyle.style_default, " | ")
1969 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1969 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1970 for part in xrepr(self.key, "default"):
1970 for part in xrepr(self.key, "default"):
1971 yield part
1971 yield part
1972 if self.reverse:
1972 if self.reverse:
1973 yield (astyle.style_default, ", ")
1973 yield (astyle.style_default, ", ")
1974 for part in xrepr(True, "default"):
1974 for part in xrepr(True, "default"):
1975 yield part
1975 yield part
1976 yield (astyle.style_default, ")")
1976 yield (astyle.style_default, ")")
1977 else:
1977 else:
1978 yield (astyle.style_default, repr(self))
1978 yield (astyle.style_default, repr(self))
1979
1979
1980 def __repr__(self):
1980 def __repr__(self):
1981 return "<%s.%s key=%r reverse=%r at 0x%x>" % \
1981 return "<%s.%s key=%r reverse=%r at 0x%x>" % \
1982 (self.__class__.__module__, self.__class__.__name__,
1982 (self.__class__.__module__, self.__class__.__name__,
1983 self.key, self.reverse, id(self))
1983 self.key, self.reverse, id(self))
1984
1984
1985
1985
1986 tab = 3 # for expandtabs()
1986 tab = 3 # for expandtabs()
1987
1987
1988 def _format(field):
1988 def _format(field):
1989 if isinstance(field, str):
1989 if isinstance(field, str):
1990 text = repr(field.expandtabs(tab))[1:-1]
1990 text = repr(field.expandtabs(tab))[1:-1]
1991 elif isinstance(field, unicode):
1991 elif isinstance(field, unicode):
1992 text = repr(field.expandtabs(tab))[2:-1]
1992 text = repr(field.expandtabs(tab))[2:-1]
1993 elif isinstance(field, datetime.datetime):
1993 elif isinstance(field, datetime.datetime):
1994 # Don't use strftime() here, as this requires year >= 1900
1994 # Don't use strftime() here, as this requires year >= 1900
1995 text = "%04d-%02d-%02d %02d:%02d:%02d.%06d" % \
1995 text = "%04d-%02d-%02d %02d:%02d:%02d.%06d" % \
1996 (field.year, field.month, field.day,
1996 (field.year, field.month, field.day,
1997 field.hour, field.minute, field.second, field.microsecond)
1997 field.hour, field.minute, field.second, field.microsecond)
1998 elif isinstance(field, datetime.date):
1998 elif isinstance(field, datetime.date):
1999 text = "%04d-%02d-%02d" % (field.year, field.month, field.day)
1999 text = "%04d-%02d-%02d" % (field.year, field.month, field.day)
2000 else:
2000 else:
2001 text = repr(field)
2001 text = repr(field)
2002 return text
2002 return text
2003
2003
2004
2004
2005 class Display(object):
2005 class Display(object):
2006 class __metaclass__(type):
2006 class __metaclass__(type):
2007 def __ror__(self, input):
2007 def __ror__(self, input):
2008 return input | self()
2008 return input | self()
2009
2009
2010 def __init__(self, input=None):
2010 def __init__(self, input=None):
2011 self.input = input
2011 self.input = input
2012
2012
2013 def __ror__(self, input):
2013 def __ror__(self, input):
2014 self.input = input
2014 self.input = input
2015 return self
2015 return self
2016
2016
2017 def display(self):
2017 def display(self):
2018 pass
2018 pass
2019
2019
2020
2020
2021 class iless(Display):
2021 class iless(Display):
2022 cmd = "less --quit-if-one-screen --LONG-PROMPT --LINE-NUMBERS --chop-long-lines --shift=8 --RAW-CONTROL-CHARS"
2022 cmd = "less --quit-if-one-screen --LONG-PROMPT --LINE-NUMBERS --chop-long-lines --shift=8 --RAW-CONTROL-CHARS"
2023
2023
2024 def display(self):
2024 def display(self):
2025 try:
2025 try:
2026 pager = os.popen(self.cmd, "w")
2026 pager = os.popen(self.cmd, "w")
2027 try:
2027 try:
2028 for item in xiter(self.input):
2028 for item in xiter(self.input):
2029 first = False
2029 first = False
2030 for attr in xattrs(item, "default"):
2030 for attr in xattrs(item, "default"):
2031 if first:
2031 if first:
2032 first = False
2032 first = False
2033 else:
2033 else:
2034 pager.write(" ")
2034 pager.write(" ")
2035 attr = upgradexattr(attr)
2035 attr = upgradexattr(attr)
2036 if not isinstance(attr, SelfDescriptor):
2036 if not isinstance(attr, SelfDescriptor):
2037 pager.write(attr.name())
2037 pager.write(attr.name())
2038 pager.write("=")
2038 pager.write("=")
2039 pager.write(str(attr.value(item)))
2039 pager.write(str(attr.value(item)))
2040 pager.write("\n")
2040 pager.write("\n")
2041 finally:
2041 finally:
2042 pager.close()
2042 pager.close()
2043 except Exception, exc:
2043 except Exception, exc:
2044 print "%s: %s" % (exc.__class__.__name__, str(exc))
2044 print "%s: %s" % (exc.__class__.__name__, str(exc))
2045
2045
2046
2046
2047 class _RedirectIO(object):
2047 class _RedirectIO(object):
2048 def __init__(self,*args,**kwargs):
2048 def __init__(self,*args,**kwargs):
2049 """
2049 """
2050 Map the system output streams to self.
2050 Map the system output streams to self.
2051 """
2051 """
2052 self.stream = StringIO.StringIO()
2052 self.stream = StringIO.StringIO()
2053 self.stdout = sys.stdout
2053 self.stdout = sys.stdout
2054 sys.stdout = self
2054 sys.stdout = self
2055 self.stderr = sys.stderr
2055 self.stderr = sys.stderr
2056 sys.stderr = self
2056 sys.stderr = self
2057
2057
2058 def write(self, text):
2058 def write(self, text):
2059 """
2059 """
2060 Write both to screen and to self.
2060 Write both to screen and to self.
2061 """
2061 """
2062 self.stream.write(text)
2062 self.stream.write(text)
2063 self.stdout.write(text)
2063 self.stdout.write(text)
2064 if "\n" in text:
2064 if "\n" in text:
2065 self.stdout.flush()
2065 self.stdout.flush()
2066
2066
2067 def writelines(self, lines):
2067 def writelines(self, lines):
2068 """
2068 """
2069 Write lines both to screen and to self.
2069 Write lines both to screen and to self.
2070 """
2070 """
2071 self.stream.writelines(lines)
2071 self.stream.writelines(lines)
2072 self.stdout.writelines(lines)
2072 self.stdout.writelines(lines)
2073 self.stdout.flush()
2073 self.stdout.flush()
2074
2074
2075 def restore(self):
2075 def restore(self):
2076 """
2076 """
2077 Restore the default system streams.
2077 Restore the default system streams.
2078 """
2078 """
2079 self.stdout.flush()
2079 self.stdout.flush()
2080 self.stderr.flush()
2080 self.stderr.flush()
2081 sys.stdout = self.stdout
2081 sys.stdout = self.stdout
2082 sys.stderr = self.stderr
2082 sys.stderr = self.stderr
2083
2083
2084
2084
2085 class icap(Table):
2085 class icap(Table):
2086 """
2086 """
2087 Execute a python string and capture any output to stderr/stdout.
2087 Execute a python string and capture any output to stderr/stdout.
2088
2088
2089 Examples::
2089 Examples::
2090
2090
2091 >>> import time
2091 >>> import time
2092 >>> icap("for i in range(10): print i, time.sleep(0.1)")
2092 >>> icap("for i in range(10): print i, time.sleep(0.1)")
2093
2093
2094 """
2094 """
2095 skip_doctest = True
2095 skip_doctest = True
2096
2096
2097 def __init__(self, expr, globals=None):
2097 def __init__(self, expr, globals=None):
2098 self.expr = expr
2098 self.expr = expr
2099 self.globals = globals
2099 self.globals = globals
2100 log = _RedirectIO()
2100 log = _RedirectIO()
2101 try:
2101 try:
2102 exec(expr, getglobals(globals))
2102 exec(expr, getglobals(globals))
2103 finally:
2103 finally:
2104 log.restore()
2104 log.restore()
2105 self.stream = log.stream
2105 self.stream = log.stream
2106
2106
2107 def __iter__(self):
2107 def __iter__(self):
2108 self.stream.seek(0)
2108 self.stream.seek(0)
2109 for line in self.stream:
2109 for line in self.stream:
2110 yield line.rstrip("\r\n")
2110 yield line.rstrip("\r\n")
2111
2111
2112 def __xrepr__(self, mode="default"):
2112 def __xrepr__(self, mode="default"):
2113 if mode == "header" or mode == "footer":
2113 if mode == "header" or mode == "footer":
2114 yield (astyle.style_default,
2114 yield (astyle.style_default,
2115 "%s(%r)" % (self.__class__.__name__, self.expr))
2115 "%s(%r)" % (self.__class__.__name__, self.expr))
2116 else:
2116 else:
2117 yield (astyle.style_default, repr(self))
2117 yield (astyle.style_default, repr(self))
2118
2118
2119 def __repr__(self):
2119 def __repr__(self):
2120 return "%s.%s(%r)" % \
2120 return "%s.%s(%r)" % \
2121 (self.__class__.__module__, self.__class__.__name__, self.expr)
2121 (self.__class__.__module__, self.__class__.__name__, self.expr)
2122
2122
2123
2123
2124 def xformat(value, mode, maxlength):
2124 def xformat(value, mode, maxlength):
2125 align = None
2125 align = None
2126 full = True
2126 full = True
2127 width = 0
2127 width = 0
2128 text = astyle.Text()
2128 text = astyle.Text()
2129 for (style, part) in xrepr(value, mode):
2129 for (style, part) in xrepr(value, mode):
2130 # only consider the first result
2130 # only consider the first result
2131 if align is None:
2131 if align is None:
2132 if isinstance(style, int):
2132 if isinstance(style, int):
2133 # (style, text) really is (alignment, stop)
2133 # (style, text) really is (alignment, stop)
2134 align = style
2134 align = style
2135 full = part
2135 full = part
2136 continue
2136 continue
2137 else:
2137 else:
2138 align = -1
2138 align = -1
2139 full = True
2139 full = True
2140 if not isinstance(style, int):
2140 if not isinstance(style, int):
2141 text.append((style, part))
2141 text.append((style, part))
2142 width += len(part)
2142 width += len(part)
2143 if width >= maxlength and not full:
2143 if width >= maxlength and not full:
2144 text.append((astyle.style_ellisis, "..."))
2144 text.append((astyle.style_ellisis, "..."))
2145 width += 3
2145 width += 3
2146 break
2146 break
2147 if align is None: # default to left alignment
2147 if align is None: # default to left alignment
2148 align = -1
2148 align = -1
2149 return (align, width, text)
2149 return (align, width, text)
2150
2150
2151
2151
2152
2152
2153 import astyle
2153 import astyle
2154
2154
2155 class idump(Display):
2155 class idump(Display):
2156 # The approximate maximum length of a column entry
2156 # The approximate maximum length of a column entry
2157 maxattrlength = 200
2157 maxattrlength = 200
2158
2158
2159 # Style for column names
2159 # Style for column names
2160 style_header = astyle.Style.fromstr("white:black:bold")
2160 style_header = astyle.Style.fromstr("white:black:bold")
2161
2161
2162 def __init__(self, input=None, *attrs):
2162 def __init__(self, input=None, *attrs):
2163 Display.__init__(self, input)
2163 Display.__init__(self, input)
2164 self.attrs = [upgradexattr(attr) for attr in attrs]
2164 self.attrs = [upgradexattr(attr) for attr in attrs]
2165 self.headerpadchar = " "
2165 self.headerpadchar = " "
2166 self.headersepchar = "|"
2166 self.headersepchar = "|"
2167 self.datapadchar = " "
2167 self.datapadchar = " "
2168 self.datasepchar = "|"
2168 self.datasepchar = "|"
2169
2169
2170 def display(self):
2170 def display(self):
2171 stream = genutils.Term.cout
2171 stream = genutils.Term.cout
2172 allattrs = []
2172 allattrs = []
2173 attrset = set()
2173 attrset = set()
2174 colwidths = {}
2174 colwidths = {}
2175 rows = []
2175 rows = []
2176 for item in xiter(self.input):
2176 for item in xiter(self.input):
2177 row = {}
2177 row = {}
2178 attrs = self.attrs
2178 attrs = self.attrs
2179 if not attrs:
2179 if not attrs:
2180 attrs = xattrs(item, "default")
2180 attrs = xattrs(item, "default")
2181 for attr in attrs:
2181 for attr in attrs:
2182 if attr not in attrset:
2182 if attr not in attrset:
2183 allattrs.append(attr)
2183 allattrs.append(attr)
2184 attrset.add(attr)
2184 attrset.add(attr)
2185 colwidths[attr] = len(attr.name())
2185 colwidths[attr] = len(attr.name())
2186 try:
2186 try:
2187 value = attr.value(item)
2187 value = attr.value(item)
2188 except (KeyboardInterrupt, SystemExit):
2188 except (KeyboardInterrupt, SystemExit):
2189 raise
2189 raise
2190 except Exception, exc:
2190 except Exception, exc:
2191 value = exc
2191 value = exc
2192 (align, width, text) = xformat(value, "cell", self.maxattrlength)
2192 (align, width, text) = xformat(value, "cell", self.maxattrlength)
2193 colwidths[attr] = max(colwidths[attr], width)
2193 colwidths[attr] = max(colwidths[attr], width)
2194 # remember alignment, length and colored parts
2194 # remember alignment, length and colored parts
2195 row[attr] = (align, width, text)
2195 row[attr] = (align, width, text)
2196 rows.append(row)
2196 rows.append(row)
2197
2197
2198 stream.write("\n")
2198 stream.write("\n")
2199 for (i, attr) in enumerate(allattrs):
2199 for (i, attr) in enumerate(allattrs):
2200 attrname = attr.name()
2200 attrname = attr.name()
2201 self.style_header(attrname).write(stream)
2201 self.style_header(attrname).write(stream)
2202 spc = colwidths[attr] - len(attrname)
2202 spc = colwidths[attr] - len(attrname)
2203 if i < len(colwidths)-1:
2203 if i < len(colwidths)-1:
2204 stream.write(self.headerpadchar*spc)
2204 stream.write(self.headerpadchar*spc)
2205 stream.write(self.headersepchar)
2205 stream.write(self.headersepchar)
2206 stream.write("\n")
2206 stream.write("\n")
2207
2207
2208 for row in rows:
2208 for row in rows:
2209 for (i, attr) in enumerate(allattrs):
2209 for (i, attr) in enumerate(allattrs):
2210 (align, width, text) = row[attr]
2210 (align, width, text) = row[attr]
2211 spc = colwidths[attr] - width
2211 spc = colwidths[attr] - width
2212 if align == -1:
2212 if align == -1:
2213 text.write(stream)
2213 text.write(stream)
2214 if i < len(colwidths)-1:
2214 if i < len(colwidths)-1:
2215 stream.write(self.datapadchar*spc)
2215 stream.write(self.datapadchar*spc)
2216 elif align == 0:
2216 elif align == 0:
2217 spc = colwidths[attr] - width
2217 spc = colwidths[attr] - width
2218 spc1 = spc//2
2218 spc1 = spc//2
2219 spc2 = spc-spc1
2219 spc2 = spc-spc1
2220 stream.write(self.datapadchar*spc1)
2220 stream.write(self.datapadchar*spc1)
2221 text.write(stream)
2221 text.write(stream)
2222 if i < len(colwidths)-1:
2222 if i < len(colwidths)-1:
2223 stream.write(self.datapadchar*spc2)
2223 stream.write(self.datapadchar*spc2)
2224 else:
2224 else:
2225 stream.write(self.datapadchar*spc)
2225 stream.write(self.datapadchar*spc)
2226 text.write(stream)
2226 text.write(stream)
2227 if i < len(colwidths)-1:
2227 if i < len(colwidths)-1:
2228 stream.write(self.datasepchar)
2228 stream.write(self.datasepchar)
2229 stream.write("\n")
2229 stream.write("\n")
2230
2230
2231
2231
2232 class AttributeDetail(Table):
2232 class AttributeDetail(Table):
2233 """
2233 """
2234 ``AttributeDetail`` objects are use for displaying a detailed list of object
2234 ``AttributeDetail`` objects are use for displaying a detailed list of object
2235 attributes.
2235 attributes.
2236 """
2236 """
2237 def __init__(self, object, descriptor):
2237 def __init__(self, object, descriptor):
2238 self.object = object
2238 self.object = object
2239 self.descriptor = descriptor
2239 self.descriptor = descriptor
2240
2240
2241 def __iter__(self):
2241 def __iter__(self):
2242 return self.descriptor.iter(self.object)
2242 return self.descriptor.iter(self.object)
2243
2243
2244 def name(self):
2244 def name(self):
2245 return self.descriptor.name()
2245 return self.descriptor.name()
2246
2246
2247 def attrtype(self):
2247 def attrtype(self):
2248 return self.descriptor.attrtype(self.object)
2248 return self.descriptor.attrtype(self.object)
2249
2249
2250 def valuetype(self):
2250 def valuetype(self):
2251 return self.descriptor.valuetype(self.object)
2251 return self.descriptor.valuetype(self.object)
2252
2252
2253 def doc(self):
2253 def doc(self):
2254 return self.descriptor.doc(self.object)
2254 return self.descriptor.doc(self.object)
2255
2255
2256 def shortdoc(self):
2256 def shortdoc(self):
2257 return self.descriptor.shortdoc(self.object)
2257 return self.descriptor.shortdoc(self.object)
2258
2258
2259 def value(self):
2259 def value(self):
2260 return self.descriptor.value(self.object)
2260 return self.descriptor.value(self.object)
2261
2261
2262 def __xattrs__(self, mode="default"):
2262 def __xattrs__(self, mode="default"):
2263 attrs = ("name()", "attrtype()", "valuetype()", "value()", "shortdoc()")
2263 attrs = ("name()", "attrtype()", "valuetype()", "value()", "shortdoc()")
2264 if mode == "detail":
2264 if mode == "detail":
2265 attrs += ("doc()",)
2265 attrs += ("doc()",)
2266 return attrs
2266 return attrs
2267
2267
2268 def __xrepr__(self, mode="default"):
2268 def __xrepr__(self, mode="default"):
2269 yield (-1, True)
2269 yield (-1, True)
2270 valuetype = self.valuetype()
2270 valuetype = self.valuetype()
2271 if valuetype is not noitem:
2271 if valuetype is not noitem:
2272 for part in xrepr(valuetype):
2272 for part in xrepr(valuetype):
2273 yield part
2273 yield part
2274 yield (astyle.style_default, " ")
2274 yield (astyle.style_default, " ")
2275 yield (astyle.style_default, self.attrtype())
2275 yield (astyle.style_default, self.attrtype())
2276 yield (astyle.style_default, " ")
2276 yield (astyle.style_default, " ")
2277 yield (astyle.style_default, self.name())
2277 yield (astyle.style_default, self.name())
2278 yield (astyle.style_default, " of ")
2278 yield (astyle.style_default, " of ")
2279 for part in xrepr(self.object):
2279 for part in xrepr(self.object):
2280 yield part
2280 yield part
2281
2281
2282
2282
2283 try:
2283 try:
2284 from ibrowse import ibrowse
2284 from ibrowse import ibrowse
2285 except ImportError:
2285 except ImportError:
2286 # No curses (probably Windows) => try igrid
2286 # No curses (probably Windows) => try igrid
2287 try:
2287 try:
2288 from igrid import igrid
2288 from igrid import igrid
2289 except ImportError:
2289 except ImportError:
2290 # no wx either => use ``idump`` as the default display.
2290 # no wx either => use ``idump`` as the default display.
2291 defaultdisplay = idump
2291 defaultdisplay = idump
2292 else:
2292 else:
2293 defaultdisplay = igrid
2293 defaultdisplay = igrid
2294 __all__.append("igrid")
2294 __all__.append("igrid")
2295 else:
2295 else:
2296 defaultdisplay = ibrowse
2296 defaultdisplay = ibrowse
2297 __all__.append("ibrowse")
2297 __all__.append("ibrowse")
2298
2298
2299
2299
2300 # If we're running under IPython, register our objects with IPython's
2300 # If we're running under IPython, register our objects with IPython's
2301 # generic function ``result_display``, else install a displayhook
2301 # generic function ``result_display``, else install a displayhook
2302 # directly as sys.displayhook
2302 # directly as sys.displayhook
2303 if generics is not None:
2303 if generics is not None:
2304 def display_display(obj):
2304 def display_display(obj):
2305 return obj.display()
2305 return obj.display()
2306 generics.result_display.when_type(Display)(display_display)
2306 generics.result_display.when_type(Display)(display_display)
2307
2307
2308 def display_tableobject(obj):
2308 def display_tableobject(obj):
2309 return display_display(defaultdisplay(obj))
2309 return display_display(defaultdisplay(obj))
2310 generics.result_display.when_type(Table)(display_tableobject)
2310 generics.result_display.when_type(Table)(display_tableobject)
2311
2311
2312 def display_tableclass(obj):
2312 def display_tableclass(obj):
2313 return display_tableobject(obj())
2313 return display_tableobject(obj())
2314 generics.result_display.when_type(Table.__metaclass__)(display_tableclass)
2314 generics.result_display.when_type(Table.__metaclass__)(display_tableclass)
2315 else:
2315 else:
2316 def installdisplayhook():
2316 def installdisplayhook():
2317 _originalhook = sys.displayhook
2317 _originalhook = sys.displayhook
2318 def displayhook(obj):
2318 def displayhook(obj):
2319 if isinstance(obj, type) and issubclass(obj, Table):
2319 if isinstance(obj, type) and issubclass(obj, Table):
2320 obj = obj()
2320 obj = obj()
2321 if isinstance(obj, Table):
2321 if isinstance(obj, Table):
2322 obj = defaultdisplay(obj)
2322 obj = defaultdisplay(obj)
2323 if isinstance(obj, Display):
2323 if isinstance(obj, Display):
2324 return obj.display()
2324 return obj.display()
2325 else:
2325 else:
2326 _originalhook(obj)
2326 _originalhook(obj)
2327 sys.displayhook = displayhook
2327 sys.displayhook = displayhook
2328 installdisplayhook()
2328 installdisplayhook()
@@ -1,271 +1,271 b''
1 """Shell mode for IPython.
1 """Shell mode for IPython.
2
2
3 Start ipython in shell mode by invoking "ipython -p sh"
3 Start ipython in shell mode by invoking "ipython -p sh"
4
4
5 (the old version, "ipython -p pysh" still works but this is the more "modern"
5 (the old version, "ipython -p pysh" still works but this is the more "modern"
6 shell mode and is recommended for users who don't care about pysh-mode
6 shell mode and is recommended for users who don't care about pysh-mode
7 compatibility)
7 compatibility)
8 """
8 """
9
9
10 from IPython.core import ipapi
10 from IPython.core import ipapi
11 from IPython.core.error import TryNext
11 from IPython.core.error import TryNext
12 import os,re,textwrap
12 import os,re,textwrap
13
13
14 # The import below effectively obsoletes your old-style ipythonrc[.ini],
14 # The import below effectively obsoletes your old-style ipythonrc[.ini],
15 # so consider yourself warned!
15 # so consider yourself warned!
16
16
17 import ipy_defaults
17 import ipy_defaults
18
18
19 def main():
19 def main():
20 ip = ipapi.get()
20 ip = ipapi.get()
21 o = ip.options
21 o = ip.options
22 # autocall to "full" mode (smart mode is default, I like full mode)
22 # autocall to "full" mode (smart mode is default, I like full mode)
23
23
24 o.autocall = 2
24 o.autocall = 2
25
25
26 # Jason Orendorff's path class is handy to have in user namespace
26 # Jason Orendorff's path class is handy to have in user namespace
27 # if you are doing shell-like stuff
27 # if you are doing shell-like stuff
28 try:
28 try:
29 ip.ex("from IPython.external.path import path" )
29 ip.ex("from IPython.external.path import path" )
30 except ImportError:
30 except ImportError:
31 pass
31 pass
32
32
33 # beefed up %env is handy in shell mode
33 # beefed up %env is handy in shell mode
34 import envpersist
34 import envpersist
35
35
36 # To see where mycmd resides (in path/aliases), do %which mycmd
36 # To see where mycmd resides (in path/aliases), do %which mycmd
37 import ipy_which
37 import ipy_which
38
38
39 # tab completers for hg, svn, ...
39 # tab completers for hg, svn, ...
40 import ipy_app_completers
40 import ipy_app_completers
41
41
42 # To make executables foo and bar in mybin usable without PATH change, do:
42 # To make executables foo and bar in mybin usable without PATH change, do:
43 # %rehashdir c:/mybin
43 # %rehashdir c:/mybin
44 # %store foo
44 # %store foo
45 # %store bar
45 # %store bar
46 import ipy_rehashdir
46 import ipy_rehashdir
47
47
48 # does not work without subprocess module!
48 # does not work without subprocess module!
49 #import ipy_signals
49 #import ipy_signals
50
50
51 ip.ex('import os')
51 ip.ex('import os')
52 ip.ex("def up(): os.chdir('..')")
52 ip.ex("def up(): os.chdir('..')")
53 ip.user_ns['LA'] = LastArgFinder()
53 ip.user_ns['LA'] = LastArgFinder()
54
54
55 # You can assign to _prompt_title variable
55 # You can assign to _prompt_title variable
56 # to provide some extra information for prompt
56 # to provide some extra information for prompt
57 # (e.g. the current mode, host/username...)
57 # (e.g. the current mode, host/username...)
58
58
59 ip.user_ns['_prompt_title'] = ''
59 ip.user_ns['_prompt_title'] = ''
60
60
61 # Nice prompt
61 # Nice prompt
62 o.prompt_in1= r'\C_Green${_prompt_title}\C_LightBlue[\C_LightCyan\Y2\C_LightBlue]\C_Green|\#> '
62 o.prompt_in1= r'\C_Green${_prompt_title}\C_LightBlue[\C_LightCyan\Y2\C_LightBlue]\C_Green|\#> '
63 o.prompt_in2= r'\C_Green|\C_LightGreen\D\C_Green> '
63 o.prompt_in2= r'\C_Green|\C_LightGreen\D\C_Green> '
64 o.prompt_out= '<\#> '
64 o.prompt_out= '<\#> '
65
65
66 from IPython.core import release
66 from IPython.core import release
67
67
68 import sys
68 import sys
69 # Non-chatty banner
69 # Non-chatty banner
70 o.banner = "IPython %s [on Py %s]\n" % (release.version,sys.version.split(None,1)[0])
70 o.banner = "IPython %s [on Py %s]\n" % (release.version,sys.version.split(None,1)[0])
71
71
72
72
73 ip.default_option('cd','-q')
73 ip.default_option('cd','-q')
74 ip.default_option('macro', '-r')
74 ip.default_option('macro', '-r')
75 # If you only rarely want to execute the things you %edit...
75 # If you only rarely want to execute the things you %edit...
76 #ip.default_option('edit','-x')
76 #ip.default_option('edit','-x')
77
77
78
78
79 o.prompts_pad_left="1"
79 o.prompts_pad_left="1"
80 # Remove all blank lines in between prompts, like a normal shell.
80 # Remove all blank lines in between prompts, like a normal shell.
81 o.separate_in="0"
81 o.separate_in="0"
82 o.separate_out="0"
82 o.separate_out="0"
83 o.separate_out2="0"
83 o.separate_out2="0"
84
84
85 # now alias all syscommands
85 # now alias all syscommands
86
86
87 db = ip.db
87 db = ip.db
88
88
89 syscmds = db.get("syscmdlist",[] )
89 syscmds = db.get("syscmdlist",[] )
90 if not syscmds:
90 if not syscmds:
91 print textwrap.dedent("""
91 print textwrap.dedent("""
92 System command list not initialized, probably the first run...
92 System command list not initialized, probably the first run...
93 running %rehashx to refresh the command list. Run %rehashx
93 running %rehashx to refresh the command list. Run %rehashx
94 again to refresh command list (after installing new software etc.)
94 again to refresh command list (after installing new software etc.)
95 """)
95 """)
96 ip.magic('rehashx')
96 ip.magic('rehashx')
97 syscmds = db.get("syscmdlist")
97 syscmds = db.get("syscmdlist")
98
98
99 # lowcase aliases on win32 only
99 # lowcase aliases on win32 only
100 if os.name == 'posix':
100 if os.name == 'posix':
101 mapper = lambda s:s
101 mapper = lambda s:s
102 else:
102 else:
103 def mapper(s): return s.lower()
103 def mapper(s): return s.lower()
104
104
105 for cmd in syscmds:
105 for cmd in syscmds:
106 # print "sys",cmd #dbg
106 # print "sys",cmd #dbg
107 noext, ext = os.path.splitext(cmd)
107 noext, ext = os.path.splitext(cmd)
108 if ext.lower() == '.exe':
108 if ext.lower() == '.exe':
109 cmd = noext
109 cmd = noext
110
110
111 key = mapper(cmd)
111 key = mapper(cmd)
112 if key not in ip.alias_table:
112 if key not in ip.alias_manager.alias_table:
113 # Dots will be removed from alias names, since ipython
113 # Dots will be removed from alias names, since ipython
114 # assumes names with dots to be python code
114 # assumes names with dots to be python code
115
115
116 ip.define_alias(key.replace('.',''), cmd)
116 ip.define_alias(key.replace('.',''), cmd)
117
117
118 # mglob combines 'find', recursion, exclusion... '%mglob?' to learn more
118 # mglob combines 'find', recursion, exclusion... '%mglob?' to learn more
119 ip.load("IPython.external.mglob")
119 ip.load("IPython.external.mglob")
120
120
121 # win32 is crippled w/o cygwin, try to help it a little bit
121 # win32 is crippled w/o cygwin, try to help it a little bit
122 if sys.platform == 'win32':
122 if sys.platform == 'win32':
123 if 'cygwin' in os.environ['PATH'].lower():
123 if 'cygwin' in os.environ['PATH'].lower():
124 # use the colors of cygwin ls (recommended)
124 # use the colors of cygwin ls (recommended)
125 ip.define_alias('d', 'ls -F --color=auto')
125 ip.define_alias('d', 'ls -F --color=auto')
126 else:
126 else:
127 # get icp, imv, imkdir, igrep, irm,...
127 # get icp, imv, imkdir, igrep, irm,...
128 ip.load('ipy_fsops')
128 ip.load('ipy_fsops')
129
129
130 # and the next best thing to real 'ls -F'
130 # and the next best thing to real 'ls -F'
131 ip.define_alias('d','dir /w /og /on')
131 ip.define_alias('d','dir /w /og /on')
132
132
133 ip.set_hook('input_prefilter', slash_prefilter_f)
133 ip.set_hook('input_prefilter', slash_prefilter_f)
134 extend_shell_behavior(ip)
134 extend_shell_behavior(ip)
135
135
136 class LastArgFinder:
136 class LastArgFinder:
137 """ Allow $LA to work as "last argument of previous command", like $! in bash
137 """ Allow $LA to work as "last argument of previous command", like $! in bash
138
138
139 To call this in normal IPython code, do LA()
139 To call this in normal IPython code, do LA()
140 """
140 """
141 def __call__(self, hist_idx = None):
141 def __call__(self, hist_idx = None):
142 ip = ipapi.get()
142 ip = ipapi.get()
143 if hist_idx is None:
143 if hist_idx is None:
144 return str(self)
144 return str(self)
145 return ip.input_hist_raw[hist_idx].strip().split()[-1]
145 return ip.input_hist_raw[hist_idx].strip().split()[-1]
146 def __str__(self):
146 def __str__(self):
147 ip = ipapi.get()
147 ip = ipapi.get()
148 for cmd in reversed(ip.input_hist_raw):
148 for cmd in reversed(ip.input_hist_raw):
149 parts = cmd.strip().split()
149 parts = cmd.strip().split()
150 if len(parts) < 2 or parts[-1] in ['$LA', 'LA()']:
150 if len(parts) < 2 or parts[-1] in ['$LA', 'LA()']:
151 continue
151 continue
152 return parts[-1]
152 return parts[-1]
153 return ""
153 return ""
154
154
155 def slash_prefilter_f(self,line):
155 def slash_prefilter_f(self,line):
156 """ ./foo, ~/foo and /bin/foo now run foo as system command
156 """ ./foo, ~/foo and /bin/foo now run foo as system command
157
157
158 Removes the need for doing !./foo, !~/foo or !/bin/foo
158 Removes the need for doing !./foo, !~/foo or !/bin/foo
159 """
159 """
160 from IPython.utils import genutils
160 from IPython.utils import genutils
161 if re.match('(?:[.~]|/[a-zA-Z_0-9]+)/', line):
161 if re.match('(?:[.~]|/[a-zA-Z_0-9]+)/', line):
162 return "_ip.system(" + genutils.make_quoted_expr(line)+")"
162 return "get_ipython().system(" + genutils.make_quoted_expr(line)+")"
163 raise TryNext
163 raise TryNext
164
164
165 # XXX You do not need to understand the next function!
165 # XXX You do not need to understand the next function!
166 # This should probably be moved out of profile
166 # This should probably be moved out of profile
167
167
168 def extend_shell_behavior(ip):
168 def extend_shell_behavior(ip):
169
169
170 # Instead of making signature a global variable tie it to IPSHELL.
170 # Instead of making signature a global variable tie it to IPSHELL.
171 # In future if it is required to distinguish between different
171 # In future if it is required to distinguish between different
172 # shells we can assign a signature per shell basis
172 # shells we can assign a signature per shell basis
173 ip.__sig__ = 0xa005
173 ip.__sig__ = 0xa005
174 # mark the IPSHELL with this signature
174 # mark the IPSHELL with this signature
175 ip.user_ns['__builtins__'].__dict__['__sig__'] = ip.__sig__
175 ip.user_ns['__builtins__'].__dict__['__sig__'] = ip.__sig__
176
176
177 from IPython.external.Itpl import ItplNS
177 from IPython.external.Itpl import ItplNS
178 from IPython.utils.genutils import shell
178 from IPython.utils.genutils import shell
179 # utility to expand user variables via Itpl
179 # utility to expand user variables via Itpl
180 # xxx do something sensible with depth?
180 # xxx do something sensible with depth?
181 ip.var_expand = lambda cmd, lvars=None, depth=2: \
181 ip.var_expand = lambda cmd, lvars=None, depth=2: \
182 str(ItplNS(cmd, ip.user_ns, get_locals()))
182 str(ItplNS(cmd, ip.user_ns, get_locals()))
183
183
184 def get_locals():
184 def get_locals():
185 """ Substituting a variable through Itpl deep inside the IPSHELL stack
185 """ Substituting a variable through Itpl deep inside the IPSHELL stack
186 requires the knowledge of all the variables in scope upto the last
186 requires the knowledge of all the variables in scope upto the last
187 IPSHELL frame. This routine simply merges all the local variables
187 IPSHELL frame. This routine simply merges all the local variables
188 on the IPSHELL stack without worrying about their scope rules
188 on the IPSHELL stack without worrying about their scope rules
189 """
189 """
190 import sys
190 import sys
191 # note lambda expression constitues a function call
191 # note lambda expression constitues a function call
192 # hence fno should be incremented by one
192 # hence fno should be incremented by one
193 getsig = lambda fno: sys._getframe(fno+1).f_globals \
193 getsig = lambda fno: sys._getframe(fno+1).f_globals \
194 ['__builtins__'].__dict__['__sig__']
194 ['__builtins__'].__dict__['__sig__']
195 getlvars = lambda fno: sys._getframe(fno+1).f_locals
195 getlvars = lambda fno: sys._getframe(fno+1).f_locals
196 # trackback until we enter the IPSHELL
196 # trackback until we enter the IPSHELL
197 frame_no = 1
197 frame_no = 1
198 sig = ip.__sig__
198 sig = ip.__sig__
199 fsig = ~sig
199 fsig = ~sig
200 while fsig != sig :
200 while fsig != sig :
201 try:
201 try:
202 fsig = getsig(frame_no)
202 fsig = getsig(frame_no)
203 except (AttributeError, KeyError):
203 except (AttributeError, KeyError):
204 frame_no += 1
204 frame_no += 1
205 except ValueError:
205 except ValueError:
206 # stack is depleted
206 # stack is depleted
207 # call did not originate from IPSHELL
207 # call did not originate from IPSHELL
208 return {}
208 return {}
209 first_frame = frame_no
209 first_frame = frame_no
210 # walk further back until we exit from IPSHELL or deplete stack
210 # walk further back until we exit from IPSHELL or deplete stack
211 try:
211 try:
212 while(sig == getsig(frame_no+1)):
212 while(sig == getsig(frame_no+1)):
213 frame_no += 1
213 frame_no += 1
214 except (AttributeError, KeyError, ValueError):
214 except (AttributeError, KeyError, ValueError):
215 pass
215 pass
216 # merge the locals from top down hence overriding
216 # merge the locals from top down hence overriding
217 # any re-definitions of variables, functions etc.
217 # any re-definitions of variables, functions etc.
218 lvars = {}
218 lvars = {}
219 for fno in range(frame_no, first_frame-1, -1):
219 for fno in range(frame_no, first_frame-1, -1):
220 lvars.update(getlvars(fno))
220 lvars.update(getlvars(fno))
221 #print '\n'*5, first_frame, frame_no, '\n', lvars, '\n'*5 #dbg
221 #print '\n'*5, first_frame, frame_no, '\n', lvars, '\n'*5 #dbg
222 return lvars
222 return lvars
223
223
224 def _runlines(lines):
224 def _runlines(lines):
225 """Run a string of one or more lines of source.
225 """Run a string of one or more lines of source.
226
226
227 This method is capable of running a string containing multiple source
227 This method is capable of running a string containing multiple source
228 lines, as if they had been entered at the IPython prompt. Since it
228 lines, as if they had been entered at the IPython prompt. Since it
229 exposes IPython's processing machinery, the given strings can contain
229 exposes IPython's processing machinery, the given strings can contain
230 magic calls (%magic), special shell access (!cmd), etc."""
230 magic calls (%magic), special shell access (!cmd), etc."""
231
231
232 # We must start with a clean buffer, in case this is run from an
232 # We must start with a clean buffer, in case this is run from an
233 # interactive IPython session (via a magic, for example).
233 # interactive IPython session (via a magic, for example).
234 ip.resetbuffer()
234 ip.resetbuffer()
235 lines = lines.split('\n')
235 lines = lines.split('\n')
236 more = 0
236 more = 0
237 command = ''
237 command = ''
238 for line in lines:
238 for line in lines:
239 # skip blank lines so we don't mess up the prompt counter, but do
239 # skip blank lines so we don't mess up the prompt counter, but do
240 # NOT skip even a blank line if we are in a code block (more is
240 # NOT skip even a blank line if we are in a code block (more is
241 # true)
241 # true)
242 # if command is not empty trim the line
242 # if command is not empty trim the line
243 if command != '' :
243 if command != '' :
244 line = line.strip()
244 line = line.strip()
245 # add the broken line to the command
245 # add the broken line to the command
246 if line and line[-1] == '\\' :
246 if line and line[-1] == '\\' :
247 command += line[0:-1] + ' '
247 command += line[0:-1] + ' '
248 more = True
248 more = True
249 continue
249 continue
250 else :
250 else :
251 # add the last (current) line to the command
251 # add the last (current) line to the command
252 command += line
252 command += line
253 if command or more:
253 if command or more:
254 # push to raw history, so hist line numbers stay in sync
254 # push to raw history, so hist line numbers stay in sync
255 ip.input_hist_raw.append("# " + command + "\n")
255 ip.input_hist_raw.append("# " + command + "\n")
256
256
257 more = ip.push_line(ip.prefilter(command,more))
257 more = ip.push_line(ip.prefilter(command,more))
258 command = ''
258 command = ''
259 # IPython's runsource returns None if there was an error
259 # IPython's runsource returns None if there was an error
260 # compiling the code. This allows us to stop processing right
260 # compiling the code. This allows us to stop processing right
261 # away, so the user gets the error message at the right place.
261 # away, so the user gets the error message at the right place.
262 if more is None:
262 if more is None:
263 break
263 break
264 # final newline in case the input didn't have it, so that the code
264 # final newline in case the input didn't have it, so that the code
265 # actually does get executed
265 # actually does get executed
266 if more:
266 if more:
267 ip.push_line('\n')
267 ip.push_line('\n')
268
268
269 ip.runlines = _runlines
269 ip.runlines = _runlines
270
270
271 main()
271 main()
@@ -1,140 +1,140 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """ IPython extension: add %rehashdir magic
2 """ IPython extension: add %rehashdir magic
3
3
4 Usage:
4 Usage:
5
5
6 %rehashdir c:/bin c:/tools
6 %rehashdir c:/bin c:/tools
7 - Add all executables under c:/bin and c:/tools to alias table, in
7 - Add all executables under c:/bin and c:/tools to alias table, in
8 order to make them directly executable from any directory.
8 order to make them directly executable from any directory.
9
9
10 This also serves as an example on how to extend ipython
10 This also serves as an example on how to extend ipython
11 with new magic functions.
11 with new magic functions.
12
12
13 Unlike rest of ipython, this requires Python 2.4 (optional
13 Unlike rest of ipython, this requires Python 2.4 (optional
14 extensions are allowed to do that).
14 extensions are allowed to do that).
15
15
16 """
16 """
17
17
18 from IPython.core import ipapi
18 from IPython.core import ipapi
19 ip = ipapi.get()
19 ip = ipapi.get()
20
20
21
21
22 import os,re,fnmatch,sys
22 import os,re,fnmatch,sys
23
23
24 def selflaunch(ip,line):
24 def selflaunch(ip,line):
25 """ Launch python script with 'this' interpreter
25 """ Launch python script with 'this' interpreter
26
26
27 e.g. d:\foo\ipykit.exe a.py
27 e.g. d:\foo\ipykit.exe a.py
28
28
29 """
29 """
30
30
31 tup = line.split(None,1)
31 tup = line.split(None,1)
32 if len(tup) == 1:
32 if len(tup) == 1:
33 print "Launching nested ipython session"
33 print "Launching nested ipython session"
34 os.system(sys.executable)
34 os.system(sys.executable)
35 return
35 return
36
36
37 cmd = sys.executable + ' ' + tup[1]
37 cmd = sys.executable + ' ' + tup[1]
38 print ">",cmd
38 print ">",cmd
39 os.system(cmd)
39 os.system(cmd)
40
40
41 class PyLauncher:
41 class PyLauncher:
42 """ Invoke selflanucher on the specified script
42 """ Invoke selflanucher on the specified script
43
43
44 This is mostly useful for associating with scripts using::
44 This is mostly useful for associating with scripts using::
45 _ip.define_alias('foo',PyLauncher('foo_script.py'))
45 _ip.define_alias('foo',PyLauncher('foo_script.py'))
46
46
47 """
47 """
48 def __init__(self,script):
48 def __init__(self,script):
49 self.script = os.path.abspath(script)
49 self.script = os.path.abspath(script)
50 def __call__(self, ip, line):
50 def __call__(self, ip, line):
51 if self.script.endswith('.ipy'):
51 if self.script.endswith('.ipy'):
52 ip.runlines(open(self.script).read())
52 ip.runlines(open(self.script).read())
53 else:
53 else:
54 # first word is the script/alias name itself, strip it
54 # first word is the script/alias name itself, strip it
55 tup = line.split(None,1)
55 tup = line.split(None,1)
56 if len(tup) == 2:
56 if len(tup) == 2:
57 tail = ' ' + tup[1]
57 tail = ' ' + tup[1]
58 else:
58 else:
59 tail = ''
59 tail = ''
60
60
61 selflaunch(ip,"py " + self.script + tail)
61 selflaunch(ip,"py " + self.script + tail)
62 def __repr__(self):
62 def __repr__(self):
63 return 'PyLauncher("%s")' % self.script
63 return 'PyLauncher("%s")' % self.script
64
64
65 def rehashdir_f(self,arg):
65 def rehashdir_f(self,arg):
66 """ Add executables in all specified dirs to alias table
66 """ Add executables in all specified dirs to alias table
67
67
68 Usage:
68 Usage:
69
69
70 %rehashdir c:/bin;c:/tools
70 %rehashdir c:/bin;c:/tools
71 - Add all executables under c:/bin and c:/tools to alias table, in
71 - Add all executables under c:/bin and c:/tools to alias table, in
72 order to make them directly executable from any directory.
72 order to make them directly executable from any directory.
73
73
74 Without arguments, add all executables in current directory.
74 Without arguments, add all executables in current directory.
75
75
76 """
76 """
77
77
78 # most of the code copied from Magic.magic_rehashx
78 # most of the code copied from Magic.magic_rehashx
79
79
80 def isjunk(fname):
80 def isjunk(fname):
81 junk = ['*~']
81 junk = ['*~']
82 for j in junk:
82 for j in junk:
83 if fnmatch.fnmatch(fname, j):
83 if fnmatch.fnmatch(fname, j):
84 return True
84 return True
85 return False
85 return False
86
86
87 created = []
87 created = []
88 if not arg:
88 if not arg:
89 arg = '.'
89 arg = '.'
90 path = map(os.path.abspath,arg.split(';'))
90 path = map(os.path.abspath,arg.split(';'))
91 alias_table = self.shell.alias_table
91 alias_table = self.shell.alias_manager.alias_table
92
92
93 if os.name == 'posix':
93 if os.name == 'posix':
94 isexec = lambda fname:os.path.isfile(fname) and \
94 isexec = lambda fname:os.path.isfile(fname) and \
95 os.access(fname,os.X_OK)
95 os.access(fname,os.X_OK)
96 else:
96 else:
97
97
98 try:
98 try:
99 winext = os.environ['pathext'].replace(';','|').replace('.','')
99 winext = os.environ['pathext'].replace(';','|').replace('.','')
100 except KeyError:
100 except KeyError:
101 winext = 'exe|com|bat|py'
101 winext = 'exe|com|bat|py'
102 if 'py' not in winext:
102 if 'py' not in winext:
103 winext += '|py'
103 winext += '|py'
104
104
105 execre = re.compile(r'(.*)\.(%s)$' % winext,re.IGNORECASE)
105 execre = re.compile(r'(.*)\.(%s)$' % winext,re.IGNORECASE)
106 isexec = lambda fname:os.path.isfile(fname) and execre.match(fname)
106 isexec = lambda fname:os.path.isfile(fname) and execre.match(fname)
107 savedir = os.getcwd()
107 savedir = os.getcwd()
108 try:
108 try:
109 # write the whole loop for posix/Windows so we don't have an if in
109 # write the whole loop for posix/Windows so we don't have an if in
110 # the innermost part
110 # the innermost part
111 if os.name == 'posix':
111 if os.name == 'posix':
112 for pdir in path:
112 for pdir in path:
113 os.chdir(pdir)
113 os.chdir(pdir)
114 for ff in os.listdir(pdir):
114 for ff in os.listdir(pdir):
115 if isexec(ff) and not isjunk(ff):
115 if isexec(ff) and not isjunk(ff):
116 # each entry in the alias table must be (N,name),
116 # each entry in the alias table must be (N,name),
117 # where N is the number of positional arguments of the
117 # where N is the number of positional arguments of the
118 # alias.
118 # alias.
119 src,tgt = os.path.splitext(ff)[0], os.path.abspath(ff)
119 src,tgt = os.path.splitext(ff)[0], os.path.abspath(ff)
120 created.append(src)
120 created.append(src)
121 alias_table[src] = (0,tgt)
121 alias_table[src] = (0,tgt)
122 else:
122 else:
123 for pdir in path:
123 for pdir in path:
124 os.chdir(pdir)
124 os.chdir(pdir)
125 for ff in os.listdir(pdir):
125 for ff in os.listdir(pdir):
126 if isexec(ff) and not isjunk(ff):
126 if isexec(ff) and not isjunk(ff):
127 src, tgt = execre.sub(r'\1',ff), os.path.abspath(ff)
127 src, tgt = execre.sub(r'\1',ff), os.path.abspath(ff)
128 src = src.lower()
128 src = src.lower()
129 created.append(src)
129 created.append(src)
130 alias_table[src] = (0,tgt)
130 alias_table[src] = (0,tgt)
131 # Make sure the alias table doesn't contain keywords or builtins
131 # Make sure the alias table doesn't contain keywords or builtins
132 self.shell.alias_table_validate()
132 self.shell.alias_table_validate()
133 # Call again init_auto_alias() so we get 'rm -i' and other
133 # Call again init_auto_alias() so we get 'rm -i' and other
134 # modified aliases since %rehashx will probably clobber them
134 # modified aliases since %rehashx will probably clobber them
135 # self.shell.init_auto_alias()
135 # self.shell.init_auto_alias()
136 finally:
136 finally:
137 os.chdir(savedir)
137 os.chdir(savedir)
138 return created
138 return created
139
139
140 ip.define_magic("rehashdir",rehashdir_f)
140 ip.define_magic("rehashdir",rehashdir_f)
@@ -1,243 +1,243 b''
1 """ Preliminary "job control" extensions for IPython
1 """ Preliminary "job control" extensions for IPython
2
2
3 requires python 2.4 (or separate 'subprocess' module
3 requires python 2.4 (or separate 'subprocess' module
4
4
5 This provides 2 features, launching background jobs and killing foreground jobs from another IPython instance.
5 This provides 2 features, launching background jobs and killing foreground jobs from another IPython instance.
6
6
7 Launching background jobs:
7 Launching background jobs:
8
8
9 Usage:
9 Usage:
10
10
11 [ipython]|2> import jobctrl
11 [ipython]|2> import jobctrl
12 [ipython]|3> &ls
12 [ipython]|3> &ls
13 <3> <jobctrl.IpyPopen object at 0x00D87FD0>
13 <3> <jobctrl.IpyPopen object at 0x00D87FD0>
14 [ipython]|4> _3.go
14 [ipython]|4> _3.go
15 -----------> _3.go()
15 -----------> _3.go()
16 ChangeLog
16 ChangeLog
17 IPython
17 IPython
18 MANIFEST.in
18 MANIFEST.in
19 README
19 README
20 README_Windows.txt
20 README_Windows.txt
21
21
22 ...
22 ...
23
23
24 Killing foreground tasks:
24 Killing foreground tasks:
25
25
26 Launch IPython instance, run a blocking command:
26 Launch IPython instance, run a blocking command:
27
27
28 [Q:/ipython]|1> import jobctrl
28 [Q:/ipython]|1> import jobctrl
29 [Q:/ipython]|2> cat
29 [Q:/ipython]|2> cat
30
30
31 Now launch a new IPython prompt and kill the process:
31 Now launch a new IPython prompt and kill the process:
32
32
33 IPython 0.8.3.svn.r2919 [on Py 2.5]
33 IPython 0.8.3.svn.r2919 [on Py 2.5]
34 [Q:/ipython]|1> import jobctrl
34 [Q:/ipython]|1> import jobctrl
35 [Q:/ipython]|2> %tasks
35 [Q:/ipython]|2> %tasks
36 6020: 'cat ' (Q:\ipython)
36 6020: 'cat ' (Q:\ipython)
37 [Q:/ipython]|3> %kill
37 [Q:/ipython]|3> %kill
38 SUCCESS: The process with PID 6020 has been terminated.
38 SUCCESS: The process with PID 6020 has been terminated.
39 [Q:/ipython]|4>
39 [Q:/ipython]|4>
40
40
41 (you don't need to specify PID for %kill if only one task is running)
41 (you don't need to specify PID for %kill if only one task is running)
42 """
42 """
43
43
44 from subprocess import *
44 from subprocess import *
45 import os,shlex,sys,time
45 import os,shlex,sys,time
46 import threading,Queue
46 import threading,Queue
47
47
48 from IPython.utils import genutils
48 from IPython.utils import genutils
49
49
50 from IPython.core import ipapi
50 from IPython.core import ipapi
51 from IPython.core.error import TryNext
51 from IPython.core.error import TryNext
52
52
53 if os.name == 'nt':
53 if os.name == 'nt':
54 def kill_process(pid):
54 def kill_process(pid):
55 os.system('taskkill /F /PID %d' % pid)
55 os.system('taskkill /F /PID %d' % pid)
56 else:
56 else:
57 def kill_process(pid):
57 def kill_process(pid):
58 os.system('kill -9 %d' % pid)
58 os.system('kill -9 %d' % pid)
59
59
60
60
61
61
62 class IpyPopen(Popen):
62 class IpyPopen(Popen):
63 def go(self):
63 def go(self):
64 print self.communicate()[0]
64 print self.communicate()[0]
65 def __repr__(self):
65 def __repr__(self):
66 return '<IPython job "%s" PID=%d>' % (self.line, self.pid)
66 return '<IPython job "%s" PID=%d>' % (self.line, self.pid)
67
67
68 def kill(self):
68 def kill(self):
69 kill_process(self.pid)
69 kill_process(self.pid)
70
70
71 def startjob(job):
71 def startjob(job):
72 p = IpyPopen(shlex.split(job), stdout=PIPE, shell = False)
72 p = IpyPopen(shlex.split(job), stdout=PIPE, shell = False)
73 p.line = job
73 p.line = job
74 return p
74 return p
75
75
76 class AsyncJobQ(threading.Thread):
76 class AsyncJobQ(threading.Thread):
77 def __init__(self):
77 def __init__(self):
78 threading.Thread.__init__(self)
78 threading.Thread.__init__(self)
79 self.q = Queue.Queue()
79 self.q = Queue.Queue()
80 self.output = []
80 self.output = []
81 self.stop = False
81 self.stop = False
82 def run(self):
82 def run(self):
83 while 1:
83 while 1:
84 cmd,cwd = self.q.get()
84 cmd,cwd = self.q.get()
85 if self.stop:
85 if self.stop:
86 self.output.append("** Discarding: '%s' - %s" % (cmd,cwd))
86 self.output.append("** Discarding: '%s' - %s" % (cmd,cwd))
87 continue
87 continue
88 self.output.append("** Task started: '%s' - %s" % (cmd,cwd))
88 self.output.append("** Task started: '%s' - %s" % (cmd,cwd))
89
89
90 p = Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT, cwd = cwd)
90 p = Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT, cwd = cwd)
91 out = p.stdout.read()
91 out = p.stdout.read()
92 self.output.append("** Task complete: '%s'\n" % cmd)
92 self.output.append("** Task complete: '%s'\n" % cmd)
93 self.output.append(out)
93 self.output.append(out)
94
94
95 def add(self,cmd):
95 def add(self,cmd):
96 self.q.put_nowait((cmd, os.getcwd()))
96 self.q.put_nowait((cmd, os.getcwd()))
97
97
98 def dumpoutput(self):
98 def dumpoutput(self):
99 while self.output:
99 while self.output:
100 item = self.output.pop(0)
100 item = self.output.pop(0)
101 print item
101 print item
102
102
103 _jobq = None
103 _jobq = None
104
104
105 def jobqueue_f(self, line):
105 def jobqueue_f(self, line):
106
106
107 global _jobq
107 global _jobq
108 if not _jobq:
108 if not _jobq:
109 print "Starting jobqueue - do '&some_long_lasting_system_command' to enqueue"
109 print "Starting jobqueue - do '&some_long_lasting_system_command' to enqueue"
110 _jobq = AsyncJobQ()
110 _jobq = AsyncJobQ()
111 _jobq.setDaemon(True)
111 _jobq.setDaemon(True)
112 _jobq.start()
112 _jobq.start()
113 ip.jobq = _jobq.add
113 ip.jobq = _jobq.add
114 return
114 return
115 if line.strip() == 'stop':
115 if line.strip() == 'stop':
116 print "Stopping and clearing jobqueue, %jobqueue start to start again"
116 print "Stopping and clearing jobqueue, %jobqueue start to start again"
117 _jobq.stop = True
117 _jobq.stop = True
118 return
118 return
119 if line.strip() == 'start':
119 if line.strip() == 'start':
120 _jobq.stop = False
120 _jobq.stop = False
121 return
121 return
122
122
123 def jobctrl_prefilter_f(self,line):
123 def jobctrl_prefilter_f(self,line):
124 if line.startswith('&'):
124 if line.startswith('&'):
125 pre,fn,rest = self.split_user_input(line[1:])
125 pre,fn,rest = self.split_user_input(line[1:])
126
126
127 line = ip.expand_aliases(fn,rest)
127 line = ip.expand_aliases(fn,rest)
128 if not _jobq:
128 if not _jobq:
129 return '_ip.startjob(%s)' % genutils.make_quoted_expr(line)
129 return 'get_ipython().startjob(%s)' % genutils.make_quoted_expr(line)
130 return '_ip.jobq(%s)' % genutils.make_quoted_expr(line)
130 return 'get_ipython().jobq(%s)' % genutils.make_quoted_expr(line)
131
131
132 raise TryNext
132 raise TryNext
133
133
134 def jobq_output_hook(self):
134 def jobq_output_hook(self):
135 if not _jobq:
135 if not _jobq:
136 return
136 return
137 _jobq.dumpoutput()
137 _jobq.dumpoutput()
138
138
139
139
140
140
141 def job_list(ip):
141 def job_list(ip):
142 keys = ip.db.keys('tasks/*')
142 keys = ip.db.keys('tasks/*')
143 ents = [ip.db[k] for k in keys]
143 ents = [ip.db[k] for k in keys]
144 return ents
144 return ents
145
145
146 def magic_tasks(self,line):
146 def magic_tasks(self,line):
147 """ Show a list of tasks.
147 """ Show a list of tasks.
148
148
149 A 'task' is a process that has been started in IPython when 'jobctrl' extension is enabled.
149 A 'task' is a process that has been started in IPython when 'jobctrl' extension is enabled.
150 Tasks can be killed with %kill.
150 Tasks can be killed with %kill.
151
151
152 '%tasks clear' clears the task list (from stale tasks)
152 '%tasks clear' clears the task list (from stale tasks)
153 """
153 """
154 ip = self.getapi()
154 ip = self.getapi()
155 if line.strip() == 'clear':
155 if line.strip() == 'clear':
156 for k in ip.db.keys('tasks/*'):
156 for k in ip.db.keys('tasks/*'):
157 print "Clearing",ip.db[k]
157 print "Clearing",ip.db[k]
158 del ip.db[k]
158 del ip.db[k]
159 return
159 return
160
160
161 ents = job_list(ip)
161 ents = job_list(ip)
162 if not ents:
162 if not ents:
163 print "No tasks running"
163 print "No tasks running"
164 for pid,cmd,cwd,t in ents:
164 for pid,cmd,cwd,t in ents:
165 dur = int(time.time()-t)
165 dur = int(time.time()-t)
166 print "%d: '%s' (%s) %d:%02d" % (pid,cmd,cwd, dur / 60,dur%60)
166 print "%d: '%s' (%s) %d:%02d" % (pid,cmd,cwd, dur / 60,dur%60)
167
167
168 def magic_kill(self,line):
168 def magic_kill(self,line):
169 """ Kill a task
169 """ Kill a task
170
170
171 Without args, either kill one task (if only one running) or show list (if many)
171 Without args, either kill one task (if only one running) or show list (if many)
172 With arg, assume it's the process id.
172 With arg, assume it's the process id.
173
173
174 %kill is typically (much) more powerful than trying to terminate a process with ctrl+C.
174 %kill is typically (much) more powerful than trying to terminate a process with ctrl+C.
175 """
175 """
176 ip = self.getapi()
176 ip = self.getapi()
177 jobs = job_list(ip)
177 jobs = job_list(ip)
178
178
179 if not line.strip():
179 if not line.strip():
180 if len(jobs) == 1:
180 if len(jobs) == 1:
181 kill_process(jobs[0][0])
181 kill_process(jobs[0][0])
182 else:
182 else:
183 magic_tasks(self,line)
183 magic_tasks(self,line)
184 return
184 return
185
185
186 try:
186 try:
187 pid = int(line)
187 pid = int(line)
188 kill_process(pid)
188 kill_process(pid)
189 except ValueError:
189 except ValueError:
190 magic_tasks(self,line)
190 magic_tasks(self,line)
191
191
192 if sys.platform == 'win32':
192 if sys.platform == 'win32':
193 shell_internal_commands = 'break chcp cls copy ctty date del erase dir md mkdir path prompt rd rmdir start time type ver vol'.split()
193 shell_internal_commands = 'break chcp cls copy ctty date del erase dir md mkdir path prompt rd rmdir start time type ver vol'.split()
194 PopenExc = WindowsError
194 PopenExc = WindowsError
195 else:
195 else:
196 # todo linux commands
196 # todo linux commands
197 shell_internal_commands = []
197 shell_internal_commands = []
198 PopenExc = OSError
198 PopenExc = OSError
199
199
200
200
201 def jobctrl_shellcmd(ip,cmd):
201 def jobctrl_shellcmd(ip,cmd):
202 """ os.system replacement that stores process info to db['tasks/t1234'] """
202 """ os.system replacement that stores process info to db['tasks/t1234'] """
203 cmd = cmd.strip()
203 cmd = cmd.strip()
204 cmdname = cmd.split(None,1)[0]
204 cmdname = cmd.split(None,1)[0]
205 if cmdname in shell_internal_commands or '|' in cmd or '>' in cmd or '<' in cmd:
205 if cmdname in shell_internal_commands or '|' in cmd or '>' in cmd or '<' in cmd:
206 use_shell = True
206 use_shell = True
207 else:
207 else:
208 use_shell = False
208 use_shell = False
209
209
210 jobentry = None
210 jobentry = None
211 try:
211 try:
212 try:
212 try:
213 p = Popen(cmd,shell = use_shell)
213 p = Popen(cmd,shell = use_shell)
214 except PopenExc :
214 except PopenExc :
215 if use_shell:
215 if use_shell:
216 # try with os.system
216 # try with os.system
217 os.system(cmd)
217 os.system(cmd)
218 return
218 return
219 else:
219 else:
220 # have to go via shell, sucks
220 # have to go via shell, sucks
221 p = Popen(cmd,shell = True)
221 p = Popen(cmd,shell = True)
222
222
223 jobentry = 'tasks/t' + str(p.pid)
223 jobentry = 'tasks/t' + str(p.pid)
224 ip.db[jobentry] = (p.pid,cmd,os.getcwd(),time.time())
224 ip.db[jobentry] = (p.pid,cmd,os.getcwd(),time.time())
225 p.communicate()
225 p.communicate()
226
226
227 finally:
227 finally:
228 if jobentry:
228 if jobentry:
229 del ip.db[jobentry]
229 del ip.db[jobentry]
230
230
231
231
232 def install():
232 def install():
233 global ip
233 global ip
234 ip = ipapi.get()
234 ip = ipapi.get()
235 # needed to make startjob visible as _ip.startjob('blah')
235 # needed to make startjob visible as _ip.startjob('blah')
236 ip.startjob = startjob
236 ip.startjob = startjob
237 ip.set_hook('input_prefilter', jobctrl_prefilter_f)
237 ip.set_hook('input_prefilter', jobctrl_prefilter_f)
238 ip.set_hook('shell_hook', jobctrl_shellcmd)
238 ip.set_hook('shell_hook', jobctrl_shellcmd)
239 ip.define_magic('kill',magic_kill)
239 ip.define_magic('kill',magic_kill)
240 ip.define_magic('tasks',magic_tasks)
240 ip.define_magic('tasks',magic_tasks)
241 ip.define_magic('jobqueue',jobqueue_f)
241 ip.define_magic('jobqueue',jobqueue_f)
242 ip.set_hook('pre_prompt_hook', jobq_output_hook)
242 ip.set_hook('pre_prompt_hook', jobq_output_hook)
243 install()
243 install()
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now