##// END OF EJS Templates
Unicode fixes (utf-8 used by default if ascii is not enough). This should fix some reported crashes....
fperez -
r5:c83aafa3
parent child Browse files
Show More

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

@@ -1,270 +1,272 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Modified input prompt for executing files.
2 """Modified input prompt for executing files.
3
3
4 We define a special input line filter to allow typing lines which begin with
4 We define a special input line filter to allow typing lines which begin with
5 '~', '/' or '.'. If one of those strings is encountered, it is automatically
5 '~', '/' or '.'. If one of those strings is encountered, it is automatically
6 executed.
6 executed.
7
7
8 $Id: InterpreterExec.py 573 2005-04-08 08:38:09Z fperez $"""
8 $Id: InterpreterExec.py 638 2005-07-18 03:01:41Z fperez $"""
9
9
10 #*****************************************************************************
10 #*****************************************************************************
11 # Copyright (C) 2004 W.J. van der Laan <gnufnork@hetdigitalegat.nl>
11 # Copyright (C) 2004 W.J. van der Laan <gnufnork@hetdigitalegat.nl>
12 # Copyright (C) 2004 Fernando Perez <fperez@colorado.edu>
12 # Copyright (C) 2004 Fernando Perez <fperez@colorado.edu>
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 from IPython import Release
18 from IPython import Release
19 __author__ = 'W.J. van der Laan <gnufnork@hetdigitalegat.nl>, '\
19 __author__ = 'W.J. van der Laan <gnufnork@hetdigitalegat.nl>, '\
20 '%s <%s>' % Release.authors['Fernando']
20 '%s <%s>' % Release.authors['Fernando']
21 __license__ = Release.license
21 __license__ = Release.license
22
22
23 def prefilter_shell(self,line,continuation):
23 def prefilter_shell(self,line,continuation):
24 """Alternate prefilter, modified for shell-like functionality.
24 """Alternate prefilter, modified for shell-like functionality.
25
25
26 - Execute all lines beginning with '~', '/' or '.'
26 - Execute all lines beginning with '~', '/' or '.'
27 - $var=cmd <=> %sc var=cmd
27 - $var=cmd <=> %sc var=cmd
28 - $$var=cmd <=> %sc -l var=cmd
28 - $$var=cmd <=> %sc -l var=cmd
29 """
29 """
30
30
31 if line:
31 if line:
32 l0 = line[0]
32 l0 = line[0]
33 if l0 in '~/.':
33 if l0 in '~/.':
34 return self._prefilter("!%s"%line,continuation)
34 return self._prefilter("!%s"%line,continuation)
35 elif l0=='$':
35 elif l0=='$':
36 lrest = line[1:]
36 lrest = line[1:]
37 if lrest.startswith('$'):
37 if lrest.startswith('$'):
38 # $$var=cmd <=> %sc -l var=cmd
38 # $$var=cmd <=> %sc -l var=cmd
39 return self._prefilter("%ssc -l %s" % (self.ESC_MAGIC,lrest[1:]),
39 return self._prefilter("%ssc -l %s" % (self.ESC_MAGIC,lrest[1:]),
40 continuation)
40 continuation)
41 else:
41 else:
42 # $var=cmd <=> %sc var=cmd
42 # $var=cmd <=> %sc var=cmd
43 return self._prefilter("%ssc %s" % (self.ESC_MAGIC,lrest),
43 return self._prefilter("%ssc %s" % (self.ESC_MAGIC,lrest),
44 continuation)
44 continuation)
45 else:
45 else:
46 return self._prefilter(line,continuation)
46 return self._prefilter(line,continuation)
47 else:
47 else:
48 return self._prefilter(line,continuation)
48 return self._prefilter(line,continuation)
49
49
50 # Rebind this to be the new IPython prefilter:
50 # Rebind this to be the new IPython prefilter:
51 from IPython.iplib import InteractiveShell
51 from IPython.iplib import InteractiveShell
52 InteractiveShell.prefilter = prefilter_shell
52 InteractiveShell.prefilter = prefilter_shell
53 # Clean up the namespace.
53 # Clean up the namespace.
54 del InteractiveShell,prefilter_shell
54 del InteractiveShell,prefilter_shell
55
55
56 # Provide pysh and further shell-oriented services
56 # Provide pysh and further shell-oriented services
57 import os,sys,shutil
57 import os,sys,shutil
58 from IPython.genutils import system,shell,getoutput,getoutputerror
58 from IPython.genutils import system,shell,getoutput,getoutputerror
59
59
60 # Short aliases for getting shell output as a string and a list
60 # Short aliases for getting shell output as a string and a list
61 sout = getoutput
61 sout = getoutput
62 lout = lambda cmd: getoutput(cmd,split=1)
62 lout = lambda cmd: getoutput(cmd,split=1)
63
63
64 # Empty function, meant as a docstring holder so help(pysh) works.
64 # Empty function, meant as a docstring holder so help(pysh) works.
65 def pysh():
65 def pysh():
66 """Pysh is a set of modules and extensions to IPython which make shell-like
66 """Pysh is a set of modules and extensions to IPython which make shell-like
67 usage with Python syntax more convenient. Keep in mind that pysh is NOT a
67 usage with Python syntax more convenient. Keep in mind that pysh is NOT a
68 full-blown shell, so don't try to make it your /etc/passwd entry!
68 full-blown shell, so don't try to make it your /etc/passwd entry!
69
69
70 In particular, it has no job control, so if you type Ctrl-Z (under Unix),
70 In particular, it has no job control, so if you type Ctrl-Z (under Unix),
71 you'll suspend pysh itself, not the process you just started.
71 you'll suspend pysh itself, not the process you just started.
72
72
73 Since pysh is really nothing but a customized IPython, you should
73 Since pysh is really nothing but a customized IPython, you should
74 familiarize yourself with IPython's features. This brief help mainly
74 familiarize yourself with IPython's features. This brief help mainly
75 documents areas in which pysh differs from the normal IPython.
75 documents areas in which pysh differs from the normal IPython.
76
76
77 ALIASES
77 ALIASES
78 -------
78 -------
79 All of your $PATH has been loaded as IPython aliases, so you should be
79 All of your $PATH has been loaded as IPython aliases, so you should be
80 able to type any normal system command and have it executed. See %alias?
80 able to type any normal system command and have it executed. See %alias?
81 and %unalias? for details on the alias facilities.
81 and %unalias? for details on the alias facilities.
82
82
83 SPECIAL SYNTAX
83 SPECIAL SYNTAX
84 --------------
84 --------------
85 Any lines which begin with '~', '/' and '.' will be executed as shell
85 Any lines which begin with '~', '/' and '.' will be executed as shell
86 commands instead of as Python code. The special escapes below are also
86 commands instead of as Python code. The special escapes below are also
87 recognized. !cmd is valid in single or multi-line input, all others are
87 recognized. !cmd is valid in single or multi-line input, all others are
88 only valid in single-line input:
88 only valid in single-line input:
89
89
90 !cmd - pass 'cmd' directly to the shell
90 !cmd - pass 'cmd' directly to the shell
91 !!cmd - execute 'cmd' and return output as a list (split on '\\n')
91 !!cmd - execute 'cmd' and return output as a list (split on '\\n')
92 $var=cmd - capture output of cmd into var, as a string
92 $var=cmd - capture output of cmd into var, as a string
93 $$var=cmd - capture output of cmd into var, as a list (split on '\\n')
93 $$var=cmd - capture output of cmd into var, as a list (split on '\\n')
94
94
95 The $/$$ syntaxes make Python variables from system output, which you can
95 The $/$$ syntaxes make Python variables from system output, which you can
96 later use for further scripting. The converse is also possible: when
96 later use for further scripting. The converse is also possible: when
97 executing an alias or calling to the system via !/!!, you can expand any
97 executing an alias or calling to the system via !/!!, you can expand any
98 python variable or expression by prepending it with $. Full details of
98 python variable or expression by prepending it with $. Full details of
99 the allowed syntax can be found in Python's PEP 215.
99 the allowed syntax can be found in Python's PEP 215.
100
100
101 A few brief examples will illustrate these:
101 A few brief examples will illustrate these:
102
102
103 fperez[~/test]|3> !ls *s.py
103 fperez[~/test]|3> !ls *s.py
104 scopes.py strings.py
104 scopes.py strings.py
105
105
106 ls is an internal alias, so there's no need to use !:
106 ls is an internal alias, so there's no need to use !:
107 fperez[~/test]|4> ls *s.py
107 fperez[~/test]|4> ls *s.py
108 scopes.py* strings.py
108 scopes.py* strings.py
109
109
110 !!ls will return the output into a Python variable:
110 !!ls will return the output into a Python variable:
111 fperez[~/test]|5> !!ls *s.py
111 fperez[~/test]|5> !!ls *s.py
112 <5> ['scopes.py', 'strings.py']
112 <5> ['scopes.py', 'strings.py']
113 fperez[~/test]|6> print _5
113 fperez[~/test]|6> print _5
114 ['scopes.py', 'strings.py']
114 ['scopes.py', 'strings.py']
115
115
116 $ and $$ allow direct capture to named variables:
116 $ and $$ allow direct capture to named variables:
117 fperez[~/test]|7> $astr = ls *s.py
117 fperez[~/test]|7> $astr = ls *s.py
118 fperez[~/test]|8> astr
118 fperez[~/test]|8> astr
119 <8> 'scopes.py\\nstrings.py'
119 <8> 'scopes.py\\nstrings.py'
120
120
121 fperez[~/test]|9> $$alist = ls *s.py
121 fperez[~/test]|9> $$alist = ls *s.py
122 fperez[~/test]|10> alist
122 fperez[~/test]|10> alist
123 <10> ['scopes.py', 'strings.py']
123 <10> ['scopes.py', 'strings.py']
124
124
125 alist is now a normal python list you can loop over. Using $ will expand
125 alist is now a normal python list you can loop over. Using $ will expand
126 back the python values when alias calls are made:
126 back the python values when alias calls are made:
127 fperez[~/test]|11> for f in alist:
127 fperez[~/test]|11> for f in alist:
128 |..> print 'file',f,
128 |..> print 'file',f,
129 |..> wc -l $f
129 |..> wc -l $f
130 |..>
130 |..>
131 file scopes.py 13 scopes.py
131 file scopes.py 13 scopes.py
132 file strings.py 4 strings.py
132 file strings.py 4 strings.py
133
133
134 Note that you may need to protect your variables with braces if you want
134 Note that you may need to protect your variables with braces if you want
135 to append strings to their names. To copy all files in alist to .bak
135 to append strings to their names. To copy all files in alist to .bak
136 extensions, you must use:
136 extensions, you must use:
137 fperez[~/test]|12> for f in alist:
137 fperez[~/test]|12> for f in alist:
138 |..> cp $f ${f}.bak
138 |..> cp $f ${f}.bak
139
139
140 If you try using $f.bak, you'll get an AttributeError exception saying
140 If you try using $f.bak, you'll get an AttributeError exception saying
141 that your string object doesn't have a .bak attribute. This is because
141 that your string object doesn't have a .bak attribute. This is because
142 the $ expansion mechanism allows you to expand full Python expressions:
142 the $ expansion mechanism allows you to expand full Python expressions:
143 fperez[~/test]|13> echo "sys.platform is: $sys.platform"
143 fperez[~/test]|13> echo "sys.platform is: $sys.platform"
144 sys.platform is: linux2
144 sys.platform is: linux2
145
145
146 IPython's input history handling is still active, which allows you to
146 IPython's input history handling is still active, which allows you to
147 rerun a single block of multi-line input by simply using exec:
147 rerun a single block of multi-line input by simply using exec:
148 fperez[~/test]|14> $$alist = ls *.eps
148 fperez[~/test]|14> $$alist = ls *.eps
149 fperez[~/test]|15> exec _i11
149 fperez[~/test]|15> exec _i11
150 file image2.eps 921 image2.eps
150 file image2.eps 921 image2.eps
151 file image.eps 921 image.eps
151 file image.eps 921 image.eps
152
152
153 While these are new special-case syntaxes, they are designed to allow very
153 While these are new special-case syntaxes, they are designed to allow very
154 efficient use of the shell with minimal typing. At an interactive shell
154 efficient use of the shell with minimal typing. At an interactive shell
155 prompt, conciseness of expression wins over readability.
155 prompt, conciseness of expression wins over readability.
156
156
157 USEFUL FUNCTIONS AND MODULES
157 USEFUL FUNCTIONS AND MODULES
158 ----------------------------
158 ----------------------------
159 The os, sys and shutil modules from the Python standard library are
159 The os, sys and shutil modules from the Python standard library are
160 automatically loaded. Some additional functions, useful for shell usage,
160 automatically loaded. Some additional functions, useful for shell usage,
161 are listed below. You can request more help about them with '?'.
161 are listed below. You can request more help about them with '?'.
162
162
163 shell - execute a command in the underlying system shell
163 shell - execute a command in the underlying system shell
164 system - like shell(), but return the exit status of the command
164 system - like shell(), but return the exit status of the command
165 sout - capture the output of a command as a string
165 sout - capture the output of a command as a string
166 lout - capture the output of a command as a list (split on '\\n')
166 lout - capture the output of a command as a list (split on '\\n')
167 getoutputerror - capture (output,error) of a shell command
167 getoutputerror - capture (output,error) of a shell command
168
168
169 sout/lout are the functional equivalents of $/$$. They are provided to
169 sout/lout are the functional equivalents of $/$$. They are provided to
170 allow you to capture system output in the middle of true python code,
170 allow you to capture system output in the middle of true python code,
171 function definitions, etc (where $ and $$ are invalid).
171 function definitions, etc (where $ and $$ are invalid).
172
172
173 DIRECTORY MANAGEMENT
173 DIRECTORY MANAGEMENT
174 --------------------
174 --------------------
175 Since each command passed by pysh to the underlying system is executed in
175 Since each command passed by pysh to the underlying system is executed in
176 a subshell which exits immediately, you can NOT use !cd to navigate the
176 a subshell which exits immediately, you can NOT use !cd to navigate the
177 filesystem.
177 filesystem.
178
178
179 Pysh provides its own builtin '%cd' magic command to move in the
179 Pysh provides its own builtin '%cd' magic command to move in the
180 filesystem (the % is not required with automagic on). It also maintains a
180 filesystem (the % is not required with automagic on). It also maintains a
181 list of visited directories (use %dhist to see it) and allows direct
181 list of visited directories (use %dhist to see it) and allows direct
182 switching to any of them. Type 'cd?' for more details.
182 switching to any of them. Type 'cd?' for more details.
183
183
184 %pushd, %popd and %dirs are provided for directory stack handling.
184 %pushd, %popd and %dirs are provided for directory stack handling.
185
185
186 PROMPT CUSTOMIZATION
186 PROMPT CUSTOMIZATION
187 --------------------
187 --------------------
188
188
189 The supplied ipythonrc-pysh profile comes with an example of a very
189 The supplied ipythonrc-pysh profile comes with an example of a very
190 colored and detailed prompt, mainly to serve as an illustration. The
190 colored and detailed prompt, mainly to serve as an illustration. The
191 valid escape sequences, besides color names, are:
191 valid escape sequences, besides color names, are:
192
192
193 \\# - Prompt number.
193 \\# - Prompt number.
194 \\D - Dots, as many as there are digits in \\# (so they align).
194 \\D - Dots, as many as there are digits in \\# (so they align).
195 \\w - Current working directory (cwd).
195 \\w - Current working directory (cwd).
196 \\W - Basename of current working directory.
196 \\W - Basename of current working directory.
197 \\XN - Where N=0..5. N terms of the cwd, with $HOME written as ~.
197 \\XN - Where N=0..5. N terms of the cwd, with $HOME written as ~.
198 \\YN - Where N=0..5. Like XN, but if ~ is term N+1 it's also shown.
198 \\YN - Where N=0..5. Like XN, but if ~ is term N+1 it's also shown.
199 \\u - Username.
199 \\u - Username.
200 \\H - Full hostname.
200 \\H - Full hostname.
201 \\h - Hostname up to first '.'
201 \\h - Hostname up to first '.'
202 \\$ - Root symbol ($ or #).
202 \\$ - Root symbol ($ or #).
203 \\t - Current time, in H:M:S format.
203 \\t - Current time, in H:M:S format.
204 \\v - IPython release version.
204 \\v - IPython release version.
205 \\n - Newline.
205 \\n - Newline.
206 \\r - Carriage return.
206 \\r - Carriage return.
207 \\\\ - An explicitly escaped '\\'.
207 \\\\ - An explicitly escaped '\\'.
208
208
209 You can configure your prompt colors using any ANSI color escape. Each
209 You can configure your prompt colors using any ANSI color escape. Each
210 color escape sets the color for any subsequent text, until another escape
210 color escape sets the color for any subsequent text, until another escape
211 comes in and changes things. The valid color escapes are:
211 comes in and changes things. The valid color escapes are:
212
212
213 \\C_Black
213 \\C_Black
214 \\C_Blue
214 \\C_Blue
215 \\C_Brown
215 \\C_Brown
216 \\C_Cyan
216 \\C_Cyan
217 \\C_DarkGray
217 \\C_DarkGray
218 \\C_Green
218 \\C_Green
219 \\C_LightBlue
219 \\C_LightBlue
220 \\C_LightCyan
220 \\C_LightCyan
221 \\C_LightGray
221 \\C_LightGray
222 \\C_LightGreen
222 \\C_LightGreen
223 \\C_LightPurple
223 \\C_LightPurple
224 \\C_LightRed
224 \\C_LightRed
225 \\C_Purple
225 \\C_Purple
226 \\C_Red
226 \\C_Red
227 \\C_White
227 \\C_White
228 \\C_Yellow
228 \\C_Yellow
229 \\C_Normal - Stop coloring, defaults to your terminal settings.
229 \\C_Normal - Stop coloring, defaults to your terminal settings.
230 """
230 """
231 pass
231 pass
232
232
233 # Configure a few things. Much of this is fairly hackish, since IPython
233 # Configure a few things. Much of this is fairly hackish, since IPython
234 # doesn't really expose a clean API for it. Be careful if you start making
234 # doesn't really expose a clean API for it. Be careful if you start making
235 # many modifications here.
235 # many modifications here.
236
236
237 print """\
237 print """\
238 Welcome to pysh, a set of extensions to IPython for shell usage.
238 Welcome to pysh, a set of extensions to IPython for shell usage.
239 help(pysh) -> help on the installed shell extensions and syntax.
239 help(pysh) -> help on the installed shell extensions and syntax.
240 """
240 """
241
241
242 # Set the 'cd' command to quiet mode, a more shell-like behavior
242 # Set the 'cd' command to quiet mode, a more shell-like behavior
243 __IPYTHON__.default_option('cd','-q')
243 __IPYTHON__.default_option('cd','-q')
244
244
245 # Load all of $PATH as aliases
245 # Load all of $PATH as aliases
246 if os.name == 'posix':
246 if os.name == 'posix':
247 # %rehash is very fast, but it doesn't check for executability, it simply
247 # %rehash is very fast, but it doesn't check for executability, it simply
248 # dumps everything in $PATH as an alias. Use rehashx if you want more
248 # dumps everything in $PATH as an alias. Use rehashx if you want more
249 # checks.
249 # checks.
250 __IPYTHON__.magic_rehash()
250 __IPYTHON__.magic_rehash()
251 else:
251 else:
252 # Windows users: the list of extensions considered executable is read from
252 # Windows users: the list of extensions considered executable is read from
253 # the environment variable 'pathext'. If this is undefined, IPython
253 # the environment variable 'pathext'. If this is undefined, IPython
254 # defaults to EXE, COM and BAT.
254 # defaults to EXE, COM and BAT.
255 # %rehashx is the one which does extension analysis, at the cost of
255 # %rehashx is the one which does extension analysis, at the cost of
256 # being much slower than %rehash.
256 # being much slower than %rehash.
257 __IPYTHON__.magic_rehashx()
257 __IPYTHON__.magic_rehashx()
258
258
259 # Remove %sc,%sx if present as aliases
259 # Remove %sc,%sx if present as aliases
260 __IPYTHON__.magic_unalias('sc')
260 __IPYTHON__.magic_unalias('sc')
261 __IPYTHON__.magic_unalias('sx')
261 __IPYTHON__.magic_unalias('sx')
262
262
263 # We need different criteria for line-splitting, so that aliases such as
263 # We need different criteria for line-splitting, so that aliases such as
264 # 'gnome-terminal' are interpreted as a single alias instead of variable
264 # 'gnome-terminal' are interpreted as a single alias instead of variable
265 # 'gnome' minus variable 'terminal'.
265 # 'gnome' minus variable 'terminal'.
266 import re
266 import re
267 __IPYTHON__.line_split = re.compile(r'^(\s*)([\?\w\.\-\+]+\w*\s*)(\(?.*$)')
267 __IPYTHON__.line_split = re.compile(r'^([\s*,;/])'
268 r'([\?\w\.\-\+]+\w*\s*)'
269 r'(\(?.*$)')
268
270
269 # Namespace cleanup
271 # Namespace cleanup
270 del re
272 del re
@@ -1,199 +1,192 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Word completion for GNU readline 2.0.
2 """Word completion for GNU readline 2.0.
3
3
4 ---------------------------------------------------------------------------
4 ---------------------------------------------------------------------------
5 NOTE: This version is a re-implementation of rlcompleter with selectable
5 NOTE: This version is a re-implementation of rlcompleter with selectable
6 namespace.
6 namespace.
7
7
8 The problem with rlcompleter is that it's hardwired to work with
8 The problem with rlcompleter is that it's hardwired to work with
9 __main__.__dict__, and in some cases one may have 'sandboxed' namespaces. So
9 __main__.__dict__, and in some cases one may have 'sandboxed' namespaces. So
10 this class is a ripoff of rlcompleter, with the namespace to work in as an
10 this class is a ripoff of rlcompleter, with the namespace to work in as an
11 optional parameter.
11 optional parameter.
12
12
13 This class can be used just like rlcompleter, but the Completer class now has
13 This class can be used just like rlcompleter, but the Completer class now has
14 a constructor with the optional 'namespace' parameter.
14 a constructor with the optional 'namespace' parameter.
15
15
16 A patch has been submitted to Python@sourceforge for these changes to go in
16 A patch has been submitted to Python@sourceforge for these changes to go in
17 the standard Python distribution.
17 the standard Python distribution.
18
18
19 The patch went in for Python 2.3. Once IPython drops support for Python 2.2,
19 The patch went in for Python 2.3. Once IPython drops support for Python 2.2,
20 this file can be significantly reduced.
20 this file can be significantly reduced.
21 ---------------------------------------------------------------------------
21 ---------------------------------------------------------------------------
22
22
23 Original rlcompleter documentation:
23 Original rlcompleter documentation:
24
24
25 This requires the latest extension to the readline module (the
25 This requires the latest extension to the readline module (the
26 completes keywords, built-ins and globals in __main__; when completing
26 completes keywords, built-ins and globals in __main__; when completing
27 NAME.NAME..., it evaluates (!) the expression up to the last dot and
27 NAME.NAME..., it evaluates (!) the expression up to the last dot and
28 completes its attributes.
28 completes its attributes.
29
29
30 It's very cool to do "import string" type "string.", hit the
30 It's very cool to do "import string" type "string.", hit the
31 completion key (twice), and see the list of names defined by the
31 completion key (twice), and see the list of names defined by the
32 string module!
32 string module!
33
33
34 Tip: to use the tab key as the completion key, call
34 Tip: to use the tab key as the completion key, call
35
35
36 readline.parse_and_bind("tab: complete")
36 readline.parse_and_bind("tab: complete")
37
37
38 Notes:
38 Notes:
39
39
40 - Exceptions raised by the completer function are *ignored* (and
40 - Exceptions raised by the completer function are *ignored* (and
41 generally cause the completion to fail). This is a feature -- since
41 generally cause the completion to fail). This is a feature -- since
42 readline sets the tty device in raw (or cbreak) mode, printing a
42 readline sets the tty device in raw (or cbreak) mode, printing a
43 traceback wouldn't work well without some complicated hoopla to save,
43 traceback wouldn't work well without some complicated hoopla to save,
44 reset and restore the tty state.
44 reset and restore the tty state.
45
45
46 - The evaluation of the NAME.NAME... form may cause arbitrary
46 - The evaluation of the NAME.NAME... form may cause arbitrary
47 application defined code to be executed if an object with a
47 application defined code to be executed if an object with a
48 __getattr__ hook is found. Since it is the responsibility of the
48 __getattr__ hook is found. Since it is the responsibility of the
49 application (or the user) to enable this feature, I consider this an
49 application (or the user) to enable this feature, I consider this an
50 acceptable risk. More complicated expressions (e.g. function calls or
50 acceptable risk. More complicated expressions (e.g. function calls or
51 indexing operations) are *not* evaluated.
51 indexing operations) are *not* evaluated.
52
52
53 - GNU readline is also used by the built-in functions input() and
53 - GNU readline is also used by the built-in functions input() and
54 raw_input(), and thus these also benefit/suffer from the completer
54 raw_input(), and thus these also benefit/suffer from the completer
55 features. Clearly an interactive application can benefit by
55 features. Clearly an interactive application can benefit by
56 specifying its own completer function and using raw_input() for all
56 specifying its own completer function and using raw_input() for all
57 its input.
57 its input.
58
58
59 - When the original stdin is not a tty device, GNU readline is never
59 - When the original stdin is not a tty device, GNU readline is never
60 used, and this module (and the readline module) are silently inactive.
60 used, and this module (and the readline module) are silently inactive.
61
61
62 """
62 """
63
63
64 #*****************************************************************************
64 #*****************************************************************************
65 #
65 #
66 # Since this file is essentially a minimally modified copy of the rlcompleter
66 # Since this file is essentially a minimally modified copy of the rlcompleter
67 # module which is part of the standard Python distribution, I assume that the
67 # module which is part of the standard Python distribution, I assume that the
68 # proper procedure is to maintain its copyright as belonging to the Python
68 # proper procedure is to maintain its copyright as belonging to the Python
69 # Software Foundation:
69 # Software Foundation:
70 #
70 #
71 # Copyright (C) 2001 Python Software Foundation, www.python.org
71 # Copyright (C) 2001 Python Software Foundation, www.python.org
72 #
72 #
73 # Distributed under the terms of the Python Software Foundation license.
73 # Distributed under the terms of the Python Software Foundation license.
74 #
74 #
75 # Full text available at:
75 # Full text available at:
76 #
76 #
77 # http://www.python.org/2.1/license.html
77 # http://www.python.org/2.1/license.html
78 #
78 #
79 #*****************************************************************************
79 #*****************************************************************************
80
80
81 import readline
81 import readline
82 import __builtin__
82 import __builtin__
83 import __main__
83 import __main__
84
84
85 __all__ = ["Completer"]
85 __all__ = ["Completer"]
86
86
87 # declares Python 2.2 compatibility symbols:
88 try:
89 basestring
90 except NameError:
91 import types
92 basestring = (types.StringType, types.UnicodeType)
93
94 class Completer:
87 class Completer:
95 def __init__(self, namespace = None):
88 def __init__(self, namespace = None):
96 """Create a new completer for the command line.
89 """Create a new completer for the command line.
97
90
98 Completer([namespace]) -> completer instance.
91 Completer([namespace]) -> completer instance.
99
92
100 If unspecified, the default namespace where completions are performed
93 If unspecified, the default namespace where completions are performed
101 is __main__ (technically, __main__.__dict__). Namespaces should be
94 is __main__ (technically, __main__.__dict__). Namespaces should be
102 given as dictionaries.
95 given as dictionaries.
103
96
104 Completer instances should be used as the completion mechanism of
97 Completer instances should be used as the completion mechanism of
105 readline via the set_completer() call:
98 readline via the set_completer() call:
106
99
107 readline.set_completer(Completer(my_namespace).complete)
100 readline.set_completer(Completer(my_namespace).complete)
108 """
101 """
109
102
110 if namespace and type(namespace) != type({}):
103 if namespace and type(namespace) != type({}):
111 raise TypeError,'namespace must be a dictionary'
104 raise TypeError,'namespace must be a dictionary'
112
105
113 # Don't bind to namespace quite yet, but flag whether the user wants a
106 # Don't bind to namespace quite yet, but flag whether the user wants a
114 # specific namespace or to use __main__.__dict__. This will allow us
107 # specific namespace or to use __main__.__dict__. This will allow us
115 # to bind to __main__.__dict__ at completion time, not now.
108 # to bind to __main__.__dict__ at completion time, not now.
116 if namespace is None:
109 if namespace is None:
117 self.use_main_ns = 1
110 self.use_main_ns = 1
118 else:
111 else:
119 self.use_main_ns = 0
112 self.use_main_ns = 0
120 self.namespace = namespace
113 self.namespace = namespace
121
114
122 def complete(self, text, state):
115 def complete(self, text, state):
123 """Return the next possible completion for 'text'.
116 """Return the next possible completion for 'text'.
124
117
125 This is called successively with state == 0, 1, 2, ... until it
118 This is called successively with state == 0, 1, 2, ... until it
126 returns None. The completion should begin with 'text'.
119 returns None. The completion should begin with 'text'.
127
120
128 """
121 """
129 if self.use_main_ns:
122 if self.use_main_ns:
130 self.namespace = __main__.__dict__
123 self.namespace = __main__.__dict__
131
124
132 if state == 0:
125 if state == 0:
133 if "." in text:
126 if "." in text:
134 self.matches = self.attr_matches(text)
127 self.matches = self.attr_matches(text)
135 else:
128 else:
136 self.matches = self.global_matches(text)
129 self.matches = self.global_matches(text)
137 try:
130 try:
138 return self.matches[state]
131 return self.matches[state]
139 except IndexError:
132 except IndexError:
140 return None
133 return None
141
134
142 def global_matches(self, text):
135 def global_matches(self, text):
143 """Compute matches when text is a simple name.
136 """Compute matches when text is a simple name.
144
137
145 Return a list of all keywords, built-in functions and names currently
138 Return a list of all keywords, built-in functions and names currently
146 defined in self.namespace that match.
139 defined in self.namespace that match.
147
140
148 """
141 """
149 import keyword
142 import keyword
150 matches = []
143 matches = []
151 n = len(text)
144 n = len(text)
152 for list in [keyword.kwlist,
145 for list in [keyword.kwlist,
153 __builtin__.__dict__.keys(),
146 __builtin__.__dict__.keys(),
154 self.namespace.keys()]:
147 self.namespace.keys()]:
155 for word in list:
148 for word in list:
156 if word[:n] == text and word != "__builtins__":
149 if word[:n] == text and word != "__builtins__":
157 matches.append(word)
150 matches.append(word)
158 return matches
151 return matches
159
152
160 def attr_matches(self, text):
153 def attr_matches(self, text):
161 """Compute matches when text contains a dot.
154 """Compute matches when text contains a dot.
162
155
163 Assuming the text is of the form NAME.NAME....[NAME], and is
156 Assuming the text is of the form NAME.NAME....[NAME], and is
164 evaluatable in self.namespace, it will be evaluated and its attributes
157 evaluatable in self.namespace, it will be evaluated and its attributes
165 (as revealed by dir()) are used as possible completions. (For class
158 (as revealed by dir()) are used as possible completions. (For class
166 instances, class members are are also considered.)
159 instances, class members are are also considered.)
167
160
168 WARNING: this can still invoke arbitrary C code, if an object
161 WARNING: this can still invoke arbitrary C code, if an object
169 with a __getattr__ hook is evaluated.
162 with a __getattr__ hook is evaluated.
170
163
171 """
164 """
172 import re
165 import re
173
166
174 # Another option, seems to work great. Catches things like ''.<tab>
167 # Another option, seems to work great. Catches things like ''.<tab>
175 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
168 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
176
169
177 if not m:
170 if not m:
178 return []
171 return []
179 expr, attr = m.group(1, 3)
172 expr, attr = m.group(1, 3)
180 object = eval(expr, self.namespace)
173 object = eval(expr, self.namespace)
181 words = [w for w in dir(object) if isinstance(w, basestring)]
174 words = [w for w in dir(object) if isinstance(w, basestring)]
182 if hasattr(object,'__class__'):
175 if hasattr(object,'__class__'):
183 words.append('__class__')
176 words.append('__class__')
184 words.extend(get_class_members(object.__class__))
177 words.extend(get_class_members(object.__class__))
185 n = len(attr)
178 n = len(attr)
186 matches = []
179 matches = []
187 for word in words:
180 for word in words:
188 if word[:n] == attr and word != "__builtins__":
181 if word[:n] == attr and word != "__builtins__":
189 matches.append("%s.%s" % (expr, word))
182 matches.append("%s.%s" % (expr, word))
190 return matches
183 return matches
191
184
192 def get_class_members(klass):
185 def get_class_members(klass):
193 ret = dir(klass)
186 ret = dir(klass)
194 if hasattr(klass,'__bases__'):
187 if hasattr(klass,'__bases__'):
195 for base in klass.__bases__:
188 for base in klass.__bases__:
196 ret.extend(get_class_members(base))
189 ret.extend(get_class_members(base))
197 return ret
190 return ret
198
191
199 readline.set_completer(Completer().complete)
192 readline.set_completer(Completer().complete)
@@ -1,253 +1,277 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """String interpolation for Python (by Ka-Ping Yee, 14 Feb 2000).
2 """String interpolation for Python (by Ka-Ping Yee, 14 Feb 2000).
3
3
4 This module lets you quickly and conveniently interpolate values into
4 This module lets you quickly and conveniently interpolate values into
5 strings (in the flavour of Perl or Tcl, but with less extraneous
5 strings (in the flavour of Perl or Tcl, but with less extraneous
6 punctuation). You get a bit more power than in the other languages,
6 punctuation). You get a bit more power than in the other languages,
7 because this module allows subscripting, slicing, function calls,
7 because this module allows subscripting, slicing, function calls,
8 attribute lookup, or arbitrary expressions. Variables and expressions
8 attribute lookup, or arbitrary expressions. Variables and expressions
9 are evaluated in the namespace of the caller.
9 are evaluated in the namespace of the caller.
10
10
11 The itpl() function returns the result of interpolating a string, and
11 The itpl() function returns the result of interpolating a string, and
12 printpl() prints out an interpolated string. Here are some examples:
12 printpl() prints out an interpolated string. Here are some examples:
13
13
14 from Itpl import printpl
14 from Itpl import printpl
15 printpl("Here is a $string.")
15 printpl("Here is a $string.")
16 printpl("Here is a $module.member.")
16 printpl("Here is a $module.member.")
17 printpl("Here is an $object.member.")
17 printpl("Here is an $object.member.")
18 printpl("Here is a $functioncall(with, arguments).")
18 printpl("Here is a $functioncall(with, arguments).")
19 printpl("Here is an ${arbitrary + expression}.")
19 printpl("Here is an ${arbitrary + expression}.")
20 printpl("Here is an $array[3] member.")
20 printpl("Here is an $array[3] member.")
21 printpl("Here is a $dictionary['member'].")
21 printpl("Here is a $dictionary['member'].")
22
22
23 The filter() function filters a file object so that output through it
23 The filter() function filters a file object so that output through it
24 is interpolated. This lets you produce the illusion that Python knows
24 is interpolated. This lets you produce the illusion that Python knows
25 how to do interpolation:
25 how to do interpolation:
26
26
27 import Itpl
27 import Itpl
28 sys.stdout = Itpl.filter()
28 sys.stdout = Itpl.filter()
29 f = "fancy"
29 f = "fancy"
30 print "Isn't this $f?"
30 print "Isn't this $f?"
31 print "Standard output has been replaced with a $sys.stdout object."
31 print "Standard output has been replaced with a $sys.stdout object."
32 sys.stdout = Itpl.unfilter()
32 sys.stdout = Itpl.unfilter()
33 print "Okay, back $to $normal."
33 print "Okay, back $to $normal."
34
34
35 Under the hood, the Itpl class represents a string that knows how to
35 Under the hood, the Itpl class represents a string that knows how to
36 interpolate values. An instance of the class parses the string once
36 interpolate values. An instance of the class parses the string once
37 upon initialization; the evaluation and substitution can then be done
37 upon initialization; the evaluation and substitution can then be done
38 each time the instance is evaluated with str(instance). For example:
38 each time the instance is evaluated with str(instance). For example:
39
39
40 from Itpl import Itpl
40 from Itpl import Itpl
41 s = Itpl("Here is $foo.")
41 s = Itpl("Here is $foo.")
42 foo = 5
42 foo = 5
43 print str(s)
43 print str(s)
44 foo = "bar"
44 foo = "bar"
45 print str(s)
45 print str(s)
46
46
47 $Id: Itpl.py 542 2005-03-18 09:16:04Z fperez $
47 $Id: Itpl.py 638 2005-07-18 03:01:41Z fperez $
48 """ # ' -> close an open quote for stupid emacs
48 """ # ' -> close an open quote for stupid emacs
49
49
50 #*****************************************************************************
50 #*****************************************************************************
51 #
51 #
52 # Copyright (c) 2001 Ka-Ping Yee <ping@lfw.org>
52 # Copyright (c) 2001 Ka-Ping Yee <ping@lfw.org>
53 #
53 #
54 #
54 #
55 # Published under the terms of the MIT license, hereby reproduced:
55 # Published under the terms of the MIT license, hereby reproduced:
56 #
56 #
57 # Permission is hereby granted, free of charge, to any person obtaining a copy
57 # Permission is hereby granted, free of charge, to any person obtaining a copy
58 # of this software and associated documentation files (the "Software"), to
58 # of this software and associated documentation files (the "Software"), to
59 # deal in the Software without restriction, including without limitation the
59 # deal in the Software without restriction, including without limitation the
60 # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
60 # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
61 # sell copies of the Software, and to permit persons to whom the Software is
61 # sell copies of the Software, and to permit persons to whom the Software is
62 # furnished to do so, subject to the following conditions:
62 # furnished to do so, subject to the following conditions:
63 #
63 #
64 # The above copyright notice and this permission notice shall be included in
64 # The above copyright notice and this permission notice shall be included in
65 # all copies or substantial portions of the Software.
65 # all copies or substantial portions of the Software.
66 #
66 #
67 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
67 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
68 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
68 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
69 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
69 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
70 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
70 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
71 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
71 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
72 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
72 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
73 # IN THE SOFTWARE.
73 # IN THE SOFTWARE.
74 #
74 #
75 #*****************************************************************************
75 #*****************************************************************************
76
76
77 __author__ = 'Ka-Ping Yee <ping@lfw.org>'
77 __author__ = 'Ka-Ping Yee <ping@lfw.org>'
78 __license__ = 'MIT'
78 __license__ = 'MIT'
79
79
80 import sys, string
80 import sys, string
81 from types import StringType
81 from types import StringType
82 from tokenize import tokenprog
82 from tokenize import tokenprog
83
83
84 class ItplError(ValueError):
84 class ItplError(ValueError):
85 def __init__(self, text, pos):
85 def __init__(self, text, pos):
86 self.text = text
86 self.text = text
87 self.pos = pos
87 self.pos = pos
88 def __str__(self):
88 def __str__(self):
89 return "unfinished expression in %s at char %d" % (
89 return "unfinished expression in %s at char %d" % (
90 repr(self.text), self.pos)
90 repr(self.text), self.pos)
91
91
92 def matchorfail(text, pos):
92 def matchorfail(text, pos):
93 match = tokenprog.match(text, pos)
93 match = tokenprog.match(text, pos)
94 if match is None:
94 if match is None:
95 raise ItplError(text, pos)
95 raise ItplError(text, pos)
96 return match, match.end()
96 return match, match.end()
97
97
98 class Itpl:
98 class Itpl:
99 """Class representing a string with interpolation abilities.
99 """Class representing a string with interpolation abilities.
100
100
101 Upon creation, an instance works out what parts of the format
101 Upon creation, an instance works out what parts of the format
102 string are literal and what parts need to be evaluated. The
102 string are literal and what parts need to be evaluated. The
103 evaluation and substitution happens in the namespace of the
103 evaluation and substitution happens in the namespace of the
104 caller when str(instance) is called."""
104 caller when str(instance) is called."""
105
105
106 def __init__(self, format):
106 def __init__(self, format,codec='utf_8',encoding_errors='backslashreplace'):
107 """The single argument to this constructor is a format string.
107 """The single mandatory argument to this constructor is a format
108 string.
108
109
109 The format string is parsed according to the following rules:
110 The format string is parsed according to the following rules:
110
111
111 1. A dollar sign and a name, possibly followed by any of:
112 1. A dollar sign and a name, possibly followed by any of:
112 - an open-paren, and anything up to the matching paren
113 - an open-paren, and anything up to the matching paren
113 - an open-bracket, and anything up to the matching bracket
114 - an open-bracket, and anything up to the matching bracket
114 - a period and a name
115 - a period and a name
115 any number of times, is evaluated as a Python expression.
116 any number of times, is evaluated as a Python expression.
116
117
117 2. A dollar sign immediately followed by an open-brace, and
118 2. A dollar sign immediately followed by an open-brace, and
118 anything up to the matching close-brace, is evaluated as
119 anything up to the matching close-brace, is evaluated as
119 a Python expression.
120 a Python expression.
120
121
121 3. Outside of the expressions described in the above two rules,
122 3. Outside of the expressions described in the above two rules,
122 two dollar signs in a row give you one literal dollar sign."""
123 two dollar signs in a row give you one literal dollar sign.
123
124
124 if type(format) != StringType:
125 Optional arguments:
126
127 - codec('utf_8'): a string containing the name of a valid Python
128 codec.
129
130 - encoding_errors('backslashreplace'): a string with a valid error handling
131 policy. See the codecs module documentation for details.
132
133 These are used to encode the format string if a call to str() fails on
134 the expanded result."""
135
136 if not isinstance(format,basestring):
125 raise TypeError, "needs string initializer"
137 raise TypeError, "needs string initializer"
126 self.format = format
138 self.format = format
139 self.codec = codec
140 self.encoding_errors = encoding_errors
127
141
128 namechars = "abcdefghijklmnopqrstuvwxyz" \
142 namechars = "abcdefghijklmnopqrstuvwxyz" \
129 "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
143 "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
130 chunks = []
144 chunks = []
131 pos = 0
145 pos = 0
132
146
133 while 1:
147 while 1:
134 dollar = string.find(format, "$", pos)
148 dollar = string.find(format, "$", pos)
135 if dollar < 0: break
149 if dollar < 0: break
136 nextchar = format[dollar+1]
150 nextchar = format[dollar+1]
137
151
138 if nextchar == "{":
152 if nextchar == "{":
139 chunks.append((0, format[pos:dollar]))
153 chunks.append((0, format[pos:dollar]))
140 pos, level = dollar+2, 1
154 pos, level = dollar+2, 1
141 while level:
155 while level:
142 match, pos = matchorfail(format, pos)
156 match, pos = matchorfail(format, pos)
143 tstart, tend = match.regs[3]
157 tstart, tend = match.regs[3]
144 token = format[tstart:tend]
158 token = format[tstart:tend]
145 if token == "{": level = level+1
159 if token == "{": level = level+1
146 elif token == "}": level = level-1
160 elif token == "}": level = level-1
147 chunks.append((1, format[dollar+2:pos-1]))
161 chunks.append((1, format[dollar+2:pos-1]))
148
162
149 elif nextchar in namechars:
163 elif nextchar in namechars:
150 chunks.append((0, format[pos:dollar]))
164 chunks.append((0, format[pos:dollar]))
151 match, pos = matchorfail(format, dollar+1)
165 match, pos = matchorfail(format, dollar+1)
152 while pos < len(format):
166 while pos < len(format):
153 if format[pos] == "." and \
167 if format[pos] == "." and \
154 pos+1 < len(format) and format[pos+1] in namechars:
168 pos+1 < len(format) and format[pos+1] in namechars:
155 match, pos = matchorfail(format, pos+1)
169 match, pos = matchorfail(format, pos+1)
156 elif format[pos] in "([":
170 elif format[pos] in "([":
157 pos, level = pos+1, 1
171 pos, level = pos+1, 1
158 while level:
172 while level:
159 match, pos = matchorfail(format, pos)
173 match, pos = matchorfail(format, pos)
160 tstart, tend = match.regs[3]
174 tstart, tend = match.regs[3]
161 token = format[tstart:tend]
175 token = format[tstart:tend]
162 if token[0] in "([": level = level+1
176 if token[0] in "([": level = level+1
163 elif token[0] in ")]": level = level-1
177 elif token[0] in ")]": level = level-1
164 else: break
178 else: break
165 chunks.append((1, format[dollar+1:pos]))
179 chunks.append((1, format[dollar+1:pos]))
166
180
167 else:
181 else:
168 chunks.append((0, format[pos:dollar+1]))
182 chunks.append((0, format[pos:dollar+1]))
169 pos = dollar + 1 + (nextchar == "$")
183 pos = dollar + 1 + (nextchar == "$")
170
184
171 if pos < len(format): chunks.append((0, format[pos:]))
185 if pos < len(format): chunks.append((0, format[pos:]))
172 self.chunks = chunks
186 self.chunks = chunks
173
187
174 def __repr__(self):
188 def __repr__(self):
175 return "<Itpl %s >" % repr(self.format)
189 return "<Itpl %s >" % repr(self.format)
176
190
191 def _str(self,glob,loc):
192 """Evaluate to a string in the given globals/locals.
193
194 The final output is built by calling str(), but if this fails, the
195 result is encoded with the instance's codec and error handling policy,
196 via a call to out.encode(self.codec,self.encoding_errors)"""
197 result = []
198 app = result.append
199 for live, chunk in self.chunks:
200 if live: app(str(eval(chunk,glob,loc)))
201 else: app(chunk)
202 out = ''.join(result)
203 try:
204 return str(out)
205 except UnicodeError:
206 return out.encode(self.codec,self.encoding_errors)
207
177 def __str__(self):
208 def __str__(self):
178 """Evaluate and substitute the appropriate parts of the string."""
209 """Evaluate and substitute the appropriate parts of the string."""
179
210
180 # We need to skip enough frames to get to the actual caller outside of
211 # We need to skip enough frames to get to the actual caller outside of
181 # Itpl.
212 # Itpl.
182 frame = sys._getframe(1)
213 frame = sys._getframe(1)
183 while frame.f_globals["__name__"] == __name__: frame = frame.f_back
214 while frame.f_globals["__name__"] == __name__: frame = frame.f_back
184 loc, glob = frame.f_locals, frame.f_globals
215 loc, glob = frame.f_locals, frame.f_globals
185
216
186 result = []
217 return self._str(glob,loc)
187 for live, chunk in self.chunks:
188 if live: result.append(str(eval(chunk,glob,loc)))
189 else: result.append(chunk)
190
191 return ''.join(result)
192
218
193 class ItplNS(Itpl):
219 class ItplNS(Itpl):
194 """Class representing a string with interpolation abilities.
220 """Class representing a string with interpolation abilities.
195
221
196 This inherits from Itpl, but at creation time a namespace is provided
222 This inherits from Itpl, but at creation time a namespace is provided
197 where the evaluation will occur. The interpolation becomes a bit more
223 where the evaluation will occur. The interpolation becomes a bit more
198 efficient, as no traceback needs to be extracte. It also allows the
224 efficient, as no traceback needs to be extracte. It also allows the
199 caller to supply a different namespace for the interpolation to occur than
225 caller to supply a different namespace for the interpolation to occur than
200 its own."""
226 its own."""
201
227
202 def __init__(self, format,globals,locals=None):
228 def __init__(self, format,globals,locals=None,
229 codec='utf_8',encoding_errors='backslashreplace'):
203 """ItplNS(format,globals[,locals]) -> interpolating string instance.
230 """ItplNS(format,globals[,locals]) -> interpolating string instance.
204
231
205 This constructor, besides a format string, takes a globals dictionary
232 This constructor, besides a format string, takes a globals dictionary
206 and optionally a locals (which defaults to globals if not provided).
233 and optionally a locals (which defaults to globals if not provided).
207
234
208 For further details, see the Itpl constructor."""
235 For further details, see the Itpl constructor."""
209
236
210 if locals is None:
237 if locals is None:
211 locals = globals
238 locals = globals
212 self.globals = globals
239 self.globals = globals
213 self.locals = locals
240 self.locals = locals
214 Itpl.__init__(self,format)
241 Itpl.__init__(self,format,codec,encoding_errors)
215
242
216 def __str__(self):
243 def __str__(self):
217 """Evaluate and substitute the appropriate parts of the string."""
244 """Evaluate and substitute the appropriate parts of the string."""
218 glob = self.globals
245 return self._str(self.globals,self.locals)
219 loc = self.locals
246
220 result = []
247 def __repr__(self):
221 for live, chunk in self.chunks:
248 return "<ItplNS %s >" % repr(self.format)
222 if live: result.append(str(eval(chunk,glob,loc)))
223 else: result.append(chunk)
224 return ''.join(result)
225
249
226 # utilities for fast printing
250 # utilities for fast printing
227 def itpl(text): return str(Itpl(text))
251 def itpl(text): return str(Itpl(text))
228 def printpl(text): print itpl(text)
252 def printpl(text): print itpl(text)
229 # versions with namespace
253 # versions with namespace
230 def itplns(text,globals,locals=None): return str(ItplNS(text,globals,locals))
254 def itplns(text,globals,locals=None): return str(ItplNS(text,globals,locals))
231 def printplns(text,globals,locals=None): print itplns(text,globals,locals)
255 def printplns(text,globals,locals=None): print itplns(text,globals,locals)
232
256
233 class ItplFile:
257 class ItplFile:
234 """A file object that filters each write() through an interpolator."""
258 """A file object that filters each write() through an interpolator."""
235 def __init__(self, file): self.file = file
259 def __init__(self, file): self.file = file
236 def __repr__(self): return "<interpolated " + repr(self.file) + ">"
260 def __repr__(self): return "<interpolated " + repr(self.file) + ">"
237 def __getattr__(self, attr): return getattr(self.file, attr)
261 def __getattr__(self, attr): return getattr(self.file, attr)
238 def write(self, text): self.file.write(str(Itpl(text)))
262 def write(self, text): self.file.write(str(Itpl(text)))
239
263
240 def filter(file=sys.stdout):
264 def filter(file=sys.stdout):
241 """Return an ItplFile that filters writes to the given file object.
265 """Return an ItplFile that filters writes to the given file object.
242
266
243 'file = filter(file)' replaces 'file' with a filtered object that
267 'file = filter(file)' replaces 'file' with a filtered object that
244 has a write() method. When called with no argument, this creates
268 has a write() method. When called with no argument, this creates
245 a filter to sys.stdout."""
269 a filter to sys.stdout."""
246 return ItplFile(file)
270 return ItplFile(file)
247
271
248 def unfilter(ifile=None):
272 def unfilter(ifile=None):
249 """Return the original file that corresponds to the given ItplFile.
273 """Return the original file that corresponds to the given ItplFile.
250
274
251 'file = unfilter(file)' undoes the effect of 'file = filter(file)'.
275 'file = unfilter(file)' undoes the effect of 'file = filter(file)'.
252 'sys.stdout = unfilter()' undoes the effect of 'sys.stdout = filter()'."""
276 'sys.stdout = unfilter()' undoes the effect of 'sys.stdout = filter()'."""
253 return ifile and ifile.file or sys.stdout.file
277 return ifile and ifile.file or sys.stdout.file
@@ -1,574 +1,572 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 $Id: Prompts.py 564 2005-03-26 22:43:58Z fperez $"""
5 $Id: Prompts.py 638 2005-07-18 03:01:41Z fperez $"""
6
6
7 #*****************************************************************************
7 #*****************************************************************************
8 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
8 # Copyright (C) 2001-2004 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 from IPython import Release
14 from IPython import Release
15 __author__ = '%s <%s>' % Release.authors['Fernando']
15 __author__ = '%s <%s>' % Release.authors['Fernando']
16 __license__ = Release.license
16 __license__ = Release.license
17 __version__ = Release.version
17 __version__ = Release.version
18
18
19 #****************************************************************************
19 #****************************************************************************
20 # Required modules
20 # Required modules
21 import __builtin__
21 import __builtin__
22 import os,sys,socket
22 import os,sys,socket
23 import time
23 import time
24 from pprint import pprint,pformat
24 from pprint import pprint,pformat
25
25
26 # IPython's own
26 # IPython's own
27 from IPython.genutils import *
27 from IPython.genutils import *
28 from IPython.Struct import Struct
28 from IPython.Struct import Struct
29 from IPython.Magic import Macro
29 from IPython.Magic import Macro
30 from IPython.Itpl import ItplNS
30 from IPython.Itpl import ItplNS
31 from IPython import ColorANSI
31 from IPython import ColorANSI
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 # make some schemes as instances so we can copy them for modification easily:
52 # make some schemes as instances so we can copy them for modification easily:
53 __PColLinux = ColorANSI.ColorScheme(
53 __PColLinux = ColorANSI.ColorScheme(
54 'Linux',
54 'Linux',
55 in_prompt = InputColors.Green,
55 in_prompt = InputColors.Green,
56 in_number = InputColors.LightGreen,
56 in_number = InputColors.LightGreen,
57 in_prompt2 = InputColors.Green,
57 in_prompt2 = InputColors.Green,
58 in_normal = InputColors.Normal, # color off (usu. Colors.Normal)
58 in_normal = InputColors.Normal, # color off (usu. Colors.Normal)
59
59
60 out_prompt = Colors.Red,
60 out_prompt = Colors.Red,
61 out_number = Colors.LightRed,
61 out_number = Colors.LightRed,
62
62
63 normal = Colors.Normal
63 normal = Colors.Normal
64 )
64 )
65 # Don't forget to enter it into the table!
65 # Don't forget to enter it into the table!
66 PromptColors.add_scheme(__PColLinux)
66 PromptColors.add_scheme(__PColLinux)
67 # Slightly modified Linux for light backgrounds
67 # Slightly modified Linux for light backgrounds
68 __PColLightBG = ColorANSI.ColorScheme('LightBG',**__PColLinux.colors.dict().copy())
68 __PColLightBG = ColorANSI.ColorScheme('LightBG',**__PColLinux.colors.dict().copy())
69
69
70 __PColLightBG.colors.update(
70 __PColLightBG.colors.update(
71 in_prompt = InputColors.Blue,
71 in_prompt = InputColors.Blue,
72 in_number = InputColors.LightBlue,
72 in_number = InputColors.LightBlue,
73 in_prompt2 = InputColors.Blue
73 in_prompt2 = InputColors.Blue
74 )
74 )
75 PromptColors.add_scheme(__PColLightBG)
75 PromptColors.add_scheme(__PColLightBG)
76
76
77 del Colors,InputColors
77 del Colors,InputColors
78
78
79 #-----------------------------------------------------------------------------
79 #-----------------------------------------------------------------------------
80 def multiple_replace(dict, text):
80 def multiple_replace(dict, text):
81 """ Replace in 'text' all occurences of any key in the given
81 """ Replace in 'text' all occurences of any key in the given
82 dictionary by its corresponding value. Returns the new string."""
82 dictionary by its corresponding value. Returns the new string."""
83
83
84 # Function by Xavier Defrang, originally found at:
84 # Function by Xavier Defrang, originally found at:
85 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/81330
85 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/81330
86
86
87 # Create a regular expression from the dictionary keys
87 # Create a regular expression from the dictionary keys
88 regex = re.compile("(%s)" % "|".join(map(re.escape, dict.keys())))
88 regex = re.compile("(%s)" % "|".join(map(re.escape, dict.keys())))
89 # For each match, look-up corresponding value in dictionary
89 # For each match, look-up corresponding value in dictionary
90 return regex.sub(lambda mo: dict[mo.string[mo.start():mo.end()]], text)
90 return regex.sub(lambda mo: dict[mo.string[mo.start():mo.end()]], text)
91
91
92 #-----------------------------------------------------------------------------
92 #-----------------------------------------------------------------------------
93 # Special characters that can be used in prompt templates, mainly bash-like
93 # Special characters that can be used in prompt templates, mainly bash-like
94
94
95 # If $HOME isn't defined (Windows), make it an absurd string so that it can
95 # If $HOME isn't defined (Windows), make it an absurd string so that it can
96 # never be expanded out into '~'. Basically anything which can never be a
96 # never be expanded out into '~'. Basically anything which can never be a
97 # reasonable directory name will do, we just want the $HOME -> '~' operation
97 # reasonable directory name will do, we just want the $HOME -> '~' operation
98 # to become a no-op. We pre-compute $HOME here so it's not done on every
98 # to become a no-op. We pre-compute $HOME here so it's not done on every
99 # prompt call.
99 # prompt call.
100
100
101 # FIXME:
101 # FIXME:
102
102
103 # - This should be turned into a class which does proper namespace management,
103 # - This should be turned into a class which does proper namespace management,
104 # since the prompt specials need to be evaluated in a certain namespace.
104 # since the prompt specials need to be evaluated in a certain namespace.
105 # Currently it's just globals, which need to be managed manually by code
105 # Currently it's just globals, which need to be managed manually by code
106 # below.
106 # below.
107
107
108 # - I also need to split up the color schemes from the prompt specials
108 # - I also need to split up the color schemes from the prompt specials
109 # somehow. I don't have a clean design for that quite yet.
109 # somehow. I don't have a clean design for that quite yet.
110
110
111 HOME = os.environ.get("HOME","//////:::::ZZZZZ,,,~~~")
111 HOME = os.environ.get("HOME","//////:::::ZZZZZ,,,~~~")
112
112
113 # We precompute a few more strings here for the prompt_specials, which are
113 # We precompute a few more strings here for the prompt_specials, which are
114 # fixed once ipython starts. This reduces the runtime overhead of computing
114 # fixed once ipython starts. This reduces the runtime overhead of computing
115 # prompt strings.
115 # prompt strings.
116 USER = os.environ.get("USER")
116 USER = os.environ.get("USER")
117 HOSTNAME = socket.gethostname()
117 HOSTNAME = socket.gethostname()
118 HOSTNAME_SHORT = HOSTNAME.split(".")[0]
118 HOSTNAME_SHORT = HOSTNAME.split(".")[0]
119 ROOT_SYMBOL = "$#"[os.name=='nt' or os.getuid()==0]
119 ROOT_SYMBOL = "$#"[os.name=='nt' or os.getuid()==0]
120
120
121 prompt_specials_color = {
121 prompt_specials_color = {
122 # Prompt/history count
122 # Prompt/history count
123 '%n' : '${self.col_num}' '${self.cache.prompt_count}' '${self.col_p}',
123 '%n' : '${self.col_num}' '${self.cache.prompt_count}' '${self.col_p}',
124 '\\#': '${self.col_num}' '${self.cache.prompt_count}' '${self.col_p}',
124 '\\#': '${self.col_num}' '${self.cache.prompt_count}' '${self.col_p}',
125 # Prompt/history count, with the actual digits replaced by dots. Used
125 # Prompt/history count, with the actual digits replaced by dots. Used
126 # mainly in continuation prompts (prompt_in2)
126 # mainly in continuation prompts (prompt_in2)
127 '\\D': '${"."*len(str(self.cache.prompt_count))}',
127 '\\D': '${"."*len(str(self.cache.prompt_count))}',
128 # Current working directory
128 # Current working directory
129 '\\w': '${os.getcwd()}',
129 '\\w': '${os.getcwd()}',
130 # Current time
130 # Current time
131 '\\t' : '${time.strftime("%H:%M:%S")}',
131 '\\t' : '${time.strftime("%H:%M:%S")}',
132 # Basename of current working directory.
132 # Basename of current working directory.
133 # (use os.sep to make this portable across OSes)
133 # (use os.sep to make this portable across OSes)
134 '\\W' : '${os.getcwd().split("%s")[-1]}' % os.sep,
134 '\\W' : '${os.getcwd().split("%s")[-1]}' % os.sep,
135 # These X<N> are an extension to the normal bash prompts. They return
135 # These X<N> are an extension to the normal bash prompts. They return
136 # N terms of the path, after replacing $HOME with '~'
136 # N terms of the path, after replacing $HOME with '~'
137 '\\X0': '${os.getcwd().replace("%s","~")}' % HOME,
137 '\\X0': '${os.getcwd().replace("%s","~")}' % HOME,
138 '\\X1': '${self.cwd_filt(1)}',
138 '\\X1': '${self.cwd_filt(1)}',
139 '\\X2': '${self.cwd_filt(2)}',
139 '\\X2': '${self.cwd_filt(2)}',
140 '\\X3': '${self.cwd_filt(3)}',
140 '\\X3': '${self.cwd_filt(3)}',
141 '\\X4': '${self.cwd_filt(4)}',
141 '\\X4': '${self.cwd_filt(4)}',
142 '\\X5': '${self.cwd_filt(5)}',
142 '\\X5': '${self.cwd_filt(5)}',
143 # Y<N> are similar to X<N>, but they show '~' if it's the directory
143 # Y<N> are similar to X<N>, but they show '~' if it's the directory
144 # N+1 in the list. Somewhat like %cN in tcsh.
144 # N+1 in the list. Somewhat like %cN in tcsh.
145 '\\Y0': '${self.cwd_filt2(0)}',
145 '\\Y0': '${self.cwd_filt2(0)}',
146 '\\Y1': '${self.cwd_filt2(1)}',
146 '\\Y1': '${self.cwd_filt2(1)}',
147 '\\Y2': '${self.cwd_filt2(2)}',
147 '\\Y2': '${self.cwd_filt2(2)}',
148 '\\Y3': '${self.cwd_filt2(3)}',
148 '\\Y3': '${self.cwd_filt2(3)}',
149 '\\Y4': '${self.cwd_filt2(4)}',
149 '\\Y4': '${self.cwd_filt2(4)}',
150 '\\Y5': '${self.cwd_filt2(5)}',
150 '\\Y5': '${self.cwd_filt2(5)}',
151 # Hostname up to first .
151 # Hostname up to first .
152 '\\h': HOSTNAME_SHORT,
152 '\\h': HOSTNAME_SHORT,
153 # Full hostname
153 # Full hostname
154 '\\H': HOSTNAME,
154 '\\H': HOSTNAME,
155 # Username of current user
155 # Username of current user
156 '\\u': USER,
156 '\\u': USER,
157 # Escaped '\'
157 # Escaped '\'
158 '\\\\': '\\',
158 '\\\\': '\\',
159 # Newline
159 # Newline
160 '\\n': '\n',
160 '\\n': '\n',
161 # Carriage return
161 # Carriage return
162 '\\r': '\r',
162 '\\r': '\r',
163 # Release version
163 # Release version
164 '\\v': __version__,
164 '\\v': __version__,
165 # Root symbol ($ or #)
165 # Root symbol ($ or #)
166 '\\$': ROOT_SYMBOL,
166 '\\$': ROOT_SYMBOL,
167 }
167 }
168
168
169 # A copy of the prompt_specials dictionary but with all color escapes removed,
169 # A copy of the prompt_specials dictionary but with all color escapes removed,
170 # so we can correctly compute the prompt length for the auto_rewrite method.
170 # so we can correctly compute the prompt length for the auto_rewrite method.
171 prompt_specials_nocolor = prompt_specials_color.copy()
171 prompt_specials_nocolor = prompt_specials_color.copy()
172 prompt_specials_nocolor['%n'] = '${self.cache.prompt_count}'
172 prompt_specials_nocolor['%n'] = '${self.cache.prompt_count}'
173 prompt_specials_nocolor['\\#'] = '${self.cache.prompt_count}'
173 prompt_specials_nocolor['\\#'] = '${self.cache.prompt_count}'
174
174
175 # Add in all the InputTermColors color escapes as valid prompt characters.
175 # Add in all the InputTermColors color escapes as valid prompt characters.
176 # They all get added as \\C_COLORNAME, so that we don't have any conflicts
176 # They all get added as \\C_COLORNAME, so that we don't have any conflicts
177 # with a color name which may begin with a letter used by any other of the
177 # with a color name which may begin with a letter used by any other of the
178 # allowed specials. This of course means that \\C will never be allowed for
178 # allowed specials. This of course means that \\C will never be allowed for
179 # anything else.
179 # anything else.
180 input_colors = ColorANSI.InputTermColors
180 input_colors = ColorANSI.InputTermColors
181 for _color in dir(input_colors):
181 for _color in dir(input_colors):
182 if _color[0] != '_':
182 if _color[0] != '_':
183 c_name = '\\C_'+_color
183 c_name = '\\C_'+_color
184 prompt_specials_color[c_name] = getattr(input_colors,_color)
184 prompt_specials_color[c_name] = getattr(input_colors,_color)
185 prompt_specials_nocolor[c_name] = ''
185 prompt_specials_nocolor[c_name] = ''
186
186
187 # we default to no color for safety. Note that prompt_specials is a global
187 # we default to no color for safety. Note that prompt_specials is a global
188 # variable used by all prompt objects.
188 # variable used by all prompt objects.
189 prompt_specials = prompt_specials_nocolor
189 prompt_specials = prompt_specials_nocolor
190
190
191 #-----------------------------------------------------------------------------
191 #-----------------------------------------------------------------------------
192 def str_safe(arg):
192 def str_safe(arg):
193 """Convert to a string, without ever raising an exception.
193 """Convert to a string, without ever raising an exception.
194
194
195 If str(arg) fails, <ERROR: ... > is returned, where ... is the exception
195 If str(arg) fails, <ERROR: ... > is returned, where ... is the exception
196 error message."""
196 error message."""
197
197
198 try:
198 try:
199 return str(arg)
199 out = str(arg)
200 except UnicodeError:
201 try:
202 out = arg.encode('utf_8','replace')
203 except Exception,msg:
204 # let's keep this little duplication here, so that the most common
205 # case doesn't suffer from a double try wrapping.
206 out = '<ERROR: %s>' % msg
200 except Exception,msg:
207 except Exception,msg:
201 return '<ERROR: %s>' % msg
208 out = '<ERROR: %s>' % msg
209 return out
202
210
203 class BasePrompt:
211 class BasePrompt:
204 """Interactive prompt similar to Mathematica's."""
212 """Interactive prompt similar to Mathematica's."""
205 def __init__(self,cache,sep,prompt,pad_left=False):
213 def __init__(self,cache,sep,prompt,pad_left=False):
206
214
207 # Hack: we access information about the primary prompt through the
215 # Hack: we access information about the primary prompt through the
208 # cache argument. We need this, because we want the secondary prompt
216 # cache argument. We need this, because we want the secondary prompt
209 # to be aligned with the primary one. Color table info is also shared
217 # to be aligned with the primary one. Color table info is also shared
210 # by all prompt classes through the cache. Nice OO spaghetti code!
218 # by all prompt classes through the cache. Nice OO spaghetti code!
211 self.cache = cache
219 self.cache = cache
212 self.sep = sep
220 self.sep = sep
213
221
214 # regexp to count the number of spaces at the end of a prompt
222 # regexp to count the number of spaces at the end of a prompt
215 # expression, useful for prompt auto-rewriting
223 # expression, useful for prompt auto-rewriting
216 self.rspace = re.compile(r'(\s*)$')
224 self.rspace = re.compile(r'(\s*)$')
217 # Flag to left-pad prompt strings to match the length of the primary
225 # Flag to left-pad prompt strings to match the length of the primary
218 # prompt
226 # prompt
219 self.pad_left = pad_left
227 self.pad_left = pad_left
220 # Set template to create each actual prompt (where numbers change)
228 # Set template to create each actual prompt (where numbers change)
221 self.p_template = prompt
229 self.p_template = prompt
222 self.set_p_str()
230 self.set_p_str()
223
231
224 def set_p_str(self):
232 def set_p_str(self):
225 """ Set the interpolating prompt strings.
233 """ Set the interpolating prompt strings.
226
234
227 This must be called every time the color settings change, because the
235 This must be called every time the color settings change, because the
228 prompt_specials global may have changed."""
236 prompt_specials global may have changed."""
229
237
230 import os,time # needed in locals for prompt string handling
238 import os,time # needed in locals for prompt string handling
231 loc = locals()
239 loc = locals()
232 self.p_str = ItplNS('%s%s%s' %
240 self.p_str = ItplNS('%s%s%s' %
233 ('${self.sep}${self.col_p}',
241 ('${self.sep}${self.col_p}',
234 multiple_replace(prompt_specials, self.p_template),
242 multiple_replace(prompt_specials, self.p_template),
235 '${self.col_norm}'),self.cache.user_ns,loc)
243 '${self.col_norm}'),self.cache.user_ns,loc)
236
244
237 self.p_str_nocolor = ItplNS(multiple_replace(prompt_specials_nocolor,
245 self.p_str_nocolor = ItplNS(multiple_replace(prompt_specials_nocolor,
238 self.p_template),
246 self.p_template),
239 self.cache.user_ns,loc)
247 self.cache.user_ns,loc)
240
248
241 def write(self,msg): # dbg
249 def write(self,msg): # dbg
242 sys.stdout.write(msg)
250 sys.stdout.write(msg)
243 return ''
251 return ''
244
252
245 def __str__(self):
253 def __str__(self):
246 """Return a string form of the prompt.
254 """Return a string form of the prompt.
247
255
248 This for is useful for continuation and output prompts, since it is
256 This for is useful for continuation and output prompts, since it is
249 left-padded to match lengths with the primary one (if the
257 left-padded to match lengths with the primary one (if the
250 self.pad_left attribute is set)."""
258 self.pad_left attribute is set)."""
251
259
252 out_str = str_safe(self.p_str)
260 out_str = str_safe(self.p_str)
253 if self.pad_left:
261 if self.pad_left:
254 # We must find the amount of padding required to match lengths,
262 # We must find the amount of padding required to match lengths,
255 # taking the color escapes (which are invisible on-screen) into
263 # taking the color escapes (which are invisible on-screen) into
256 # account.
264 # account.
257 esc_pad = len(out_str) - len(str_safe(self.p_str_nocolor))
265 esc_pad = len(out_str) - len(str_safe(self.p_str_nocolor))
258 format = '%%%ss' % (len(str(self.cache.last_prompt))+esc_pad)
266 format = '%%%ss' % (len(str(self.cache.last_prompt))+esc_pad)
259 return format % out_str
267 return format % out_str
260 else:
268 else:
261 return out_str
269 return out_str
262
270
263 # these path filters are put in as methods so that we can control the
271 # these path filters are put in as methods so that we can control the
264 # namespace where the prompt strings get evaluated
272 # namespace where the prompt strings get evaluated
265 def cwd_filt(self,depth):
273 def cwd_filt(self,depth):
266 """Return the last depth elements of the current working directory.
274 """Return the last depth elements of the current working directory.
267
275
268 $HOME is always replaced with '~'.
276 $HOME is always replaced with '~'.
269 If depth==0, the full path is returned."""
277 If depth==0, the full path is returned."""
270
278
271 cwd = os.getcwd().replace(HOME,"~")
279 cwd = os.getcwd().replace(HOME,"~")
272 out = os.sep.join(cwd.split(os.sep)[-depth:])
280 out = os.sep.join(cwd.split(os.sep)[-depth:])
273 if out:
281 if out:
274 return out
282 return out
275 else:
283 else:
276 return os.sep
284 return os.sep
277
285
278 def cwd_filt2(self,depth):
286 def cwd_filt2(self,depth):
279 """Return the last depth elements of the current working directory.
287 """Return the last depth elements of the current working directory.
280
288
281 $HOME is always replaced with '~'.
289 $HOME is always replaced with '~'.
282 If depth==0, the full path is returned."""
290 If depth==0, the full path is returned."""
283
291
284 cwd = os.getcwd().replace(HOME,"~").split(os.sep)
292 cwd = os.getcwd().replace(HOME,"~").split(os.sep)
285 if '~' in cwd and len(cwd) == depth+1:
293 if '~' in cwd and len(cwd) == depth+1:
286 depth += 1
294 depth += 1
287 out = os.sep.join(cwd[-depth:])
295 out = os.sep.join(cwd[-depth:])
288 if out:
296 if out:
289 return out
297 return out
290 else:
298 else:
291 return os.sep
299 return os.sep
292
300
293 class Prompt1(BasePrompt):
301 class Prompt1(BasePrompt):
294 """Input interactive prompt similar to Mathematica's."""
302 """Input interactive prompt similar to Mathematica's."""
295
303
296 def __init__(self,cache,sep='\n',prompt='In [\\#]: ',pad_left=True):
304 def __init__(self,cache,sep='\n',prompt='In [\\#]: ',pad_left=True):
297 BasePrompt.__init__(self,cache,sep,prompt,pad_left)
305 BasePrompt.__init__(self,cache,sep,prompt,pad_left)
298
306
299 def set_colors(self):
307 def set_colors(self):
300 self.set_p_str()
308 self.set_p_str()
301 Colors = self.cache.color_table.active_colors # shorthand
309 Colors = self.cache.color_table.active_colors # shorthand
302 self.col_p = Colors.in_prompt
310 self.col_p = Colors.in_prompt
303 self.col_num = Colors.in_number
311 self.col_num = Colors.in_number
304 self.col_norm = Colors.in_normal
312 self.col_norm = Colors.in_normal
305 # We need a non-input version of these escapes for the '--->'
313 # We need a non-input version of these escapes for the '--->'
306 # auto-call prompts used in the auto_rewrite() method.
314 # auto-call prompts used in the auto_rewrite() method.
307 self.col_p_ni = self.col_p.replace('\001','').replace('\002','')
315 self.col_p_ni = self.col_p.replace('\001','').replace('\002','')
308 self.col_norm_ni = Colors.normal
316 self.col_norm_ni = Colors.normal
309
317
310 def __str__(self):
318 def __str__(self):
311 self.cache.prompt_count += 1
319 self.cache.prompt_count += 1
312 self.cache.last_prompt = str_safe(self.p_str_nocolor).split('\n')[-1]
320 self.cache.last_prompt = str_safe(self.p_str_nocolor).split('\n')[-1]
313 return str_safe(self.p_str)
321 return str_safe(self.p_str)
314
322
315 def auto_rewrite(self):
323 def auto_rewrite(self):
316 """Print a string of the form '--->' which lines up with the previous
324 """Print a string of the form '--->' which lines up with the previous
317 input string. Useful for systems which re-write the user input when
325 input string. Useful for systems which re-write the user input when
318 handling automatically special syntaxes."""
326 handling automatically special syntaxes."""
319
327
320 curr = str(self.cache.last_prompt)
328 curr = str(self.cache.last_prompt)
321 nrspaces = len(self.rspace.search(curr).group())
329 nrspaces = len(self.rspace.search(curr).group())
322 return '%s%s>%s%s' % (self.col_p_ni,'-'*(len(curr)-nrspaces-1),
330 return '%s%s>%s%s' % (self.col_p_ni,'-'*(len(curr)-nrspaces-1),
323 ' '*nrspaces,self.col_norm_ni)
331 ' '*nrspaces,self.col_norm_ni)
324
332
325 class PromptOut(BasePrompt):
333 class PromptOut(BasePrompt):
326 """Output interactive prompt similar to Mathematica's."""
334 """Output interactive prompt similar to Mathematica's."""
327
335
328 def __init__(self,cache,sep='',prompt='Out[\\#]: ',pad_left=True):
336 def __init__(self,cache,sep='',prompt='Out[\\#]: ',pad_left=True):
329 BasePrompt.__init__(self,cache,sep,prompt,pad_left)
337 BasePrompt.__init__(self,cache,sep,prompt,pad_left)
330 if not self.p_template:
338 if not self.p_template:
331 self.__str__ = lambda: ''
339 self.__str__ = lambda: ''
332
340
333 def set_colors(self):
341 def set_colors(self):
334 self.set_p_str()
342 self.set_p_str()
335 Colors = self.cache.color_table.active_colors # shorthand
343 Colors = self.cache.color_table.active_colors # shorthand
336 self.col_p = Colors.out_prompt
344 self.col_p = Colors.out_prompt
337 self.col_num = Colors.out_number
345 self.col_num = Colors.out_number
338 self.col_norm = Colors.normal
346 self.col_norm = Colors.normal
339
347
340 class Prompt2(BasePrompt):
348 class Prompt2(BasePrompt):
341 """Interactive continuation prompt."""
349 """Interactive continuation prompt."""
342
350
343 def __init__(self,cache,prompt=' .\\D.: ',pad_left=True):
351 def __init__(self,cache,prompt=' .\\D.: ',pad_left=True):
344 self.cache = cache
352 self.cache = cache
345 self.p_template = prompt
353 self.p_template = prompt
346 self.pad_left = pad_left
354 self.pad_left = pad_left
347 self.set_p_str()
355 self.set_p_str()
348
356
349 def set_p_str(self):
357 def set_p_str(self):
350 import os,time # needed in locals for prompt string handling
358 import os,time # needed in locals for prompt string handling
351 loc = locals()
359 loc = locals()
352 self.p_str = ItplNS('%s%s%s' %
360 self.p_str = ItplNS('%s%s%s' %
353 ('${self.col_p2}',
361 ('${self.col_p2}',
354 multiple_replace(prompt_specials, self.p_template),
362 multiple_replace(prompt_specials, self.p_template),
355 '$self.col_norm'),
363 '$self.col_norm'),
356 self.cache.user_ns,loc)
364 self.cache.user_ns,loc)
357 self.p_str_nocolor = ItplNS(multiple_replace(prompt_specials_nocolor,
365 self.p_str_nocolor = ItplNS(multiple_replace(prompt_specials_nocolor,
358 self.p_template),
366 self.p_template),
359 self.cache.user_ns,loc)
367 self.cache.user_ns,loc)
360
368
361 def set_colors(self):
369 def set_colors(self):
362 self.set_p_str()
370 self.set_p_str()
363 Colors = self.cache.color_table.active_colors
371 Colors = self.cache.color_table.active_colors
364 self.col_p2 = Colors.in_prompt2
372 self.col_p2 = Colors.in_prompt2
365 self.col_norm = Colors.in_normal
373 self.col_norm = Colors.in_normal
366 # FIXME (2004-06-16) HACK: prevent crashes for users who haven't
374 # FIXME (2004-06-16) HACK: prevent crashes for users who haven't
367 # updated their prompt_in2 definitions. Remove eventually.
375 # updated their prompt_in2 definitions. Remove eventually.
368 self.col_p = Colors.out_prompt
376 self.col_p = Colors.out_prompt
369 self.col_num = Colors.out_number
377 self.col_num = Colors.out_number
370
378
371 #-----------------------------------------------------------------------------
379 #-----------------------------------------------------------------------------
372 class CachedOutput:
380 class CachedOutput:
373 """Class for printing output from calculations while keeping a cache of
381 """Class for printing output from calculations while keeping a cache of
374 reults. It dynamically creates global variables prefixed with _ which
382 reults. It dynamically creates global variables prefixed with _ which
375 contain these results.
383 contain these results.
376
384
377 Meant to be used as a sys.displayhook replacement, providing numbered
385 Meant to be used as a sys.displayhook replacement, providing numbered
378 prompts and cache services.
386 prompts and cache services.
379
387
380 Initialize with initial and final values for cache counter (this defines
388 Initialize with initial and final values for cache counter (this defines
381 the maximum size of the cache."""
389 the maximum size of the cache."""
382
390
383 def __init__(self,cache_size,Pprint,colors='NoColor',input_sep='\n',
391 def __init__(self,cache_size,Pprint,colors='NoColor',input_sep='\n',
384 output_sep='\n',output_sep2='',user_ns={},
392 output_sep='\n',output_sep2='',user_ns={},
385 ps1 = None, ps2 = None,ps_out = None,
393 ps1 = None, ps2 = None,ps_out = None,
386 input_hist = None,pad_left=True):
394 input_hist = None,pad_left=True):
387
395
388 cache_size_min = 20
396 cache_size_min = 20
389 if cache_size <= 0:
397 if cache_size <= 0:
390 self.do_full_cache = 0
398 self.do_full_cache = 0
391 cache_size = 0
399 cache_size = 0
392 elif cache_size < cache_size_min:
400 elif cache_size < cache_size_min:
393 self.do_full_cache = 0
401 self.do_full_cache = 0
394 cache_size = 0
402 cache_size = 0
395 warn('caching was disabled (min value for cache size is %s).' %
403 warn('caching was disabled (min value for cache size is %s).' %
396 cache_size_min,level=3)
404 cache_size_min,level=3)
397 else:
405 else:
398 self.do_full_cache = 1
406 self.do_full_cache = 1
399
407
400 self.cache_size = cache_size
408 self.cache_size = cache_size
401 self.input_sep = input_sep
409 self.input_sep = input_sep
402
410
403 # we need a reference to the user-level namespace
411 # we need a reference to the user-level namespace
404 self.user_ns = user_ns
412 self.user_ns = user_ns
405 # and to the user's input
413 # and to the user's input
406 self.input_hist = input_hist
414 self.input_hist = input_hist
407
415
408 # Set input prompt strings and colors
416 # Set input prompt strings and colors
409 if cache_size == 0:
417 if cache_size == 0:
410 if ps1.find('%n') > -1 or ps1.find('\\#') > -1: ps1 = '>>> '
418 if ps1.find('%n') > -1 or ps1.find('\\#') > -1: ps1 = '>>> '
411 if ps2.find('%n') > -1 or ps2.find('\\#') > -1: ps2 = '... '
419 if ps2.find('%n') > -1 or ps2.find('\\#') > -1: ps2 = '... '
412 self.ps1_str = self._set_prompt_str(ps1,'In [\\#]: ','>>> ')
420 self.ps1_str = self._set_prompt_str(ps1,'In [\\#]: ','>>> ')
413 self.ps2_str = self._set_prompt_str(ps2,' .\\D.: ','... ')
421 self.ps2_str = self._set_prompt_str(ps2,' .\\D.: ','... ')
414 self.ps_out_str = self._set_prompt_str(ps_out,'Out[\\#]: ','')
422 self.ps_out_str = self._set_prompt_str(ps_out,'Out[\\#]: ','')
415
423
424 self.color_table = PromptColors
416 self.prompt1 = Prompt1(self,sep=input_sep,prompt=self.ps1_str,
425 self.prompt1 = Prompt1(self,sep=input_sep,prompt=self.ps1_str,
417 pad_left=pad_left)
426 pad_left=pad_left)
418 self.prompt2 = Prompt2(self,prompt=self.ps2_str,pad_left=pad_left)
427 self.prompt2 = Prompt2(self,prompt=self.ps2_str,pad_left=pad_left)
419 self.prompt_out = PromptOut(self,sep='',prompt=self.ps_out_str,
428 self.prompt_out = PromptOut(self,sep='',prompt=self.ps_out_str,
420 pad_left=pad_left)
429 pad_left=pad_left)
421 self.color_table = PromptColors
422 self.set_colors(colors)
430 self.set_colors(colors)
423
431
424 # other more normal stuff
432 # other more normal stuff
425 # b/c each call to the In[] prompt raises it by 1, even the first.
433 # b/c each call to the In[] prompt raises it by 1, even the first.
426 self.prompt_count = 0
434 self.prompt_count = 0
427 self.cache_count = 1
435 self.cache_count = 1
428 # Store the last prompt string each time, we need it for aligning
436 # Store the last prompt string each time, we need it for aligning
429 # continuation and auto-rewrite prompts
437 # continuation and auto-rewrite prompts
430 self.last_prompt = ''
438 self.last_prompt = ''
431 self.entries = [None] # output counter starts at 1 for the user
439 self.entries = [None] # output counter starts at 1 for the user
432 self.Pprint = Pprint
440 self.Pprint = Pprint
433 self.output_sep = output_sep
441 self.output_sep = output_sep
434 self.output_sep2 = output_sep2
442 self.output_sep2 = output_sep2
435 self._,self.__,self.___ = '','',''
443 self._,self.__,self.___ = '','',''
436 self.pprint_types = map(type,[(),[],{}])
444 self.pprint_types = map(type,[(),[],{}])
437
445
438 # these are deliberately global:
446 # these are deliberately global:
439 to_user_ns = {'_':self._,'__':self.__,'___':self.___}
447 to_user_ns = {'_':self._,'__':self.__,'___':self.___}
440 self.user_ns.update(to_user_ns)
448 self.user_ns.update(to_user_ns)
441
449
442 def _set_prompt_str(self,p_str,cache_def,no_cache_def):
450 def _set_prompt_str(self,p_str,cache_def,no_cache_def):
443 if p_str is None:
451 if p_str is None:
444 if self.do_full_cache:
452 if self.do_full_cache:
445 return cache_def
453 return cache_def
446 else:
454 else:
447 return no_cache_def
455 return no_cache_def
448 else:
456 else:
449 return p_str
457 return p_str
450
458
451 def set_colors(self,colors):
459 def set_colors(self,colors):
452 """Set the active color scheme and configure colors for the three
460 """Set the active color scheme and configure colors for the three
453 prompt subsystems."""
461 prompt subsystems."""
454
462
455 # FIXME: the prompt_specials global should be gobbled inside this
463 # FIXME: the prompt_specials global should be gobbled inside this
456 # class instead. Do it when cleaning up the whole 3-prompt system.
464 # class instead. Do it when cleaning up the whole 3-prompt system.
457 global prompt_specials
465 global prompt_specials
458 if colors.lower()=='nocolor':
466 if colors.lower()=='nocolor':
459 prompt_specials = prompt_specials_nocolor
467 prompt_specials = prompt_specials_nocolor
460 else:
468 else:
461 prompt_specials = prompt_specials_color
469 prompt_specials = prompt_specials_color
462
470
463 self.color_table.set_active_scheme(colors)
471 self.color_table.set_active_scheme(colors)
464 self.prompt1.set_colors()
472 self.prompt1.set_colors()
465 self.prompt2.set_colors()
473 self.prompt2.set_colors()
466 self.prompt_out.set_colors()
474 self.prompt_out.set_colors()
467
475
468 def __call__(self,arg=None):
476 def __call__(self,arg=None):
469 """Printing with history cache management.
477 """Printing with history cache management.
470
478
471 This is invoked everytime the interpreter needs to print, and is
479 This is invoked everytime the interpreter needs to print, and is
472 activated by setting the variable sys.displayhook to it."""
480 activated by setting the variable sys.displayhook to it."""
473
481
474 # If something injected a '_' variable in __builtin__, delete
482 # If something injected a '_' variable in __builtin__, delete
475 # ipython's automatic one so we don't clobber that. gettext() in
483 # ipython's automatic one so we don't clobber that. gettext() in
476 # particular uses _, so we need to stay away from it.
484 # particular uses _, so we need to stay away from it.
477 if '_' in __builtin__.__dict__:
485 if '_' in __builtin__.__dict__:
478 try:
486 try:
479 del self.user_ns['_']
487 del self.user_ns['_']
480 except KeyError:
488 except KeyError:
481 pass
489 pass
482 if arg is not None:
490 if arg is not None:
491 cout_write = Term.cout.write # fast lookup
483 # first handle the cache and counters
492 # first handle the cache and counters
484 self.update(arg)
493 self.update(arg)
485 # do not print output if input ends in ';'
494 # do not print output if input ends in ';'
486 if self.input_hist[self.prompt_count].endswith(';\n'):
495 if self.input_hist[self.prompt_count].endswith(';\n'):
487 return
496 return
488 # don't use print, puts an extra space
497 # don't use print, puts an extra space
489 Term.cout.write(self.output_sep)
498 cout_write(self.output_sep)
490 if self.do_full_cache:
499 if self.do_full_cache:
491 Term.cout.write(str(self.prompt_out))
500 cout_write(str(self.prompt_out))
492
501
493 if isinstance(arg,Macro):
502 if isinstance(arg,Macro):
494 print 'Executing Macro...'
503 print 'Executing Macro...'
495 # in case the macro takes a long time to execute
504 # in case the macro takes a long time to execute
496 Term.cout.flush()
505 Term.cout.flush()
497 exec arg.value in self.user_ns
506 exec arg.value in self.user_ns
498 return None
507 return None
499
508
500 # and now call a possibly user-defined print mechanism
509 # and now call a possibly user-defined print mechanism
501 self.display(arg)
510 self.display(arg)
502 Term.cout.write(self.output_sep2)
511 cout_write(self.output_sep2)
503 Term.cout.flush()
512 Term.cout.flush()
504
513
505 def _display(self,arg):
514 def _display(self,arg):
506 """Default printer method, uses pprint.
515 """Default printer method, uses pprint.
507
516
508 This can be over-ridden by the users to implement special formatting
517 This can be over-ridden by the users to implement special formatting
509 of certain types of output."""
518 of certain types of output."""
510
519
511 if self.Pprint:
520 if self.Pprint:
512 # The following is an UGLY kludge, b/c python fails to properly
513 # identify instances of classes imported in the user namespace
514 # (they have different memory locations, I guess). Structs are
515 # essentially dicts but pprint doesn't know what to do with them.
516 try:
517 if arg.__class__.__module__ == 'Struct' and \
518 arg.__class__.__name__ == 'Struct':
519 out = 'Struct:\n%s' % pformat(arg.dict())
520 else:
521 out = pformat(arg)
522 except:
523 out = pformat(arg)
521 out = pformat(arg)
524 if '\n' in out:
522 if '\n' in out:
525 # So that multi-line strings line up with the left column of
523 # So that multi-line strings line up with the left column of
526 # the screen, instead of having the output prompt mess up
524 # the screen, instead of having the output prompt mess up
527 # their first line.
525 # their first line.
528 Term.cout.write('\n')
526 Term.cout.write('\n')
529 print >>Term.cout, out
527 print >>Term.cout, out
530 else:
528 else:
531 print >>Term.cout, arg
529 print >>Term.cout, arg
532
530
533 # Assign the default display method:
531 # Assign the default display method:
534 display = _display
532 display = _display
535
533
536 def update(self,arg):
534 def update(self,arg):
537 #print '***cache_count', self.cache_count # dbg
535 #print '***cache_count', self.cache_count # dbg
538 if self.cache_count >= self.cache_size and self.do_full_cache:
536 if self.cache_count >= self.cache_size and self.do_full_cache:
539 self.flush()
537 self.flush()
540 # Don't overwrite '_' and friends if '_' is in __builtin__ (otherwise
538 # Don't overwrite '_' and friends if '_' is in __builtin__ (otherwise
541 # we cause buggy behavior for things like gettext).
539 # we cause buggy behavior for things like gettext).
542 if '_' not in __builtin__.__dict__:
540 if '_' not in __builtin__.__dict__:
543 self.___ = self.__
541 self.___ = self.__
544 self.__ = self._
542 self.__ = self._
545 self._ = arg
543 self._ = arg
546 self.user_ns.update({'_':self._,'__':self.__,'___':self.___})
544 self.user_ns.update({'_':self._,'__':self.__,'___':self.___})
547
545
548 # hackish access to top-level namespace to create _1,_2... dynamically
546 # hackish access to top-level namespace to create _1,_2... dynamically
549 to_main = {}
547 to_main = {}
550 if self.do_full_cache:
548 if self.do_full_cache:
551 self.cache_count += 1
549 self.cache_count += 1
552 self.entries.append(arg)
550 self.entries.append(arg)
553 new_result = '_'+`self.prompt_count`
551 new_result = '_'+`self.prompt_count`
554 to_main[new_result] = self.entries[-1]
552 to_main[new_result] = self.entries[-1]
555 self.user_ns.update(to_main)
553 self.user_ns.update(to_main)
556 self.user_ns['_oh'][self.prompt_count] = arg
554 self.user_ns['_oh'][self.prompt_count] = arg
557
555
558 def flush(self):
556 def flush(self):
559 if not self.do_full_cache:
557 if not self.do_full_cache:
560 raise ValueError,"You shouldn't have reached the cache flush "\
558 raise ValueError,"You shouldn't have reached the cache flush "\
561 "if full caching is not enabled!"
559 "if full caching is not enabled!"
562 warn('Output cache limit (currently '+\
560 warn('Output cache limit (currently '+\
563 `self.cache_count`+' entries) hit.\n'
561 `self.cache_count`+' entries) hit.\n'
564 'Flushing cache and resetting history counter...\n'
562 'Flushing cache and resetting history counter...\n'
565 'The only history variables available will be _,__,___ and _1\n'
563 'The only history variables available will be _,__,___ and _1\n'
566 'with the current result.')
564 'with the current result.')
567 # delete auto-generated vars from global namespace
565 # delete auto-generated vars from global namespace
568 for n in range(1,self.prompt_count + 1):
566 for n in range(1,self.prompt_count + 1):
569 key = '_'+`n`
567 key = '_'+`n`
570 try:
568 try:
571 del self.user_ns[key]
569 del self.user_ns[key]
572 except: pass
570 except: pass
573 self.prompt_count = 1
571 self.prompt_count = 1
574 self.cache_count = 1
572 self.cache_count = 1
@@ -1,376 +1,375 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Mimic C structs with lots of extra functionality.
2 """Mimic C structs with lots of extra functionality.
3
3
4 $Id: Struct.py 410 2004-11-04 07:58:17Z fperez $"""
4 $Id: Struct.py 638 2005-07-18 03:01:41Z fperez $"""
5
5
6 #*****************************************************************************
6 #*****************************************************************************
7 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
7 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
8 #
8 #
9 # Distributed under the terms of the BSD License. The full license is in
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
10 # the file COPYING, distributed as part of this software.
11 #*****************************************************************************
11 #*****************************************************************************
12
12
13 from IPython import Release
13 from IPython import Release
14 __author__ = '%s <%s>' % Release.authors['Fernando']
14 __author__ = '%s <%s>' % Release.authors['Fernando']
15 __license__ = Release.license
15 __license__ = Release.license
16
16
17 __all__ = ['Struct']
17 __all__ = ['Struct']
18
18
19 import types
19 import types
20 from IPython.genutils import list2dict2
20 from IPython.genutils import list2dict2
21
21
22 class Struct:
22 class Struct:
23 """Class to mimic C structs but also provide convenient dictionary-like
23 """Class to mimic C structs but also provide convenient dictionary-like
24 functionality.
24 functionality.
25
25
26 Instances can be initialized with a dictionary, a list of key=value pairs
26 Instances can be initialized with a dictionary, a list of key=value pairs
27 or both. If both are present, the dictionary must come first.
27 or both. If both are present, the dictionary must come first.
28
28
29 Because Python classes provide direct assignment to their members, it's
29 Because Python classes provide direct assignment to their members, it's
30 easy to overwrite normal methods (S.copy = 1 would destroy access to
30 easy to overwrite normal methods (S.copy = 1 would destroy access to
31 S.copy()). For this reason, all builtin method names are protected and
31 S.copy()). For this reason, all builtin method names are protected and
32 can't be assigned to. An attempt to do s.copy=1 or s['copy']=1 will raise
32 can't be assigned to. An attempt to do s.copy=1 or s['copy']=1 will raise
33 a KeyError exception. If you really want to, you can bypass this
33 a KeyError exception. If you really want to, you can bypass this
34 protection by directly assigning to __dict__: s.__dict__['copy']=1 will
34 protection by directly assigning to __dict__: s.__dict__['copy']=1 will
35 still work. Doing this will break functionality, though. As in most of
35 still work. Doing this will break functionality, though. As in most of
36 Python, namespace protection is weakly enforced, so feel free to shoot
36 Python, namespace protection is weakly enforced, so feel free to shoot
37 yourself if you really want to.
37 yourself if you really want to.
38
38
39 Note that this class uses more memory and is *much* slower than a regular
39 Note that this class uses more memory and is *much* slower than a regular
40 dictionary, so be careful in situations where memory or performance are
40 dictionary, so be careful in situations where memory or performance are
41 critical. But for day to day use it should behave fine. It is particularly
41 critical. But for day to day use it should behave fine. It is particularly
42 convenient for storing configuration data in programs.
42 convenient for storing configuration data in programs.
43
43
44 +,+=,- and -= are implemented. +/+= do merges (non-destructive updates),
44 +,+=,- and -= are implemented. +/+= do merges (non-destructive updates),
45 -/-= remove keys from the original. See the method descripitions.
45 -/-= remove keys from the original. See the method descripitions.
46
46
47 This class allows a quick access syntax: both s.key and s['key'] are
47 This class allows a quick access syntax: both s.key and s['key'] are
48 valid. This syntax has a limitation: each 'key' has to be explicitly
48 valid. This syntax has a limitation: each 'key' has to be explicitly
49 accessed by its original name. The normal s.key syntax doesn't provide
49 accessed by its original name. The normal s.key syntax doesn't provide
50 access to the keys via variables whose values evaluate to the desired
50 access to the keys via variables whose values evaluate to the desired
51 keys. An example should clarify this:
51 keys. An example should clarify this:
52
52
53 Define a dictionary and initialize both with dict and k=v pairs:
53 Define a dictionary and initialize both with dict and k=v pairs:
54 >>> d={'a':1,'b':2}
54 >>> d={'a':1,'b':2}
55 >>> s=Struct(d,hi=10,ho=20)
55 >>> s=Struct(d,hi=10,ho=20)
56 The return of __repr__ can be used to create a new instance:
56 The return of __repr__ can be used to create a new instance:
57 >>> s
57 >>> s
58 Struct({'ho': 20, 'b': 2, 'hi': 10, 'a': 1})
58 Struct({'ho': 20, 'b': 2, 'hi': 10, 'a': 1})
59 __str__ (called by print) shows it's not quite a regular dictionary:
59 __str__ (called by print) shows it's not quite a regular dictionary:
60 >>> print s
60 >>> print s
61 Struct {a: 1, b: 2, hi: 10, ho: 20}
61 Struct {a: 1, b: 2, hi: 10, ho: 20}
62 Access by explicitly named key with dot notation:
62 Access by explicitly named key with dot notation:
63 >>> s.a
63 >>> s.a
64 1
64 1
65 Or like a dictionary:
65 Or like a dictionary:
66 >>> s['a']
66 >>> s['a']
67 1
67 1
68 If you want a variable to hold the key value, only dictionary access works:
68 If you want a variable to hold the key value, only dictionary access works:
69 >>> key='hi'
69 >>> key='hi'
70 >>> s.key
70 >>> s.key
71 Traceback (most recent call last):
71 Traceback (most recent call last):
72 File "<stdin>", line 1, in ?
72 File "<stdin>", line 1, in ?
73 AttributeError: Struct instance has no attribute 'key'
73 AttributeError: Struct instance has no attribute 'key'
74 >>> s[key]
74 >>> s[key]
75 10
75 10
76
76
77 Another limitation of the s.key syntax (and Struct(key=val)
77 Another limitation of the s.key syntax (and Struct(key=val)
78 initialization): keys can't be numbers. But numeric keys can be used and
78 initialization): keys can't be numbers. But numeric keys can be used and
79 accessed using the dictionary syntax. Again, an example:
79 accessed using the dictionary syntax. Again, an example:
80
80
81 This doesn't work:
81 This doesn't work:
82 >>> s=Struct(4='hi')
82 >>> s=Struct(4='hi')
83 SyntaxError: keyword can't be an expression
83 SyntaxError: keyword can't be an expression
84 But this does:
84 But this does:
85 >>> s=Struct()
85 >>> s=Struct()
86 >>> s[4]='hi'
86 >>> s[4]='hi'
87 >>> s
87 >>> s
88 Struct({4: 'hi'})
88 Struct({4: 'hi'})
89 >>> s[4]
89 >>> s[4]
90 'hi'
90 'hi'
91 """
91 """
92
92
93 # Attributes to which __setitem__ and __setattr__ will block access.
93 # Attributes to which __setitem__ and __setattr__ will block access.
94 # Note: much of this will be moot in Python 2.2 and will be done in a much
94 # Note: much of this will be moot in Python 2.2 and will be done in a much
95 # cleaner way.
95 # cleaner way.
96 __protected = ('copy dict dictcopy get has_attr has_key items keys '
96 __protected = ('copy dict dictcopy get has_attr has_key items keys '
97 'merge popitem setdefault update values '
97 'merge popitem setdefault update values '
98 '__make_dict __dict_invert ').split()
98 '__make_dict __dict_invert ').split()
99
99
100 def __init__(self,dict=None,**kw):
100 def __init__(self,dict=None,**kw):
101 """Initialize with a dictionary, another Struct, or by giving
101 """Initialize with a dictionary, another Struct, or by giving
102 explicitly the list of attributes.
102 explicitly the list of attributes.
103
103
104 Both can be used, but the dictionary must come first:
104 Both can be used, but the dictionary must come first:
105 Struct(dict), Struct(k1=v1,k2=v2) or Struct(dict,k1=v1,k2=v2).
105 Struct(dict), Struct(k1=v1,k2=v2) or Struct(dict,k1=v1,k2=v2).
106 """
106 """
107 if dict is None:
107 if dict is None:
108 dict = {}
108 dict = {}
109 if isinstance(dict,Struct):
109 if isinstance(dict,Struct):
110 dict = dict.dict()
110 dict = dict.dict()
111 elif dict and type(dict) is not types.DictType:
111 elif dict and type(dict) is not types.DictType:
112 raise TypeError,\
112 raise TypeError,\
113 'Initialize with a dictionary or key=val pairs.'
113 'Initialize with a dictionary or key=val pairs.'
114 dict.update(kw)
114 dict.update(kw)
115 # do the updating by hand to guarantee that we go through the
115 # do the updating by hand to guarantee that we go through the
116 # safety-checked __setitem__
116 # safety-checked __setitem__
117 for k,v in dict.items():
117 for k,v in dict.items():
118 self[k] = v
118 self[k] = v
119
119
120 def __setitem__(self,key,value):
120 def __setitem__(self,key,value):
121 """Used when struct[key] = val calls are made."""
121 """Used when struct[key] = val calls are made."""
122 if key in Struct.__protected:
122 if key in Struct.__protected:
123 raise KeyError,'Key '+`key`+' is a protected key of class Struct.'
123 raise KeyError,'Key '+`key`+' is a protected key of class Struct.'
124 self.__dict__[key] = value
124 self.__dict__[key] = value
125
125
126 def __setattr__(self, key, value):
126 def __setattr__(self, key, value):
127 """Used when struct.key = val calls are made."""
127 """Used when struct.key = val calls are made."""
128 self.__setitem__(key,value)
128 self.__setitem__(key,value)
129
129
130 def __str__(self):
130 def __str__(self):
131 """Gets called by print."""
131 """Gets called by print."""
132
132
133 return 'Struct('+str(self.__dict__)+')'
133 return 'Struct('+str(self.__dict__)+')'
134
134
135 def __repr__(self):
135 def __repr__(self):
136 """Gets called by repr.
136 """Gets called by repr.
137
137
138 A Struct can be recreated with S_new=eval(repr(S_old))."""
138 A Struct can be recreated with S_new=eval(repr(S_old))."""
139 return 'Struct('+str(self.__dict__)+')'
139 return 'Struct('+str(self.__dict__)+')'
140
140
141 def __getitem__(self,key):
141 def __getitem__(self,key):
142 """Allows struct[key] access."""
142 """Allows struct[key] access."""
143 return self.__dict__[key]
143 return self.__dict__[key]
144
144
145 def __contains__(self,key):
145 def __contains__(self,key):
146 """Allows use of the 'in' operator."""
146 """Allows use of the 'in' operator."""
147 return self.__dict__.has_key(key)
147 return self.__dict__.has_key(key)
148
148
149 def __iadd__(self,other):
149 def __iadd__(self,other):
150 """S += S2 is a shorthand for S.merge(S2)."""
150 """S += S2 is a shorthand for S.merge(S2)."""
151 self.merge(other)
151 self.merge(other)
152 return self
152 return self
153
153
154 def __add__(self,other):
154 def __add__(self,other):
155 """S + S2 -> New Struct made form S and S.merge(S2)"""
155 """S + S2 -> New Struct made form S and S.merge(S2)"""
156 Sout = self.copy()
156 Sout = self.copy()
157 Sout.merge(other)
157 Sout.merge(other)
158 return Sout
158 return Sout
159
159
160 def __sub__(self,other):
160 def __sub__(self,other):
161 """Return S1-S2, where all keys in S2 have been deleted (if present)
161 """Return S1-S2, where all keys in S2 have been deleted (if present)
162 from S1."""
162 from S1."""
163 Sout = self.copy()
163 Sout = self.copy()
164 Sout -= other
164 Sout -= other
165 return Sout
165 return Sout
166
166
167 def __isub__(self,other):
167 def __isub__(self,other):
168 """Do in place S = S - S2, meaning all keys in S2 have been deleted
168 """Do in place S = S - S2, meaning all keys in S2 have been deleted
169 (if present) from S1."""
169 (if present) from S1."""
170
170
171 for k in other.keys():
171 for k in other.keys():
172 if self.has_key(k):
172 if self.has_key(k):
173 del self.__dict__[k]
173 del self.__dict__[k]
174
174
175 def __make_dict(self,__loc_data__,**kw):
175 def __make_dict(self,__loc_data__,**kw):
176 "Helper function for update and merge. Return a dict from data."
176 "Helper function for update and merge. Return a dict from data."
177
177
178 if __loc_data__ == None:
178 if __loc_data__ == None:
179 dict = {}
179 dict = {}
180 elif type(__loc_data__) is types.DictType:
180 elif type(__loc_data__) is types.DictType:
181 dict = __loc_data__
181 dict = __loc_data__
182 elif isinstance(__loc_data__,Struct):
182 elif isinstance(__loc_data__,Struct):
183 dict = __loc_data__.__dict__
183 dict = __loc_data__.__dict__
184 else:
184 else:
185 raise TypeError, 'Update with a dict, a Struct or key=val pairs.'
185 raise TypeError, 'Update with a dict, a Struct or key=val pairs.'
186 if kw:
186 if kw:
187 dict.update(kw)
187 dict.update(kw)
188 return dict
188 return dict
189
189
190 def __dict_invert(self,dict):
190 def __dict_invert(self,dict):
191 """Helper function for merge. Takes a dictionary whose values are
191 """Helper function for merge. Takes a dictionary whose values are
192 lists and returns a dict. with the elements of each list as keys and
192 lists and returns a dict. with the elements of each list as keys and
193 the original keys as values."""
193 the original keys as values."""
194
194
195 outdict = {}
195 outdict = {}
196 for k,lst in dict.items():
196 for k,lst in dict.items():
197 if type(lst) is types.StringType:
197 if type(lst) is types.StringType:
198 lst = lst.split()
198 lst = lst.split()
199 for entry in lst:
199 for entry in lst:
200 outdict[entry] = k
200 outdict[entry] = k
201 return outdict
201 return outdict
202
202
203 def clear(self):
203 def clear(self):
204 """Clear all attributes."""
204 """Clear all attributes."""
205 self.__dict__.clear()
205 self.__dict__.clear()
206
206
207 def copy(self):
207 def copy(self):
208 """Return a (shallow) copy of a Struct."""
208 """Return a (shallow) copy of a Struct."""
209 return Struct(self.__dict__.copy())
209 return Struct(self.__dict__.copy())
210
210
211 def dict(self):
211 def dict(self):
212 """Return the Struct's dictionary."""
212 """Return the Struct's dictionary."""
213 return self.__dict__
213 return self.__dict__
214
214
215 def dictcopy(self):
215 def dictcopy(self):
216 """Return a (shallow) copy of the Struct's dictionary."""
216 """Return a (shallow) copy of the Struct's dictionary."""
217 return self.__dict__.copy()
217 return self.__dict__.copy()
218
218
219 def popitem(self):
219 def popitem(self):
220 """S.popitem() -> (k, v), remove and return some (key, value) pair as
220 """S.popitem() -> (k, v), remove and return some (key, value) pair as
221 a 2-tuple; but raise KeyError if S is empty."""
221 a 2-tuple; but raise KeyError if S is empty."""
222 return self.__dict__.popitem()
222 return self.__dict__.popitem()
223
223
224 def update(self,__loc_data__=None,**kw):
224 def update(self,__loc_data__=None,**kw):
225 """Update (merge) with data from another Struct or from a dictionary.
225 """Update (merge) with data from another Struct or from a dictionary.
226 Optionally, one or more key=value pairs can be given at the end for
226 Optionally, one or more key=value pairs can be given at the end for
227 direct update."""
227 direct update."""
228
228
229 # The funny name __loc_data__ is to prevent a common variable name which
229 # The funny name __loc_data__ is to prevent a common variable name which
230 # could be a fieled of a Struct to collide with this parameter. The problem
230 # could be a fieled of a Struct to collide with this parameter. The problem
231 # would arise if the function is called with a keyword with this same name
231 # would arise if the function is called with a keyword with this same name
232 # that a user means to add as a Struct field.
232 # that a user means to add as a Struct field.
233 newdict = Struct.__make_dict(self,__loc_data__,**kw)
233 newdict = Struct.__make_dict(self,__loc_data__,**kw)
234 for k,v in newdict.items():
234 for k,v in newdict.items():
235 self[k] = v
235 self[k] = v
236
236
237 def merge(self,__loc_data__=None,__conflict_solve=None,**kw):
237 def merge(self,__loc_data__=None,__conflict_solve=None,**kw):
238 """S.merge(data,conflict,k=v1,k=v2,...) -> merge data and k=v into S.
238 """S.merge(data,conflict,k=v1,k=v2,...) -> merge data and k=v into S.
239
239
240 This is similar to update(), but much more flexible. First, a dict is
240 This is similar to update(), but much more flexible. First, a dict is
241 made from data+key=value pairs. When merging this dict with the Struct
241 made from data+key=value pairs. When merging this dict with the Struct
242 S, the optional dictionary 'conflict' is used to decide what to do.
242 S, the optional dictionary 'conflict' is used to decide what to do.
243
243
244 If conflict is not given, the default behavior is to preserve any keys
244 If conflict is not given, the default behavior is to preserve any keys
245 with their current value (the opposite of the update method's
245 with their current value (the opposite of the update method's
246 behavior).
246 behavior).
247
247
248 conflict is a dictionary of binary functions which will be used to
248 conflict is a dictionary of binary functions which will be used to
249 solve key conflicts. It must have the following structure:
249 solve key conflicts. It must have the following structure:
250
250
251 conflict == { fn1 : [Skey1,Skey2,...], fn2 : [Skey3], etc }
251 conflict == { fn1 : [Skey1,Skey2,...], fn2 : [Skey3], etc }
252
252
253 Values must be lists or whitespace separated strings which are
253 Values must be lists or whitespace separated strings which are
254 automatically converted to lists of strings by calling string.split().
254 automatically converted to lists of strings by calling string.split().
255
255
256 Each key of conflict is a function which defines a policy for
256 Each key of conflict is a function which defines a policy for
257 resolving conflicts when merging with the input data. Each fn must be
257 resolving conflicts when merging with the input data. Each fn must be
258 a binary function which returns the desired outcome for a key
258 a binary function which returns the desired outcome for a key
259 conflict. These functions will be called as fn(old,new).
259 conflict. These functions will be called as fn(old,new).
260
260
261 An example is probably in order. Suppose you are merging the struct S
261 An example is probably in order. Suppose you are merging the struct S
262 with a dict D and the following conflict policy dict:
262 with a dict D and the following conflict policy dict:
263
263
264 S.merge(D,{fn1:['a','b',4], fn2:'key_c key_d'})
264 S.merge(D,{fn1:['a','b',4], fn2:'key_c key_d'})
265
265
266 If the key 'a' is found in both S and D, the merge method will call:
266 If the key 'a' is found in both S and D, the merge method will call:
267
267
268 S['a'] = fn1(S['a'],D['a'])
268 S['a'] = fn1(S['a'],D['a'])
269
269
270 As a convenience, merge() provides five (the most commonly needed)
270 As a convenience, merge() provides five (the most commonly needed)
271 pre-defined policies: preserve, update, add, add_flip and add_s. The
271 pre-defined policies: preserve, update, add, add_flip and add_s. The
272 easiest explanation is their implementation:
272 easiest explanation is their implementation:
273
273
274 preserve = lambda old,new: old
274 preserve = lambda old,new: old
275 update = lambda old,new: new
275 update = lambda old,new: new
276 add = lambda old,new: old + new
276 add = lambda old,new: old + new
277 add_flip = lambda old,new: new + old # note change of order!
277 add_flip = lambda old,new: new + old # note change of order!
278 add_s = lambda old,new: old + ' ' + new # only works for strings!
278 add_s = lambda old,new: old + ' ' + new # only works for strings!
279
279
280 You can use those four words (as strings) as keys in conflict instead
280 You can use those four words (as strings) as keys in conflict instead
281 of defining them as functions, and the merge method will substitute
281 of defining them as functions, and the merge method will substitute
282 the appropriate functions for you. That is, the call
282 the appropriate functions for you. That is, the call
283
283
284 S.merge(D,{'preserve':'a b c','add':[4,5,'d'],my_function:[6]})
284 S.merge(D,{'preserve':'a b c','add':[4,5,'d'],my_function:[6]})
285
285
286 will automatically substitute the functions preserve and add for the
286 will automatically substitute the functions preserve and add for the
287 names 'preserve' and 'add' before making any function calls.
287 names 'preserve' and 'add' before making any function calls.
288
288
289 For more complicated conflict resolution policies, you still need to
289 For more complicated conflict resolution policies, you still need to
290 construct your own functions. """
290 construct your own functions. """
291
291
292 data_dict = Struct.__make_dict(self,__loc_data__,**kw)
292 data_dict = Struct.__make_dict(self,__loc_data__,**kw)
293
293
294 # policies for conflict resolution: two argument functions which return
294 # policies for conflict resolution: two argument functions which return
295 # the value that will go in the new struct
295 # the value that will go in the new struct
296 preserve = lambda old,new: old
296 preserve = lambda old,new: old
297 update = lambda old,new: new
297 update = lambda old,new: new
298 add = lambda old,new: old + new
298 add = lambda old,new: old + new
299 add_flip = lambda old,new: new + old # note change of order!
299 add_flip = lambda old,new: new + old # note change of order!
300 add_s = lambda old,new: old + ' ' + new
300 add_s = lambda old,new: old + ' ' + new
301
301
302 # default policy is to keep current keys when there's a conflict
302 # default policy is to keep current keys when there's a conflict
303 conflict_solve = list2dict2(self.keys(),default = preserve)
303 conflict_solve = list2dict2(self.keys(),default = preserve)
304
304
305 # the conflict_solve dictionary is given by the user 'inverted': we
305 # the conflict_solve dictionary is given by the user 'inverted': we
306 # need a name-function mapping, it comes as a function -> names
306 # need a name-function mapping, it comes as a function -> names
307 # dict. Make a local copy (b/c we'll make changes), replace user
307 # dict. Make a local copy (b/c we'll make changes), replace user
308 # strings for the three builtin policies and invert it.
308 # strings for the three builtin policies and invert it.
309 if __conflict_solve:
309 if __conflict_solve:
310 inv_conflict_solve_user = __conflict_solve.copy()
310 inv_conflict_solve_user = __conflict_solve.copy()
311 for name, func in [('preserve',preserve), ('update',update),
311 for name, func in [('preserve',preserve), ('update',update),
312 ('add',add), ('add_flip',add_flip), ('add_s',add_s)]:
312 ('add',add), ('add_flip',add_flip), ('add_s',add_s)]:
313 if name in inv_conflict_solve_user.keys():
313 if name in inv_conflict_solve_user.keys():
314 inv_conflict_solve_user[func] = inv_conflict_solve_user[name]
314 inv_conflict_solve_user[func] = inv_conflict_solve_user[name]
315 del inv_conflict_solve_user[name]
315 del inv_conflict_solve_user[name]
316 conflict_solve.update(Struct.__dict_invert(self,inv_conflict_solve_user))
316 conflict_solve.update(Struct.__dict_invert(self,inv_conflict_solve_user))
317 #print 'merge. conflict_solve: '; pprint(conflict_solve) # dbg
317 #print 'merge. conflict_solve: '; pprint(conflict_solve) # dbg
318 # after Python 2.2, use iterators: for key in data_dict will then work
319 #print '*'*50,'in merger. conflict_solver:'; pprint(conflict_solve)
318 #print '*'*50,'in merger. conflict_solver:'; pprint(conflict_solve)
320 for key in data_dict.keys():
319 for key in data_dict:
321 if key not in self:
320 if key not in self:
322 self[key] = data_dict[key]
321 self[key] = data_dict[key]
323 else:
322 else:
324 self[key] = conflict_solve[key](self[key],data_dict[key])
323 self[key] = conflict_solve[key](self[key],data_dict[key])
325
324
326 def has_key(self,key):
325 def has_key(self,key):
327 """Like has_key() dictionary method."""
326 """Like has_key() dictionary method."""
328 return self.__dict__.has_key(key)
327 return self.__dict__.has_key(key)
329
328
330 def hasattr(self,key):
329 def hasattr(self,key):
331 """hasattr function available as a method.
330 """hasattr function available as a method.
332
331
333 Implemented like has_key, to make sure that all available keys in the
332 Implemented like has_key, to make sure that all available keys in the
334 internal dictionary of the Struct appear also as attributes (even
333 internal dictionary of the Struct appear also as attributes (even
335 numeric keys)."""
334 numeric keys)."""
336 return self.__dict__.has_key(key)
335 return self.__dict__.has_key(key)
337
336
338 def items(self):
337 def items(self):
339 """Return the items in the Struct's dictionary, in the same format
338 """Return the items in the Struct's dictionary, in the same format
340 as a call to {}.items()."""
339 as a call to {}.items()."""
341 return self.__dict__.items()
340 return self.__dict__.items()
342
341
343 def keys(self):
342 def keys(self):
344 """Return the keys in the Struct's dictionary, in the same format
343 """Return the keys in the Struct's dictionary, in the same format
345 as a call to {}.keys()."""
344 as a call to {}.keys()."""
346 return self.__dict__.keys()
345 return self.__dict__.keys()
347
346
348 def values(self,keys=None):
347 def values(self,keys=None):
349 """Return the values in the Struct's dictionary, in the same format
348 """Return the values in the Struct's dictionary, in the same format
350 as a call to {}.values().
349 as a call to {}.values().
351
350
352 Can be called with an optional argument keys, which must be a list or
351 Can be called with an optional argument keys, which must be a list or
353 tuple of keys. In this case it returns only the values corresponding
352 tuple of keys. In this case it returns only the values corresponding
354 to those keys (allowing a form of 'slicing' for Structs)."""
353 to those keys (allowing a form of 'slicing' for Structs)."""
355 if not keys:
354 if not keys:
356 return self.__dict__.values()
355 return self.__dict__.values()
357 else:
356 else:
358 ret=[]
357 ret=[]
359 for k in keys:
358 for k in keys:
360 ret.append(self[k])
359 ret.append(self[k])
361 return ret
360 return ret
362
361
363 def get(self,attr,val=None):
362 def get(self,attr,val=None):
364 """S.get(k[,d]) -> S[k] if S.has_key(k), else d. d defaults to None."""
363 """S.get(k[,d]) -> S[k] if S.has_key(k), else d. d defaults to None."""
365 try:
364 try:
366 return self[attr]
365 return self[attr]
367 except KeyError:
366 except KeyError:
368 return val
367 return val
369
368
370 def setdefault(self,attr,val=None):
369 def setdefault(self,attr,val=None):
371 """S.setdefault(k[,d]) -> S.get(k,d), also set S[k]=d if not S.has_key(k)"""
370 """S.setdefault(k[,d]) -> S.get(k,d), also set S[k]=d if not S.has_key(k)"""
372 if not self.has_key(attr):
371 if not self.has_key(attr):
373 self[attr] = val
372 self[attr] = val
374 return self.get(attr,val)
373 return self.get(attr,val)
375 # end class Struct
374 # end class Struct
376
375
@@ -1,504 +1,495 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Manage background (threaded) jobs conveniently from an interactive shell.
2 """Manage background (threaded) jobs conveniently from an interactive shell.
3
3
4 This module provides a BackgroundJobManager class. This is the main class
4 This module provides a BackgroundJobManager class. This is the main class
5 meant for public usage, it implements an object which can create and manage
5 meant for public usage, it implements an object which can create and manage
6 new background jobs.
6 new background jobs.
7
7
8 It also provides the actual job classes managed by these BackgroundJobManager
8 It also provides the actual job classes managed by these BackgroundJobManager
9 objects, see their docstrings below.
9 objects, see their docstrings below.
10
10
11
11
12 This system was inspired by discussions with B. Granger and the
12 This system was inspired by discussions with B. Granger and the
13 BackgroundCommand class described in the book Python Scripting for
13 BackgroundCommand class described in the book Python Scripting for
14 Computational Science, by H. P. Langtangen:
14 Computational Science, by H. P. Langtangen:
15
15
16 http://folk.uio.no/hpl/scripting
16 http://folk.uio.no/hpl/scripting
17
17
18 (although ultimately no code from this text was used, as IPython's system is a
18 (although ultimately no code from this text was used, as IPython's system is a
19 separate implementation).
19 separate implementation).
20
20
21 $Id: background_jobs.py 515 2005-02-15 07:41:41Z fperez $
21 $Id: background_jobs.py 638 2005-07-18 03:01:41Z fperez $
22 """
22 """
23
23
24 #*****************************************************************************
24 #*****************************************************************************
25 # Copyright (C) 2005 Fernando Perez <fperez@colorado.edu>
25 # Copyright (C) 2005 Fernando Perez <fperez@colorado.edu>
26 #
26 #
27 # Distributed under the terms of the BSD License. The full license is in
27 # Distributed under the terms of the BSD License. The full license is in
28 # the file COPYING, distributed as part of this software.
28 # the file COPYING, distributed as part of this software.
29 #*****************************************************************************
29 #*****************************************************************************
30
30
31 from IPython import Release
31 from IPython import Release
32 __author__ = '%s <%s>' % Release.authors['Fernando']
32 __author__ = '%s <%s>' % Release.authors['Fernando']
33 __license__ = Release.license
33 __license__ = Release.license
34
34
35 # Code begins
35 # Code begins
36 import threading,sys
36 import threading,sys
37
37
38 from IPython.ultraTB import AutoFormattedTB
38 from IPython.ultraTB import AutoFormattedTB
39 from IPython.genutils import warn,error
39 from IPython.genutils import warn,error
40
40
41 # declares Python 2.2 compatibility symbols:
42 try:
43 basestring
44 except NameError:
45 import types
46 basestring = (types.StringType, types.UnicodeType)
47 True = 1==1
48 False = 1==0
49
50 class BackgroundJobManager:
41 class BackgroundJobManager:
51 """Class to manage a pool of backgrounded threaded jobs.
42 """Class to manage a pool of backgrounded threaded jobs.
52
43
53 Below, we assume that 'jobs' is a BackgroundJobManager instance.
44 Below, we assume that 'jobs' is a BackgroundJobManager instance.
54
45
55 Usage summary (see the method docstrings for details):
46 Usage summary (see the method docstrings for details):
56
47
57 jobs.new(...) -> start a new job
48 jobs.new(...) -> start a new job
58
49
59 jobs() or jobs.status() -> print status summary of all jobs
50 jobs() or jobs.status() -> print status summary of all jobs
60
51
61 jobs[N] -> returns job number N.
52 jobs[N] -> returns job number N.
62
53
63 foo = jobs[N].result -> assign to variable foo the result of job N
54 foo = jobs[N].result -> assign to variable foo the result of job N
64
55
65 jobs[N].traceback() -> print the traceback of dead job N
56 jobs[N].traceback() -> print the traceback of dead job N
66
57
67 jobs.remove(N) -> remove (finished) job N
58 jobs.remove(N) -> remove (finished) job N
68
59
69 jobs.flush_finished() -> remove all finished jobs
60 jobs.flush_finished() -> remove all finished jobs
70
61
71 As a convenience feature, BackgroundJobManager instances provide the
62 As a convenience feature, BackgroundJobManager instances provide the
72 utility result and traceback methods which retrieve the corresponding
63 utility result and traceback methods which retrieve the corresponding
73 information from the jobs list:
64 information from the jobs list:
74
65
75 jobs.result(N) <--> jobs[N].result
66 jobs.result(N) <--> jobs[N].result
76 jobs.traceback(N) <--> jobs[N].traceback()
67 jobs.traceback(N) <--> jobs[N].traceback()
77
68
78 While this appears minor, it allows you to use tab completion
69 While this appears minor, it allows you to use tab completion
79 interactively on the job manager instance.
70 interactively on the job manager instance.
80
71
81 In interactive mode, IPython provides the magic fuction %bg for quick
72 In interactive mode, IPython provides the magic fuction %bg for quick
82 creation of backgrounded expression-based jobs. Type bg? for details."""
73 creation of backgrounded expression-based jobs. Type bg? for details."""
83
74
84 def __init__(self):
75 def __init__(self):
85 # Lists for job management
76 # Lists for job management
86 self.jobs_run = []
77 self.jobs_run = []
87 self.jobs_comp = []
78 self.jobs_comp = []
88 self.jobs_dead = []
79 self.jobs_dead = []
89 # A dict of all jobs, so users can easily access any of them
80 # A dict of all jobs, so users can easily access any of them
90 self.jobs_all = {}
81 self.jobs_all = {}
91 # For reporting
82 # For reporting
92 self._comp_report = []
83 self._comp_report = []
93 self._dead_report = []
84 self._dead_report = []
94 # Store status codes locally for fast lookups
85 # Store status codes locally for fast lookups
95 self._s_created = BackgroundJobBase.stat_created_c
86 self._s_created = BackgroundJobBase.stat_created_c
96 self._s_running = BackgroundJobBase.stat_running_c
87 self._s_running = BackgroundJobBase.stat_running_c
97 self._s_completed = BackgroundJobBase.stat_completed_c
88 self._s_completed = BackgroundJobBase.stat_completed_c
98 self._s_dead = BackgroundJobBase.stat_dead_c
89 self._s_dead = BackgroundJobBase.stat_dead_c
99
90
100 def new(self,func_or_exp,*args,**kwargs):
91 def new(self,func_or_exp,*args,**kwargs):
101 """Add a new background job and start it in a separate thread.
92 """Add a new background job and start it in a separate thread.
102
93
103 There are two types of jobs which can be created:
94 There are two types of jobs which can be created:
104
95
105 1. Jobs based on expressions which can be passed to an eval() call.
96 1. Jobs based on expressions which can be passed to an eval() call.
106 The expression must be given as a string. For example:
97 The expression must be given as a string. For example:
107
98
108 job_manager.new('myfunc(x,y,z=1)'[,glob[,loc]])
99 job_manager.new('myfunc(x,y,z=1)'[,glob[,loc]])
109
100
110 The given expression is passed to eval(), along with the optional
101 The given expression is passed to eval(), along with the optional
111 global/local dicts provided. If no dicts are given, they are
102 global/local dicts provided. If no dicts are given, they are
112 extracted automatically from the caller's frame.
103 extracted automatically from the caller's frame.
113
104
114 A Python statement is NOT a valid eval() expression. Basically, you
105 A Python statement is NOT a valid eval() expression. Basically, you
115 can only use as an eval() argument something which can go on the right
106 can only use as an eval() argument something which can go on the right
116 of an '=' sign and be assigned to a variable.
107 of an '=' sign and be assigned to a variable.
117
108
118 For example,"print 'hello'" is not valid, but '2+3' is.
109 For example,"print 'hello'" is not valid, but '2+3' is.
119
110
120 2. Jobs given a function object, optionally passing additional
111 2. Jobs given a function object, optionally passing additional
121 positional arguments:
112 positional arguments:
122
113
123 job_manager.new(myfunc,x,y)
114 job_manager.new(myfunc,x,y)
124
115
125 The function is called with the given arguments.
116 The function is called with the given arguments.
126
117
127 If you need to pass keyword arguments to your function, you must
118 If you need to pass keyword arguments to your function, you must
128 supply them as a dict named kw:
119 supply them as a dict named kw:
129
120
130 job_manager.new(myfunc,x,y,kw=dict(z=1))
121 job_manager.new(myfunc,x,y,kw=dict(z=1))
131
122
132 The reason for this assymmetry is that the new() method needs to
123 The reason for this assymmetry is that the new() method needs to
133 maintain access to its own keywords, and this prevents name collisions
124 maintain access to its own keywords, and this prevents name collisions
134 between arguments to new() and arguments to your own functions.
125 between arguments to new() and arguments to your own functions.
135
126
136 In both cases, the result is stored in the job.result field of the
127 In both cases, the result is stored in the job.result field of the
137 background job object.
128 background job object.
138
129
139
130
140 Notes and caveats:
131 Notes and caveats:
141
132
142 1. All threads running share the same standard output. Thus, if your
133 1. All threads running share the same standard output. Thus, if your
143 background jobs generate output, it will come out on top of whatever
134 background jobs generate output, it will come out on top of whatever
144 you are currently writing. For this reason, background jobs are best
135 you are currently writing. For this reason, background jobs are best
145 used with silent functions which simply return their output.
136 used with silent functions which simply return their output.
146
137
147 2. Threads also all work within the same global namespace, and this
138 2. Threads also all work within the same global namespace, and this
148 system does not lock interactive variables. So if you send job to the
139 system does not lock interactive variables. So if you send job to the
149 background which operates on a mutable object for a long time, and
140 background which operates on a mutable object for a long time, and
150 start modifying that same mutable object interactively (or in another
141 start modifying that same mutable object interactively (or in another
151 backgrounded job), all sorts of bizarre behaviour will occur.
142 backgrounded job), all sorts of bizarre behaviour will occur.
152
143
153 3. If a background job is spending a lot of time inside a C extension
144 3. If a background job is spending a lot of time inside a C extension
154 module which does not release the Python Global Interpreter Lock
145 module which does not release the Python Global Interpreter Lock
155 (GIL), this will block the IPython prompt. This is simply because the
146 (GIL), this will block the IPython prompt. This is simply because the
156 Python interpreter can only switch between threads at Python
147 Python interpreter can only switch between threads at Python
157 bytecodes. While the execution is inside C code, the interpreter must
148 bytecodes. While the execution is inside C code, the interpreter must
158 simply wait unless the extension module releases the GIL.
149 simply wait unless the extension module releases the GIL.
159
150
160 4. There is no way, due to limitations in the Python threads library,
151 4. There is no way, due to limitations in the Python threads library,
161 to kill a thread once it has started."""
152 to kill a thread once it has started."""
162
153
163 if callable(func_or_exp):
154 if callable(func_or_exp):
164 kw = kwargs.get('kw',{})
155 kw = kwargs.get('kw',{})
165 job = BackgroundJobFunc(func_or_exp,*args,**kw)
156 job = BackgroundJobFunc(func_or_exp,*args,**kw)
166 elif isinstance(func_or_exp,basestring):
157 elif isinstance(func_or_exp,basestring):
167 if not args:
158 if not args:
168 frame = sys._getframe(1)
159 frame = sys._getframe(1)
169 glob, loc = frame.f_globals, frame.f_locals
160 glob, loc = frame.f_globals, frame.f_locals
170 elif len(args)==1:
161 elif len(args)==1:
171 glob = loc = args[0]
162 glob = loc = args[0]
172 elif len(args)==2:
163 elif len(args)==2:
173 glob,loc = args
164 glob,loc = args
174 else:
165 else:
175 raise ValueError,\
166 raise ValueError,\
176 'Expression jobs take at most 2 args (globals,locals)'
167 'Expression jobs take at most 2 args (globals,locals)'
177 job = BackgroundJobExpr(func_or_exp,glob,loc)
168 job = BackgroundJobExpr(func_or_exp,glob,loc)
178 else:
169 else:
179 raise
170 raise
180 jkeys = self.jobs_all.keys()
171 jkeys = self.jobs_all.keys()
181 if jkeys:
172 if jkeys:
182 job.num = max(jkeys)+1
173 job.num = max(jkeys)+1
183 else:
174 else:
184 job.num = 0
175 job.num = 0
185 self.jobs_run.append(job)
176 self.jobs_run.append(job)
186 self.jobs_all[job.num] = job
177 self.jobs_all[job.num] = job
187 print 'Starting job # %s in a separate thread.' % job.num
178 print 'Starting job # %s in a separate thread.' % job.num
188 job.start()
179 job.start()
189 return job
180 return job
190
181
191 def __getitem__(self,key):
182 def __getitem__(self,key):
192 return self.jobs_all[key]
183 return self.jobs_all[key]
193
184
194 def __call__(self):
185 def __call__(self):
195 """An alias to self.status(),
186 """An alias to self.status(),
196
187
197 This allows you to simply call a job manager instance much like the
188 This allows you to simply call a job manager instance much like the
198 Unix jobs shell command."""
189 Unix jobs shell command."""
199
190
200 return self.status()
191 return self.status()
201
192
202 def _update_status(self):
193 def _update_status(self):
203 """Update the status of the job lists.
194 """Update the status of the job lists.
204
195
205 This method moves finished jobs to one of two lists:
196 This method moves finished jobs to one of two lists:
206 - self.jobs_comp: jobs which completed successfully
197 - self.jobs_comp: jobs which completed successfully
207 - self.jobs_dead: jobs which finished but died.
198 - self.jobs_dead: jobs which finished but died.
208
199
209 It also copies those jobs to corresponding _report lists. These lists
200 It also copies those jobs to corresponding _report lists. These lists
210 are used to report jobs completed/dead since the last update, and are
201 are used to report jobs completed/dead since the last update, and are
211 then cleared by the reporting function after each call."""
202 then cleared by the reporting function after each call."""
212
203
213 run,comp,dead = self._s_running,self._s_completed,self._s_dead
204 run,comp,dead = self._s_running,self._s_completed,self._s_dead
214 jobs_run = self.jobs_run
205 jobs_run = self.jobs_run
215 for num in range(len(jobs_run)):
206 for num in range(len(jobs_run)):
216 job = jobs_run[num]
207 job = jobs_run[num]
217 stat = job.stat_code
208 stat = job.stat_code
218 if stat == run:
209 if stat == run:
219 continue
210 continue
220 elif stat == comp:
211 elif stat == comp:
221 self.jobs_comp.append(job)
212 self.jobs_comp.append(job)
222 self._comp_report.append(job)
213 self._comp_report.append(job)
223 jobs_run[num] = False
214 jobs_run[num] = False
224 elif stat == dead:
215 elif stat == dead:
225 self.jobs_dead.append(job)
216 self.jobs_dead.append(job)
226 self._dead_report.append(job)
217 self._dead_report.append(job)
227 jobs_run[num] = False
218 jobs_run[num] = False
228 self.jobs_run = filter(None,self.jobs_run)
219 self.jobs_run = filter(None,self.jobs_run)
229
220
230 def _group_report(self,group,name):
221 def _group_report(self,group,name):
231 """Report summary for a given job group.
222 """Report summary for a given job group.
232
223
233 Return True if the group had any elements."""
224 Return True if the group had any elements."""
234
225
235 if group:
226 if group:
236 print '%s jobs:' % name
227 print '%s jobs:' % name
237 for job in group:
228 for job in group:
238 print '%s : %s' % (job.num,job)
229 print '%s : %s' % (job.num,job)
239 print
230 print
240 return True
231 return True
241
232
242 def _group_flush(self,group,name):
233 def _group_flush(self,group,name):
243 """Flush a given job group
234 """Flush a given job group
244
235
245 Return True if the group had any elements."""
236 Return True if the group had any elements."""
246
237
247 njobs = len(group)
238 njobs = len(group)
248 if njobs:
239 if njobs:
249 plural = {1:''}.setdefault(njobs,'s')
240 plural = {1:''}.setdefault(njobs,'s')
250 print 'Flushing %s %s job%s.' % (njobs,name,plural)
241 print 'Flushing %s %s job%s.' % (njobs,name,plural)
251 group[:] = []
242 group[:] = []
252 return True
243 return True
253
244
254 def _status_new(self):
245 def _status_new(self):
255 """Print the status of newly finished jobs.
246 """Print the status of newly finished jobs.
256
247
257 Return True if any new jobs are reported.
248 Return True if any new jobs are reported.
258
249
259 This call resets its own state every time, so it only reports jobs
250 This call resets its own state every time, so it only reports jobs
260 which have finished since the last time it was called."""
251 which have finished since the last time it was called."""
261
252
262 self._update_status()
253 self._update_status()
263 new_comp = self._group_report(self._comp_report,'Completed')
254 new_comp = self._group_report(self._comp_report,'Completed')
264 new_dead = self._group_report(self._dead_report,
255 new_dead = self._group_report(self._dead_report,
265 'Dead, call job.traceback() for details')
256 'Dead, call job.traceback() for details')
266 self._comp_report[:] = []
257 self._comp_report[:] = []
267 self._dead_report[:] = []
258 self._dead_report[:] = []
268 return new_comp or new_dead
259 return new_comp or new_dead
269
260
270 def status(self,verbose=0):
261 def status(self,verbose=0):
271 """Print a status of all jobs currently being managed."""
262 """Print a status of all jobs currently being managed."""
272
263
273 self._update_status()
264 self._update_status()
274 self._group_report(self.jobs_run,'Running')
265 self._group_report(self.jobs_run,'Running')
275 self._group_report(self.jobs_comp,'Completed')
266 self._group_report(self.jobs_comp,'Completed')
276 self._group_report(self.jobs_dead,'Dead')
267 self._group_report(self.jobs_dead,'Dead')
277 # Also flush the report queues
268 # Also flush the report queues
278 self._comp_report[:] = []
269 self._comp_report[:] = []
279 self._dead_report[:] = []
270 self._dead_report[:] = []
280
271
281 def remove(self,num):
272 def remove(self,num):
282 """Remove a finished (completed or dead) job."""
273 """Remove a finished (completed or dead) job."""
283
274
284 try:
275 try:
285 job = self.jobs_all[num]
276 job = self.jobs_all[num]
286 except KeyError:
277 except KeyError:
287 error('Job #%s not found' % num)
278 error('Job #%s not found' % num)
288 else:
279 else:
289 stat_code = job.stat_code
280 stat_code = job.stat_code
290 if stat_code == self._s_running:
281 if stat_code == self._s_running:
291 error('Job #%s is still running, it can not be removed.' % num)
282 error('Job #%s is still running, it can not be removed.' % num)
292 return
283 return
293 elif stat_code == self._s_completed:
284 elif stat_code == self._s_completed:
294 self.jobs_comp.remove(job)
285 self.jobs_comp.remove(job)
295 elif stat_code == self._s_dead:
286 elif stat_code == self._s_dead:
296 self.jobs_dead.remove(job)
287 self.jobs_dead.remove(job)
297
288
298 def flush_finished(self):
289 def flush_finished(self):
299 """Flush all jobs finished (completed and dead) from lists.
290 """Flush all jobs finished (completed and dead) from lists.
300
291
301 Running jobs are never flushed.
292 Running jobs are never flushed.
302
293
303 It first calls _status_new(), to update info. If any jobs have
294 It first calls _status_new(), to update info. If any jobs have
304 completed since the last _status_new() call, the flush operation
295 completed since the last _status_new() call, the flush operation
305 aborts."""
296 aborts."""
306
297
307 if self._status_new():
298 if self._status_new():
308 error('New jobs completed since last '\
299 error('New jobs completed since last '\
309 '_status_new(), aborting flush.')
300 '_status_new(), aborting flush.')
310 return
301 return
311
302
312 # Remove the finished jobs from the master dict
303 # Remove the finished jobs from the master dict
313 jobs_all = self.jobs_all
304 jobs_all = self.jobs_all
314 for job in self.jobs_comp+self.jobs_dead:
305 for job in self.jobs_comp+self.jobs_dead:
315 del(jobs_all[job.num])
306 del(jobs_all[job.num])
316
307
317 # Now flush these lists completely
308 # Now flush these lists completely
318 fl_comp = self._group_flush(self.jobs_comp,'Completed')
309 fl_comp = self._group_flush(self.jobs_comp,'Completed')
319 fl_dead = self._group_flush(self.jobs_dead,'Dead')
310 fl_dead = self._group_flush(self.jobs_dead,'Dead')
320 if not (fl_comp or fl_dead):
311 if not (fl_comp or fl_dead):
321 print 'No jobs to flush.'
312 print 'No jobs to flush.'
322
313
323 def result(self,num):
314 def result(self,num):
324 """result(N) -> return the result of job N."""
315 """result(N) -> return the result of job N."""
325 try:
316 try:
326 return self.jobs_all[num].result
317 return self.jobs_all[num].result
327 except KeyError:
318 except KeyError:
328 error('Job #%s not found' % num)
319 error('Job #%s not found' % num)
329
320
330 def traceback(self,num):
321 def traceback(self,num):
331 try:
322 try:
332 self.jobs_all[num].traceback()
323 self.jobs_all[num].traceback()
333 except KeyError:
324 except KeyError:
334 error('Job #%s not found' % num)
325 error('Job #%s not found' % num)
335
326
336
327
337 class BackgroundJobBase(threading.Thread):
328 class BackgroundJobBase(threading.Thread):
338 """Base class to build BackgroundJob classes.
329 """Base class to build BackgroundJob classes.
339
330
340 The derived classes must implement:
331 The derived classes must implement:
341
332
342 - Their own __init__, since the one here raises NotImplementedError. The
333 - Their own __init__, since the one here raises NotImplementedError. The
343 derived constructor must call self._init() at the end, to provide common
334 derived constructor must call self._init() at the end, to provide common
344 initialization.
335 initialization.
345
336
346 - A strform attribute used in calls to __str__.
337 - A strform attribute used in calls to __str__.
347
338
348 - A call() method, which will make the actual execution call and must
339 - A call() method, which will make the actual execution call and must
349 return a value to be held in the 'result' field of the job object."""
340 return a value to be held in the 'result' field of the job object."""
350
341
351 # Class constants for status, in string and as numerical codes (when
342 # Class constants for status, in string and as numerical codes (when
352 # updating jobs lists, we don't want to do string comparisons). This will
343 # updating jobs lists, we don't want to do string comparisons). This will
353 # be done at every user prompt, so it has to be as fast as possible
344 # be done at every user prompt, so it has to be as fast as possible
354 stat_created = 'Created'; stat_created_c = 0
345 stat_created = 'Created'; stat_created_c = 0
355 stat_running = 'Running'; stat_running_c = 1
346 stat_running = 'Running'; stat_running_c = 1
356 stat_completed = 'Completed'; stat_completed_c = 2
347 stat_completed = 'Completed'; stat_completed_c = 2
357 stat_dead = 'Dead (Exception), call job.traceback() for details'
348 stat_dead = 'Dead (Exception), call job.traceback() for details'
358 stat_dead_c = -1
349 stat_dead_c = -1
359
350
360 def __init__(self):
351 def __init__(self):
361 raise NotImplementedError, \
352 raise NotImplementedError, \
362 "This class can not be instantiated directly."
353 "This class can not be instantiated directly."
363
354
364 def _init(self):
355 def _init(self):
365 """Common initialization for all BackgroundJob objects"""
356 """Common initialization for all BackgroundJob objects"""
366
357
367 for attr in ['call','strform']:
358 for attr in ['call','strform']:
368 assert hasattr(self,attr), "Missing attribute <%s>" % attr
359 assert hasattr(self,attr), "Missing attribute <%s>" % attr
369
360
370 # The num tag can be set by an external job manager
361 # The num tag can be set by an external job manager
371 self.num = None
362 self.num = None
372
363
373 self.status = BackgroundJobBase.stat_created
364 self.status = BackgroundJobBase.stat_created
374 self.stat_code = BackgroundJobBase.stat_created_c
365 self.stat_code = BackgroundJobBase.stat_created_c
375 self.finished = False
366 self.finished = False
376 self.result = '<BackgroundJob has not completed>'
367 self.result = '<BackgroundJob has not completed>'
377 # reuse the ipython traceback handler if we can get to it, otherwise
368 # reuse the ipython traceback handler if we can get to it, otherwise
378 # make a new one
369 # make a new one
379 try:
370 try:
380 self._make_tb = __IPYTHON__.InteractiveTB.text
371 self._make_tb = __IPYTHON__.InteractiveTB.text
381 except:
372 except:
382 self._make_tb = AutoFormattedTB(mode = 'Context',
373 self._make_tb = AutoFormattedTB(mode = 'Context',
383 color_scheme='NoColor',
374 color_scheme='NoColor',
384 tb_offset = 1).text
375 tb_offset = 1).text
385 # Hold a formatted traceback if one is generated.
376 # Hold a formatted traceback if one is generated.
386 self._tb = None
377 self._tb = None
387
378
388 threading.Thread.__init__(self)
379 threading.Thread.__init__(self)
389
380
390 def __str__(self):
381 def __str__(self):
391 return self.strform
382 return self.strform
392
383
393 def __repr__(self):
384 def __repr__(self):
394 return '<BackgroundJob: %s>' % self.strform
385 return '<BackgroundJob: %s>' % self.strform
395
386
396 def traceback(self):
387 def traceback(self):
397 print self._tb
388 print self._tb
398
389
399 def run(self):
390 def run(self):
400 try:
391 try:
401 self.status = BackgroundJobBase.stat_running
392 self.status = BackgroundJobBase.stat_running
402 self.stat_code = BackgroundJobBase.stat_running_c
393 self.stat_code = BackgroundJobBase.stat_running_c
403 self.result = self.call()
394 self.result = self.call()
404 except:
395 except:
405 self.status = BackgroundJobBase.stat_dead
396 self.status = BackgroundJobBase.stat_dead
406 self.stat_code = BackgroundJobBase.stat_dead_c
397 self.stat_code = BackgroundJobBase.stat_dead_c
407 self.finished = None
398 self.finished = None
408 self.result = ('<BackgroundJob died, call job.traceback() for details>')
399 self.result = ('<BackgroundJob died, call job.traceback() for details>')
409 self._tb = self._make_tb()
400 self._tb = self._make_tb()
410 else:
401 else:
411 self.status = BackgroundJobBase.stat_completed
402 self.status = BackgroundJobBase.stat_completed
412 self.stat_code = BackgroundJobBase.stat_completed_c
403 self.stat_code = BackgroundJobBase.stat_completed_c
413 self.finished = True
404 self.finished = True
414
405
415 class BackgroundJobExpr(BackgroundJobBase):
406 class BackgroundJobExpr(BackgroundJobBase):
416 """Evaluate an expression as a background job (uses a separate thread)."""
407 """Evaluate an expression as a background job (uses a separate thread)."""
417
408
418 def __init__(self,expression,glob=None,loc=None):
409 def __init__(self,expression,glob=None,loc=None):
419 """Create a new job from a string which can be fed to eval().
410 """Create a new job from a string which can be fed to eval().
420
411
421 global/locals dicts can be provided, which will be passed to the eval
412 global/locals dicts can be provided, which will be passed to the eval
422 call."""
413 call."""
423
414
424 # fail immediately if the given expression can't be compiled
415 # fail immediately if the given expression can't be compiled
425 self.code = compile(expression,'<BackgroundJob compilation>','eval')
416 self.code = compile(expression,'<BackgroundJob compilation>','eval')
426
417
427 if glob is None:
418 if glob is None:
428 glob = {}
419 glob = {}
429 if loc is None:
420 if loc is None:
430 loc = {}
421 loc = {}
431
422
432 self.expression = self.strform = expression
423 self.expression = self.strform = expression
433 self.glob = glob
424 self.glob = glob
434 self.loc = loc
425 self.loc = loc
435 self._init()
426 self._init()
436
427
437 def call(self):
428 def call(self):
438 return eval(self.code,self.glob,self.loc)
429 return eval(self.code,self.glob,self.loc)
439
430
440 class BackgroundJobFunc(BackgroundJobBase):
431 class BackgroundJobFunc(BackgroundJobBase):
441 """Run a function call as a background job (uses a separate thread)."""
432 """Run a function call as a background job (uses a separate thread)."""
442
433
443 def __init__(self,func,*args,**kwargs):
434 def __init__(self,func,*args,**kwargs):
444 """Create a new job from a callable object.
435 """Create a new job from a callable object.
445
436
446 Any positional arguments and keyword args given to this constructor
437 Any positional arguments and keyword args given to this constructor
447 after the initial callable are passed directly to it."""
438 after the initial callable are passed directly to it."""
448
439
449 assert callable(func),'first argument must be callable'
440 assert callable(func),'first argument must be callable'
450
441
451 if args is None:
442 if args is None:
452 args = []
443 args = []
453 if kwargs is None:
444 if kwargs is None:
454 kwargs = {}
445 kwargs = {}
455
446
456 self.func = func
447 self.func = func
457 self.args = args
448 self.args = args
458 self.kwargs = kwargs
449 self.kwargs = kwargs
459 # The string form will only include the function passed, because
450 # The string form will only include the function passed, because
460 # generating string representations of the arguments is a potentially
451 # generating string representations of the arguments is a potentially
461 # _very_ expensive operation (e.g. with large arrays).
452 # _very_ expensive operation (e.g. with large arrays).
462 self.strform = str(func)
453 self.strform = str(func)
463 self._init()
454 self._init()
464
455
465 def call(self):
456 def call(self):
466 return self.func(*self.args,**self.kwargs)
457 return self.func(*self.args,**self.kwargs)
467
458
468
459
469 if __name__=='__main__':
460 if __name__=='__main__':
470
461
471 import time
462 import time
472
463
473 def sleepfunc(interval=2,*a,**kw):
464 def sleepfunc(interval=2,*a,**kw):
474 args = dict(interval=interval,
465 args = dict(interval=interval,
475 args=a,
466 args=a,
476 kwargs=kw)
467 kwargs=kw)
477 time.sleep(interval)
468 time.sleep(interval)
478 return args
469 return args
479
470
480 def diefunc(interval=2,*a,**kw):
471 def diefunc(interval=2,*a,**kw):
481 time.sleep(interval)
472 time.sleep(interval)
482 die
473 die
483
474
484 def printfunc(interval=1,reps=5):
475 def printfunc(interval=1,reps=5):
485 for n in range(reps):
476 for n in range(reps):
486 time.sleep(interval)
477 time.sleep(interval)
487 print 'In the background...'
478 print 'In the background...'
488
479
489 jobs = BackgroundJobManager()
480 jobs = BackgroundJobManager()
490 # first job will have # 0
481 # first job will have # 0
491 jobs.new(sleepfunc,4)
482 jobs.new(sleepfunc,4)
492 jobs.new(sleepfunc,kw={'reps':2})
483 jobs.new(sleepfunc,kw={'reps':2})
493 # This makes a job which will die
484 # This makes a job which will die
494 jobs.new(diefunc,1)
485 jobs.new(diefunc,1)
495 jobs.new('printfunc(1,3)')
486 jobs.new('printfunc(1,3)')
496
487
497 # after a while, you can get the traceback of a dead job. Run the line
488 # after a while, you can get the traceback of a dead job. Run the line
498 # below again interactively until it prints a traceback (check the status
489 # below again interactively until it prints a traceback (check the status
499 # of the job):
490 # of the job):
500 print jobs[1].status
491 print jobs[1].status
501 jobs[1].traceback()
492 jobs[1].traceback()
502
493
503 # Run this line again until the printed result changes
494 # Run this line again until the printed result changes
504 print "The result of job #0 is:",jobs[0].result
495 print "The result of job #0 is:",jobs[0].result
@@ -1,1519 +1,1508 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 General purpose utilities.
3 General purpose utilities.
4
4
5 This is a grab-bag of stuff I find useful in most programs I write. Some of
5 This is a grab-bag of stuff I find useful in most programs I write. Some of
6 these things are also convenient when working at the command line.
6 these things are also convenient when working at the command line.
7
7
8 $Id: genutils.py 633 2005-07-17 01:03:15Z tzanko $"""
8 $Id: genutils.py 638 2005-07-18 03:01:41Z fperez $"""
9
9
10 #*****************************************************************************
10 #*****************************************************************************
11 # Copyright (C) 2001-2004 Fernando Perez. <fperez@colorado.edu>
11 # Copyright (C) 2001-2004 Fernando Perez. <fperez@colorado.edu>
12 #
12 #
13 # 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
14 # the file COPYING, distributed as part of this software.
14 # the file COPYING, distributed as part of this software.
15 #*****************************************************************************
15 #*****************************************************************************
16
16
17 from IPython import Release
17 from IPython import Release
18 __author__ = '%s <%s>' % Release.authors['Fernando']
18 __author__ = '%s <%s>' % Release.authors['Fernando']
19 __license__ = Release.license
19 __license__ = Release.license
20
20
21 #****************************************************************************
21 #****************************************************************************
22 # required modules
22 # required modules
23 import __main__
23 import __main__
24 import types,commands,time,sys,os,re,shutil
24 import types,commands,time,sys,os,re,shutil
25 import tempfile
25 import tempfile
26 import codecs
26 from IPython.Itpl import Itpl,itpl,printpl
27 from IPython.Itpl import Itpl,itpl,printpl
27 from IPython import DPyGetOpt
28 from IPython import DPyGetOpt
28
29
30 # Build objects which appeared in Python 2.3 for 2.2, to make ipython
31 # 2.2-friendly
32 try:
33 basestring
34 except NameError:
35 import types
36 basestring = (types.StringType, types.UnicodeType)
37 True = 1==1
38 False = 1==0
39
40 def enumerate(obj):
41 i = -1
42 for item in obj:
43 i += 1
44 yield i, item
45
46 # add these to the builtin namespace, so that all modules find them
47 import __builtin__
48 __builtin__.basestring = basestring
49 __builtin__.True = True
50 __builtin__.False = False
51 __builtin__.enumerate = enumerate
52
29 #****************************************************************************
53 #****************************************************************************
30 # Exceptions
54 # Exceptions
31 class Error(Exception):
55 class Error(Exception):
32 """Base class for exceptions in this module."""
56 """Base class for exceptions in this module."""
33 pass
57 pass
34
58
35 #----------------------------------------------------------------------------
59 #----------------------------------------------------------------------------
36 class Stream:
60 class IOStream:
37 """Simple class to hold the various I/O streams in Term"""
61 def __init__(self,stream,fallback):
38
62 if not hasattr(stream,'write') or not hasattr(stream,'flush'):
39 def __init__(self,stream,name):
63 stream = fallback
40 self.stream = stream
64 self.stream = stream
41 self.name = name
65 self._swrite = stream.write
66 self.flush = stream.flush
67
68 def write(self,data):
42 try:
69 try:
43 self.fileno = stream.fileno()
70 self._swrite(data)
44 except AttributeError:
71 except:
45 msg = ("Stream <%s> looks suspicious: it lacks a 'fileno' attribute."
46 % name)
47 print >> sys.stderr, 'WARNING:',msg
48 try:
72 try:
49 self.mode = stream.mode
73 # print handles some unicode issues which may trip a plain
50 except AttributeError:
74 # write() call. Attempt to emulate write() by using a
51 msg = ("Stream <%s> looks suspicious: it lacks a 'mode' attribute."
75 # trailing comma
52 % name)
76 print >> self.stream, data,
53 print >> sys.stderr, 'WARNING:',msg
77 except:
78 # if we get here, something is seriously broken.
79 print >> sys.stderr, \
80 'ERROR - failed to write data to stream:', stream
54
81
55 class Term:
82 class IOTerm:
56 """ Term holds the file or file-like objects for handling I/O operations.
83 """ Term holds the file or file-like objects for handling I/O operations.
57
84
58 These are normally just sys.stdin, sys.stdout and sys.stderr but for
85 These are normally just sys.stdin, sys.stdout and sys.stderr but for
59 Windows they can can replaced to allow editing the strings before they are
86 Windows they can can replaced to allow editing the strings before they are
60 displayed."""
87 displayed."""
61
88
62 # In the future, having IPython channel all its I/O operations through
89 # In the future, having IPython channel all its I/O operations through
63 # this class will make it easier to embed it into other environments which
90 # this class will make it easier to embed it into other environments which
64 # are not a normal terminal (such as a GUI-based shell)
91 # are not a normal terminal (such as a GUI-based shell)
65 in_s = Stream(sys.stdin,'cin')
92 def __init__(self,cin=None,cout=None,cerr=None):
66 out_s = Stream(sys.stdout,'cout')
93 self.cin = IOStream(cin,sys.stdin)
67 err_s = Stream(sys.stderr,'cerr')
94 self.cout = IOStream(cout,sys.stdout)
68
95 self.cerr = IOStream(cerr,sys.stderr)
69 # Store the three streams in (err,out,in) order so that if we need to reopen
70 # them, the error channel is reopened first to provide info.
71 streams = [err_s,out_s,in_s]
72
73 # The class globals should be the actual 'bare' streams for normal I/O to work
74 cin = streams[2].stream
75 cout = streams[1].stream
76 cerr = streams[0].stream
77
78 def reopen_all(cls):
79 """Reopen all streams if necessary.
80
81 This should only be called if it is suspected that someting closed
82 accidentally one of the I/O streams."""
83
84 any_closed = 0
85
86 for sn in range(len(cls.streams)):
87 st = cls.streams[sn]
88 if st.stream.closed:
89 any_closed = 1
90 new_stream = os.fdopen(os.dup(st.fileno), st.mode,0)
91 cls.streams[sn] = Stream(new_stream,st.name)
92 print >> cls.streams[0].stream, \
93 '\nWARNING:\nStream Term.%s had to be reopened!' % st.name
94
95 # Rebuild the class globals
96 cls.cin = cls.streams[2].stream
97 cls.cout = cls.streams[1].stream
98 cls.cerr = cls.streams[0].stream
99
100 reopen_all = classmethod(reopen_all)
101
102 def set_stdout(cls,stream):
103 """Set the stream """
104 cls.cout = stream
105 set_stdout = classmethod(set_stdout)
106
96
107 def set_stderr(cls,stream):
97 # Global variable to be used for all I/O
108 cls.cerr = stream
98 Term = IOTerm()
109 set_stderr = classmethod(set_stderr)
110
99
111 # Windows-specific code to load Gary Bishop's readline and configure it
100 # Windows-specific code to load Gary Bishop's readline and configure it
112 # automatically for the users
101 # automatically for the users
113 # Note: os.name on cygwin returns posix, so this should only pick up 'native'
102 # Note: os.name on cygwin returns posix, so this should only pick up 'native'
114 # windows. Cygwin returns 'cygwin' for sys.platform.
103 # windows. Cygwin returns 'cygwin' for sys.platform.
115 if os.name == 'nt':
104 if os.name == 'nt':
116 try:
105 try:
117 import readline
106 import readline
118 except ImportError:
107 except ImportError:
119 pass
108 pass
120 else:
109 else:
121 try:
110 try:
122 _out = readline.GetOutputFile()
111 _out = readline.GetOutputFile()
123 except AttributeError:
112 except AttributeError:
124 pass
113 pass
125 else:
114 else:
126 Term.set_stdout(_out)
115 # Remake Term to use the readline i/o facilities
127 Term.set_stderr(_out)
116 Term = IOTerm(cout=_out,cerr=_out)
128 del _out
117 del _out
129
118
130 #****************************************************************************
119 #****************************************************************************
131 # Generic warning/error printer, used by everything else
120 # Generic warning/error printer, used by everything else
132 def warn(msg,level=2,exit_val=1):
121 def warn(msg,level=2,exit_val=1):
133 """Standard warning printer. Gives formatting consistency.
122 """Standard warning printer. Gives formatting consistency.
134
123
135 Output is sent to Term.cerr (sys.stderr by default).
124 Output is sent to Term.cerr (sys.stderr by default).
136
125
137 Options:
126 Options:
138
127
139 -level(2): allows finer control:
128 -level(2): allows finer control:
140 0 -> Do nothing, dummy function.
129 0 -> Do nothing, dummy function.
141 1 -> Print message.
130 1 -> Print message.
142 2 -> Print 'WARNING:' + message. (Default level).
131 2 -> Print 'WARNING:' + message. (Default level).
143 3 -> Print 'ERROR:' + message.
132 3 -> Print 'ERROR:' + message.
144 4 -> Print 'FATAL ERROR:' + message and trigger a sys.exit(exit_val).
133 4 -> Print 'FATAL ERROR:' + message and trigger a sys.exit(exit_val).
145
134
146 -exit_val (1): exit value returned by sys.exit() for a level 4
135 -exit_val (1): exit value returned by sys.exit() for a level 4
147 warning. Ignored for all other levels."""
136 warning. Ignored for all other levels."""
148
137
149 if level>0:
138 if level>0:
150 header = ['','','WARNING: ','ERROR: ','FATAL ERROR: ']
139 header = ['','','WARNING: ','ERROR: ','FATAL ERROR: ']
151 print >> Term.cerr, '%s%s' % (header[level],msg)
140 print >> Term.cerr, '%s%s' % (header[level],msg)
152 if level == 4:
141 if level == 4:
153 print >> Term.cerr,'Exiting.\n'
142 print >> Term.cerr,'Exiting.\n'
154 sys.exit(exit_val)
143 sys.exit(exit_val)
155
144
156 def info(msg):
145 def info(msg):
157 """Equivalent to warn(msg,level=1)."""
146 """Equivalent to warn(msg,level=1)."""
158
147
159 warn(msg,level=1)
148 warn(msg,level=1)
160
149
161 def error(msg):
150 def error(msg):
162 """Equivalent to warn(msg,level=3)."""
151 """Equivalent to warn(msg,level=3)."""
163
152
164 warn(msg,level=3)
153 warn(msg,level=3)
165
154
166 def fatal(msg,exit_val=1):
155 def fatal(msg,exit_val=1):
167 """Equivalent to warn(msg,exit_val=exit_val,level=4)."""
156 """Equivalent to warn(msg,exit_val=exit_val,level=4)."""
168
157
169 warn(msg,exit_val=exit_val,level=4)
158 warn(msg,exit_val=exit_val,level=4)
170
159
171 #----------------------------------------------------------------------------
160 #----------------------------------------------------------------------------
172 StringTypes = types.StringTypes
161 StringTypes = types.StringTypes
173
162
174 # Basic timing functionality
163 # Basic timing functionality
175
164
176 # If possible (Unix), use the resource module instead of time.clock()
165 # If possible (Unix), use the resource module instead of time.clock()
177 try:
166 try:
178 import resource
167 import resource
179 def clock():
168 def clock():
180 """clock() -> floating point number
169 """clock() -> floating point number
181
170
182 Return the CPU time in seconds (user time only, system time is
171 Return the CPU time in seconds (user time only, system time is
183 ignored) since the start of the process. This is done via a call to
172 ignored) since the start of the process. This is done via a call to
184 resource.getrusage, so it avoids the wraparound problems in
173 resource.getrusage, so it avoids the wraparound problems in
185 time.clock()."""
174 time.clock()."""
186
175
187 return resource.getrusage(resource.RUSAGE_SELF)[0]
176 return resource.getrusage(resource.RUSAGE_SELF)[0]
188
177
189 def clock2():
178 def clock2():
190 """clock2() -> (t_user,t_system)
179 """clock2() -> (t_user,t_system)
191
180
192 Similar to clock(), but return a tuple of user/system times."""
181 Similar to clock(), but return a tuple of user/system times."""
193 return resource.getrusage(resource.RUSAGE_SELF)[:2]
182 return resource.getrusage(resource.RUSAGE_SELF)[:2]
194
183
195 except ImportError:
184 except ImportError:
196 clock = time.clock
185 clock = time.clock
197 def clock2():
186 def clock2():
198 """Under windows, system CPU time can't be measured.
187 """Under windows, system CPU time can't be measured.
199
188
200 This just returns clock() and zero."""
189 This just returns clock() and zero."""
201 return time.clock(),0.0
190 return time.clock(),0.0
202
191
203 def timings_out(reps,func,*args,**kw):
192 def timings_out(reps,func,*args,**kw):
204 """timings_out(reps,func,*args,**kw) -> (t_total,t_per_call,output)
193 """timings_out(reps,func,*args,**kw) -> (t_total,t_per_call,output)
205
194
206 Execute a function reps times, return a tuple with the elapsed total
195 Execute a function reps times, return a tuple with the elapsed total
207 CPU time in seconds, the time per call and the function's output.
196 CPU time in seconds, the time per call and the function's output.
208
197
209 Under Unix, the return value is the sum of user+system time consumed by
198 Under Unix, the return value is the sum of user+system time consumed by
210 the process, computed via the resource module. This prevents problems
199 the process, computed via the resource module. This prevents problems
211 related to the wraparound effect which the time.clock() function has.
200 related to the wraparound effect which the time.clock() function has.
212
201
213 Under Windows the return value is in wall clock seconds. See the
202 Under Windows the return value is in wall clock seconds. See the
214 documentation for the time module for more details."""
203 documentation for the time module for more details."""
215
204
216 reps = int(reps)
205 reps = int(reps)
217 assert reps >=1, 'reps must be >= 1'
206 assert reps >=1, 'reps must be >= 1'
218 if reps==1:
207 if reps==1:
219 start = clock()
208 start = clock()
220 out = func(*args,**kw)
209 out = func(*args,**kw)
221 tot_time = clock()-start
210 tot_time = clock()-start
222 else:
211 else:
223 rng = xrange(reps-1) # the last time is executed separately to store output
212 rng = xrange(reps-1) # the last time is executed separately to store output
224 start = clock()
213 start = clock()
225 for dummy in rng: func(*args,**kw)
214 for dummy in rng: func(*args,**kw)
226 out = func(*args,**kw) # one last time
215 out = func(*args,**kw) # one last time
227 tot_time = clock()-start
216 tot_time = clock()-start
228 av_time = tot_time / reps
217 av_time = tot_time / reps
229 return tot_time,av_time,out
218 return tot_time,av_time,out
230
219
231 def timings(reps,func,*args,**kw):
220 def timings(reps,func,*args,**kw):
232 """timings(reps,func,*args,**kw) -> (t_total,t_per_call)
221 """timings(reps,func,*args,**kw) -> (t_total,t_per_call)
233
222
234 Execute a function reps times, return a tuple with the elapsed total CPU
223 Execute a function reps times, return a tuple with the elapsed total CPU
235 time in seconds and the time per call. These are just the first two values
224 time in seconds and the time per call. These are just the first two values
236 in timings_out()."""
225 in timings_out()."""
237
226
238 return timings_out(reps,func,*args,**kw)[0:2]
227 return timings_out(reps,func,*args,**kw)[0:2]
239
228
240 def timing(func,*args,**kw):
229 def timing(func,*args,**kw):
241 """timing(func,*args,**kw) -> t_total
230 """timing(func,*args,**kw) -> t_total
242
231
243 Execute a function once, return the elapsed total CPU time in
232 Execute a function once, return the elapsed total CPU time in
244 seconds. This is just the first value in timings_out()."""
233 seconds. This is just the first value in timings_out()."""
245
234
246 return timings_out(1,func,*args,**kw)[0]
235 return timings_out(1,func,*args,**kw)[0]
247
236
248 #****************************************************************************
237 #****************************************************************************
249 # file and system
238 # file and system
250
239
251 def system(cmd,verbose=0,debug=0,header=''):
240 def system(cmd,verbose=0,debug=0,header=''):
252 """Execute a system command, return its exit status.
241 """Execute a system command, return its exit status.
253
242
254 Options:
243 Options:
255
244
256 - verbose (0): print the command to be executed.
245 - verbose (0): print the command to be executed.
257
246
258 - debug (0): only print, do not actually execute.
247 - debug (0): only print, do not actually execute.
259
248
260 - header (''): Header to print on screen prior to the executed command (it
249 - header (''): Header to print on screen prior to the executed command (it
261 is only prepended to the command, no newlines are added).
250 is only prepended to the command, no newlines are added).
262
251
263 Note: a stateful version of this function is available through the
252 Note: a stateful version of this function is available through the
264 SystemExec class."""
253 SystemExec class."""
265
254
266 stat = 0
255 stat = 0
267 if verbose or debug: print header+cmd
256 if verbose or debug: print header+cmd
268 sys.stdout.flush()
257 sys.stdout.flush()
269 if not debug: stat = os.system(cmd)
258 if not debug: stat = os.system(cmd)
270 return stat
259 return stat
271
260
272 def shell(cmd,verbose=0,debug=0,header=''):
261 def shell(cmd,verbose=0,debug=0,header=''):
273 """Execute a command in the system shell, always return None.
262 """Execute a command in the system shell, always return None.
274
263
275 Options:
264 Options:
276
265
277 - verbose (0): print the command to be executed.
266 - verbose (0): print the command to be executed.
278
267
279 - debug (0): only print, do not actually execute.
268 - debug (0): only print, do not actually execute.
280
269
281 - header (''): Header to print on screen prior to the executed command (it
270 - header (''): Header to print on screen prior to the executed command (it
282 is only prepended to the command, no newlines are added).
271 is only prepended to the command, no newlines are added).
283
272
284 Note: this is similar to genutils.system(), but it returns None so it can
273 Note: this is similar to genutils.system(), but it returns None so it can
285 be conveniently used in interactive loops without getting the return value
274 be conveniently used in interactive loops without getting the return value
286 (typically 0) printed many times."""
275 (typically 0) printed many times."""
287
276
288 stat = 0
277 stat = 0
289 if verbose or debug: print header+cmd
278 if verbose or debug: print header+cmd
290 # flush stdout so we don't mangle python's buffering
279 # flush stdout so we don't mangle python's buffering
291 sys.stdout.flush()
280 sys.stdout.flush()
292 if not debug:
281 if not debug:
293 os.system(cmd)
282 os.system(cmd)
294
283
295 def getoutput(cmd,verbose=0,debug=0,header='',split=0):
284 def getoutput(cmd,verbose=0,debug=0,header='',split=0):
296 """Dummy substitute for perl's backquotes.
285 """Dummy substitute for perl's backquotes.
297
286
298 Executes a command and returns the output.
287 Executes a command and returns the output.
299
288
300 Accepts the same arguments as system(), plus:
289 Accepts the same arguments as system(), plus:
301
290
302 - split(0): if true, the output is returned as a list split on newlines.
291 - split(0): if true, the output is returned as a list split on newlines.
303
292
304 Note: a stateful version of this function is available through the
293 Note: a stateful version of this function is available through the
305 SystemExec class."""
294 SystemExec class."""
306
295
307 if verbose or debug: print header+cmd
296 if verbose or debug: print header+cmd
308 if not debug:
297 if not debug:
309 output = commands.getoutput(cmd)
298 output = commands.getoutput(cmd)
310 if split:
299 if split:
311 return output.split('\n')
300 return output.split('\n')
312 else:
301 else:
313 return output
302 return output
314
303
315 def getoutputerror(cmd,verbose=0,debug=0,header='',split=0):
304 def getoutputerror(cmd,verbose=0,debug=0,header='',split=0):
316 """Return (standard output,standard error) of executing cmd in a shell.
305 """Return (standard output,standard error) of executing cmd in a shell.
317
306
318 Accepts the same arguments as system(), plus:
307 Accepts the same arguments as system(), plus:
319
308
320 - split(0): if true, each of stdout/err is returned as a list split on
309 - split(0): if true, each of stdout/err is returned as a list split on
321 newlines.
310 newlines.
322
311
323 Note: a stateful version of this function is available through the
312 Note: a stateful version of this function is available through the
324 SystemExec class."""
313 SystemExec class."""
325
314
326 if verbose or debug: print header+cmd
315 if verbose or debug: print header+cmd
327 if not cmd:
316 if not cmd:
328 if split:
317 if split:
329 return [],[]
318 return [],[]
330 else:
319 else:
331 return '',''
320 return '',''
332 if not debug:
321 if not debug:
333 pin,pout,perr = os.popen3(cmd)
322 pin,pout,perr = os.popen3(cmd)
334 tout = pout.read().rstrip()
323 tout = pout.read().rstrip()
335 terr = perr.read().rstrip()
324 terr = perr.read().rstrip()
336 pin.close()
325 pin.close()
337 pout.close()
326 pout.close()
338 perr.close()
327 perr.close()
339 if split:
328 if split:
340 return tout.split('\n'),terr.split('\n')
329 return tout.split('\n'),terr.split('\n')
341 else:
330 else:
342 return tout,terr
331 return tout,terr
343
332
344 # for compatibility with older naming conventions
333 # for compatibility with older naming conventions
345 xsys = system
334 xsys = system
346 bq = getoutput
335 bq = getoutput
347
336
348 class SystemExec:
337 class SystemExec:
349 """Access the system and getoutput functions through a stateful interface.
338 """Access the system and getoutput functions through a stateful interface.
350
339
351 Note: here we refer to the system and getoutput functions from this
340 Note: here we refer to the system and getoutput functions from this
352 library, not the ones from the standard python library.
341 library, not the ones from the standard python library.
353
342
354 This class offers the system and getoutput functions as methods, but the
343 This class offers the system and getoutput functions as methods, but the
355 verbose, debug and header parameters can be set for the instance (at
344 verbose, debug and header parameters can be set for the instance (at
356 creation time or later) so that they don't need to be specified on each
345 creation time or later) so that they don't need to be specified on each
357 call.
346 call.
358
347
359 For efficiency reasons, there's no way to override the parameters on a
348 For efficiency reasons, there's no way to override the parameters on a
360 per-call basis other than by setting instance attributes. If you need
349 per-call basis other than by setting instance attributes. If you need
361 local overrides, it's best to directly call system() or getoutput().
350 local overrides, it's best to directly call system() or getoutput().
362
351
363 The following names are provided as alternate options:
352 The following names are provided as alternate options:
364 - xsys: alias to system
353 - xsys: alias to system
365 - bq: alias to getoutput
354 - bq: alias to getoutput
366
355
367 An instance can then be created as:
356 An instance can then be created as:
368 >>> sysexec = SystemExec(verbose=1,debug=0,header='Calling: ')
357 >>> sysexec = SystemExec(verbose=1,debug=0,header='Calling: ')
369
358
370 And used as:
359 And used as:
371 >>> sysexec.xsys('pwd')
360 >>> sysexec.xsys('pwd')
372 >>> dirlist = sysexec.bq('ls -l')
361 >>> dirlist = sysexec.bq('ls -l')
373 """
362 """
374
363
375 def __init__(self,verbose=0,debug=0,header='',split=0):
364 def __init__(self,verbose=0,debug=0,header='',split=0):
376 """Specify the instance's values for verbose, debug and header."""
365 """Specify the instance's values for verbose, debug and header."""
377 setattr_list(self,'verbose debug header split')
366 setattr_list(self,'verbose debug header split')
378
367
379 def system(self,cmd):
368 def system(self,cmd):
380 """Stateful interface to system(), with the same keyword parameters."""
369 """Stateful interface to system(), with the same keyword parameters."""
381
370
382 system(cmd,self.verbose,self.debug,self.header)
371 system(cmd,self.verbose,self.debug,self.header)
383
372
384 def shell(self,cmd):
373 def shell(self,cmd):
385 """Stateful interface to shell(), with the same keyword parameters."""
374 """Stateful interface to shell(), with the same keyword parameters."""
386
375
387 shell(cmd,self.verbose,self.debug,self.header)
376 shell(cmd,self.verbose,self.debug,self.header)
388
377
389 xsys = system # alias
378 xsys = system # alias
390
379
391 def getoutput(self,cmd):
380 def getoutput(self,cmd):
392 """Stateful interface to getoutput()."""
381 """Stateful interface to getoutput()."""
393
382
394 return getoutput(cmd,self.verbose,self.debug,self.header,self.split)
383 return getoutput(cmd,self.verbose,self.debug,self.header,self.split)
395
384
396 def getoutputerror(self,cmd):
385 def getoutputerror(self,cmd):
397 """Stateful interface to getoutputerror()."""
386 """Stateful interface to getoutputerror()."""
398
387
399 return getoutputerror(cmd,self.verbose,self.debug,self.header,self.split)
388 return getoutputerror(cmd,self.verbose,self.debug,self.header,self.split)
400
389
401 bq = getoutput # alias
390 bq = getoutput # alias
402
391
403 #-----------------------------------------------------------------------------
392 #-----------------------------------------------------------------------------
404 def mutex_opts(dict,ex_op):
393 def mutex_opts(dict,ex_op):
405 """Check for presence of mutually exclusive keys in a dict.
394 """Check for presence of mutually exclusive keys in a dict.
406
395
407 Call: mutex_opts(dict,[[op1a,op1b],[op2a,op2b]...]"""
396 Call: mutex_opts(dict,[[op1a,op1b],[op2a,op2b]...]"""
408 for op1,op2 in ex_op:
397 for op1,op2 in ex_op:
409 if op1 in dict and op2 in dict:
398 if op1 in dict and op2 in dict:
410 raise ValueError,'\n*** ERROR in Arguments *** '\
399 raise ValueError,'\n*** ERROR in Arguments *** '\
411 'Options '+op1+' and '+op2+' are mutually exclusive.'
400 'Options '+op1+' and '+op2+' are mutually exclusive.'
412
401
413 #-----------------------------------------------------------------------------
402 #-----------------------------------------------------------------------------
414 def filefind(fname,alt_dirs = None):
403 def filefind(fname,alt_dirs = None):
415 """Return the given filename either in the current directory, if it
404 """Return the given filename either in the current directory, if it
416 exists, or in a specified list of directories.
405 exists, or in a specified list of directories.
417
406
418 ~ expansion is done on all file and directory names.
407 ~ expansion is done on all file and directory names.
419
408
420 Upon an unsuccessful search, raise an IOError exception."""
409 Upon an unsuccessful search, raise an IOError exception."""
421
410
422 if alt_dirs is None:
411 if alt_dirs is None:
423 try:
412 try:
424 alt_dirs = get_home_dir()
413 alt_dirs = get_home_dir()
425 except HomeDirError:
414 except HomeDirError:
426 alt_dirs = os.getcwd()
415 alt_dirs = os.getcwd()
427 search = [fname] + list_strings(alt_dirs)
416 search = [fname] + list_strings(alt_dirs)
428 search = map(os.path.expanduser,search)
417 search = map(os.path.expanduser,search)
429 #print 'search list for',fname,'list:',search # dbg
418 #print 'search list for',fname,'list:',search # dbg
430 fname = search[0]
419 fname = search[0]
431 if os.path.isfile(fname):
420 if os.path.isfile(fname):
432 return fname
421 return fname
433 for direc in search[1:]:
422 for direc in search[1:]:
434 testname = os.path.join(direc,fname)
423 testname = os.path.join(direc,fname)
435 #print 'testname',testname # dbg
424 #print 'testname',testname # dbg
436 if os.path.isfile(testname):
425 if os.path.isfile(testname):
437 return testname
426 return testname
438 raise IOError,'File' + `fname` + \
427 raise IOError,'File' + `fname` + \
439 ' not found in current or supplied directories:' + `alt_dirs`
428 ' not found in current or supplied directories:' + `alt_dirs`
440
429
441 #----------------------------------------------------------------------------
430 #----------------------------------------------------------------------------
442 def target_outdated(target,deps):
431 def target_outdated(target,deps):
443 """Determine whether a target is out of date.
432 """Determine whether a target is out of date.
444
433
445 target_outdated(target,deps) -> 1/0
434 target_outdated(target,deps) -> 1/0
446
435
447 deps: list of filenames which MUST exist.
436 deps: list of filenames which MUST exist.
448 target: single filename which may or may not exist.
437 target: single filename which may or may not exist.
449
438
450 If target doesn't exist or is older than any file listed in deps, return
439 If target doesn't exist or is older than any file listed in deps, return
451 true, otherwise return false.
440 true, otherwise return false.
452 """
441 """
453 try:
442 try:
454 target_time = os.path.getmtime(target)
443 target_time = os.path.getmtime(target)
455 except os.error:
444 except os.error:
456 return 1
445 return 1
457 for dep in deps:
446 for dep in deps:
458 dep_time = os.path.getmtime(dep)
447 dep_time = os.path.getmtime(dep)
459 if dep_time > target_time:
448 if dep_time > target_time:
460 #print "For target",target,"Dep failed:",dep # dbg
449 #print "For target",target,"Dep failed:",dep # dbg
461 #print "times (dep,tar):",dep_time,target_time # dbg
450 #print "times (dep,tar):",dep_time,target_time # dbg
462 return 1
451 return 1
463 return 0
452 return 0
464
453
465 #-----------------------------------------------------------------------------
454 #-----------------------------------------------------------------------------
466 def target_update(target,deps,cmd):
455 def target_update(target,deps,cmd):
467 """Update a target with a given command given a list of dependencies.
456 """Update a target with a given command given a list of dependencies.
468
457
469 target_update(target,deps,cmd) -> runs cmd if target is outdated.
458 target_update(target,deps,cmd) -> runs cmd if target is outdated.
470
459
471 This is just a wrapper around target_outdated() which calls the given
460 This is just a wrapper around target_outdated() which calls the given
472 command if target is outdated."""
461 command if target is outdated."""
473
462
474 if target_outdated(target,deps):
463 if target_outdated(target,deps):
475 xsys(cmd)
464 xsys(cmd)
476
465
477 #----------------------------------------------------------------------------
466 #----------------------------------------------------------------------------
478 def unquote_ends(istr):
467 def unquote_ends(istr):
479 """Remove a single pair of quotes from the endpoints of a string."""
468 """Remove a single pair of quotes from the endpoints of a string."""
480
469
481 if not istr:
470 if not istr:
482 return istr
471 return istr
483 if (istr[0]=="'" and istr[-1]=="'") or \
472 if (istr[0]=="'" and istr[-1]=="'") or \
484 (istr[0]=='"' and istr[-1]=='"'):
473 (istr[0]=='"' and istr[-1]=='"'):
485 return istr[1:-1]
474 return istr[1:-1]
486 else:
475 else:
487 return istr
476 return istr
488
477
489 #----------------------------------------------------------------------------
478 #----------------------------------------------------------------------------
490 def process_cmdline(argv,names=[],defaults={},usage=''):
479 def process_cmdline(argv,names=[],defaults={},usage=''):
491 """ Process command-line options and arguments.
480 """ Process command-line options and arguments.
492
481
493 Arguments:
482 Arguments:
494
483
495 - argv: list of arguments, typically sys.argv.
484 - argv: list of arguments, typically sys.argv.
496
485
497 - names: list of option names. See DPyGetOpt docs for details on options
486 - names: list of option names. See DPyGetOpt docs for details on options
498 syntax.
487 syntax.
499
488
500 - defaults: dict of default values.
489 - defaults: dict of default values.
501
490
502 - usage: optional usage notice to print if a wrong argument is passed.
491 - usage: optional usage notice to print if a wrong argument is passed.
503
492
504 Return a dict of options and a list of free arguments."""
493 Return a dict of options and a list of free arguments."""
505
494
506 getopt = DPyGetOpt.DPyGetOpt()
495 getopt = DPyGetOpt.DPyGetOpt()
507 getopt.setIgnoreCase(0)
496 getopt.setIgnoreCase(0)
508 getopt.parseConfiguration(names)
497 getopt.parseConfiguration(names)
509
498
510 try:
499 try:
511 getopt.processArguments(argv)
500 getopt.processArguments(argv)
512 except:
501 except:
513 print usage
502 print usage
514 warn(`sys.exc_value`,level=4)
503 warn(`sys.exc_value`,level=4)
515
504
516 defaults.update(getopt.optionValues)
505 defaults.update(getopt.optionValues)
517 args = getopt.freeValues
506 args = getopt.freeValues
518
507
519 return defaults,args
508 return defaults,args
520
509
521 #----------------------------------------------------------------------------
510 #----------------------------------------------------------------------------
522 def optstr2types(ostr):
511 def optstr2types(ostr):
523 """Convert a string of option names to a dict of type mappings.
512 """Convert a string of option names to a dict of type mappings.
524
513
525 optstr2types(str) -> {None:'string_opts',int:'int_opts',float:'float_opts'}
514 optstr2types(str) -> {None:'string_opts',int:'int_opts',float:'float_opts'}
526
515
527 This is used to get the types of all the options in a string formatted
516 This is used to get the types of all the options in a string formatted
528 with the conventions of DPyGetOpt. The 'type' None is used for options
517 with the conventions of DPyGetOpt. The 'type' None is used for options
529 which are strings (they need no further conversion). This function's main
518 which are strings (they need no further conversion). This function's main
530 use is to get a typemap for use with read_dict().
519 use is to get a typemap for use with read_dict().
531 """
520 """
532
521
533 typeconv = {None:'',int:'',float:''}
522 typeconv = {None:'',int:'',float:''}
534 typemap = {'s':None,'i':int,'f':float}
523 typemap = {'s':None,'i':int,'f':float}
535 opt_re = re.compile(r'([\w]*)([^:=]*:?=?)([sif]?)')
524 opt_re = re.compile(r'([\w]*)([^:=]*:?=?)([sif]?)')
536
525
537 for w in ostr.split():
526 for w in ostr.split():
538 oname,alias,otype = opt_re.match(w).groups()
527 oname,alias,otype = opt_re.match(w).groups()
539 if otype == '' or alias == '!': # simple switches are integers too
528 if otype == '' or alias == '!': # simple switches are integers too
540 otype = 'i'
529 otype = 'i'
541 typeconv[typemap[otype]] += oname + ' '
530 typeconv[typemap[otype]] += oname + ' '
542 return typeconv
531 return typeconv
543
532
544 #----------------------------------------------------------------------------
533 #----------------------------------------------------------------------------
545 def read_dict(filename,type_conv=None,**opt):
534 def read_dict(filename,type_conv=None,**opt):
546
535
547 """Read a dictionary of key=value pairs from an input file, optionally
536 """Read a dictionary of key=value pairs from an input file, optionally
548 performing conversions on the resulting values.
537 performing conversions on the resulting values.
549
538
550 read_dict(filename,type_conv,**opt) -> dict
539 read_dict(filename,type_conv,**opt) -> dict
551
540
552 Only one value per line is accepted, the format should be
541 Only one value per line is accepted, the format should be
553 # optional comments are ignored
542 # optional comments are ignored
554 key value\n
543 key value\n
555
544
556 Args:
545 Args:
557
546
558 - type_conv: A dictionary specifying which keys need to be converted to
547 - type_conv: A dictionary specifying which keys need to be converted to
559 which types. By default all keys are read as strings. This dictionary
548 which types. By default all keys are read as strings. This dictionary
560 should have as its keys valid conversion functions for strings
549 should have as its keys valid conversion functions for strings
561 (int,long,float,complex, or your own). The value for each key
550 (int,long,float,complex, or your own). The value for each key
562 (converter) should be a whitespace separated string containing the names
551 (converter) should be a whitespace separated string containing the names
563 of all the entries in the file to be converted using that function. For
552 of all the entries in the file to be converted using that function. For
564 keys to be left alone, use None as the conversion function (only needed
553 keys to be left alone, use None as the conversion function (only needed
565 with purge=1, see below).
554 with purge=1, see below).
566
555
567 - opt: dictionary with extra options as below (default in parens)
556 - opt: dictionary with extra options as below (default in parens)
568
557
569 purge(0): if set to 1, all keys *not* listed in type_conv are purged out
558 purge(0): if set to 1, all keys *not* listed in type_conv are purged out
570 of the dictionary to be returned. If purge is going to be used, the
559 of the dictionary to be returned. If purge is going to be used, the
571 set of keys to be left as strings also has to be explicitly specified
560 set of keys to be left as strings also has to be explicitly specified
572 using the (non-existent) conversion function None.
561 using the (non-existent) conversion function None.
573
562
574 fs(None): field separator. This is the key/value separator to be used
563 fs(None): field separator. This is the key/value separator to be used
575 when parsing the file. The None default means any whitespace [behavior
564 when parsing the file. The None default means any whitespace [behavior
576 of string.split()].
565 of string.split()].
577
566
578 strip(0): if 1, strip string values of leading/trailinig whitespace.
567 strip(0): if 1, strip string values of leading/trailinig whitespace.
579
568
580 warn(1): warning level if requested keys are not found in file.
569 warn(1): warning level if requested keys are not found in file.
581 - 0: silently ignore.
570 - 0: silently ignore.
582 - 1: inform but proceed.
571 - 1: inform but proceed.
583 - 2: raise KeyError exception.
572 - 2: raise KeyError exception.
584
573
585 no_empty(0): if 1, remove keys with whitespace strings as a value.
574 no_empty(0): if 1, remove keys with whitespace strings as a value.
586
575
587 unique([]): list of keys (or space separated string) which can't be
576 unique([]): list of keys (or space separated string) which can't be
588 repeated. If one such key is found in the file, each new instance
577 repeated. If one such key is found in the file, each new instance
589 overwrites the previous one. For keys not listed here, the behavior is
578 overwrites the previous one. For keys not listed here, the behavior is
590 to make a list of all appearances.
579 to make a list of all appearances.
591
580
592 Example:
581 Example:
593 If the input file test.ini has:
582 If the input file test.ini has:
594 i 3
583 i 3
595 x 4.5
584 x 4.5
596 y 5.5
585 y 5.5
597 s hi ho
586 s hi ho
598 Then:
587 Then:
599
588
600 >>> type_conv={int:'i',float:'x',None:'s'}
589 >>> type_conv={int:'i',float:'x',None:'s'}
601 >>> read_dict('test.ini')
590 >>> read_dict('test.ini')
602 {'i': '3', 's': 'hi ho', 'x': '4.5', 'y': '5.5'}
591 {'i': '3', 's': 'hi ho', 'x': '4.5', 'y': '5.5'}
603 >>> read_dict('test.ini',type_conv)
592 >>> read_dict('test.ini',type_conv)
604 {'i': 3, 's': 'hi ho', 'x': 4.5, 'y': '5.5'}
593 {'i': 3, 's': 'hi ho', 'x': 4.5, 'y': '5.5'}
605 >>> read_dict('test.ini',type_conv,purge=1)
594 >>> read_dict('test.ini',type_conv,purge=1)
606 {'i': 3, 's': 'hi ho', 'x': 4.5}
595 {'i': 3, 's': 'hi ho', 'x': 4.5}
607 """
596 """
608
597
609 # starting config
598 # starting config
610 opt.setdefault('purge',0)
599 opt.setdefault('purge',0)
611 opt.setdefault('fs',None) # field sep defaults to any whitespace
600 opt.setdefault('fs',None) # field sep defaults to any whitespace
612 opt.setdefault('strip',0)
601 opt.setdefault('strip',0)
613 opt.setdefault('warn',1)
602 opt.setdefault('warn',1)
614 opt.setdefault('no_empty',0)
603 opt.setdefault('no_empty',0)
615 opt.setdefault('unique','')
604 opt.setdefault('unique','')
616 if type(opt['unique']) in StringTypes:
605 if type(opt['unique']) in StringTypes:
617 unique_keys = qw(opt['unique'])
606 unique_keys = qw(opt['unique'])
618 elif type(opt['unique']) in (types.TupleType,types.ListType):
607 elif type(opt['unique']) in (types.TupleType,types.ListType):
619 unique_keys = opt['unique']
608 unique_keys = opt['unique']
620 else:
609 else:
621 raise ValueError, 'Unique keys must be given as a string, List or Tuple'
610 raise ValueError, 'Unique keys must be given as a string, List or Tuple'
622
611
623 dict = {}
612 dict = {}
624 # first read in table of values as strings
613 # first read in table of values as strings
625 file = open(filename,'r')
614 file = open(filename,'r')
626 for line in file.readlines():
615 for line in file.readlines():
627 line = line.strip()
616 line = line.strip()
628 if len(line) and line[0]=='#': continue
617 if len(line) and line[0]=='#': continue
629 if len(line)>0:
618 if len(line)>0:
630 lsplit = line.split(opt['fs'],1)
619 lsplit = line.split(opt['fs'],1)
631 try:
620 try:
632 key,val = lsplit
621 key,val = lsplit
633 except ValueError:
622 except ValueError:
634 key,val = lsplit[0],''
623 key,val = lsplit[0],''
635 key = key.strip()
624 key = key.strip()
636 if opt['strip']: val = val.strip()
625 if opt['strip']: val = val.strip()
637 if val == "''" or val == '""': val = ''
626 if val == "''" or val == '""': val = ''
638 if opt['no_empty'] and (val=='' or val.isspace()):
627 if opt['no_empty'] and (val=='' or val.isspace()):
639 continue
628 continue
640 # if a key is found more than once in the file, build a list
629 # if a key is found more than once in the file, build a list
641 # unless it's in the 'unique' list. In that case, last found in file
630 # unless it's in the 'unique' list. In that case, last found in file
642 # takes precedence. User beware.
631 # takes precedence. User beware.
643 try:
632 try:
644 if dict[key] and key in unique_keys:
633 if dict[key] and key in unique_keys:
645 dict[key] = val
634 dict[key] = val
646 elif type(dict[key]) is types.ListType:
635 elif type(dict[key]) is types.ListType:
647 dict[key].append(val)
636 dict[key].append(val)
648 else:
637 else:
649 dict[key] = [dict[key],val]
638 dict[key] = [dict[key],val]
650 except KeyError:
639 except KeyError:
651 dict[key] = val
640 dict[key] = val
652 # purge if requested
641 # purge if requested
653 if opt['purge']:
642 if opt['purge']:
654 accepted_keys = qwflat(type_conv.values())
643 accepted_keys = qwflat(type_conv.values())
655 for key in dict.keys():
644 for key in dict.keys():
656 if key in accepted_keys: continue
645 if key in accepted_keys: continue
657 del(dict[key])
646 del(dict[key])
658 # now convert if requested
647 # now convert if requested
659 if type_conv==None: return dict
648 if type_conv==None: return dict
660 conversions = type_conv.keys()
649 conversions = type_conv.keys()
661 try: conversions.remove(None)
650 try: conversions.remove(None)
662 except: pass
651 except: pass
663 for convert in conversions:
652 for convert in conversions:
664 for val in qw(type_conv[convert]):
653 for val in qw(type_conv[convert]):
665 try:
654 try:
666 dict[val] = convert(dict[val])
655 dict[val] = convert(dict[val])
667 except KeyError,e:
656 except KeyError,e:
668 if opt['warn'] == 0:
657 if opt['warn'] == 0:
669 pass
658 pass
670 elif opt['warn'] == 1:
659 elif opt['warn'] == 1:
671 print >>sys.stderr, 'Warning: key',val,\
660 print >>sys.stderr, 'Warning: key',val,\
672 'not found in file',filename
661 'not found in file',filename
673 elif opt['warn'] == 2:
662 elif opt['warn'] == 2:
674 raise KeyError,e
663 raise KeyError,e
675 else:
664 else:
676 raise ValueError,'Warning level must be 0,1 or 2'
665 raise ValueError,'Warning level must be 0,1 or 2'
677
666
678 return dict
667 return dict
679
668
680 #----------------------------------------------------------------------------
669 #----------------------------------------------------------------------------
681 def flag_calls(func):
670 def flag_calls(func):
682 """Wrap a function to detect and flag when it gets called.
671 """Wrap a function to detect and flag when it gets called.
683
672
684 This is a decorator which takes a function and wraps it in a function with
673 This is a decorator which takes a function and wraps it in a function with
685 a 'called' attribute. wrapper.called is initialized to False.
674 a 'called' attribute. wrapper.called is initialized to False.
686
675
687 The wrapper.called attribute is set to False right before each call to the
676 The wrapper.called attribute is set to False right before each call to the
688 wrapped function, so if the call fails it remains False. After the call
677 wrapped function, so if the call fails it remains False. After the call
689 completes, wrapper.called is set to True and the output is returned.
678 completes, wrapper.called is set to True and the output is returned.
690
679
691 Testing for truth in wrapper.called allows you to determine if a call to
680 Testing for truth in wrapper.called allows you to determine if a call to
692 func() was attempted and succeeded."""
681 func() was attempted and succeeded."""
693
682
694 def wrapper(*args,**kw):
683 def wrapper(*args,**kw):
695 wrapper.called = False
684 wrapper.called = False
696 out = func(*args,**kw)
685 out = func(*args,**kw)
697 wrapper.called = True
686 wrapper.called = True
698 return out
687 return out
699
688
700 wrapper.called = False
689 wrapper.called = False
701 wrapper.__doc__ = func.__doc__
690 wrapper.__doc__ = func.__doc__
702 return wrapper
691 return wrapper
703
692
704 #----------------------------------------------------------------------------
693 #----------------------------------------------------------------------------
705 class HomeDirError(Error):
694 class HomeDirError(Error):
706 pass
695 pass
707
696
708 def get_home_dir():
697 def get_home_dir():
709 """Return the closest possible equivalent to a 'home' directory.
698 """Return the closest possible equivalent to a 'home' directory.
710
699
711 We first try $HOME. Absent that, on NT it's $HOMEDRIVE\$HOMEPATH.
700 We first try $HOME. Absent that, on NT it's $HOMEDRIVE\$HOMEPATH.
712
701
713 Currently only Posix and NT are implemented, a HomeDirError exception is
702 Currently only Posix and NT are implemented, a HomeDirError exception is
714 raised for all other OSes. """
703 raised for all other OSes. """
715
704
716 try:
705 try:
717 return os.environ['HOME']
706 return os.environ['HOME']
718 except KeyError:
707 except KeyError:
719 if os.name == 'posix':
708 if os.name == 'posix':
720 raise HomeDirError,'undefined $HOME, IPython can not proceed.'
709 raise HomeDirError,'undefined $HOME, IPython can not proceed.'
721 elif os.name == 'nt':
710 elif os.name == 'nt':
722 # For some strange reason, win9x returns 'nt' for os.name.
711 # For some strange reason, win9x returns 'nt' for os.name.
723 try:
712 try:
724 return os.path.join(os.environ['HOMEDRIVE'],os.environ['HOMEPATH'])
713 return os.path.join(os.environ['HOMEDRIVE'],os.environ['HOMEPATH'])
725 except:
714 except:
726 try:
715 try:
727 # Use the registry to get the 'My Documents' folder.
716 # Use the registry to get the 'My Documents' folder.
728 import _winreg as wreg
717 import _winreg as wreg
729 key = wreg.OpenKey(wreg.HKEY_CURRENT_USER,
718 key = wreg.OpenKey(wreg.HKEY_CURRENT_USER,
730 "Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders")
719 "Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders")
731 homedir = wreg.QueryValueEx(key,'Personal')[0]
720 homedir = wreg.QueryValueEx(key,'Personal')[0]
732 key.Close()
721 key.Close()
733 return homedir
722 return homedir
734 except:
723 except:
735 return 'C:\\'
724 return 'C:\\'
736 elif os.name == 'dos':
725 elif os.name == 'dos':
737 # Desperate, may do absurd things in classic MacOS. May work under DOS.
726 # Desperate, may do absurd things in classic MacOS. May work under DOS.
738 return 'C:\\'
727 return 'C:\\'
739 else:
728 else:
740 raise HomeDirError,'support for your operating system not implemented.'
729 raise HomeDirError,'support for your operating system not implemented.'
741
730
742 #****************************************************************************
731 #****************************************************************************
743 # strings and text
732 # strings and text
744
733
745 class LSString(str):
734 class LSString(str):
746 """String derivative with a special access attributes.
735 """String derivative with a special access attributes.
747
736
748 These are normal strings, but with the special attributes:
737 These are normal strings, but with the special attributes:
749
738
750 .l (or .list) : value as list (split on newlines).
739 .l (or .list) : value as list (split on newlines).
751 .n (or .nlstr): original value (the string itself).
740 .n (or .nlstr): original value (the string itself).
752 .s (or .spstr): value as whitespace-separated string.
741 .s (or .spstr): value as whitespace-separated string.
753
742
754 Any values which require transformations are computed only once and
743 Any values which require transformations are computed only once and
755 cached.
744 cached.
756
745
757 Such strings are very useful to efficiently interact with the shell, which
746 Such strings are very useful to efficiently interact with the shell, which
758 typically only understands whitespace-separated options for commands."""
747 typically only understands whitespace-separated options for commands."""
759
748
760 def get_list(self):
749 def get_list(self):
761 try:
750 try:
762 return self.__list
751 return self.__list
763 except AttributeError:
752 except AttributeError:
764 self.__list = self.split('\n')
753 self.__list = self.split('\n')
765 return self.__list
754 return self.__list
766
755
767 l = list = property(get_list)
756 l = list = property(get_list)
768
757
769 def get_spstr(self):
758 def get_spstr(self):
770 try:
759 try:
771 return self.__spstr
760 return self.__spstr
772 except AttributeError:
761 except AttributeError:
773 self.__spstr = self.replace('\n',' ')
762 self.__spstr = self.replace('\n',' ')
774 return self.__spstr
763 return self.__spstr
775
764
776 s = spstr = property(get_spstr)
765 s = spstr = property(get_spstr)
777
766
778 def get_nlstr(self):
767 def get_nlstr(self):
779 return self
768 return self
780
769
781 n = nlstr = property(get_nlstr)
770 n = nlstr = property(get_nlstr)
782
771
783 class SList(list):
772 class SList(list):
784 """List derivative with a special access attributes.
773 """List derivative with a special access attributes.
785
774
786 These are normal lists, but with the special attributes:
775 These are normal lists, but with the special attributes:
787
776
788 .l (or .list) : value as list (the list itself).
777 .l (or .list) : value as list (the list itself).
789 .n (or .nlstr): value as a string, joined on newlines.
778 .n (or .nlstr): value as a string, joined on newlines.
790 .s (or .spstr): value as a string, joined on spaces.
779 .s (or .spstr): value as a string, joined on spaces.
791
780
792 Any values which require transformations are computed only once and
781 Any values which require transformations are computed only once and
793 cached."""
782 cached."""
794
783
795 def get_list(self):
784 def get_list(self):
796 return self
785 return self
797
786
798 l = list = property(get_list)
787 l = list = property(get_list)
799
788
800 def get_spstr(self):
789 def get_spstr(self):
801 try:
790 try:
802 return self.__spstr
791 return self.__spstr
803 except AttributeError:
792 except AttributeError:
804 self.__spstr = ' '.join(self)
793 self.__spstr = ' '.join(self)
805 return self.__spstr
794 return self.__spstr
806
795
807 s = spstr = property(get_spstr)
796 s = spstr = property(get_spstr)
808
797
809 def get_nlstr(self):
798 def get_nlstr(self):
810 try:
799 try:
811 return self.__nlstr
800 return self.__nlstr
812 except AttributeError:
801 except AttributeError:
813 self.__nlstr = '\n'.join(self)
802 self.__nlstr = '\n'.join(self)
814 return self.__nlstr
803 return self.__nlstr
815
804
816 n = nlstr = property(get_nlstr)
805 n = nlstr = property(get_nlstr)
817
806
818 def raw_input_multi(header='', ps1='==> ', ps2='..> ',terminate_str = '.'):
807 def raw_input_multi(header='', ps1='==> ', ps2='..> ',terminate_str = '.'):
819 """Take multiple lines of input.
808 """Take multiple lines of input.
820
809
821 A list with each line of input as a separate element is returned when a
810 A list with each line of input as a separate element is returned when a
822 termination string is entered (defaults to a single '.'). Input can also
811 termination string is entered (defaults to a single '.'). Input can also
823 terminate via EOF (^D in Unix, ^Z-RET in Windows).
812 terminate via EOF (^D in Unix, ^Z-RET in Windows).
824
813
825 Lines of input which end in \\ are joined into single entries (and a
814 Lines of input which end in \\ are joined into single entries (and a
826 secondary continuation prompt is issued as long as the user terminates
815 secondary continuation prompt is issued as long as the user terminates
827 lines with \\). This allows entering very long strings which are still
816 lines with \\). This allows entering very long strings which are still
828 meant to be treated as single entities.
817 meant to be treated as single entities.
829 """
818 """
830
819
831 try:
820 try:
832 if header:
821 if header:
833 header += '\n'
822 header += '\n'
834 lines = [raw_input(header + ps1)]
823 lines = [raw_input(header + ps1)]
835 except EOFError:
824 except EOFError:
836 return []
825 return []
837 terminate = [terminate_str]
826 terminate = [terminate_str]
838 try:
827 try:
839 while lines[-1:] != terminate:
828 while lines[-1:] != terminate:
840 new_line = raw_input(ps1)
829 new_line = raw_input(ps1)
841 while new_line.endswith('\\'):
830 while new_line.endswith('\\'):
842 new_line = new_line[:-1] + raw_input(ps2)
831 new_line = new_line[:-1] + raw_input(ps2)
843 lines.append(new_line)
832 lines.append(new_line)
844
833
845 return lines[:-1] # don't return the termination command
834 return lines[:-1] # don't return the termination command
846 except EOFError:
835 except EOFError:
847 print
836 print
848 return lines
837 return lines
849
838
850 #----------------------------------------------------------------------------
839 #----------------------------------------------------------------------------
851 def raw_input_ext(prompt='', ps2='... '):
840 def raw_input_ext(prompt='', ps2='... '):
852 """Similar to raw_input(), but accepts extended lines if input ends with \\."""
841 """Similar to raw_input(), but accepts extended lines if input ends with \\."""
853
842
854 line = raw_input(prompt)
843 line = raw_input(prompt)
855 while line.endswith('\\'):
844 while line.endswith('\\'):
856 line = line[:-1] + raw_input(ps2)
845 line = line[:-1] + raw_input(ps2)
857 return line
846 return line
858
847
859 #----------------------------------------------------------------------------
848 #----------------------------------------------------------------------------
860 def ask_yes_no(prompt,default=None):
849 def ask_yes_no(prompt,default=None):
861 """Asks a question and returns an integer 1/0 (y/n) answer.
850 """Asks a question and returns an integer 1/0 (y/n) answer.
862
851
863 If default is given (one of 'y','n'), it is used if the user input is
852 If default is given (one of 'y','n'), it is used if the user input is
864 empty. Otherwise the question is repeated until an answer is given.
853 empty. Otherwise the question is repeated until an answer is given.
865 If EOF occurs 20 times consecutively, the default answer is assumed,
854 If EOF occurs 20 times consecutively, the default answer is assumed,
866 or if there is no default, an exception is raised to prevent infinite
855 or if there is no default, an exception is raised to prevent infinite
867 loops.
856 loops.
868
857
869 Valid answers are: y/yes/n/no (match is not case sensitive)."""
858 Valid answers are: y/yes/n/no (match is not case sensitive)."""
870
859
871 answers = {'y':1,'n':0,'yes':1,'no':0}
860 answers = {'y':1,'n':0,'yes':1,'no':0}
872 ans = None
861 ans = None
873 eofs, max_eofs = 0, 20
862 eofs, max_eofs = 0, 20
874 while ans not in answers.keys():
863 while ans not in answers.keys():
875 try:
864 try:
876 ans = raw_input(prompt+' ').lower()
865 ans = raw_input(prompt+' ').lower()
877 if not ans: # response was an empty string
866 if not ans: # response was an empty string
878 ans = default
867 ans = default
879 eofs = 0
868 eofs = 0
880 except (EOFError,KeyboardInterrupt):
869 except (EOFError,KeyboardInterrupt):
881 eofs = eofs + 1
870 eofs = eofs + 1
882 if eofs >= max_eofs:
871 if eofs >= max_eofs:
883 if default in answers.keys():
872 if default in answers.keys():
884 ans = default
873 ans = default
885 else:
874 else:
886 raise
875 raise
887
876
888 return answers[ans]
877 return answers[ans]
889
878
890 #----------------------------------------------------------------------------
879 #----------------------------------------------------------------------------
891 class EvalDict:
880 class EvalDict:
892 """
881 """
893 Emulate a dict which evaluates its contents in the caller's frame.
882 Emulate a dict which evaluates its contents in the caller's frame.
894
883
895 Usage:
884 Usage:
896 >>>number = 19
885 >>>number = 19
897 >>>text = "python"
886 >>>text = "python"
898 >>>print "%(text.capitalize())s %(number/9.0).1f rules!" % EvalDict()
887 >>>print "%(text.capitalize())s %(number/9.0).1f rules!" % EvalDict()
899 """
888 """
900
889
901 # This version is due to sismex01@hebmex.com on c.l.py, and is basically a
890 # This version is due to sismex01@hebmex.com on c.l.py, and is basically a
902 # modified (shorter) version of:
891 # modified (shorter) version of:
903 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66018 by
892 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66018 by
904 # Skip Montanaro (skip@pobox.com).
893 # Skip Montanaro (skip@pobox.com).
905
894
906 def __getitem__(self, name):
895 def __getitem__(self, name):
907 frame = sys._getframe(1)
896 frame = sys._getframe(1)
908 return eval(name, frame.f_globals, frame.f_locals)
897 return eval(name, frame.f_globals, frame.f_locals)
909
898
910 EvalString = EvalDict # for backwards compatibility
899 EvalString = EvalDict # for backwards compatibility
911 #----------------------------------------------------------------------------
900 #----------------------------------------------------------------------------
912 def qw(words,flat=0,sep=None,maxsplit=-1):
901 def qw(words,flat=0,sep=None,maxsplit=-1):
913 """Similar to Perl's qw() operator, but with some more options.
902 """Similar to Perl's qw() operator, but with some more options.
914
903
915 qw(words,flat=0,sep=' ',maxsplit=-1) -> words.split(sep,maxsplit)
904 qw(words,flat=0,sep=' ',maxsplit=-1) -> words.split(sep,maxsplit)
916
905
917 words can also be a list itself, and with flat=1, the output will be
906 words can also be a list itself, and with flat=1, the output will be
918 recursively flattened. Examples:
907 recursively flattened. Examples:
919
908
920 >>> qw('1 2')
909 >>> qw('1 2')
921 ['1', '2']
910 ['1', '2']
922 >>> qw(['a b','1 2',['m n','p q']])
911 >>> qw(['a b','1 2',['m n','p q']])
923 [['a', 'b'], ['1', '2'], [['m', 'n'], ['p', 'q']]]
912 [['a', 'b'], ['1', '2'], [['m', 'n'], ['p', 'q']]]
924 >>> qw(['a b','1 2',['m n','p q']],flat=1)
913 >>> qw(['a b','1 2',['m n','p q']],flat=1)
925 ['a', 'b', '1', '2', 'm', 'n', 'p', 'q'] """
914 ['a', 'b', '1', '2', 'm', 'n', 'p', 'q'] """
926
915
927 if type(words) in StringTypes:
916 if type(words) in StringTypes:
928 return [word.strip() for word in words.split(sep,maxsplit)
917 return [word.strip() for word in words.split(sep,maxsplit)
929 if word and not word.isspace() ]
918 if word and not word.isspace() ]
930 if flat:
919 if flat:
931 return flatten(map(qw,words,[1]*len(words)))
920 return flatten(map(qw,words,[1]*len(words)))
932 return map(qw,words)
921 return map(qw,words)
933
922
934 #----------------------------------------------------------------------------
923 #----------------------------------------------------------------------------
935 def qwflat(words,sep=None,maxsplit=-1):
924 def qwflat(words,sep=None,maxsplit=-1):
936 """Calls qw(words) in flat mode. It's just a convenient shorthand."""
925 """Calls qw(words) in flat mode. It's just a convenient shorthand."""
937 return qw(words,1,sep,maxsplit)
926 return qw(words,1,sep,maxsplit)
938
927
939 #-----------------------------------------------------------------------------
928 #-----------------------------------------------------------------------------
940 def list_strings(arg):
929 def list_strings(arg):
941 """Always return a list of strings, given a string or list of strings
930 """Always return a list of strings, given a string or list of strings
942 as input."""
931 as input."""
943
932
944 if type(arg) in StringTypes: return [arg]
933 if type(arg) in StringTypes: return [arg]
945 else: return arg
934 else: return arg
946
935
947 #----------------------------------------------------------------------------
936 #----------------------------------------------------------------------------
948 def grep(pat,list,case=1):
937 def grep(pat,list,case=1):
949 """Simple minded grep-like function.
938 """Simple minded grep-like function.
950 grep(pat,list) returns occurrences of pat in list, None on failure.
939 grep(pat,list) returns occurrences of pat in list, None on failure.
951
940
952 It only does simple string matching, with no support for regexps. Use the
941 It only does simple string matching, with no support for regexps. Use the
953 option case=0 for case-insensitive matching."""
942 option case=0 for case-insensitive matching."""
954
943
955 # This is pretty crude. At least it should implement copying only references
944 # This is pretty crude. At least it should implement copying only references
956 # to the original data in case it's big. Now it copies the data for output.
945 # to the original data in case it's big. Now it copies the data for output.
957 out=[]
946 out=[]
958 if case:
947 if case:
959 for term in list:
948 for term in list:
960 if term.find(pat)>-1: out.append(term)
949 if term.find(pat)>-1: out.append(term)
961 else:
950 else:
962 lpat=pat.lower()
951 lpat=pat.lower()
963 for term in list:
952 for term in list:
964 if term.lower().find(lpat)>-1: out.append(term)
953 if term.lower().find(lpat)>-1: out.append(term)
965
954
966 if len(out): return out
955 if len(out): return out
967 else: return None
956 else: return None
968
957
969 #----------------------------------------------------------------------------
958 #----------------------------------------------------------------------------
970 def dgrep(pat,*opts):
959 def dgrep(pat,*opts):
971 """Return grep() on dir()+dir(__builtins__).
960 """Return grep() on dir()+dir(__builtins__).
972
961
973 A very common use of grep() when working interactively."""
962 A very common use of grep() when working interactively."""
974
963
975 return grep(pat,dir(__main__)+dir(__main__.__builtins__),*opts)
964 return grep(pat,dir(__main__)+dir(__main__.__builtins__),*opts)
976
965
977 #----------------------------------------------------------------------------
966 #----------------------------------------------------------------------------
978 def idgrep(pat):
967 def idgrep(pat):
979 """Case-insensitive dgrep()"""
968 """Case-insensitive dgrep()"""
980
969
981 return dgrep(pat,0)
970 return dgrep(pat,0)
982
971
983 #----------------------------------------------------------------------------
972 #----------------------------------------------------------------------------
984 def igrep(pat,list):
973 def igrep(pat,list):
985 """Synonym for case-insensitive grep."""
974 """Synonym for case-insensitive grep."""
986
975
987 return grep(pat,list,case=0)
976 return grep(pat,list,case=0)
988
977
989 #----------------------------------------------------------------------------
978 #----------------------------------------------------------------------------
990 def indent(str,nspaces=4,ntabs=0):
979 def indent(str,nspaces=4,ntabs=0):
991 """Indent a string a given number of spaces or tabstops.
980 """Indent a string a given number of spaces or tabstops.
992
981
993 indent(str,nspaces=4,ntabs=0) -> indent str by ntabs+nspaces.
982 indent(str,nspaces=4,ntabs=0) -> indent str by ntabs+nspaces.
994 """
983 """
995 if str is None:
984 if str is None:
996 return
985 return
997 ind = '\t'*ntabs+' '*nspaces
986 ind = '\t'*ntabs+' '*nspaces
998 outstr = '%s%s' % (ind,str.replace(os.linesep,os.linesep+ind))
987 outstr = '%s%s' % (ind,str.replace(os.linesep,os.linesep+ind))
999 if outstr.endswith(os.linesep+ind):
988 if outstr.endswith(os.linesep+ind):
1000 return outstr[:-len(ind)]
989 return outstr[:-len(ind)]
1001 else:
990 else:
1002 return outstr
991 return outstr
1003
992
1004 #-----------------------------------------------------------------------------
993 #-----------------------------------------------------------------------------
1005 def native_line_ends(filename,backup=1):
994 def native_line_ends(filename,backup=1):
1006 """Convert (in-place) a file to line-ends native to the current OS.
995 """Convert (in-place) a file to line-ends native to the current OS.
1007
996
1008 If the optional backup argument is given as false, no backup of the
997 If the optional backup argument is given as false, no backup of the
1009 original file is left. """
998 original file is left. """
1010
999
1011 backup_suffixes = {'posix':'~','dos':'.bak','nt':'.bak','mac':'.bak'}
1000 backup_suffixes = {'posix':'~','dos':'.bak','nt':'.bak','mac':'.bak'}
1012
1001
1013 bak_filename = filename + backup_suffixes[os.name]
1002 bak_filename = filename + backup_suffixes[os.name]
1014
1003
1015 original = open(filename).read()
1004 original = open(filename).read()
1016 shutil.copy2(filename,bak_filename)
1005 shutil.copy2(filename,bak_filename)
1017 try:
1006 try:
1018 new = open(filename,'wb')
1007 new = open(filename,'wb')
1019 new.write(os.linesep.join(original.splitlines()))
1008 new.write(os.linesep.join(original.splitlines()))
1020 new.write(os.linesep) # ALWAYS put an eol at the end of the file
1009 new.write(os.linesep) # ALWAYS put an eol at the end of the file
1021 new.close()
1010 new.close()
1022 except:
1011 except:
1023 os.rename(bak_filename,filename)
1012 os.rename(bak_filename,filename)
1024 if not backup:
1013 if not backup:
1025 try:
1014 try:
1026 os.remove(bak_filename)
1015 os.remove(bak_filename)
1027 except:
1016 except:
1028 pass
1017 pass
1029
1018
1030 #----------------------------------------------------------------------------
1019 #----------------------------------------------------------------------------
1031 def get_pager_cmd(pager_cmd = None):
1020 def get_pager_cmd(pager_cmd = None):
1032 """Return a pager command.
1021 """Return a pager command.
1033
1022
1034 Makes some attempts at finding an OS-correct one."""
1023 Makes some attempts at finding an OS-correct one."""
1035
1024
1036 if os.name == 'posix':
1025 if os.name == 'posix':
1037 default_pager_cmd = 'less -r' # -r for color control sequences
1026 default_pager_cmd = 'less -r' # -r for color control sequences
1038 elif os.name in ['nt','dos']:
1027 elif os.name in ['nt','dos']:
1039 default_pager_cmd = 'type'
1028 default_pager_cmd = 'type'
1040
1029
1041 if pager_cmd is None:
1030 if pager_cmd is None:
1042 try:
1031 try:
1043 pager_cmd = os.environ['PAGER']
1032 pager_cmd = os.environ['PAGER']
1044 except:
1033 except:
1045 pager_cmd = default_pager_cmd
1034 pager_cmd = default_pager_cmd
1046 return pager_cmd
1035 return pager_cmd
1047
1036
1048 #-----------------------------------------------------------------------------
1037 #-----------------------------------------------------------------------------
1049 def get_pager_start(pager,start):
1038 def get_pager_start(pager,start):
1050 """Return the string for paging files with an offset.
1039 """Return the string for paging files with an offset.
1051
1040
1052 This is the '+N' argument which less and more (under Unix) accept.
1041 This is the '+N' argument which less and more (under Unix) accept.
1053 """
1042 """
1054
1043
1055 if pager in ['less','more']:
1044 if pager in ['less','more']:
1056 if start:
1045 if start:
1057 start_string = '+' + str(start)
1046 start_string = '+' + str(start)
1058 else:
1047 else:
1059 start_string = ''
1048 start_string = ''
1060 else:
1049 else:
1061 start_string = ''
1050 start_string = ''
1062 return start_string
1051 return start_string
1063
1052
1064 #----------------------------------------------------------------------------
1053 #----------------------------------------------------------------------------
1065 def page_dumb(strng,start=0,screen_lines=25):
1054 def page_dumb(strng,start=0,screen_lines=25):
1066 """Very dumb 'pager' in Python, for when nothing else works.
1055 """Very dumb 'pager' in Python, for when nothing else works.
1067
1056
1068 Only moves forward, same interface as page(), except for pager_cmd and
1057 Only moves forward, same interface as page(), except for pager_cmd and
1069 mode."""
1058 mode."""
1070
1059
1071 out_ln = strng.splitlines()[start:]
1060 out_ln = strng.splitlines()[start:]
1072 screens = chop(out_ln,screen_lines-1)
1061 screens = chop(out_ln,screen_lines-1)
1073 if len(screens) == 1:
1062 if len(screens) == 1:
1074 print >>Term.cout, os.linesep.join(screens[0])
1063 print >>Term.cout, os.linesep.join(screens[0])
1075 else:
1064 else:
1076 for scr in screens[0:-1]:
1065 for scr in screens[0:-1]:
1077 print >>Term.cout, os.linesep.join(scr)
1066 print >>Term.cout, os.linesep.join(scr)
1078 ans = raw_input('---Return to continue, q to quit--- ')
1067 ans = raw_input('---Return to continue, q to quit--- ')
1079 if ans.lower().startswith('q'):
1068 if ans.lower().startswith('q'):
1080 return
1069 return
1081 print >>Term.cout, os.linesep.join(screens[-1])
1070 print >>Term.cout, os.linesep.join(screens[-1])
1082
1071
1083 #----------------------------------------------------------------------------
1072 #----------------------------------------------------------------------------
1084 def page(strng,start=0,screen_lines=0,pager_cmd = None):
1073 def page(strng,start=0,screen_lines=0,pager_cmd = None):
1085 """Print a string, piping through a pager after a certain length.
1074 """Print a string, piping through a pager after a certain length.
1086
1075
1087 The screen_lines parameter specifies the number of *usable* lines of your
1076 The screen_lines parameter specifies the number of *usable* lines of your
1088 terminal screen (total lines minus lines you need to reserve to show other
1077 terminal screen (total lines minus lines you need to reserve to show other
1089 information).
1078 information).
1090
1079
1091 If you set screen_lines to a number <=0, page() will try to auto-determine
1080 If you set screen_lines to a number <=0, page() will try to auto-determine
1092 your screen size and will only use up to (screen_size+screen_lines) for
1081 your screen size and will only use up to (screen_size+screen_lines) for
1093 printing, paging after that. That is, if you want auto-detection but need
1082 printing, paging after that. That is, if you want auto-detection but need
1094 to reserve the bottom 3 lines of the screen, use screen_lines = -3, and for
1083 to reserve the bottom 3 lines of the screen, use screen_lines = -3, and for
1095 auto-detection without any lines reserved simply use screen_lines = 0.
1084 auto-detection without any lines reserved simply use screen_lines = 0.
1096
1085
1097 If a string won't fit in the allowed lines, it is sent through the
1086 If a string won't fit in the allowed lines, it is sent through the
1098 specified pager command. If none given, look for PAGER in the environment,
1087 specified pager command. If none given, look for PAGER in the environment,
1099 and ultimately default to less.
1088 and ultimately default to less.
1100
1089
1101 If no system pager works, the string is sent through a 'dumb pager'
1090 If no system pager works, the string is sent through a 'dumb pager'
1102 written in python, very simplistic.
1091 written in python, very simplistic.
1103 """
1092 """
1104
1093
1105 # Ugly kludge, but calling curses.initscr() flat out crashes in emacs
1094 # Ugly kludge, but calling curses.initscr() flat out crashes in emacs
1106 TERM = os.environ.get('TERM','dumb')
1095 TERM = os.environ.get('TERM','dumb')
1107 if TERM in ['dumb','emacs'] and os.name != 'nt':
1096 if TERM in ['dumb','emacs'] and os.name != 'nt':
1108 print strng
1097 print strng
1109 return
1098 return
1110 # chop off the topmost part of the string we don't want to see
1099 # chop off the topmost part of the string we don't want to see
1111 str_lines = strng.split(os.linesep)[start:]
1100 str_lines = strng.split(os.linesep)[start:]
1112 str_toprint = os.linesep.join(str_lines)
1101 str_toprint = os.linesep.join(str_lines)
1113 num_newlines = len(str_lines)
1102 num_newlines = len(str_lines)
1114 len_str = len(str_toprint)
1103 len_str = len(str_toprint)
1115
1104
1116 # Dumb heuristics to guesstimate number of on-screen lines the string
1105 # Dumb heuristics to guesstimate number of on-screen lines the string
1117 # takes. Very basic, but good enough for docstrings in reasonable
1106 # takes. Very basic, but good enough for docstrings in reasonable
1118 # terminals. If someone later feels like refining it, it's not hard.
1107 # terminals. If someone later feels like refining it, it's not hard.
1119 numlines = max(num_newlines,int(len_str/80)+1)
1108 numlines = max(num_newlines,int(len_str/80)+1)
1120
1109
1121 screen_lines_def = 25 # default value if we can't auto-determine
1110 screen_lines_def = 25 # default value if we can't auto-determine
1122
1111
1123 # auto-determine screen size
1112 # auto-determine screen size
1124 if screen_lines <= 0:
1113 if screen_lines <= 0:
1125 if TERM=='xterm':
1114 if TERM=='xterm':
1126 try:
1115 try:
1127 import curses
1116 import curses
1128 if hasattr(curses,'initscr'):
1117 if hasattr(curses,'initscr'):
1129 use_curses = 1
1118 use_curses = 1
1130 else:
1119 else:
1131 use_curses = 0
1120 use_curses = 0
1132 except ImportError:
1121 except ImportError:
1133 use_curses = 0
1122 use_curses = 0
1134 else:
1123 else:
1135 # curses causes problems on many terminals other than xterm.
1124 # curses causes problems on many terminals other than xterm.
1136 use_curses = 0
1125 use_curses = 0
1137 if use_curses:
1126 if use_curses:
1138 scr = curses.initscr()
1127 scr = curses.initscr()
1139 screen_lines_real,screen_cols = scr.getmaxyx()
1128 screen_lines_real,screen_cols = scr.getmaxyx()
1140 curses.endwin()
1129 curses.endwin()
1141 screen_lines += screen_lines_real
1130 screen_lines += screen_lines_real
1142 #print '***Screen size:',screen_lines_real,'lines x',\
1131 #print '***Screen size:',screen_lines_real,'lines x',\
1143 #screen_cols,'columns.' # dbg
1132 #screen_cols,'columns.' # dbg
1144 else:
1133 else:
1145 screen_lines += screen_lines_def
1134 screen_lines += screen_lines_def
1146
1135
1147 #print 'numlines',numlines,'screenlines',screen_lines # dbg
1136 #print 'numlines',numlines,'screenlines',screen_lines # dbg
1148 if numlines <= screen_lines :
1137 if numlines <= screen_lines :
1149 #print '*** normal print' # dbg
1138 #print '*** normal print' # dbg
1150 print >>Term.cout, str_toprint
1139 print >>Term.cout, str_toprint
1151 else:
1140 else:
1152 # Try to open pager and default to internal one if that fails.
1141 # Try to open pager and default to internal one if that fails.
1153 # All failure modes are tagged as 'retval=1', to match the return
1142 # All failure modes are tagged as 'retval=1', to match the return
1154 # value of a failed system command. If any intermediate attempt
1143 # value of a failed system command. If any intermediate attempt
1155 # sets retval to 1, at the end we resort to our own page_dumb() pager.
1144 # sets retval to 1, at the end we resort to our own page_dumb() pager.
1156 pager_cmd = get_pager_cmd(pager_cmd)
1145 pager_cmd = get_pager_cmd(pager_cmd)
1157 pager_cmd += ' ' + get_pager_start(pager_cmd,start)
1146 pager_cmd += ' ' + get_pager_start(pager_cmd,start)
1158 if os.name == 'nt':
1147 if os.name == 'nt':
1159 if pager_cmd.startswith('type'):
1148 if pager_cmd.startswith('type'):
1160 # The default WinXP 'type' command is failing on complex strings.
1149 # The default WinXP 'type' command is failing on complex strings.
1161 retval = 1
1150 retval = 1
1162 else:
1151 else:
1163 tmpname = tempfile.mktemp('.txt')
1152 tmpname = tempfile.mktemp('.txt')
1164 tmpfile = file(tmpname,'wt')
1153 tmpfile = file(tmpname,'wt')
1165 tmpfile.write(strng)
1154 tmpfile.write(strng)
1166 tmpfile.close()
1155 tmpfile.close()
1167 cmd = "%s < %s" % (pager_cmd,tmpname)
1156 cmd = "%s < %s" % (pager_cmd,tmpname)
1168 if os.system(cmd):
1157 if os.system(cmd):
1169 retval = 1
1158 retval = 1
1170 else:
1159 else:
1171 retval = None
1160 retval = None
1172 os.remove(tmpname)
1161 os.remove(tmpname)
1173 else:
1162 else:
1174 try:
1163 try:
1175 retval = None
1164 retval = None
1176 # if I use popen4, things hang. No idea why.
1165 # if I use popen4, things hang. No idea why.
1177 #pager,shell_out = os.popen4(pager_cmd)
1166 #pager,shell_out = os.popen4(pager_cmd)
1178 pager = os.popen(pager_cmd,'w')
1167 pager = os.popen(pager_cmd,'w')
1179 pager.write(strng)
1168 pager.write(strng)
1180 pager.close()
1169 pager.close()
1181 retval = pager.close() # success returns None
1170 retval = pager.close() # success returns None
1182 except IOError,msg: # broken pipe when user quits
1171 except IOError,msg: # broken pipe when user quits
1183 if msg.args == (32,'Broken pipe'):
1172 if msg.args == (32,'Broken pipe'):
1184 retval = None
1173 retval = None
1185 else:
1174 else:
1186 retval = 1
1175 retval = 1
1187 except OSError:
1176 except OSError:
1188 # Other strange problems, sometimes seen in Win2k/cygwin
1177 # Other strange problems, sometimes seen in Win2k/cygwin
1189 retval = 1
1178 retval = 1
1190 if retval is not None:
1179 if retval is not None:
1191 page_dumb(strng,screen_lines=screen_lines)
1180 page_dumb(strng,screen_lines=screen_lines)
1192
1181
1193 #----------------------------------------------------------------------------
1182 #----------------------------------------------------------------------------
1194 def page_file(fname,start = 0, pager_cmd = None):
1183 def page_file(fname,start = 0, pager_cmd = None):
1195 """Page a file, using an optional pager command and starting line.
1184 """Page a file, using an optional pager command and starting line.
1196 """
1185 """
1197
1186
1198 pager_cmd = get_pager_cmd(pager_cmd)
1187 pager_cmd = get_pager_cmd(pager_cmd)
1199 pager_cmd += ' ' + get_pager_start(pager_cmd,start)
1188 pager_cmd += ' ' + get_pager_start(pager_cmd,start)
1200
1189
1201 try:
1190 try:
1202 if os.environ['TERM'] in ['emacs','dumb']:
1191 if os.environ['TERM'] in ['emacs','dumb']:
1203 raise EnvironmentError
1192 raise EnvironmentError
1204 xsys(pager_cmd + ' ' + fname)
1193 xsys(pager_cmd + ' ' + fname)
1205 except:
1194 except:
1206 try:
1195 try:
1207 if start > 0:
1196 if start > 0:
1208 start -= 1
1197 start -= 1
1209 page(open(fname).read(),start)
1198 page(open(fname).read(),start)
1210 except:
1199 except:
1211 print 'Unable to show file',`fname`
1200 print 'Unable to show file',`fname`
1212
1201
1213 #----------------------------------------------------------------------------
1202 #----------------------------------------------------------------------------
1214 def snip_print(str,width = 75,print_full = 0,header = ''):
1203 def snip_print(str,width = 75,print_full = 0,header = ''):
1215 """Print a string snipping the midsection to fit in width.
1204 """Print a string snipping the midsection to fit in width.
1216
1205
1217 print_full: mode control:
1206 print_full: mode control:
1218 - 0: only snip long strings
1207 - 0: only snip long strings
1219 - 1: send to page() directly.
1208 - 1: send to page() directly.
1220 - 2: snip long strings and ask for full length viewing with page()
1209 - 2: snip long strings and ask for full length viewing with page()
1221 Return 1 if snipping was necessary, 0 otherwise."""
1210 Return 1 if snipping was necessary, 0 otherwise."""
1222
1211
1223 if print_full == 1:
1212 if print_full == 1:
1224 page(header+str)
1213 page(header+str)
1225 return 0
1214 return 0
1226
1215
1227 print header,
1216 print header,
1228 if len(str) < width:
1217 if len(str) < width:
1229 print str
1218 print str
1230 snip = 0
1219 snip = 0
1231 else:
1220 else:
1232 whalf = int((width -5)/2)
1221 whalf = int((width -5)/2)
1233 print str[:whalf] + ' <...> ' + str[-whalf:]
1222 print str[:whalf] + ' <...> ' + str[-whalf:]
1234 snip = 1
1223 snip = 1
1235 if snip and print_full == 2:
1224 if snip and print_full == 2:
1236 if raw_input(header+' Snipped. View (y/n)? [N]').lower() == 'y':
1225 if raw_input(header+' Snipped. View (y/n)? [N]').lower() == 'y':
1237 page(str)
1226 page(str)
1238 return snip
1227 return snip
1239
1228
1240 #****************************************************************************
1229 #****************************************************************************
1241 # lists, dicts and structures
1230 # lists, dicts and structures
1242
1231
1243 def belong(candidates,checklist):
1232 def belong(candidates,checklist):
1244 """Check whether a list of items appear in a given list of options.
1233 """Check whether a list of items appear in a given list of options.
1245
1234
1246 Returns a list of 1 and 0, one for each candidate given."""
1235 Returns a list of 1 and 0, one for each candidate given."""
1247
1236
1248 return [x in checklist for x in candidates]
1237 return [x in checklist for x in candidates]
1249
1238
1250 #----------------------------------------------------------------------------
1239 #----------------------------------------------------------------------------
1251 def uniq_stable(elems):
1240 def uniq_stable(elems):
1252 """uniq_stable(elems) -> list
1241 """uniq_stable(elems) -> list
1253
1242
1254 Return from an iterable, a list of all the unique elements in the input,
1243 Return from an iterable, a list of all the unique elements in the input,
1255 but maintaining the order in which they first appear.
1244 but maintaining the order in which they first appear.
1256
1245
1257 A naive solution to this problem which just makes a dictionary with the
1246 A naive solution to this problem which just makes a dictionary with the
1258 elements as keys fails to respect the stability condition, since
1247 elements as keys fails to respect the stability condition, since
1259 dictionaries are unsorted by nature.
1248 dictionaries are unsorted by nature.
1260
1249
1261 Note: All elements in the input must be valid dictionary keys for this
1250 Note: All elements in the input must be valid dictionary keys for this
1262 routine to work, as it internally uses a dictionary for efficiency
1251 routine to work, as it internally uses a dictionary for efficiency
1263 reasons."""
1252 reasons."""
1264
1253
1265 unique = []
1254 unique = []
1266 unique_dict = {}
1255 unique_dict = {}
1267 for nn in elems:
1256 for nn in elems:
1268 if nn not in unique_dict:
1257 if nn not in unique_dict:
1269 unique.append(nn)
1258 unique.append(nn)
1270 unique_dict[nn] = None
1259 unique_dict[nn] = None
1271 return unique
1260 return unique
1272
1261
1273 #----------------------------------------------------------------------------
1262 #----------------------------------------------------------------------------
1274 class NLprinter:
1263 class NLprinter:
1275 """Print an arbitrarily nested list, indicating index numbers.
1264 """Print an arbitrarily nested list, indicating index numbers.
1276
1265
1277 An instance of this class called nlprint is available and callable as a
1266 An instance of this class called nlprint is available and callable as a
1278 function.
1267 function.
1279
1268
1280 nlprint(list,indent=' ',sep=': ') -> prints indenting each level by 'indent'
1269 nlprint(list,indent=' ',sep=': ') -> prints indenting each level by 'indent'
1281 and using 'sep' to separate the index from the value. """
1270 and using 'sep' to separate the index from the value. """
1282
1271
1283 def __init__(self):
1272 def __init__(self):
1284 self.depth = 0
1273 self.depth = 0
1285
1274
1286 def __call__(self,lst,pos='',**kw):
1275 def __call__(self,lst,pos='',**kw):
1287 """Prints the nested list numbering levels."""
1276 """Prints the nested list numbering levels."""
1288 kw.setdefault('indent',' ')
1277 kw.setdefault('indent',' ')
1289 kw.setdefault('sep',': ')
1278 kw.setdefault('sep',': ')
1290 kw.setdefault('start',0)
1279 kw.setdefault('start',0)
1291 kw.setdefault('stop',len(lst))
1280 kw.setdefault('stop',len(lst))
1292 # we need to remove start and stop from kw so they don't propagate
1281 # we need to remove start and stop from kw so they don't propagate
1293 # into a recursive call for a nested list.
1282 # into a recursive call for a nested list.
1294 start = kw['start']; del kw['start']
1283 start = kw['start']; del kw['start']
1295 stop = kw['stop']; del kw['stop']
1284 stop = kw['stop']; del kw['stop']
1296 if self.depth == 0 and 'header' in kw.keys():
1285 if self.depth == 0 and 'header' in kw.keys():
1297 print kw['header']
1286 print kw['header']
1298
1287
1299 for idx in range(start,stop):
1288 for idx in range(start,stop):
1300 elem = lst[idx]
1289 elem = lst[idx]
1301 if type(elem)==type([]):
1290 if type(elem)==type([]):
1302 self.depth += 1
1291 self.depth += 1
1303 self.__call__(elem,itpl('$pos$idx,'),**kw)
1292 self.__call__(elem,itpl('$pos$idx,'),**kw)
1304 self.depth -= 1
1293 self.depth -= 1
1305 else:
1294 else:
1306 printpl(kw['indent']*self.depth+'$pos$idx$kw["sep"]$elem')
1295 printpl(kw['indent']*self.depth+'$pos$idx$kw["sep"]$elem')
1307
1296
1308 nlprint = NLprinter()
1297 nlprint = NLprinter()
1309 #----------------------------------------------------------------------------
1298 #----------------------------------------------------------------------------
1310 def all_belong(candidates,checklist):
1299 def all_belong(candidates,checklist):
1311 """Check whether a list of items ALL appear in a given list of options.
1300 """Check whether a list of items ALL appear in a given list of options.
1312
1301
1313 Returns a single 1 or 0 value."""
1302 Returns a single 1 or 0 value."""
1314
1303
1315 return 1-(0 in [x in checklist for x in candidates])
1304 return 1-(0 in [x in checklist for x in candidates])
1316
1305
1317 #----------------------------------------------------------------------------
1306 #----------------------------------------------------------------------------
1318 def sort_compare(lst1,lst2,inplace = 1):
1307 def sort_compare(lst1,lst2,inplace = 1):
1319 """Sort and compare two lists.
1308 """Sort and compare two lists.
1320
1309
1321 By default it does it in place, thus modifying the lists. Use inplace = 0
1310 By default it does it in place, thus modifying the lists. Use inplace = 0
1322 to avoid that (at the cost of temporary copy creation)."""
1311 to avoid that (at the cost of temporary copy creation)."""
1323 if not inplace:
1312 if not inplace:
1324 lst1 = lst1[:]
1313 lst1 = lst1[:]
1325 lst2 = lst2[:]
1314 lst2 = lst2[:]
1326 lst1.sort(); lst2.sort()
1315 lst1.sort(); lst2.sort()
1327 return lst1 == lst2
1316 return lst1 == lst2
1328
1317
1329 #----------------------------------------------------------------------------
1318 #----------------------------------------------------------------------------
1330 def mkdict(**kwargs):
1319 def mkdict(**kwargs):
1331 """Return a dict from a keyword list.
1320 """Return a dict from a keyword list.
1332
1321
1333 It's just syntactic sugar for making ditcionary creation more convenient:
1322 It's just syntactic sugar for making ditcionary creation more convenient:
1334 # the standard way
1323 # the standard way
1335 >>>data = { 'red' : 1, 'green' : 2, 'blue' : 3 }
1324 >>>data = { 'red' : 1, 'green' : 2, 'blue' : 3 }
1336 # a cleaner way
1325 # a cleaner way
1337 >>>data = dict(red=1, green=2, blue=3)
1326 >>>data = dict(red=1, green=2, blue=3)
1338
1327
1339 If you need more than this, look at the Struct() class."""
1328 If you need more than this, look at the Struct() class."""
1340
1329
1341 return kwargs
1330 return kwargs
1342
1331
1343 #----------------------------------------------------------------------------
1332 #----------------------------------------------------------------------------
1344 def list2dict(lst):
1333 def list2dict(lst):
1345 """Takes a list of (key,value) pairs and turns it into a dict."""
1334 """Takes a list of (key,value) pairs and turns it into a dict."""
1346
1335
1347 dic = {}
1336 dic = {}
1348 for k,v in lst: dic[k] = v
1337 for k,v in lst: dic[k] = v
1349 return dic
1338 return dic
1350
1339
1351 #----------------------------------------------------------------------------
1340 #----------------------------------------------------------------------------
1352 def list2dict2(lst,default=''):
1341 def list2dict2(lst,default=''):
1353 """Takes a list and turns it into a dict.
1342 """Takes a list and turns it into a dict.
1354 Much slower than list2dict, but more versatile. This version can take
1343 Much slower than list2dict, but more versatile. This version can take
1355 lists with sublists of arbitrary length (including sclars)."""
1344 lists with sublists of arbitrary length (including sclars)."""
1356
1345
1357 dic = {}
1346 dic = {}
1358 for elem in lst:
1347 for elem in lst:
1359 if type(elem) in (types.ListType,types.TupleType):
1348 if type(elem) in (types.ListType,types.TupleType):
1360 size = len(elem)
1349 size = len(elem)
1361 if size == 0:
1350 if size == 0:
1362 pass
1351 pass
1363 elif size == 1:
1352 elif size == 1:
1364 dic[elem] = default
1353 dic[elem] = default
1365 else:
1354 else:
1366 k,v = elem[0], elem[1:]
1355 k,v = elem[0], elem[1:]
1367 if len(v) == 1: v = v[0]
1356 if len(v) == 1: v = v[0]
1368 dic[k] = v
1357 dic[k] = v
1369 else:
1358 else:
1370 dic[elem] = default
1359 dic[elem] = default
1371 return dic
1360 return dic
1372
1361
1373 #----------------------------------------------------------------------------
1362 #----------------------------------------------------------------------------
1374 def flatten(seq):
1363 def flatten(seq):
1375 """Flatten a list of lists (NOT recursive, only works for 2d lists)."""
1364 """Flatten a list of lists (NOT recursive, only works for 2d lists)."""
1376
1365
1377 # bug in python??? (YES. Fixed in 2.2, let's leave the kludgy fix in).
1366 # bug in python??? (YES. Fixed in 2.2, let's leave the kludgy fix in).
1378
1367
1379 # if the x=0 isn't made, a *global* variable x is left over after calling
1368 # if the x=0 isn't made, a *global* variable x is left over after calling
1380 # this function, with the value of the last element in the return
1369 # this function, with the value of the last element in the return
1381 # list. This does seem like a bug big time to me.
1370 # list. This does seem like a bug big time to me.
1382
1371
1383 # the problem is fixed with the x=0, which seems to force the creation of
1372 # the problem is fixed with the x=0, which seems to force the creation of
1384 # a local name
1373 # a local name
1385
1374
1386 x = 0
1375 x = 0
1387 return [x for subseq in seq for x in subseq]
1376 return [x for subseq in seq for x in subseq]
1388
1377
1389 #----------------------------------------------------------------------------
1378 #----------------------------------------------------------------------------
1390 def get_slice(seq,start=0,stop=None,step=1):
1379 def get_slice(seq,start=0,stop=None,step=1):
1391 """Get a slice of a sequence with variable step. Specify start,stop,step."""
1380 """Get a slice of a sequence with variable step. Specify start,stop,step."""
1392 if stop == None:
1381 if stop == None:
1393 stop = len(seq)
1382 stop = len(seq)
1394 item = lambda i: seq[i]
1383 item = lambda i: seq[i]
1395 return map(item,xrange(start,stop,step))
1384 return map(item,xrange(start,stop,step))
1396
1385
1397 #----------------------------------------------------------------------------
1386 #----------------------------------------------------------------------------
1398 def chop(seq,size):
1387 def chop(seq,size):
1399 """Chop a sequence into chunks of the given size."""
1388 """Chop a sequence into chunks of the given size."""
1400 chunk = lambda i: seq[i:i+size]
1389 chunk = lambda i: seq[i:i+size]
1401 return map(chunk,xrange(0,len(seq),size))
1390 return map(chunk,xrange(0,len(seq),size))
1402
1391
1403 #----------------------------------------------------------------------------
1392 #----------------------------------------------------------------------------
1404 def with(object, **args):
1393 def with(object, **args):
1405 """Set multiple attributes for an object, similar to Pascal's with.
1394 """Set multiple attributes for an object, similar to Pascal's with.
1406
1395
1407 Example:
1396 Example:
1408 with(jim,
1397 with(jim,
1409 born = 1960,
1398 born = 1960,
1410 haircolour = 'Brown',
1399 haircolour = 'Brown',
1411 eyecolour = 'Green')
1400 eyecolour = 'Green')
1412
1401
1413 Credit: Greg Ewing, in
1402 Credit: Greg Ewing, in
1414 http://mail.python.org/pipermail/python-list/2001-May/040703.html"""
1403 http://mail.python.org/pipermail/python-list/2001-May/040703.html"""
1415
1404
1416 object.__dict__.update(args)
1405 object.__dict__.update(args)
1417
1406
1418 #----------------------------------------------------------------------------
1407 #----------------------------------------------------------------------------
1419 def setattr_list(obj,alist,nspace = None):
1408 def setattr_list(obj,alist,nspace = None):
1420 """Set a list of attributes for an object taken from a namespace.
1409 """Set a list of attributes for an object taken from a namespace.
1421
1410
1422 setattr_list(obj,alist,nspace) -> sets in obj all the attributes listed in
1411 setattr_list(obj,alist,nspace) -> sets in obj all the attributes listed in
1423 alist with their values taken from nspace, which must be a dict (something
1412 alist with their values taken from nspace, which must be a dict (something
1424 like locals() will often do) If nspace isn't given, locals() of the
1413 like locals() will often do) If nspace isn't given, locals() of the
1425 *caller* is used, so in most cases you can omit it.
1414 *caller* is used, so in most cases you can omit it.
1426
1415
1427 Note that alist can be given as a string, which will be automatically
1416 Note that alist can be given as a string, which will be automatically
1428 split into a list on whitespace. If given as a list, it must be a list of
1417 split into a list on whitespace. If given as a list, it must be a list of
1429 *strings* (the variable names themselves), not of variables."""
1418 *strings* (the variable names themselves), not of variables."""
1430
1419
1431 # this grabs the local variables from the *previous* call frame -- that is
1420 # this grabs the local variables from the *previous* call frame -- that is
1432 # the locals from the function that called setattr_list().
1421 # the locals from the function that called setattr_list().
1433 # - snipped from weave.inline()
1422 # - snipped from weave.inline()
1434 if nspace is None:
1423 if nspace is None:
1435 call_frame = sys._getframe().f_back
1424 call_frame = sys._getframe().f_back
1436 nspace = call_frame.f_locals
1425 nspace = call_frame.f_locals
1437
1426
1438 if type(alist) in StringTypes:
1427 if type(alist) in StringTypes:
1439 alist = alist.split()
1428 alist = alist.split()
1440 for attr in alist:
1429 for attr in alist:
1441 val = eval(attr,nspace)
1430 val = eval(attr,nspace)
1442 setattr(obj,attr,val)
1431 setattr(obj,attr,val)
1443
1432
1444 #----------------------------------------------------------------------------
1433 #----------------------------------------------------------------------------
1445 def getattr_list(obj,alist,*args):
1434 def getattr_list(obj,alist,*args):
1446 """getattr_list(obj,alist[, default]) -> attribute list.
1435 """getattr_list(obj,alist[, default]) -> attribute list.
1447
1436
1448 Get a list of named attributes for an object. When a default argument is
1437 Get a list of named attributes for an object. When a default argument is
1449 given, it is returned when the attribute doesn't exist; without it, an
1438 given, it is returned when the attribute doesn't exist; without it, an
1450 exception is raised in that case.
1439 exception is raised in that case.
1451
1440
1452 Note that alist can be given as a string, which will be automatically
1441 Note that alist can be given as a string, which will be automatically
1453 split into a list on whitespace. If given as a list, it must be a list of
1442 split into a list on whitespace. If given as a list, it must be a list of
1454 *strings* (the variable names themselves), not of variables."""
1443 *strings* (the variable names themselves), not of variables."""
1455
1444
1456 if type(alist) in StringTypes:
1445 if type(alist) in StringTypes:
1457 alist = alist.split()
1446 alist = alist.split()
1458 if args:
1447 if args:
1459 if len(args)==1:
1448 if len(args)==1:
1460 default = args[0]
1449 default = args[0]
1461 return map(lambda attr: getattr(obj,attr,default),alist)
1450 return map(lambda attr: getattr(obj,attr,default),alist)
1462 else:
1451 else:
1463 raise ValueError,'getattr_list() takes only one optional argument'
1452 raise ValueError,'getattr_list() takes only one optional argument'
1464 else:
1453 else:
1465 return map(lambda attr: getattr(obj,attr),alist)
1454 return map(lambda attr: getattr(obj,attr),alist)
1466
1455
1467 #----------------------------------------------------------------------------
1456 #----------------------------------------------------------------------------
1468 def map_method(method,object_list,*argseq,**kw):
1457 def map_method(method,object_list,*argseq,**kw):
1469 """map_method(method,object_list,*args,**kw) -> list
1458 """map_method(method,object_list,*args,**kw) -> list
1470
1459
1471 Return a list of the results of applying the methods to the items of the
1460 Return a list of the results of applying the methods to the items of the
1472 argument sequence(s). If more than one sequence is given, the method is
1461 argument sequence(s). If more than one sequence is given, the method is
1473 called with an argument list consisting of the corresponding item of each
1462 called with an argument list consisting of the corresponding item of each
1474 sequence. All sequences must be of the same length.
1463 sequence. All sequences must be of the same length.
1475
1464
1476 Keyword arguments are passed verbatim to all objects called.
1465 Keyword arguments are passed verbatim to all objects called.
1477
1466
1478 This is Python code, so it's not nearly as fast as the builtin map()."""
1467 This is Python code, so it's not nearly as fast as the builtin map()."""
1479
1468
1480 out_list = []
1469 out_list = []
1481 idx = 0
1470 idx = 0
1482 for object in object_list:
1471 for object in object_list:
1483 try:
1472 try:
1484 handler = getattr(object, method)
1473 handler = getattr(object, method)
1485 except AttributeError:
1474 except AttributeError:
1486 out_list.append(None)
1475 out_list.append(None)
1487 else:
1476 else:
1488 if argseq:
1477 if argseq:
1489 args = map(lambda lst:lst[idx],argseq)
1478 args = map(lambda lst:lst[idx],argseq)
1490 #print 'ob',object,'hand',handler,'ar',args # dbg
1479 #print 'ob',object,'hand',handler,'ar',args # dbg
1491 out_list.append(handler(args,**kw))
1480 out_list.append(handler(args,**kw))
1492 else:
1481 else:
1493 out_list.append(handler(**kw))
1482 out_list.append(handler(**kw))
1494 idx += 1
1483 idx += 1
1495 return out_list
1484 return out_list
1496
1485
1497 #----------------------------------------------------------------------------
1486 #----------------------------------------------------------------------------
1498 # Proposed popitem() extension, written as a method
1487 # Proposed popitem() extension, written as a method
1499
1488
1500 class NotGiven: pass
1489 class NotGiven: pass
1501
1490
1502 def popkey(dct,key,default=NotGiven):
1491 def popkey(dct,key,default=NotGiven):
1503 """Return dct[key] and delete dct[key].
1492 """Return dct[key] and delete dct[key].
1504
1493
1505 If default is given, return it if dct[key] doesn't exist, otherwise raise
1494 If default is given, return it if dct[key] doesn't exist, otherwise raise
1506 KeyError. """
1495 KeyError. """
1507
1496
1508 try:
1497 try:
1509 val = dct[key]
1498 val = dct[key]
1510 except KeyError:
1499 except KeyError:
1511 if default is NotGiven:
1500 if default is NotGiven:
1512 raise
1501 raise
1513 else:
1502 else:
1514 return default
1503 return default
1515 else:
1504 else:
1516 del dct[key]
1505 del dct[key]
1517 return val
1506 return val
1518 #*************************** end of file <genutils.py> **********************
1507 #*************************** end of file <genutils.py> **********************
1519
1508
@@ -1,2084 +1,1999 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 IPython -- An enhanced Interactive Python
3 IPython -- An enhanced Interactive Python
4
4
5 Requires Python 2.1 or newer.
5 Requires Python 2.1 or newer.
6
6
7 This file contains all the classes and helper functions specific to IPython.
7 This file contains all the classes and helper functions specific to IPython.
8
8
9 $Id: iplib.py 602 2005-06-09 03:02:30Z fperez $
9 $Id: iplib.py 638 2005-07-18 03:01:41Z fperez $
10 """
10 """
11
11
12 #*****************************************************************************
12 #*****************************************************************************
13 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and
13 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and
14 # Copyright (C) 2001-2004 Fernando Perez. <fperez@colorado.edu>
14 # Copyright (C) 2001-2004 Fernando Perez. <fperez@colorado.edu>
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 # Note: this code originally subclassed code.InteractiveConsole from the
19 # Note: this code originally subclassed code.InteractiveConsole from the
20 # Python standard library. Over time, much of that class has been copied
20 # Python standard library. Over time, much of that class has been copied
21 # verbatim here for modifications which could not be accomplished by
21 # verbatim here for modifications which could not be accomplished by
22 # subclassing. The Python License (sec. 2) allows for this, but it's always
22 # subclassing. The Python License (sec. 2) allows for this, but it's always
23 # nice to acknowledge credit where credit is due.
23 # nice to acknowledge credit where credit is due.
24 #*****************************************************************************
24 #*****************************************************************************
25
25
26 #****************************************************************************
26 #****************************************************************************
27 # Modules and globals
27 # Modules and globals
28
28
29 from __future__ import generators # for 2.2 backwards-compatibility
29 from __future__ import generators # for 2.2 backwards-compatibility
30
30
31 from IPython import Release
31 from IPython import Release
32 __author__ = '%s <%s>\n%s <%s>' % \
32 __author__ = '%s <%s>\n%s <%s>' % \
33 ( Release.authors['Janko'] + Release.authors['Fernando'] )
33 ( Release.authors['Janko'] + Release.authors['Fernando'] )
34 __license__ = Release.license
34 __license__ = Release.license
35 __version__ = Release.version
35 __version__ = Release.version
36
36
37 # Python standard modules
37 # Python standard modules
38 import __main__
38 import __main__
39 import __builtin__
39 import __builtin__
40 import exceptions
40 import exceptions
41 import keyword
41 import keyword
42 import new
42 import new
43 import os, sys, shutil
43 import os, sys, shutil
44 import code, glob, types, re
44 import code, glob, types, re
45 import string, StringIO
45 import string, StringIO
46 import inspect, pydoc
46 import inspect, pydoc
47 import bdb, pdb
47 import bdb, pdb
48 import UserList # don't subclass list so this works with Python2.1
48 import UserList # don't subclass list so this works with Python2.1
49 from pprint import pprint, pformat
49 from pprint import pprint, pformat
50 import cPickle as pickle
50 import cPickle as pickle
51 import traceback
51 import traceback
52
52
53 # IPython's own modules
53 # IPython's own modules
54 import IPython
54 import IPython
55 from IPython import OInspect,PyColorize,ultraTB
55 from IPython import OInspect,PyColorize,ultraTB
56 from IPython.ultraTB import ColorScheme,ColorSchemeTable # too long names
56 from IPython.ultraTB import ColorScheme,ColorSchemeTable # too long names
57 from IPython.Logger import Logger
57 from IPython.Logger import Logger
58 from IPython.Magic import Magic,magic2python,shlex_split
58 from IPython.Magic import Magic,magic2python,shlex_split
59 from IPython.usage import cmd_line_usage,interactive_usage
59 from IPython.usage import cmd_line_usage,interactive_usage
60 from IPython.Struct import Struct
60 from IPython.Struct import Struct
61 from IPython.Itpl import Itpl,itpl,printpl,ItplNS,itplns
61 from IPython.Itpl import Itpl,itpl,printpl,ItplNS,itplns
62 from IPython.FakeModule import FakeModule
62 from IPython.FakeModule import FakeModule
63 from IPython.background_jobs import BackgroundJobManager
63 from IPython.background_jobs import BackgroundJobManager
64 from IPython.genutils import *
64 from IPython.genutils import *
65
65
66 # Global pointer to the running
66 # Global pointer to the running
67
67
68 # store the builtin raw_input globally, and use this always, in case user code
68 # store the builtin raw_input globally, and use this always, in case user code
69 # overwrites it (like wx.py.PyShell does)
69 # overwrites it (like wx.py.PyShell does)
70 raw_input_original = raw_input
70 raw_input_original = raw_input
71
71
72 # declares Python 2.2 compatibility symbols:
73 try:
74 enumerate
75 except NameError:
76 def enumerate(obj):
77 i = -1
78 for item in obj:
79 i += 1
80 yield i, item
81 #****************************************************************************
72 #****************************************************************************
82 # Some utility function definitions
73 # Some utility function definitions
83
74
84 class Bunch: pass
75 class Bunch: pass
85
76
86 def esc_quotes(strng):
77 def esc_quotes(strng):
87 """Return the input string with single and double quotes escaped out"""
78 """Return the input string with single and double quotes escaped out"""
88
79
89 return strng.replace('"','\\"').replace("'","\\'")
80 return strng.replace('"','\\"').replace("'","\\'")
90
81
91 def import_fail_info(mod_name,fns=None):
82 def import_fail_info(mod_name,fns=None):
92 """Inform load failure for a module."""
83 """Inform load failure for a module."""
93
84
94 if fns == None:
85 if fns == None:
95 warn("Loading of %s failed.\n" % (mod_name,))
86 warn("Loading of %s failed.\n" % (mod_name,))
96 else:
87 else:
97 warn("Loading of %s from %s failed.\n" % (fns,mod_name))
88 warn("Loading of %s from %s failed.\n" % (fns,mod_name))
98
89
99 def qw_lol(indata):
90 def qw_lol(indata):
100 """qw_lol('a b') -> [['a','b']],
91 """qw_lol('a b') -> [['a','b']],
101 otherwise it's just a call to qw().
92 otherwise it's just a call to qw().
102
93
103 We need this to make sure the modules_some keys *always* end up as a
94 We need this to make sure the modules_some keys *always* end up as a
104 list of lists."""
95 list of lists."""
105
96
106 if type(indata) in StringTypes:
97 if type(indata) in StringTypes:
107 return [qw(indata)]
98 return [qw(indata)]
108 else:
99 else:
109 return qw(indata)
100 return qw(indata)
110
101
111 def ipmagic(arg_s):
102 def ipmagic(arg_s):
112 """Call a magic function by name.
103 """Call a magic function by name.
113
104
114 Input: a string containing the name of the magic function to call and any
105 Input: a string containing the name of the magic function to call and any
115 additional arguments to be passed to the magic.
106 additional arguments to be passed to the magic.
116
107
117 ipmagic('name -opt foo bar') is equivalent to typing at the ipython
108 ipmagic('name -opt foo bar') is equivalent to typing at the ipython
118 prompt:
109 prompt:
119
110
120 In[1]: %name -opt foo bar
111 In[1]: %name -opt foo bar
121
112
122 To call a magic without arguments, simply use ipmagic('name').
113 To call a magic without arguments, simply use ipmagic('name').
123
114
124 This provides a proper Python function to call IPython's magics in any
115 This provides a proper Python function to call IPython's magics in any
125 valid Python code you can type at the interpreter, including loops and
116 valid Python code you can type at the interpreter, including loops and
126 compound statements. It is added by IPython to the Python builtin
117 compound statements. It is added by IPython to the Python builtin
127 namespace upon initialization."""
118 namespace upon initialization."""
128
119
129 args = arg_s.split(' ',1)
120 args = arg_s.split(' ',1)
130 magic_name = args[0]
121 magic_name = args[0]
131 if magic_name.startswith(__IPYTHON__.ESC_MAGIC):
122 if magic_name.startswith(__IPYTHON__.ESC_MAGIC):
132 magic_name = magic_name[1:]
123 magic_name = magic_name[1:]
133 try:
124 try:
134 magic_args = args[1]
125 magic_args = args[1]
135 except IndexError:
126 except IndexError:
136 magic_args = ''
127 magic_args = ''
137 fn = getattr(__IPYTHON__,'magic_'+magic_name,None)
128 fn = getattr(__IPYTHON__,'magic_'+magic_name,None)
138 if fn is None:
129 if fn is None:
139 error("Magic function `%s` not found." % magic_name)
130 error("Magic function `%s` not found." % magic_name)
140 else:
131 else:
141 magic_args = __IPYTHON__.var_expand(magic_args)
132 magic_args = __IPYTHON__.var_expand(magic_args)
142 return fn(magic_args)
133 return fn(magic_args)
143
134
144 def ipalias(arg_s):
135 def ipalias(arg_s):
145 """Call an alias by name.
136 """Call an alias by name.
146
137
147 Input: a string containing the name of the alias to call and any
138 Input: a string containing the name of the alias to call and any
148 additional arguments to be passed to the magic.
139 additional arguments to be passed to the magic.
149
140
150 ipalias('name -opt foo bar') is equivalent to typing at the ipython
141 ipalias('name -opt foo bar') is equivalent to typing at the ipython
151 prompt:
142 prompt:
152
143
153 In[1]: name -opt foo bar
144 In[1]: name -opt foo bar
154
145
155 To call an alias without arguments, simply use ipalias('name').
146 To call an alias without arguments, simply use ipalias('name').
156
147
157 This provides a proper Python function to call IPython's aliases in any
148 This provides a proper Python function to call IPython's aliases in any
158 valid Python code you can type at the interpreter, including loops and
149 valid Python code you can type at the interpreter, including loops and
159 compound statements. It is added by IPython to the Python builtin
150 compound statements. It is added by IPython to the Python builtin
160 namespace upon initialization."""
151 namespace upon initialization."""
161
152
162 args = arg_s.split(' ',1)
153 args = arg_s.split(' ',1)
163 alias_name = args[0]
154 alias_name = args[0]
164 try:
155 try:
165 alias_args = args[1]
156 alias_args = args[1]
166 except IndexError:
157 except IndexError:
167 alias_args = ''
158 alias_args = ''
168 if alias_name in __IPYTHON__.alias_table:
159 if alias_name in __IPYTHON__.alias_table:
169 __IPYTHON__.call_alias(alias_name,alias_args)
160 __IPYTHON__.call_alias(alias_name,alias_args)
170 else:
161 else:
171 error("Alias `%s` not found." % alias_name)
162 error("Alias `%s` not found." % alias_name)
172
163
173 #-----------------------------------------------------------------------------
164 #-----------------------------------------------------------------------------
174 # Local use classes
165 # Local use classes
175 try:
166 try:
176 from IPython import FlexCompleter
167 from IPython import FlexCompleter
177
168
178 class MagicCompleter(FlexCompleter.Completer):
169 class MagicCompleter(FlexCompleter.Completer):
179 """Extension of the completer class to work on %-prefixed lines."""
170 """Extension of the completer class to work on %-prefixed lines."""
180
171
181 def __init__(self,shell,namespace=None,omit__names=0,alias_table=None):
172 def __init__(self,shell,namespace=None,omit__names=0,alias_table=None):
182 """MagicCompleter() -> completer
173 """MagicCompleter() -> completer
183
174
184 Return a completer object suitable for use by the readline library
175 Return a completer object suitable for use by the readline library
185 via readline.set_completer().
176 via readline.set_completer().
186
177
187 Inputs:
178 Inputs:
188
179
189 - shell: a pointer to the ipython shell itself. This is needed
180 - shell: a pointer to the ipython shell itself. This is needed
190 because this completer knows about magic functions, and those can
181 because this completer knows about magic functions, and those can
191 only be accessed via the ipython instance.
182 only be accessed via the ipython instance.
192
183
193 - namespace: an optional dict where completions are performed.
184 - namespace: an optional dict where completions are performed.
194
185
195 - The optional omit__names parameter sets the completer to omit the
186 - The optional omit__names parameter sets the completer to omit the
196 'magic' names (__magicname__) for python objects unless the text
187 'magic' names (__magicname__) for python objects unless the text
197 to be completed explicitly starts with one or more underscores.
188 to be completed explicitly starts with one or more underscores.
198
189
199 - If alias_table is supplied, it should be a dictionary of aliases
190 - If alias_table is supplied, it should be a dictionary of aliases
200 to complete. """
191 to complete. """
201
192
202 FlexCompleter.Completer.__init__(self,namespace)
193 FlexCompleter.Completer.__init__(self,namespace)
203 self.magic_prefix = shell.name+'.magic_'
194 self.magic_prefix = shell.name+'.magic_'
204 self.magic_escape = shell.ESC_MAGIC
195 self.magic_escape = shell.ESC_MAGIC
205 self.readline = FlexCompleter.readline
196 self.readline = FlexCompleter.readline
206 delims = self.readline.get_completer_delims()
197 delims = self.readline.get_completer_delims()
207 delims = delims.replace(self.magic_escape,'')
198 delims = delims.replace(self.magic_escape,'')
208 self.readline.set_completer_delims(delims)
199 self.readline.set_completer_delims(delims)
209 self.get_line_buffer = self.readline.get_line_buffer
200 self.get_line_buffer = self.readline.get_line_buffer
210 self.omit__names = omit__names
201 self.omit__names = omit__names
211 self.merge_completions = shell.rc.readline_merge_completions
202 self.merge_completions = shell.rc.readline_merge_completions
212
203
213 if alias_table is None:
204 if alias_table is None:
214 alias_table = {}
205 alias_table = {}
215 self.alias_table = alias_table
206 self.alias_table = alias_table
216 # Regexp to split filenames with spaces in them
207 # Regexp to split filenames with spaces in them
217 self.space_name_re = re.compile(r'([^\\] )')
208 self.space_name_re = re.compile(r'([^\\] )')
218 # Hold a local ref. to glob.glob for speed
209 # Hold a local ref. to glob.glob for speed
219 self.glob = glob.glob
210 self.glob = glob.glob
220 # Special handling of backslashes needed in win32 platforms
211 # Special handling of backslashes needed in win32 platforms
221 if sys.platform == "win32":
212 if sys.platform == "win32":
222 self.clean_glob = self._clean_glob_win32
213 self.clean_glob = self._clean_glob_win32
223 else:
214 else:
224 self.clean_glob = self._clean_glob
215 self.clean_glob = self._clean_glob
225 self.matchers = [self.python_matches,
216 self.matchers = [self.python_matches,
226 self.file_matches,
217 self.file_matches,
227 self.alias_matches,
218 self.alias_matches,
228 self.python_func_kw_matches]
219 self.python_func_kw_matches]
229
220
230 # Code contributed by Alex Schmolck, for ipython/emacs integration
221 # Code contributed by Alex Schmolck, for ipython/emacs integration
231 def all_completions(self, text):
222 def all_completions(self, text):
232 """Return all possible completions for the benefit of emacs."""
223 """Return all possible completions for the benefit of emacs."""
233
224
234 completions = []
225 completions = []
235 try:
226 try:
236 for i in xrange(sys.maxint):
227 for i in xrange(sys.maxint):
237 res = self.complete(text, i)
228 res = self.complete(text, i)
238
229
239 if not res: break
230 if not res: break
240
231
241 completions.append(res)
232 completions.append(res)
242 #XXX workaround for ``notDefined.<tab>``
233 #XXX workaround for ``notDefined.<tab>``
243 except NameError:
234 except NameError:
244 pass
235 pass
245 return completions
236 return completions
246 # /end Alex Schmolck code.
237 # /end Alex Schmolck code.
247
238
248 def _clean_glob(self,text):
239 def _clean_glob(self,text):
249 return self.glob("%s*" % text)
240 return self.glob("%s*" % text)
250
241
251 def _clean_glob_win32(self,text):
242 def _clean_glob_win32(self,text):
252 return [f.replace("\\","/")
243 return [f.replace("\\","/")
253 for f in self.glob("%s*" % text)]
244 for f in self.glob("%s*" % text)]
254
245
255 def file_matches(self, text):
246 def file_matches(self, text):
256 """Match filneames, expanding ~USER type strings.
247 """Match filneames, expanding ~USER type strings.
257
248
258 Most of the seemingly convoluted logic in this completer is an
249 Most of the seemingly convoluted logic in this completer is an
259 attempt to handle filenames with spaces in them. And yet it's not
250 attempt to handle filenames with spaces in them. And yet it's not
260 quite perfect, because Python's readline doesn't expose all of the
251 quite perfect, because Python's readline doesn't expose all of the
261 GNU readline details needed for this to be done correctly.
252 GNU readline details needed for this to be done correctly.
262
253
263 For a filename with a space in it, the printed completions will be
254 For a filename with a space in it, the printed completions will be
264 only the parts after what's already been typed (instead of the
255 only the parts after what's already been typed (instead of the
265 full completions, as is normally done). I don't think with the
256 full completions, as is normally done). I don't think with the
266 current (as of Python 2.3) Python readline it's possible to do
257 current (as of Python 2.3) Python readline it's possible to do
267 better."""
258 better."""
268
259
269 #print 'Completer->file_matches: <%s>' % text # dbg
260 #print 'Completer->file_matches: <%s>' % text # dbg
270
261
271 # chars that require escaping with backslash - i.e. chars
262 # chars that require escaping with backslash - i.e. chars
272 # that readline treats incorrectly as delimiters, but we
263 # that readline treats incorrectly as delimiters, but we
273 # don't want to treat as delimiters in filename matching
264 # don't want to treat as delimiters in filename matching
274 # when escaped with backslash
265 # when escaped with backslash
275
266
276 protectables = ' ()[]{}'
267 protectables = ' ()[]{}'
277
268
278 def protect_filename(s):
269 def protect_filename(s):
279 return "".join([(ch in protectables and '\\' + ch or ch)
270 return "".join([(ch in protectables and '\\' + ch or ch)
280 for ch in s])
271 for ch in s])
281
272
282 lbuf = self.get_line_buffer()[:self.readline.get_endidx()]
273 lbuf = self.get_line_buffer()[:self.readline.get_endidx()]
283 open_quotes = 0 # track strings with open quotes
274 open_quotes = 0 # track strings with open quotes
284 try:
275 try:
285 lsplit = shlex_split(lbuf)[-1]
276 lsplit = shlex_split(lbuf)[-1]
286 except ValueError:
277 except ValueError:
287 # typically an unmatched ", or backslash without escaped char.
278 # typically an unmatched ", or backslash without escaped char.
288 if lbuf.count('"')==1:
279 if lbuf.count('"')==1:
289 open_quotes = 1
280 open_quotes = 1
290 lsplit = lbuf.split('"')[-1]
281 lsplit = lbuf.split('"')[-1]
291 elif lbuf.count("'")==1:
282 elif lbuf.count("'")==1:
292 open_quotes = 1
283 open_quotes = 1
293 lsplit = lbuf.split("'")[-1]
284 lsplit = lbuf.split("'")[-1]
294 else:
285 else:
295 return None
286 return None
296 except IndexError:
287 except IndexError:
297 # tab pressed on empty line
288 # tab pressed on empty line
298 lsplit = ""
289 lsplit = ""
299
290
300 if lsplit != protect_filename(lsplit):
291 if lsplit != protect_filename(lsplit):
301 # if protectables are found, do matching on the whole escaped
292 # if protectables are found, do matching on the whole escaped
302 # name
293 # name
303 has_protectables = 1
294 has_protectables = 1
304 text0,text = text,lsplit
295 text0,text = text,lsplit
305 else:
296 else:
306 has_protectables = 0
297 has_protectables = 0
307 text = os.path.expanduser(text)
298 text = os.path.expanduser(text)
308
299
309 if text == "":
300 if text == "":
310 return [protect_filename(f) for f in self.glob("*")]
301 return [protect_filename(f) for f in self.glob("*")]
311
302
312 m0 = self.clean_glob(text.replace('\\',''))
303 m0 = self.clean_glob(text.replace('\\',''))
313 if has_protectables:
304 if has_protectables:
314 # If we had protectables, we need to revert our changes to the
305 # If we had protectables, we need to revert our changes to the
315 # beginning of filename so that we don't double-write the part
306 # beginning of filename so that we don't double-write the part
316 # of the filename we have so far
307 # of the filename we have so far
317 len_lsplit = len(lsplit)
308 len_lsplit = len(lsplit)
318 matches = [text0 + protect_filename(f[len_lsplit:]) for f in m0]
309 matches = [text0 + protect_filename(f[len_lsplit:]) for f in m0]
319 else:
310 else:
320 if open_quotes:
311 if open_quotes:
321 # if we have a string with an open quote, we don't need to
312 # if we have a string with an open quote, we don't need to
322 # protect the names at all (and we _shouldn't_, as it
313 # protect the names at all (and we _shouldn't_, as it
323 # would cause bugs when the filesystem call is made).
314 # would cause bugs when the filesystem call is made).
324 matches = m0
315 matches = m0
325 else:
316 else:
326 matches = [protect_filename(f) for f in m0]
317 matches = [protect_filename(f) for f in m0]
327 if len(matches) == 1 and os.path.isdir(matches[0]):
318 if len(matches) == 1 and os.path.isdir(matches[0]):
328 # Takes care of links to directories also. Use '/'
319 # Takes care of links to directories also. Use '/'
329 # explicitly, even under Windows, so that name completions
320 # explicitly, even under Windows, so that name completions
330 # don't end up escaped.
321 # don't end up escaped.
331 matches[0] += '/'
322 matches[0] += '/'
332 return matches
323 return matches
333
324
334 def alias_matches(self, text):
325 def alias_matches(self, text):
335 """Match internal system aliases"""
326 """Match internal system aliases"""
336 #print 'Completer->alias_matches:',text # dbg
327 #print 'Completer->alias_matches:',text # dbg
337 text = os.path.expanduser(text)
328 text = os.path.expanduser(text)
338 aliases = self.alias_table.keys()
329 aliases = self.alias_table.keys()
339 if text == "":
330 if text == "":
340 return aliases
331 return aliases
341 else:
332 else:
342 return [alias for alias in aliases if alias.startswith(text)]
333 return [alias for alias in aliases if alias.startswith(text)]
343
334
344 def python_matches(self,text):
335 def python_matches(self,text):
345 """Match attributes or global python names"""
336 """Match attributes or global python names"""
346 #print 'Completer->python_matches' # dbg
337 #print 'Completer->python_matches' # dbg
347 if "." in text:
338 if "." in text:
348 try:
339 try:
349 matches = self.attr_matches(text)
340 matches = self.attr_matches(text)
350 if text.endswith('.') and self.omit__names:
341 if text.endswith('.') and self.omit__names:
351 if self.omit__names == 1:
342 if self.omit__names == 1:
352 # true if txt is _not_ a __ name, false otherwise:
343 # true if txt is _not_ a __ name, false otherwise:
353 no__name = (lambda txt:
344 no__name = (lambda txt:
354 re.match(r'.*\.__.*?__',txt) is None)
345 re.match(r'.*\.__.*?__',txt) is None)
355 else:
346 else:
356 # true if txt is _not_ a _ name, false otherwise:
347 # true if txt is _not_ a _ name, false otherwise:
357 no__name = (lambda txt:
348 no__name = (lambda txt:
358 re.match(r'.*\._.*?',txt) is None)
349 re.match(r'.*\._.*?',txt) is None)
359 matches = filter(no__name, matches)
350 matches = filter(no__name, matches)
360 except NameError:
351 except NameError:
361 # catches <undefined attributes>.<tab>
352 # catches <undefined attributes>.<tab>
362 matches = []
353 matches = []
363 else:
354 else:
364 matches = self.global_matches(text)
355 matches = self.global_matches(text)
365 # this is so completion finds magics when automagic is on:
356 # this is so completion finds magics when automagic is on:
366 if matches == [] and not text.startswith(os.sep):
357 if matches == [] and not text.startswith(os.sep):
367 matches = self.attr_matches(self.magic_prefix+text)
358 matches = self.attr_matches(self.magic_prefix+text)
368 return matches
359 return matches
369
360
370 def _default_arguments(self, obj):
361 def _default_arguments(self, obj):
371 """Return the list of default arguments of obj if it is callable,
362 """Return the list of default arguments of obj if it is callable,
372 or empty list otherwise."""
363 or empty list otherwise."""
373
364
374 if not (inspect.isfunction(obj) or inspect.ismethod(obj)):
365 if not (inspect.isfunction(obj) or inspect.ismethod(obj)):
375 # for classes, check for __init__,__new__
366 # for classes, check for __init__,__new__
376 if inspect.isclass(obj):
367 if inspect.isclass(obj):
377 obj = (getattr(obj,'__init__',None) or
368 obj = (getattr(obj,'__init__',None) or
378 getattr(obj,'__new__',None))
369 getattr(obj,'__new__',None))
379 # for all others, check if they are __call__able
370 # for all others, check if they are __call__able
380 elif hasattr(obj, '__call__'):
371 elif hasattr(obj, '__call__'):
381 obj = obj.__call__
372 obj = obj.__call__
382 # XXX: is there a way to handle the builtins ?
373 # XXX: is there a way to handle the builtins ?
383 try:
374 try:
384 args,_,_1,defaults = inspect.getargspec(obj)
375 args,_,_1,defaults = inspect.getargspec(obj)
385 if defaults:
376 if defaults:
386 return args[-len(defaults):]
377 return args[-len(defaults):]
387 except TypeError: pass
378 except TypeError: pass
388 return []
379 return []
389
380
390 def python_func_kw_matches(self,text):
381 def python_func_kw_matches(self,text):
391 """Match named parameters (kwargs) of the last open function"""
382 """Match named parameters (kwargs) of the last open function"""
392
383
393 if "." in text: # a parameter cannot be dotted
384 if "." in text: # a parameter cannot be dotted
394 return []
385 return []
395 try: regexp = self.__funcParamsRegex
386 try: regexp = self.__funcParamsRegex
396 except AttributeError:
387 except AttributeError:
397 regexp = self.__funcParamsRegex = re.compile(r'''
388 regexp = self.__funcParamsRegex = re.compile(r'''
398 '.*?' | # single quoted strings or
389 '.*?' | # single quoted strings or
399 ".*?" | # double quoted strings or
390 ".*?" | # double quoted strings or
400 \w+ | # identifier
391 \w+ | # identifier
401 \S # other characters
392 \S # other characters
402 ''', re.VERBOSE | re.DOTALL)
393 ''', re.VERBOSE | re.DOTALL)
403 # 1. find the nearest identifier that comes before an unclosed
394 # 1. find the nearest identifier that comes before an unclosed
404 # parenthesis e.g. for "foo (1+bar(x), pa", the candidate is "foo"
395 # parenthesis e.g. for "foo (1+bar(x), pa", the candidate is "foo"
405 tokens = regexp.findall(self.get_line_buffer())
396 tokens = regexp.findall(self.get_line_buffer())
406 tokens.reverse()
397 tokens.reverse()
407 iterTokens = iter(tokens); openPar = 0
398 iterTokens = iter(tokens); openPar = 0
408 for token in iterTokens:
399 for token in iterTokens:
409 if token == ')':
400 if token == ')':
410 openPar -= 1
401 openPar -= 1
411 elif token == '(':
402 elif token == '(':
412 openPar += 1
403 openPar += 1
413 if openPar > 0:
404 if openPar > 0:
414 # found the last unclosed parenthesis
405 # found the last unclosed parenthesis
415 break
406 break
416 else:
407 else:
417 return []
408 return []
418 # 2. Concatenate any dotted names (e.g. "foo.bar" for "foo.bar(x, pa" )
409 # 2. Concatenate any dotted names (e.g. "foo.bar" for "foo.bar(x, pa" )
419 ids = []
410 ids = []
420 isId = re.compile(r'\w+$').match
411 isId = re.compile(r'\w+$').match
421 while True:
412 while True:
422 try:
413 try:
423 ids.append(iterTokens.next())
414 ids.append(iterTokens.next())
424 if not isId(ids[-1]):
415 if not isId(ids[-1]):
425 ids.pop(); break
416 ids.pop(); break
426 if not iterTokens.next() == '.':
417 if not iterTokens.next() == '.':
427 break
418 break
428 except StopIteration:
419 except StopIteration:
429 break
420 break
430 # lookup the candidate callable matches either using global_matches
421 # lookup the candidate callable matches either using global_matches
431 # or attr_matches for dotted names
422 # or attr_matches for dotted names
432 if len(ids) == 1:
423 if len(ids) == 1:
433 callableMatches = self.global_matches(ids[0])
424 callableMatches = self.global_matches(ids[0])
434 else:
425 else:
435 callableMatches = self.attr_matches('.'.join(ids[::-1]))
426 callableMatches = self.attr_matches('.'.join(ids[::-1]))
436 argMatches = []
427 argMatches = []
437 for callableMatch in callableMatches:
428 for callableMatch in callableMatches:
438 try: namedArgs = self._default_arguments(eval(callableMatch,
429 try: namedArgs = self._default_arguments(eval(callableMatch,
439 self.namespace))
430 self.namespace))
440 except: continue
431 except: continue
441 for namedArg in namedArgs:
432 for namedArg in namedArgs:
442 if namedArg.startswith(text):
433 if namedArg.startswith(text):
443 argMatches.append("%s=" %namedArg)
434 argMatches.append("%s=" %namedArg)
444 return argMatches
435 return argMatches
445
436
446 def complete(self, text, state):
437 def complete(self, text, state):
447 """Return the next possible completion for 'text'.
438 """Return the next possible completion for 'text'.
448
439
449 This is called successively with state == 0, 1, 2, ... until it
440 This is called successively with state == 0, 1, 2, ... until it
450 returns None. The completion should begin with 'text'. """
441 returns None. The completion should begin with 'text'. """
451
442
452 #print '\n*** COMPLETE: <%s> (%s)' % (text,state) # dbg
443 #print '\n*** COMPLETE: <%s> (%s)' % (text,state) # dbg
453 magic_escape = self.magic_escape
444 magic_escape = self.magic_escape
454 magic_prefix = self.magic_prefix
445 magic_prefix = self.magic_prefix
455
446
456 try:
447 try:
457 if text.startswith(magic_escape):
448 if text.startswith(magic_escape):
458 text = text.replace(magic_escape,magic_prefix)
449 text = text.replace(magic_escape,magic_prefix)
459 elif text.startswith('~'):
450 elif text.startswith('~'):
460 text = os.path.expanduser(text)
451 text = os.path.expanduser(text)
461 if state == 0:
452 if state == 0:
462 # Extend the list of completions with the results of each
453 # Extend the list of completions with the results of each
463 # matcher, so we return results to the user from all
454 # matcher, so we return results to the user from all
464 # namespaces.
455 # namespaces.
465 if self.merge_completions:
456 if self.merge_completions:
466 self.matches = []
457 self.matches = []
467 for matcher in self.matchers:
458 for matcher in self.matchers:
468 self.matches.extend(matcher(text))
459 self.matches.extend(matcher(text))
469 else:
460 else:
470 for matcher in self.matchers:
461 for matcher in self.matchers:
471 self.matches = matcher(text)
462 self.matches = matcher(text)
472 if self.matches:
463 if self.matches:
473 break
464 break
474
465
475 try:
466 try:
476 return self.matches[state].replace(magic_prefix,magic_escape)
467 return self.matches[state].replace(magic_prefix,magic_escape)
477 except IndexError:
468 except IndexError:
478 return None
469 return None
479 except:
470 except:
480 # If completion fails, don't annoy the user.
471 # If completion fails, don't annoy the user.
481 pass
472 pass
482
473
483 except ImportError:
474 except ImportError:
484 pass # no readline support
475 pass # no readline support
485
476
486 except KeyError:
477 except KeyError:
487 pass # Windows doesn't set TERM, it doesn't matter
478 pass # Windows doesn't set TERM, it doesn't matter
488
479
489
480
490 class InputList(UserList.UserList):
481 class InputList(UserList.UserList):
491 """Class to store user input.
482 """Class to store user input.
492
483
493 It's basically a list, but slices return a string instead of a list, thus
484 It's basically a list, but slices return a string instead of a list, thus
494 allowing things like (assuming 'In' is an instance):
485 allowing things like (assuming 'In' is an instance):
495
486
496 exec In[4:7]
487 exec In[4:7]
497
488
498 or
489 or
499
490
500 exec In[5:9] + In[14] + In[21:25]"""
491 exec In[5:9] + In[14] + In[21:25]"""
501
492
502 def __getslice__(self,i,j):
493 def __getslice__(self,i,j):
503 return ''.join(UserList.UserList.__getslice__(self,i,j))
494 return ''.join(UserList.UserList.__getslice__(self,i,j))
504
495
505 #****************************************************************************
496 #****************************************************************************
506 # Local use exceptions
497 # Local use exceptions
507 class SpaceInInput(exceptions.Exception):
498 class SpaceInInput(exceptions.Exception):
508 pass
499 pass
509
500
510 #****************************************************************************
501 #****************************************************************************
511 # Main IPython class
502 # Main IPython class
512
503
513 class InteractiveShell(code.InteractiveConsole, Logger, Magic):
504 class InteractiveShell(code.InteractiveConsole, Logger, Magic):
514 """An enhanced console for Python."""
505 """An enhanced console for Python."""
515
506
516 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
507 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
517 user_ns = None,banner2='',
508 user_ns = None,banner2='',
518 custom_exceptions=((),None)):
509 custom_exceptions=((),None)):
519
510
520 # Put a reference to self in builtins so that any form of embedded or
511 # Put a reference to self in builtins so that any form of embedded or
521 # imported code can test for being inside IPython.
512 # imported code can test for being inside IPython.
522 __builtin__.__IPYTHON__ = self
513 __builtin__.__IPYTHON__ = self
523
514
524 # And load into builtins ipmagic/ipalias as well
515 # And load into builtins ipmagic/ipalias as well
525 __builtin__.ipmagic = ipmagic
516 __builtin__.ipmagic = ipmagic
526 __builtin__.ipalias = ipalias
517 __builtin__.ipalias = ipalias
527
518
528 # Add to __builtin__ other parts of IPython's public API
519 # Add to __builtin__ other parts of IPython's public API
529 __builtin__.ip_set_hook = self.set_hook
520 __builtin__.ip_set_hook = self.set_hook
530
521
531 # Keep in the builtins a flag for when IPython is active. We set it
522 # Keep in the builtins a flag for when IPython is active. We set it
532 # with setdefault so that multiple nested IPythons don't clobber one
523 # with setdefault so that multiple nested IPythons don't clobber one
533 # another. Each will increase its value by one upon being activated,
524 # another. Each will increase its value by one upon being activated,
534 # which also gives us a way to determine the nesting level.
525 # which also gives us a way to determine the nesting level.
535 __builtin__.__dict__.setdefault('__IPYTHON__active',0)
526 __builtin__.__dict__.setdefault('__IPYTHON__active',0)
536
527
537 # Inform the user of ipython's fast exit magics.
528 # Inform the user of ipython's fast exit magics.
538 _exit = ' Use %Exit or %Quit to exit without confirmation.'
529 _exit = ' Use %Exit or %Quit to exit without confirmation.'
539 __builtin__.exit += _exit
530 __builtin__.exit += _exit
540 __builtin__.quit += _exit
531 __builtin__.quit += _exit
541
532
542 # Create the namespace where the user will operate:
533 # Create the namespace where the user will operate:
543
534
544 # FIXME. For some strange reason, __builtins__ is showing up at user
535 # FIXME. For some strange reason, __builtins__ is showing up at user
545 # level as a dict instead of a module. This is a manual fix, but I
536 # level as a dict instead of a module. This is a manual fix, but I
546 # should really track down where the problem is coming from. Alex
537 # should really track down where the problem is coming from. Alex
547 # Schmolck reported this problem first.
538 # Schmolck reported this problem first.
548
539
549 # A useful post by Alex Martelli on this topic:
540 # A useful post by Alex Martelli on this topic:
550 # Re: inconsistent value from __builtins__
541 # Re: inconsistent value from __builtins__
551 # Von: Alex Martelli <aleaxit@yahoo.com>
542 # Von: Alex Martelli <aleaxit@yahoo.com>
552 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
543 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
553 # Gruppen: comp.lang.python
544 # Gruppen: comp.lang.python
554 # Referenzen: 1
545 # Referenzen: 1
555
546
556 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
547 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
557 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
548 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
558 # > <type 'dict'>
549 # > <type 'dict'>
559 # > >>> print type(__builtins__)
550 # > >>> print type(__builtins__)
560 # > <type 'module'>
551 # > <type 'module'>
561 # > Is this difference in return value intentional?
552 # > Is this difference in return value intentional?
562
553
563 # Well, it's documented that '__builtins__' can be either a dictionary
554 # Well, it's documented that '__builtins__' can be either a dictionary
564 # or a module, and it's been that way for a long time. Whether it's
555 # or a module, and it's been that way for a long time. Whether it's
565 # intentional (or sensible), I don't know. In any case, the idea is that
556 # intentional (or sensible), I don't know. In any case, the idea is that
566 # if you need to access the built-in namespace directly, you should start
557 # if you need to access the built-in namespace directly, you should start
567 # with "import __builtin__" (note, no 's') which will definitely give you
558 # with "import __builtin__" (note, no 's') which will definitely give you
568 # a module. Yeah, it's somewhat confusing:-(.
559 # a module. Yeah, it's somewhat confusing:-(.
569
560
570 if user_ns is None:
561 if user_ns is None:
571 # Set __name__ to __main__ to better match the behavior of the
562 # Set __name__ to __main__ to better match the behavior of the
572 # normal interpreter.
563 # normal interpreter.
573 self.user_ns = {'__name__' :'__main__',
564 self.user_ns = {'__name__' :'__main__',
574 '__builtins__' : __builtin__,
565 '__builtins__' : __builtin__,
575 }
566 }
576 else:
567 else:
577 self.user_ns = user_ns
568 self.user_ns = user_ns
578
569
579 # The user namespace MUST have a pointer to the shell itself.
570 # The user namespace MUST have a pointer to the shell itself.
580 self.user_ns[name] = self
571 self.user_ns[name] = self
581
572
582 # We need to insert into sys.modules something that looks like a
573 # We need to insert into sys.modules something that looks like a
583 # module but which accesses the IPython namespace, for shelve and
574 # module but which accesses the IPython namespace, for shelve and
584 # pickle to work interactively. Normally they rely on getting
575 # pickle to work interactively. Normally they rely on getting
585 # everything out of __main__, but for embedding purposes each IPython
576 # everything out of __main__, but for embedding purposes each IPython
586 # instance has its own private namespace, so we can't go shoving
577 # instance has its own private namespace, so we can't go shoving
587 # everything into __main__.
578 # everything into __main__.
588
579
589 try:
580 try:
590 main_name = self.user_ns['__name__']
581 main_name = self.user_ns['__name__']
591 except KeyError:
582 except KeyError:
592 raise KeyError,'user_ns dictionary MUST have a "__name__" key'
583 raise KeyError,'user_ns dictionary MUST have a "__name__" key'
593 else:
584 else:
594 #print "pickle hack in place" # dbg
585 #print "pickle hack in place" # dbg
595 sys.modules[main_name] = FakeModule(self.user_ns)
586 sys.modules[main_name] = FakeModule(self.user_ns)
596
587
597 # List of input with multi-line handling.
588 # List of input with multi-line handling.
598 # Fill its zero entry, user counter starts at 1
589 # Fill its zero entry, user counter starts at 1
599 self.input_hist = InputList(['\n'])
590 self.input_hist = InputList(['\n'])
600
591
601 # list of visited directories
592 # list of visited directories
602 self.dir_hist = [os.getcwd()]
593 self.dir_hist = [os.getcwd()]
603
594
604 # dict of output history
595 # dict of output history
605 self.output_hist = {}
596 self.output_hist = {}
606
597
607 # dict of names to be treated as system aliases. Each entry in the
598 # dict of names to be treated as system aliases. Each entry in the
608 # alias table must be a 2-tuple of the form (N,name), where N is the
599 # alias table must be a 2-tuple of the form (N,name), where N is the
609 # number of positional arguments of the alias.
600 # number of positional arguments of the alias.
610 self.alias_table = {}
601 self.alias_table = {}
611
602
612 # dict of things NOT to alias (keywords and builtins)
603 # dict of things NOT to alias (keywords and builtins)
613 self.no_alias = {}
604 self.no_alias = {}
614 for key in keyword.kwlist:
605 for key in keyword.kwlist:
615 self.no_alias[key] = 1
606 self.no_alias[key] = 1
616 self.no_alias.update(__builtin__.__dict__)
607 self.no_alias.update(__builtin__.__dict__)
617
608
618 # make global variables for user access to these
609 # make global variables for user access to these
619 self.user_ns['_ih'] = self.input_hist
610 self.user_ns['_ih'] = self.input_hist
620 self.user_ns['_oh'] = self.output_hist
611 self.user_ns['_oh'] = self.output_hist
621 self.user_ns['_dh'] = self.dir_hist
612 self.user_ns['_dh'] = self.dir_hist
622
613
623 # user aliases to input and output histories
614 # user aliases to input and output histories
624 self.user_ns['In'] = self.input_hist
615 self.user_ns['In'] = self.input_hist
625 self.user_ns['Out'] = self.output_hist
616 self.user_ns['Out'] = self.output_hist
626
617
627 # Store the actual shell's name
618 # Store the actual shell's name
628 self.name = name
619 self.name = name
629
620
630 # Object variable to store code object waiting execution. This is
621 # Object variable to store code object waiting execution. This is
631 # used mainly by the multithreaded shells, but it can come in handy in
622 # used mainly by the multithreaded shells, but it can come in handy in
632 # other situations. No need to use a Queue here, since it's a single
623 # other situations. No need to use a Queue here, since it's a single
633 # item which gets cleared once run.
624 # item which gets cleared once run.
634 self.code_to_run = None
625 self.code_to_run = None
635 self.code_to_run_src = '' # corresponding source
626 self.code_to_run_src = '' # corresponding source
636
627
637 # Job manager (for jobs run as background threads)
628 # Job manager (for jobs run as background threads)
638 self.jobs = BackgroundJobManager()
629 self.jobs = BackgroundJobManager()
639 # Put the job manager into builtins so it's always there.
630 # Put the job manager into builtins so it's always there.
640 __builtin__.jobs = self.jobs
631 __builtin__.jobs = self.jobs
641
632
642 # escapes for automatic behavior on the command line
633 # escapes for automatic behavior on the command line
643 self.ESC_SHELL = '!'
634 self.ESC_SHELL = '!'
644 self.ESC_HELP = '?'
635 self.ESC_HELP = '?'
645 self.ESC_MAGIC = '%'
636 self.ESC_MAGIC = '%'
646 self.ESC_QUOTE = ','
637 self.ESC_QUOTE = ','
647 self.ESC_QUOTE2 = ';'
638 self.ESC_QUOTE2 = ';'
648 self.ESC_PAREN = '/'
639 self.ESC_PAREN = '/'
649
640
650 # And their associated handlers
641 # And their associated handlers
651 self.esc_handlers = {self.ESC_PAREN:self.handle_auto,
642 self.esc_handlers = {self.ESC_PAREN:self.handle_auto,
652 self.ESC_QUOTE:self.handle_auto,
643 self.ESC_QUOTE:self.handle_auto,
653 self.ESC_QUOTE2:self.handle_auto,
644 self.ESC_QUOTE2:self.handle_auto,
654 self.ESC_MAGIC:self.handle_magic,
645 self.ESC_MAGIC:self.handle_magic,
655 self.ESC_HELP:self.handle_help,
646 self.ESC_HELP:self.handle_help,
656 self.ESC_SHELL:self.handle_shell_escape,
647 self.ESC_SHELL:self.handle_shell_escape,
657 }
648 }
658
649
659 # class initializations
650 # class initializations
660 code.InteractiveConsole.__init__(self,locals = self.user_ns)
651 code.InteractiveConsole.__init__(self,locals = self.user_ns)
661 Logger.__init__(self,log_ns = self.user_ns)
652 Logger.__init__(self,log_ns = self.user_ns)
662 Magic.__init__(self,self)
653 Magic.__init__(self,self)
663
654
664 # an ugly hack to get a pointer to the shell, so I can start writing
655 # an ugly hack to get a pointer to the shell, so I can start writing
665 # magic code via this pointer instead of the current mixin salad.
656 # magic code via this pointer instead of the current mixin salad.
666 Magic.set_shell(self,self)
657 Magic.set_shell(self,self)
667
658
668 # hooks holds pointers used for user-side customizations
659 # hooks holds pointers used for user-side customizations
669 self.hooks = Struct()
660 self.hooks = Struct()
670
661
671 # Set all default hooks, defined in the IPython.hooks module.
662 # Set all default hooks, defined in the IPython.hooks module.
672 hooks = IPython.hooks
663 hooks = IPython.hooks
673 for hook_name in hooks.__all__:
664 for hook_name in hooks.__all__:
674 self.set_hook(hook_name,getattr(hooks,hook_name))
665 self.set_hook(hook_name,getattr(hooks,hook_name))
675
666
676 # Flag to mark unconditional exit
667 # Flag to mark unconditional exit
677 self.exit_now = False
668 self.exit_now = False
678
669
679 self.usage_min = """\
670 self.usage_min = """\
680 An enhanced console for Python.
671 An enhanced console for Python.
681 Some of its features are:
672 Some of its features are:
682 - Readline support if the readline library is present.
673 - Readline support if the readline library is present.
683 - Tab completion in the local namespace.
674 - Tab completion in the local namespace.
684 - Logging of input, see command-line options.
675 - Logging of input, see command-line options.
685 - System shell escape via ! , eg !ls.
676 - System shell escape via ! , eg !ls.
686 - Magic commands, starting with a % (like %ls, %pwd, %cd, etc.)
677 - Magic commands, starting with a % (like %ls, %pwd, %cd, etc.)
687 - Keeps track of locally defined variables via %who, %whos.
678 - Keeps track of locally defined variables via %who, %whos.
688 - Show object information with a ? eg ?x or x? (use ?? for more info).
679 - Show object information with a ? eg ?x or x? (use ?? for more info).
689 """
680 """
690 if usage: self.usage = usage
681 if usage: self.usage = usage
691 else: self.usage = self.usage_min
682 else: self.usage = self.usage_min
692
683
693 # Storage
684 # Storage
694 self.rc = rc # This will hold all configuration information
685 self.rc = rc # This will hold all configuration information
695 self.inputcache = []
686 self.inputcache = []
696 self._boundcache = []
687 self._boundcache = []
697 self.pager = 'less'
688 self.pager = 'less'
698 # temporary files used for various purposes. Deleted at exit.
689 # temporary files used for various purposes. Deleted at exit.
699 self.tempfiles = []
690 self.tempfiles = []
700
691
701 # for pushd/popd management
692 # for pushd/popd management
702 try:
693 try:
703 self.home_dir = get_home_dir()
694 self.home_dir = get_home_dir()
704 except HomeDirError,msg:
695 except HomeDirError,msg:
705 fatal(msg)
696 fatal(msg)
706
697
707 self.dir_stack = [os.getcwd().replace(self.home_dir,'~')]
698 self.dir_stack = [os.getcwd().replace(self.home_dir,'~')]
708
699
709 # Functions to call the underlying shell.
700 # Functions to call the underlying shell.
710
701
711 # utility to expand user variables via Itpl
702 # utility to expand user variables via Itpl
712 self.var_expand = lambda cmd: str(ItplNS(cmd.replace('#','\#'),
703 self.var_expand = lambda cmd: str(ItplNS(cmd.replace('#','\#'),
713 self.user_ns))
704 self.user_ns))
714 # The first is similar to os.system, but it doesn't return a value,
705 # The first is similar to os.system, but it doesn't return a value,
715 # and it allows interpolation of variables in the user's namespace.
706 # and it allows interpolation of variables in the user's namespace.
716 self.system = lambda cmd: shell(self.var_expand(cmd),
707 self.system = lambda cmd: shell(self.var_expand(cmd),
717 header='IPython system call: ',
708 header='IPython system call: ',
718 verbose=self.rc.system_verbose)
709 verbose=self.rc.system_verbose)
719 # These are for getoutput and getoutputerror:
710 # These are for getoutput and getoutputerror:
720 self.getoutput = lambda cmd: \
711 self.getoutput = lambda cmd: \
721 getoutput(self.var_expand(cmd),
712 getoutput(self.var_expand(cmd),
722 header='IPython system call: ',
713 header='IPython system call: ',
723 verbose=self.rc.system_verbose)
714 verbose=self.rc.system_verbose)
724 self.getoutputerror = lambda cmd: \
715 self.getoutputerror = lambda cmd: \
725 getoutputerror(str(ItplNS(cmd.replace('#','\#'),
716 getoutputerror(str(ItplNS(cmd.replace('#','\#'),
726 self.user_ns)),
717 self.user_ns)),
727 header='IPython system call: ',
718 header='IPython system call: ',
728 verbose=self.rc.system_verbose)
719 verbose=self.rc.system_verbose)
729
720
730 # RegExp for splitting line contents into pre-char//first
721 # RegExp for splitting line contents into pre-char//first
731 # word-method//rest. For clarity, each group in on one line.
722 # word-method//rest. For clarity, each group in on one line.
732
723
733 # WARNING: update the regexp if the above escapes are changed, as they
724 # WARNING: update the regexp if the above escapes are changed, as they
734 # are hardwired in.
725 # are hardwired in.
735
726
736 # Don't get carried away with trying to make the autocalling catch too
727 # Don't get carried away with trying to make the autocalling catch too
737 # much: it's better to be conservative rather than to trigger hidden
728 # much: it's better to be conservative rather than to trigger hidden
738 # evals() somewhere and end up causing side effects.
729 # evals() somewhere and end up causing side effects.
739
730
740 self.line_split = re.compile(r'^([\s*,;/])'
731 self.line_split = re.compile(r'^([\s*,;/])'
741 r'([\?\w\.]+\w*\s*)'
732 r'([\?\w\.]+\w*\s*)'
742 r'(\(?.*$)')
733 r'(\(?.*$)')
743
734
744 # Original re, keep around for a while in case changes break something
735 # Original re, keep around for a while in case changes break something
745 #self.line_split = re.compile(r'(^[\s*!\?%,/]?)'
736 #self.line_split = re.compile(r'(^[\s*!\?%,/]?)'
746 # r'(\s*[\?\w\.]+\w*\s*)'
737 # r'(\s*[\?\w\.]+\w*\s*)'
747 # r'(\(?.*$)')
738 # r'(\(?.*$)')
748
739
749 # RegExp to identify potential function names
740 # RegExp to identify potential function names
750 self.re_fun_name = re.compile(r'[a-zA-Z_]([a-zA-Z0-9_.]*) *$')
741 self.re_fun_name = re.compile(r'[a-zA-Z_]([a-zA-Z0-9_.]*) *$')
751 # RegExp to exclude strings with this start from autocalling
742 # RegExp to exclude strings with this start from autocalling
752 self.re_exclude_auto = re.compile('^[!=()<>,\*/\+-]|^is ')
743 self.re_exclude_auto = re.compile('^[!=()<>,\*/\+-]|^is ')
753 # try to catch also methods for stuff in lists/tuples/dicts: off
744 # try to catch also methods for stuff in lists/tuples/dicts: off
754 # (experimental). For this to work, the line_split regexp would need
745 # (experimental). For this to work, the line_split regexp would need
755 # to be modified so it wouldn't break things at '['. That line is
746 # to be modified so it wouldn't break things at '['. That line is
756 # nasty enough that I shouldn't change it until I can test it _well_.
747 # nasty enough that I shouldn't change it until I can test it _well_.
757 #self.re_fun_name = re.compile (r'[a-zA-Z_]([a-zA-Z0-9_.\[\]]*) ?$')
748 #self.re_fun_name = re.compile (r'[a-zA-Z_]([a-zA-Z0-9_.\[\]]*) ?$')
758
749
759 # keep track of where we started running (mainly for crash post-mortem)
750 # keep track of where we started running (mainly for crash post-mortem)
760 self.starting_dir = os.getcwd()
751 self.starting_dir = os.getcwd()
761
752
762 # Attributes for Logger mixin class, make defaults here
753 # Attributes for Logger mixin class, make defaults here
763 self._dolog = 0
754 self._dolog = 0
764 self.LOG = ''
755 self.LOG = ''
765 self.LOGDEF = '.InteractiveShell.log'
756 self.LOGDEF = '.InteractiveShell.log'
766 self.LOGMODE = 'over'
757 self.LOGMODE = 'over'
767 self.LOGHEAD = Itpl(
758 self.LOGHEAD = Itpl(
768 """#log# Automatic Logger file. *** THIS MUST BE THE FIRST LINE ***
759 """#log# Automatic Logger file. *** THIS MUST BE THE FIRST LINE ***
769 #log# DO NOT CHANGE THIS LINE OR THE TWO BELOW
760 #log# DO NOT CHANGE THIS LINE OR THE TWO BELOW
770 #log# opts = $self.rc.opts
761 #log# opts = $self.rc.opts
771 #log# args = $self.rc.args
762 #log# args = $self.rc.args
772 #log# It is safe to make manual edits below here.
763 #log# It is safe to make manual edits below here.
773 #log#-----------------------------------------------------------------------
764 #log#-----------------------------------------------------------------------
774 """)
765 """)
775 # Various switches which can be set
766 # Various switches which can be set
776 self.CACHELENGTH = 5000 # this is cheap, it's just text
767 self.CACHELENGTH = 5000 # this is cheap, it's just text
777 self.BANNER = "Python %(version)s on %(platform)s\n" % sys.__dict__
768 self.BANNER = "Python %(version)s on %(platform)s\n" % sys.__dict__
778 self.banner2 = banner2
769 self.banner2 = banner2
779
770
780 # TraceBack handlers:
771 # TraceBack handlers:
781 # Need two, one for syntax errors and one for other exceptions.
772 # Need two, one for syntax errors and one for other exceptions.
782 self.SyntaxTB = ultraTB.ListTB(color_scheme='NoColor')
773 self.SyntaxTB = ultraTB.ListTB(color_scheme='NoColor')
783 # This one is initialized with an offset, meaning we always want to
774 # This one is initialized with an offset, meaning we always want to
784 # remove the topmost item in the traceback, which is our own internal
775 # remove the topmost item in the traceback, which is our own internal
785 # code. Valid modes: ['Plain','Context','Verbose']
776 # code. Valid modes: ['Plain','Context','Verbose']
786 self.InteractiveTB = ultraTB.AutoFormattedTB(mode = 'Plain',
777 self.InteractiveTB = ultraTB.AutoFormattedTB(mode = 'Plain',
787 color_scheme='NoColor',
778 color_scheme='NoColor',
788 tb_offset = 1)
779 tb_offset = 1)
789 # and add any custom exception handlers the user may have specified
780 # and add any custom exception handlers the user may have specified
790 self.set_custom_exc(*custom_exceptions)
781 self.set_custom_exc(*custom_exceptions)
791
782
792 # Object inspector
783 # Object inspector
793 ins_colors = OInspect.InspectColors
784 ins_colors = OInspect.InspectColors
794 code_colors = PyColorize.ANSICodeColors
785 code_colors = PyColorize.ANSICodeColors
795 self.inspector = OInspect.Inspector(ins_colors,code_colors,'NoColor')
786 self.inspector = OInspect.Inspector(ins_colors,code_colors,'NoColor')
796 self.autoindent = 0
787 self.autoindent = 0
797
788
798 # Make some aliases automatically
789 # Make some aliases automatically
799 # Prepare list of shell aliases to auto-define
790 # Prepare list of shell aliases to auto-define
800 if os.name == 'posix':
791 if os.name == 'posix':
801 auto_alias = ('mkdir mkdir', 'rmdir rmdir',
792 auto_alias = ('mkdir mkdir', 'rmdir rmdir',
802 'mv mv -i','rm rm -i','cp cp -i',
793 'mv mv -i','rm rm -i','cp cp -i',
803 'cat cat','less less','clear clear',
794 'cat cat','less less','clear clear',
804 # a better ls
795 # a better ls
805 'ls ls -F',
796 'ls ls -F',
806 # long ls
797 # long ls
807 'll ls -lF',
798 'll ls -lF',
808 # color ls
799 # color ls
809 'lc ls -F -o --color',
800 'lc ls -F -o --color',
810 # ls normal files only
801 # ls normal files only
811 'lf ls -F -o --color %l | grep ^-',
802 'lf ls -F -o --color %l | grep ^-',
812 # ls symbolic links
803 # ls symbolic links
813 'lk ls -F -o --color %l | grep ^l',
804 'lk ls -F -o --color %l | grep ^l',
814 # directories or links to directories,
805 # directories or links to directories,
815 'ldir ls -F -o --color %l | grep /$',
806 'ldir ls -F -o --color %l | grep /$',
816 # things which are executable
807 # things which are executable
817 'lx ls -F -o --color %l | grep ^-..x',
808 'lx ls -F -o --color %l | grep ^-..x',
818 )
809 )
819 elif os.name in ['nt','dos']:
810 elif os.name in ['nt','dos']:
820 auto_alias = ('dir dir /on', 'ls dir /on',
811 auto_alias = ('dir dir /on', 'ls dir /on',
821 'ddir dir /ad /on', 'ldir dir /ad /on',
812 'ddir dir /ad /on', 'ldir dir /ad /on',
822 'mkdir mkdir','rmdir rmdir','echo echo',
813 'mkdir mkdir','rmdir rmdir','echo echo',
823 'ren ren','cls cls','copy copy')
814 'ren ren','cls cls','copy copy')
824 else:
815 else:
825 auto_alias = ()
816 auto_alias = ()
826 self.auto_alias = map(lambda s:s.split(None,1),auto_alias)
817 self.auto_alias = map(lambda s:s.split(None,1),auto_alias)
827 # Call the actual (public) initializer
818 # Call the actual (public) initializer
828 self.init_auto_alias()
819 self.init_auto_alias()
829 # end __init__
820 # end __init__
830
821
831 def set_hook(self,name,hook):
822 def set_hook(self,name,hook):
832 """set_hook(name,hook) -> sets an internal IPython hook.
823 """set_hook(name,hook) -> sets an internal IPython hook.
833
824
834 IPython exposes some of its internal API as user-modifiable hooks. By
825 IPython exposes some of its internal API as user-modifiable hooks. By
835 resetting one of these hooks, you can modify IPython's behavior to
826 resetting one of these hooks, you can modify IPython's behavior to
836 call at runtime your own routines."""
827 call at runtime your own routines."""
837
828
838 # At some point in the future, this should validate the hook before it
829 # At some point in the future, this should validate the hook before it
839 # accepts it. Probably at least check that the hook takes the number
830 # accepts it. Probably at least check that the hook takes the number
840 # of args it's supposed to.
831 # of args it's supposed to.
841 setattr(self.hooks,name,new.instancemethod(hook,self,self.__class__))
832 setattr(self.hooks,name,new.instancemethod(hook,self,self.__class__))
842
833
843 def set_custom_exc(self,exc_tuple,handler):
834 def set_custom_exc(self,exc_tuple,handler):
844 """set_custom_exc(exc_tuple,handler)
835 """set_custom_exc(exc_tuple,handler)
845
836
846 Set a custom exception handler, which will be called if any of the
837 Set a custom exception handler, which will be called if any of the
847 exceptions in exc_tuple occur in the mainloop (specifically, in the
838 exceptions in exc_tuple occur in the mainloop (specifically, in the
848 runcode() method.
839 runcode() method.
849
840
850 Inputs:
841 Inputs:
851
842
852 - exc_tuple: a *tuple* of valid exceptions to call the defined
843 - exc_tuple: a *tuple* of valid exceptions to call the defined
853 handler for. It is very important that you use a tuple, and NOT A
844 handler for. It is very important that you use a tuple, and NOT A
854 LIST here, because of the way Python's except statement works. If
845 LIST here, because of the way Python's except statement works. If
855 you only want to trap a single exception, use a singleton tuple:
846 you only want to trap a single exception, use a singleton tuple:
856
847
857 exc_tuple == (MyCustomException,)
848 exc_tuple == (MyCustomException,)
858
849
859 - handler: this must be defined as a function with the following
850 - handler: this must be defined as a function with the following
860 basic interface: def my_handler(self,etype,value,tb).
851 basic interface: def my_handler(self,etype,value,tb).
861
852
862 This will be made into an instance method (via new.instancemethod)
853 This will be made into an instance method (via new.instancemethod)
863 of IPython itself, and it will be called if any of the exceptions
854 of IPython itself, and it will be called if any of the exceptions
864 listed in the exc_tuple are caught. If the handler is None, an
855 listed in the exc_tuple are caught. If the handler is None, an
865 internal basic one is used, which just prints basic info.
856 internal basic one is used, which just prints basic info.
866
857
867 WARNING: by putting in your own exception handler into IPython's main
858 WARNING: by putting in your own exception handler into IPython's main
868 execution loop, you run a very good chance of nasty crashes. This
859 execution loop, you run a very good chance of nasty crashes. This
869 facility should only be used if you really know what you are doing."""
860 facility should only be used if you really know what you are doing."""
870
861
871 assert type(exc_tuple)==type(()) , \
862 assert type(exc_tuple)==type(()) , \
872 "The custom exceptions must be given AS A TUPLE."
863 "The custom exceptions must be given AS A TUPLE."
873
864
874 def dummy_handler(self,etype,value,tb):
865 def dummy_handler(self,etype,value,tb):
875 print '*** Simple custom exception handler ***'
866 print '*** Simple custom exception handler ***'
876 print 'Exception type :',etype
867 print 'Exception type :',etype
877 print 'Exception value:',value
868 print 'Exception value:',value
878 print 'Traceback :',tb
869 print 'Traceback :',tb
879 print 'Source code :',self.code_to_run_src
870 print 'Source code :',self.code_to_run_src
880
871
881 if handler is None: handler = dummy_handler
872 if handler is None: handler = dummy_handler
882
873
883 self.CustomTB = new.instancemethod(handler,self,self.__class__)
874 self.CustomTB = new.instancemethod(handler,self,self.__class__)
884 self.custom_exceptions = exc_tuple
875 self.custom_exceptions = exc_tuple
885
876
886 def set_custom_completer(self,completer,pos=0):
877 def set_custom_completer(self,completer,pos=0):
887 """set_custom_completer(completer,pos=0)
878 """set_custom_completer(completer,pos=0)
888
879
889 Adds a new custom completer function.
880 Adds a new custom completer function.
890
881
891 The position argument (defaults to 0) is the index in the completers
882 The position argument (defaults to 0) is the index in the completers
892 list where you want the completer to be inserted."""
883 list where you want the completer to be inserted."""
893
884
894 newcomp = new.instancemethod(completer,self.Completer,
885 newcomp = new.instancemethod(completer,self.Completer,
895 self.Completer.__class__)
886 self.Completer.__class__)
896 self.Completer.matchers.insert(pos,newcomp)
887 self.Completer.matchers.insert(pos,newcomp)
897
888
898 def post_config_initialization(self):
889 def post_config_initialization(self):
899 """Post configuration init method
890 """Post configuration init method
900
891
901 This is called after the configuration files have been processed to
892 This is called after the configuration files have been processed to
902 'finalize' the initialization."""
893 'finalize' the initialization."""
903
894
904 # dynamic data that survives through sessions
895 # dynamic data that survives through sessions
905 # XXX make the filename a config option?
896 # XXX make the filename a config option?
906 persist_base = 'persist'
897 persist_base = 'persist'
907 if self.rc.profile:
898 if self.rc.profile:
908 persist_base += '_%s' % self.rc.profile
899 persist_base += '_%s' % self.rc.profile
909 self.persist_fname = os.path.join(self.rc.ipythondir,persist_base)
900 self.persist_fname = os.path.join(self.rc.ipythondir,persist_base)
910
901
911 try:
902 try:
912 self.persist = pickle.load(file(self.persist_fname))
903 self.persist = pickle.load(file(self.persist_fname))
913 except:
904 except:
914 self.persist = {}
905 self.persist = {}
915
906
916 def init_auto_alias(self):
907 def init_auto_alias(self):
917 """Define some aliases automatically.
908 """Define some aliases automatically.
918
909
919 These are ALL parameter-less aliases"""
910 These are ALL parameter-less aliases"""
920 for alias,cmd in self.auto_alias:
911 for alias,cmd in self.auto_alias:
921 self.alias_table[alias] = (0,cmd)
912 self.alias_table[alias] = (0,cmd)
922
913
923 def alias_table_validate(self,verbose=0):
914 def alias_table_validate(self,verbose=0):
924 """Update information about the alias table.
915 """Update information about the alias table.
925
916
926 In particular, make sure no Python keywords/builtins are in it."""
917 In particular, make sure no Python keywords/builtins are in it."""
927
918
928 no_alias = self.no_alias
919 no_alias = self.no_alias
929 for k in self.alias_table.keys():
920 for k in self.alias_table.keys():
930 if k in no_alias:
921 if k in no_alias:
931 del self.alias_table[k]
922 del self.alias_table[k]
932 if verbose:
923 if verbose:
933 print ("Deleting alias <%s>, it's a Python "
924 print ("Deleting alias <%s>, it's a Python "
934 "keyword or builtin." % k)
925 "keyword or builtin." % k)
935
926
936 def set_autoindent(self,value=None):
927 def set_autoindent(self,value=None):
937 """Set the autoindent flag, checking for readline support.
928 """Set the autoindent flag, checking for readline support.
938
929
939 If called with no arguments, it acts as a toggle."""
930 If called with no arguments, it acts as a toggle."""
940
931
941 if not self.has_readline:
932 if not self.has_readline:
942 if os.name == 'posix':
933 if os.name == 'posix':
943 warn("The auto-indent feature requires the readline library")
934 warn("The auto-indent feature requires the readline library")
944 self.autoindent = 0
935 self.autoindent = 0
945 return
936 return
946 if value is None:
937 if value is None:
947 self.autoindent = not self.autoindent
938 self.autoindent = not self.autoindent
948 else:
939 else:
949 self.autoindent = value
940 self.autoindent = value
950
941
951 def rc_set_toggle(self,rc_field,value=None):
942 def rc_set_toggle(self,rc_field,value=None):
952 """Set or toggle a field in IPython's rc config. structure.
943 """Set or toggle a field in IPython's rc config. structure.
953
944
954 If called with no arguments, it acts as a toggle.
945 If called with no arguments, it acts as a toggle.
955
946
956 If called with a non-existent field, the resulting AttributeError
947 If called with a non-existent field, the resulting AttributeError
957 exception will propagate out."""
948 exception will propagate out."""
958
949
959 rc_val = getattr(self.rc,rc_field)
950 rc_val = getattr(self.rc,rc_field)
960 if value is None:
951 if value is None:
961 value = not rc_val
952 value = not rc_val
962 setattr(self.rc,rc_field,value)
953 setattr(self.rc,rc_field,value)
963
954
964 def user_setup(self,ipythondir,rc_suffix,mode='install'):
955 def user_setup(self,ipythondir,rc_suffix,mode='install'):
965 """Install the user configuration directory.
956 """Install the user configuration directory.
966
957
967 Can be called when running for the first time or to upgrade the user's
958 Can be called when running for the first time or to upgrade the user's
968 .ipython/ directory with the mode parameter. Valid modes are 'install'
959 .ipython/ directory with the mode parameter. Valid modes are 'install'
969 and 'upgrade'."""
960 and 'upgrade'."""
970
961
971 def wait():
962 def wait():
972 try:
963 try:
973 raw_input("Please press <RETURN> to start IPython.")
964 raw_input("Please press <RETURN> to start IPython.")
974 except EOFError:
965 except EOFError:
975 print >> Term.cout
966 print >> Term.cout
976 print '*'*70
967 print '*'*70
977
968
978 cwd = os.getcwd() # remember where we started
969 cwd = os.getcwd() # remember where we started
979 glb = glob.glob
970 glb = glob.glob
980 print '*'*70
971 print '*'*70
981 if mode == 'install':
972 if mode == 'install':
982 print \
973 print \
983 """Welcome to IPython. I will try to create a personal configuration directory
974 """Welcome to IPython. I will try to create a personal configuration directory
984 where you can customize many aspects of IPython's functionality in:\n"""
975 where you can customize many aspects of IPython's functionality in:\n"""
985 else:
976 else:
986 print 'I am going to upgrade your configuration in:'
977 print 'I am going to upgrade your configuration in:'
987
978
988 print ipythondir
979 print ipythondir
989
980
990 rcdirend = os.path.join('IPython','UserConfig')
981 rcdirend = os.path.join('IPython','UserConfig')
991 cfg = lambda d: os.path.join(d,rcdirend)
982 cfg = lambda d: os.path.join(d,rcdirend)
992 try:
983 try:
993 rcdir = filter(os.path.isdir,map(cfg,sys.path))[0]
984 rcdir = filter(os.path.isdir,map(cfg,sys.path))[0]
994 except IOError:
985 except IOError:
995 warning = """
986 warning = """
996 Installation error. IPython's directory was not found.
987 Installation error. IPython's directory was not found.
997
988
998 Check the following:
989 Check the following:
999
990
1000 The ipython/IPython directory should be in a directory belonging to your
991 The ipython/IPython directory should be in a directory belonging to your
1001 PYTHONPATH environment variable (that is, it should be in a directory
992 PYTHONPATH environment variable (that is, it should be in a directory
1002 belonging to sys.path). You can copy it explicitly there or just link to it.
993 belonging to sys.path). You can copy it explicitly there or just link to it.
1003
994
1004 IPython will proceed with builtin defaults.
995 IPython will proceed with builtin defaults.
1005 """
996 """
1006 warn(warning)
997 warn(warning)
1007 wait()
998 wait()
1008 return
999 return
1009
1000
1010 if mode == 'install':
1001 if mode == 'install':
1011 try:
1002 try:
1012 shutil.copytree(rcdir,ipythondir)
1003 shutil.copytree(rcdir,ipythondir)
1013 os.chdir(ipythondir)
1004 os.chdir(ipythondir)
1014 rc_files = glb("ipythonrc*")
1005 rc_files = glb("ipythonrc*")
1015 for rc_file in rc_files:
1006 for rc_file in rc_files:
1016 os.rename(rc_file,rc_file+rc_suffix)
1007 os.rename(rc_file,rc_file+rc_suffix)
1017 except:
1008 except:
1018 warning = """
1009 warning = """
1019
1010
1020 There was a problem with the installation:
1011 There was a problem with the installation:
1021 %s
1012 %s
1022 Try to correct it or contact the developers if you think it's a bug.
1013 Try to correct it or contact the developers if you think it's a bug.
1023 IPython will proceed with builtin defaults.""" % sys.exc_info()[1]
1014 IPython will proceed with builtin defaults.""" % sys.exc_info()[1]
1024 warn(warning)
1015 warn(warning)
1025 wait()
1016 wait()
1026 return
1017 return
1027
1018
1028 elif mode == 'upgrade':
1019 elif mode == 'upgrade':
1029 try:
1020 try:
1030 os.chdir(ipythondir)
1021 os.chdir(ipythondir)
1031 except:
1022 except:
1032 print """
1023 print """
1033 Can not upgrade: changing to directory %s failed. Details:
1024 Can not upgrade: changing to directory %s failed. Details:
1034 %s
1025 %s
1035 """ % (ipythondir,sys.exc_info()[1])
1026 """ % (ipythondir,sys.exc_info()[1])
1036 wait()
1027 wait()
1037 return
1028 return
1038 else:
1029 else:
1039 sources = glb(os.path.join(rcdir,'[A-Za-z]*'))
1030 sources = glb(os.path.join(rcdir,'[A-Za-z]*'))
1040 for new_full_path in sources:
1031 for new_full_path in sources:
1041 new_filename = os.path.basename(new_full_path)
1032 new_filename = os.path.basename(new_full_path)
1042 if new_filename.startswith('ipythonrc'):
1033 if new_filename.startswith('ipythonrc'):
1043 new_filename = new_filename + rc_suffix
1034 new_filename = new_filename + rc_suffix
1044 # The config directory should only contain files, skip any
1035 # The config directory should only contain files, skip any
1045 # directories which may be there (like CVS)
1036 # directories which may be there (like CVS)
1046 if os.path.isdir(new_full_path):
1037 if os.path.isdir(new_full_path):
1047 continue
1038 continue
1048 if os.path.exists(new_filename):
1039 if os.path.exists(new_filename):
1049 old_file = new_filename+'.old'
1040 old_file = new_filename+'.old'
1050 if os.path.exists(old_file):
1041 if os.path.exists(old_file):
1051 os.remove(old_file)
1042 os.remove(old_file)
1052 os.rename(new_filename,old_file)
1043 os.rename(new_filename,old_file)
1053 shutil.copy(new_full_path,new_filename)
1044 shutil.copy(new_full_path,new_filename)
1054 else:
1045 else:
1055 raise ValueError,'unrecognized mode for install:',`mode`
1046 raise ValueError,'unrecognized mode for install:',`mode`
1056
1047
1057 # Fix line-endings to those native to each platform in the config
1048 # Fix line-endings to those native to each platform in the config
1058 # directory.
1049 # directory.
1059 try:
1050 try:
1060 os.chdir(ipythondir)
1051 os.chdir(ipythondir)
1061 except:
1052 except:
1062 print """
1053 print """
1063 Problem: changing to directory %s failed.
1054 Problem: changing to directory %s failed.
1064 Details:
1055 Details:
1065 %s
1056 %s
1066
1057
1067 Some configuration files may have incorrect line endings. This should not
1058 Some configuration files may have incorrect line endings. This should not
1068 cause any problems during execution. """ % (ipythondir,sys.exc_info()[1])
1059 cause any problems during execution. """ % (ipythondir,sys.exc_info()[1])
1069 wait()
1060 wait()
1070 else:
1061 else:
1071 for fname in glb('ipythonrc*'):
1062 for fname in glb('ipythonrc*'):
1072 try:
1063 try:
1073 native_line_ends(fname,backup=0)
1064 native_line_ends(fname,backup=0)
1074 except IOError:
1065 except IOError:
1075 pass
1066 pass
1076
1067
1077 if mode == 'install':
1068 if mode == 'install':
1078 print """
1069 print """
1079 Successful installation!
1070 Successful installation!
1080
1071
1081 Please read the sections 'Initial Configuration' and 'Quick Tips' in the
1072 Please read the sections 'Initial Configuration' and 'Quick Tips' in the
1082 IPython manual (there are both HTML and PDF versions supplied with the
1073 IPython manual (there are both HTML and PDF versions supplied with the
1083 distribution) to make sure that your system environment is properly configured
1074 distribution) to make sure that your system environment is properly configured
1084 to take advantage of IPython's features."""
1075 to take advantage of IPython's features."""
1085 else:
1076 else:
1086 print """
1077 print """
1087 Successful upgrade!
1078 Successful upgrade!
1088
1079
1089 All files in your directory:
1080 All files in your directory:
1090 %(ipythondir)s
1081 %(ipythondir)s
1091 which would have been overwritten by the upgrade were backed up with a .old
1082 which would have been overwritten by the upgrade were backed up with a .old
1092 extension. If you had made particular customizations in those files you may
1083 extension. If you had made particular customizations in those files you may
1093 want to merge them back into the new files.""" % locals()
1084 want to merge them back into the new files.""" % locals()
1094 wait()
1085 wait()
1095 os.chdir(cwd)
1086 os.chdir(cwd)
1096 # end user_setup()
1087 # end user_setup()
1097
1088
1098 def atexit_operations(self):
1089 def atexit_operations(self):
1099 """This will be executed at the time of exit.
1090 """This will be executed at the time of exit.
1100
1091
1101 Saving of persistent data should be performed here. """
1092 Saving of persistent data should be performed here. """
1102
1093
1103 # input history
1094 # input history
1104 self.savehist()
1095 self.savehist()
1105
1096
1106 # Cleanup all tempfiles left around
1097 # Cleanup all tempfiles left around
1107 for tfile in self.tempfiles:
1098 for tfile in self.tempfiles:
1108 try:
1099 try:
1109 os.unlink(tfile)
1100 os.unlink(tfile)
1110 except OSError:
1101 except OSError:
1111 pass
1102 pass
1112
1103
1113 # save the "persistent data" catch-all dictionary
1104 # save the "persistent data" catch-all dictionary
1114 try:
1105 try:
1115 pickle.dump(self.persist, open(self.persist_fname,"w"))
1106 pickle.dump(self.persist, open(self.persist_fname,"w"))
1116 except:
1107 except:
1117 print "*** ERROR *** persistent data saving failed."
1108 print "*** ERROR *** persistent data saving failed."
1118
1109
1119 def savehist(self):
1110 def savehist(self):
1120 """Save input history to a file (via readline library)."""
1111 """Save input history to a file (via readline library)."""
1121 try:
1112 try:
1122 self.readline.write_history_file(self.histfile)
1113 self.readline.write_history_file(self.histfile)
1123 except:
1114 except:
1124 print 'Unable to save IPython command history to file: ' + \
1115 print 'Unable to save IPython command history to file: ' + \
1125 `self.histfile`
1116 `self.histfile`
1126
1117
1127 def pre_readline(self):
1118 def pre_readline(self):
1128 """readline hook to be used at the start of each line.
1119 """readline hook to be used at the start of each line.
1129
1120
1130 Currently it handles auto-indent only."""
1121 Currently it handles auto-indent only."""
1131
1122
1132 self.readline.insert_text(' '* self.readline_indent)
1123 self.readline.insert_text(' '* self.readline_indent)
1133
1124
1134 def init_readline(self):
1125 def init_readline(self):
1135 """Command history completion/saving/reloading."""
1126 """Command history completion/saving/reloading."""
1136 try:
1127 try:
1137 import readline
1128 import readline
1138 self.Completer = MagicCompleter(self,
1129 self.Completer = MagicCompleter(self,
1139 self.user_ns,
1130 self.user_ns,
1140 self.rc.readline_omit__names,
1131 self.rc.readline_omit__names,
1141 self.alias_table)
1132 self.alias_table)
1142 except ImportError,NameError:
1133 except ImportError,NameError:
1143 # If FlexCompleter failed to import, MagicCompleter won't be
1134 # If FlexCompleter failed to import, MagicCompleter won't be
1144 # defined. This can happen because of a problem with readline
1135 # defined. This can happen because of a problem with readline
1145 self.has_readline = 0
1136 self.has_readline = 0
1146 # no point in bugging windows users with this every time:
1137 # no point in bugging windows users with this every time:
1147 if os.name == 'posix':
1138 if os.name == 'posix':
1148 warn('Readline services not available on this platform.')
1139 warn('Readline services not available on this platform.')
1149 else:
1140 else:
1150 import atexit
1141 import atexit
1151
1142
1152 # Platform-specific configuration
1143 # Platform-specific configuration
1153 if os.name == 'nt':
1144 if os.name == 'nt':
1154 # readline under Windows modifies the default exit behavior
1145 # readline under Windows modifies the default exit behavior
1155 # from being Ctrl-Z/Return to the Unix Ctrl-D one.
1146 # from being Ctrl-Z/Return to the Unix Ctrl-D one.
1156 __builtin__.exit = __builtin__.quit = \
1147 __builtin__.exit = __builtin__.quit = \
1157 ('Use Ctrl-D (i.e. EOF) to exit. '
1148 ('Use Ctrl-D (i.e. EOF) to exit. '
1158 'Use %Exit or %Quit to exit without confirmation.')
1149 'Use %Exit or %Quit to exit without confirmation.')
1159 self.readline_startup_hook = readline.set_pre_input_hook
1150 self.readline_startup_hook = readline.set_pre_input_hook
1160 else:
1151 else:
1161 self.readline_startup_hook = readline.set_startup_hook
1152 self.readline_startup_hook = readline.set_startup_hook
1162
1153
1163 # Load user's initrc file (readline config)
1154 # Load user's initrc file (readline config)
1164 inputrc_name = os.environ.get('INPUTRC')
1155 inputrc_name = os.environ.get('INPUTRC')
1165 if inputrc_name is None:
1156 if inputrc_name is None:
1166 home_dir = get_home_dir()
1157 home_dir = get_home_dir()
1167 if home_dir is not None:
1158 if home_dir is not None:
1168 inputrc_name = os.path.join(home_dir,'.inputrc')
1159 inputrc_name = os.path.join(home_dir,'.inputrc')
1169 if os.path.isfile(inputrc_name):
1160 if os.path.isfile(inputrc_name):
1170 try:
1161 try:
1171 readline.read_init_file(inputrc_name)
1162 readline.read_init_file(inputrc_name)
1172 except:
1163 except:
1173 warn('Problems reading readline initialization file <%s>'
1164 warn('Problems reading readline initialization file <%s>'
1174 % inputrc_name)
1165 % inputrc_name)
1175
1166
1176 self.has_readline = 1
1167 self.has_readline = 1
1177 self.readline = readline
1168 self.readline = readline
1178 self.readline_indent = 0 # for auto-indenting via readline
1169 self.readline_indent = 0 # for auto-indenting via readline
1179 # save this in sys so embedded copies can restore it properly
1170 # save this in sys so embedded copies can restore it properly
1180 sys.ipcompleter = self.Completer.complete
1171 sys.ipcompleter = self.Completer.complete
1181 readline.set_completer(self.Completer.complete)
1172 readline.set_completer(self.Completer.complete)
1182
1173
1183 # Configure readline according to user's prefs
1174 # Configure readline according to user's prefs
1184 for rlcommand in self.rc.readline_parse_and_bind:
1175 for rlcommand in self.rc.readline_parse_and_bind:
1185 readline.parse_and_bind(rlcommand)
1176 readline.parse_and_bind(rlcommand)
1186
1177
1187 # remove some chars from the delimiters list
1178 # remove some chars from the delimiters list
1188 delims = readline.get_completer_delims()
1179 delims = readline.get_completer_delims()
1189 delims = delims.translate(string._idmap,
1180 delims = delims.translate(string._idmap,
1190 self.rc.readline_remove_delims)
1181 self.rc.readline_remove_delims)
1191 readline.set_completer_delims(delims)
1182 readline.set_completer_delims(delims)
1192 # otherwise we end up with a monster history after a while:
1183 # otherwise we end up with a monster history after a while:
1193 readline.set_history_length(1000)
1184 readline.set_history_length(1000)
1194 try:
1185 try:
1195 #print '*** Reading readline history' # dbg
1186 #print '*** Reading readline history' # dbg
1196 readline.read_history_file(self.histfile)
1187 readline.read_history_file(self.histfile)
1197 except IOError:
1188 except IOError:
1198 pass # It doesn't exist yet.
1189 pass # It doesn't exist yet.
1199
1190
1200 atexit.register(self.atexit_operations)
1191 atexit.register(self.atexit_operations)
1201 del atexit
1192 del atexit
1202
1193
1203 # Configure auto-indent for all platforms
1194 # Configure auto-indent for all platforms
1204 self.set_autoindent(self.rc.autoindent)
1195 self.set_autoindent(self.rc.autoindent)
1205
1196
1206 def showsyntaxerror(self, filename=None):
1197 def showsyntaxerror(self, filename=None):
1207 """Display the syntax error that just occurred.
1198 """Display the syntax error that just occurred.
1208
1199
1209 This doesn't display a stack trace because there isn't one.
1200 This doesn't display a stack trace because there isn't one.
1210
1201
1211 If a filename is given, it is stuffed in the exception instead
1202 If a filename is given, it is stuffed in the exception instead
1212 of what was there before (because Python's parser always uses
1203 of what was there before (because Python's parser always uses
1213 "<string>" when reading from a string).
1204 "<string>" when reading from a string).
1214 """
1205 """
1215 type, value, sys.last_traceback = sys.exc_info()
1206 type, value, sys.last_traceback = sys.exc_info()
1216 sys.last_type = type
1207 sys.last_type = type
1217 sys.last_value = value
1208 sys.last_value = value
1218 if filename and type is SyntaxError:
1209 if filename and type is SyntaxError:
1219 # Work hard to stuff the correct filename in the exception
1210 # Work hard to stuff the correct filename in the exception
1220 try:
1211 try:
1221 msg, (dummy_filename, lineno, offset, line) = value
1212 msg, (dummy_filename, lineno, offset, line) = value
1222 except:
1213 except:
1223 # Not the format we expect; leave it alone
1214 # Not the format we expect; leave it alone
1224 pass
1215 pass
1225 else:
1216 else:
1226 # Stuff in the right filename
1217 # Stuff in the right filename
1227 try:
1218 try:
1228 # Assume SyntaxError is a class exception
1219 # Assume SyntaxError is a class exception
1229 value = SyntaxError(msg, (filename, lineno, offset, line))
1220 value = SyntaxError(msg, (filename, lineno, offset, line))
1230 except:
1221 except:
1231 # If that failed, assume SyntaxError is a string
1222 # If that failed, assume SyntaxError is a string
1232 value = msg, (filename, lineno, offset, line)
1223 value = msg, (filename, lineno, offset, line)
1233 self.SyntaxTB(type,value,[])
1224 self.SyntaxTB(type,value,[])
1234
1225
1235 def debugger(self):
1226 def debugger(self):
1236 """Call the pdb debugger."""
1227 """Call the pdb debugger."""
1237
1228
1238 if not self.rc.pdb:
1229 if not self.rc.pdb:
1239 return
1230 return
1240 pdb.pm()
1231 pdb.pm()
1241
1232
1242 def showtraceback(self,exc_tuple = None):
1233 def showtraceback(self,exc_tuple = None):
1243 """Display the exception that just occurred."""
1234 """Display the exception that just occurred."""
1244
1235
1245 # Though this won't be called by syntax errors in the input line,
1236 # Though this won't be called by syntax errors in the input line,
1246 # there may be SyntaxError cases whith imported code.
1237 # there may be SyntaxError cases whith imported code.
1247 if exc_tuple is None:
1238 if exc_tuple is None:
1248 type, value, tb = sys.exc_info()
1239 type, value, tb = sys.exc_info()
1249 else:
1240 else:
1250 type, value, tb = exc_tuple
1241 type, value, tb = exc_tuple
1251 if type is SyntaxError:
1242 if type is SyntaxError:
1252 self.showsyntaxerror()
1243 self.showsyntaxerror()
1253 else:
1244 else:
1254 sys.last_type = type
1245 sys.last_type = type
1255 sys.last_value = value
1246 sys.last_value = value
1256 sys.last_traceback = tb
1247 sys.last_traceback = tb
1257 self.InteractiveTB()
1248 self.InteractiveTB()
1258 if self.InteractiveTB.call_pdb and self.has_readline:
1249 if self.InteractiveTB.call_pdb and self.has_readline:
1259 # pdb mucks up readline, fix it back
1250 # pdb mucks up readline, fix it back
1260 self.readline.set_completer(self.Completer.complete)
1251 self.readline.set_completer(self.Completer.complete)
1261
1252
1262 def update_cache(self, line):
1253 def update_cache(self, line):
1263 """puts line into cache"""
1254 """puts line into cache"""
1264 self.inputcache.insert(0, line) # This copies the cache every time ... :-(
1255 self.inputcache.insert(0, line) # This copies the cache every time ... :-(
1265 if len(self.inputcache) >= self.CACHELENGTH:
1256 if len(self.inputcache) >= self.CACHELENGTH:
1266 self.inputcache.pop() # This not :-)
1257 self.inputcache.pop() # This not :-)
1267
1258
1268 def name_space_init(self):
1259 def name_space_init(self):
1269 """Create local namespace."""
1260 """Create local namespace."""
1270 # We want this to be a method to facilitate embedded initialization.
1261 # We want this to be a method to facilitate embedded initialization.
1271 code.InteractiveConsole.__init__(self,self.user_ns)
1262 code.InteractiveConsole.__init__(self,self.user_ns)
1272
1263
1273 def mainloop(self,banner=None):
1264 def mainloop(self,banner=None):
1274 """Creates the local namespace and starts the mainloop.
1265 """Creates the local namespace and starts the mainloop.
1275
1266
1276 If an optional banner argument is given, it will override the
1267 If an optional banner argument is given, it will override the
1277 internally created default banner."""
1268 internally created default banner."""
1278
1269
1279 self.name_space_init()
1270 self.name_space_init()
1280 if self.rc.c: # Emulate Python's -c option
1271 if self.rc.c: # Emulate Python's -c option
1281 self.exec_init_cmd()
1272 self.exec_init_cmd()
1282 if banner is None:
1273 if banner is None:
1283 if self.rc.banner:
1274 if self.rc.banner:
1284 banner = self.BANNER+self.banner2
1275 banner = self.BANNER+self.banner2
1285 else:
1276 else:
1286 banner = ''
1277 banner = ''
1287 self.interact(banner)
1278 self.interact(banner)
1288
1279
1289 def exec_init_cmd(self):
1280 def exec_init_cmd(self):
1290 """Execute a command given at the command line.
1281 """Execute a command given at the command line.
1291
1282
1292 This emulates Python's -c option."""
1283 This emulates Python's -c option."""
1293
1284
1294 sys.argv = ['-c']
1285 sys.argv = ['-c']
1295 self.push(self.rc.c)
1286 self.push(self.rc.c)
1296
1287
1297 def embed_mainloop(self,header='',local_ns=None,global_ns=None,stack_depth=0):
1288 def embed_mainloop(self,header='',local_ns=None,global_ns=None,stack_depth=0):
1298 """Embeds IPython into a running python program.
1289 """Embeds IPython into a running python program.
1299
1290
1300 Input:
1291 Input:
1301
1292
1302 - header: An optional header message can be specified.
1293 - header: An optional header message can be specified.
1303
1294
1304 - local_ns, global_ns: working namespaces. If given as None, the
1295 - local_ns, global_ns: working namespaces. If given as None, the
1305 IPython-initialized one is updated with __main__.__dict__, so that
1296 IPython-initialized one is updated with __main__.__dict__, so that
1306 program variables become visible but user-specific configuration
1297 program variables become visible but user-specific configuration
1307 remains possible.
1298 remains possible.
1308
1299
1309 - stack_depth: specifies how many levels in the stack to go to
1300 - stack_depth: specifies how many levels in the stack to go to
1310 looking for namespaces (when local_ns and global_ns are None). This
1301 looking for namespaces (when local_ns and global_ns are None). This
1311 allows an intermediate caller to make sure that this function gets
1302 allows an intermediate caller to make sure that this function gets
1312 the namespace from the intended level in the stack. By default (0)
1303 the namespace from the intended level in the stack. By default (0)
1313 it will get its locals and globals from the immediate caller.
1304 it will get its locals and globals from the immediate caller.
1314
1305
1315 Warning: it's possible to use this in a program which is being run by
1306 Warning: it's possible to use this in a program which is being run by
1316 IPython itself (via %run), but some funny things will happen (a few
1307 IPython itself (via %run), but some funny things will happen (a few
1317 globals get overwritten). In the future this will be cleaned up, as
1308 globals get overwritten). In the future this will be cleaned up, as
1318 there is no fundamental reason why it can't work perfectly."""
1309 there is no fundamental reason why it can't work perfectly."""
1319
1310
1320 # Patch for global embedding to make sure that things don't overwrite
1311 # Patch for global embedding to make sure that things don't overwrite
1321 # user globals accidentally. Thanks to Richard <rxe@renre-europe.com>
1312 # user globals accidentally. Thanks to Richard <rxe@renre-europe.com>
1322 # FIXME. Test this a bit more carefully (the if.. is new)
1313 # FIXME. Test this a bit more carefully (the if.. is new)
1323 if local_ns is None and global_ns is None:
1314 if local_ns is None and global_ns is None:
1324 self.user_ns.update(__main__.__dict__)
1315 self.user_ns.update(__main__.__dict__)
1325
1316
1326 # Get locals and globals from caller
1317 # Get locals and globals from caller
1327 if local_ns is None or global_ns is None:
1318 if local_ns is None or global_ns is None:
1328 call_frame = sys._getframe(stack_depth).f_back
1319 call_frame = sys._getframe(stack_depth).f_back
1329
1320
1330 if local_ns is None:
1321 if local_ns is None:
1331 local_ns = call_frame.f_locals
1322 local_ns = call_frame.f_locals
1332 if global_ns is None:
1323 if global_ns is None:
1333 global_ns = call_frame.f_globals
1324 global_ns = call_frame.f_globals
1334
1325
1335 # Update namespaces and fire up interpreter
1326 # Update namespaces and fire up interpreter
1336 self.user_ns.update(local_ns)
1327 self.user_ns.update(local_ns)
1337 self.interact(header)
1328 self.interact(header)
1338
1329
1339 # Remove locals from namespace
1330 # Remove locals from namespace
1340 for k in local_ns.keys():
1331 for k in local_ns:
1341 del self.user_ns[k]
1332 del self.user_ns[k]
1342
1333
1343 def interact(self, banner=None):
1334 def interact(self, banner=None):
1344 """Closely emulate the interactive Python console.
1335 """Closely emulate the interactive Python console.
1345
1336
1346 The optional banner argument specify the banner to print
1337 The optional banner argument specify the banner to print
1347 before the first interaction; by default it prints a banner
1338 before the first interaction; by default it prints a banner
1348 similar to the one printed by the real Python interpreter,
1339 similar to the one printed by the real Python interpreter,
1349 followed by the current class name in parentheses (so as not
1340 followed by the current class name in parentheses (so as not
1350 to confuse this with the real interpreter -- since it's so
1341 to confuse this with the real interpreter -- since it's so
1351 close!).
1342 close!).
1352
1343
1353 """
1344 """
1354 cprt = 'Type "copyright", "credits" or "license" for more information.'
1345 cprt = 'Type "copyright", "credits" or "license" for more information.'
1355 if banner is None:
1346 if banner is None:
1356 self.write("Python %s on %s\n%s\n(%s)\n" %
1347 self.write("Python %s on %s\n%s\n(%s)\n" %
1357 (sys.version, sys.platform, cprt,
1348 (sys.version, sys.platform, cprt,
1358 self.__class__.__name__))
1349 self.__class__.__name__))
1359 else:
1350 else:
1360 self.write(banner)
1351 self.write(banner)
1361
1352
1362 more = 0
1353 more = 0
1363
1354
1364 # Mark activity in the builtins
1355 # Mark activity in the builtins
1365 __builtin__.__dict__['__IPYTHON__active'] += 1
1356 __builtin__.__dict__['__IPYTHON__active'] += 1
1366 while 1:
1357
1367 # This is set by a call to %Exit or %Quit
1358 # exit_now is set by a call to %Exit or %Quit
1368 if self.exit_now:
1359 while not self.exit_now:
1369 break
1370 try:
1360 try:
1371 if more:
1361 if more:
1372 prompt = self.outputcache.prompt2
1362 prompt = self.outputcache.prompt2
1373 if self.autoindent:
1363 if self.autoindent:
1374 self.readline_startup_hook(self.pre_readline)
1364 self.readline_startup_hook(self.pre_readline)
1375 else:
1365 else:
1376 prompt = self.outputcache.prompt1
1366 prompt = self.outputcache.prompt1
1377 try:
1367 try:
1378 line = self.raw_input(prompt)
1368 line = self.raw_input(prompt)
1379 if self.autoindent:
1369 if self.autoindent:
1380 self.readline_startup_hook(None)
1370 self.readline_startup_hook(None)
1381 except EOFError:
1371 except EOFError:
1382 if self.autoindent:
1372 if self.autoindent:
1383 self.readline_startup_hook(None)
1373 self.readline_startup_hook(None)
1384 self.write("\n")
1374 self.write("\n")
1385 if self.rc.confirm_exit:
1375 if self.rc.confirm_exit:
1386 if ask_yes_no('Do you really want to exit ([y]/n)?','y'):
1376 if ask_yes_no('Do you really want to exit ([y]/n)?','y'):
1387 break
1377 break
1388 else:
1378 else:
1389 break
1379 break
1390 else:
1380 else:
1391 more = self.push(line)
1381 more = self.push(line)
1392 # Auto-indent management
1382 # Auto-indent management
1393 if self.autoindent:
1383 if self.autoindent:
1394 if line:
1384 if line:
1395 ini_spaces = re.match('^(\s+)',line)
1385 ini_spaces = re.match('^(\s+)',line)
1396 if ini_spaces:
1386 if ini_spaces:
1397 nspaces = ini_spaces.end()
1387 nspaces = ini_spaces.end()
1398 else:
1388 else:
1399 nspaces = 0
1389 nspaces = 0
1400 self.readline_indent = nspaces
1390 self.readline_indent = nspaces
1401
1391
1402 if line[-1] == ':':
1392 if line[-1] == ':':
1403 self.readline_indent += 4
1393 self.readline_indent += 4
1404 elif re.match(r'^\s+raise|^\s+return',line):
1394 elif re.match(r'^\s+raise|^\s+return',line):
1405 self.readline_indent -= 4
1395 self.readline_indent -= 4
1406 else:
1396 else:
1407 self.readline_indent = 0
1397 self.readline_indent = 0
1408
1398
1409 except KeyboardInterrupt:
1399 except KeyboardInterrupt:
1410 self.write("\nKeyboardInterrupt\n")
1400 self.write("\nKeyboardInterrupt\n")
1411 self.resetbuffer()
1401 self.resetbuffer()
1412 more = 0
1402 more = 0
1413 # keep cache in sync with the prompt counter:
1403 # keep cache in sync with the prompt counter:
1414 self.outputcache.prompt_count -= 1
1404 self.outputcache.prompt_count -= 1
1415
1405
1416 if self.autoindent:
1406 if self.autoindent:
1417 self.readline_indent = 0
1407 self.readline_indent = 0
1418
1408
1419 except bdb.BdbQuit:
1409 except bdb.BdbQuit:
1420 warn("The Python debugger has exited with a BdbQuit exception.\n"
1410 warn("The Python debugger has exited with a BdbQuit exception.\n"
1421 "Because of how pdb handles the stack, it is impossible\n"
1411 "Because of how pdb handles the stack, it is impossible\n"
1422 "for IPython to properly format this particular exception.\n"
1412 "for IPython to properly format this particular exception.\n"
1423 "IPython will resume normal operation.")
1413 "IPython will resume normal operation.")
1424 except:
1425 # We should never get here except in fairly bizarre situations
1426 # (or b/c of an IPython bug). One reasonable exception is if
1427 # the user sets stdin/out/err to a broken object (or closes
1428 # any of them!)
1429
1430 fixed_in_out_err = 0
1431
1432 # Call the Term I/O class and have it reopen any stream which
1433 # the user might have closed.
1434 Term.reopen_all()
1435
1436 # Do the same manually for sys.stderr/out/in
1437
1438 # err first, so we can print at least warnings
1439 if sys.__stderr__.closed:
1440 sys.__stderr__ = os.fdopen(os.dup(2),'w',0)
1441 fixed_err_err = 1
1442 print >> sys.__stderr__,"""
1443 WARNING:
1444 sys.__stderr__ was closed!
1445 I've tried to reopen it, but bear in mind that things may not work normally
1446 from now. In particular, readline support may have broken.
1447 """
1448 # Next, check stdin/out
1449 if sys.__stdin__.closed:
1450 sys.__stdin__ = os.fdopen(os.dup(0),'r',0)
1451 fixed_in_out_err = 1
1452 print >> sys.__stderr__,"""
1453 WARNING:
1454 sys.__stdin__ was closed!
1455 I've tried to reopen it, but bear in mind that things may not work normally
1456 from now. In particular, readline support may have broken.
1457 """
1458 if sys.__stdout__.closed:
1459 sys.__stdout__ = os.fdopen(os.dup(1),'w',0)
1460 fixed_in_out_err = 1
1461 print >> sys.__stderr__,"""
1462 WARNING:
1463 sys.__stdout__ was closed!
1464 I've tried to reopen it, but bear in mind that things may not work normally
1465 from now. In particular, readline support may have broken.
1466 """
1467
1468 # Now, check mismatch of objects
1469 if sys.stdin is not sys.__stdin__:
1470 sys.stdin = sys.__stdin__
1471 fixed_in_out_err = 1
1472 print >> sys.__stderr__,"""
1473 WARNING:
1474 sys.stdin has been reset to sys.__stdin__.
1475 There seemed to be a problem with your sys.stdin.
1476 """
1477 if sys.stdout is not sys.__stdout__:
1478 sys.stdout = sys.__stdout__
1479 fixed_in_out_err = 1
1480 print >> sys.__stderr__,"""
1481 WARNING:
1482 sys.stdout has been reset to sys.__stdout__.
1483 There seemed to be a problem with your sys.stdout.
1484 """
1485
1486 if sys.stderr is not sys.__stderr__:
1487 sys.stderr = sys.__stderr__
1488 fixed_in_out_err = 1
1489 print >> sys.__stderr__,"""
1490 WARNING:
1491 sys.stderr has been reset to sys.__stderr__.
1492 There seemed to be a problem with your sys.stderr.
1493 """
1494 # If the problem wasn't a broken out/err, it's an IPython bug
1495 # I wish we could ask the user whether to crash or not, but
1496 # calling any function at this point messes up the stack.
1497 if not fixed_in_out_err:
1498 raise
1499
1414
1500 # We are off again...
1415 # We are off again...
1501 __builtin__.__dict__['__IPYTHON__active'] -= 1
1416 __builtin__.__dict__['__IPYTHON__active'] -= 1
1502
1417
1503 def excepthook(self, type, value, tb):
1418 def excepthook(self, type, value, tb):
1504 """One more defense for GUI apps that call sys.excepthook.
1419 """One more defense for GUI apps that call sys.excepthook.
1505
1420
1506 GUI frameworks like wxPython trap exceptions and call
1421 GUI frameworks like wxPython trap exceptions and call
1507 sys.excepthook themselves. I guess this is a feature that
1422 sys.excepthook themselves. I guess this is a feature that
1508 enables them to keep running after exceptions that would
1423 enables them to keep running after exceptions that would
1509 otherwise kill their mainloop. This is a bother for IPython
1424 otherwise kill their mainloop. This is a bother for IPython
1510 which excepts to catch all of the program exceptions with a try:
1425 which excepts to catch all of the program exceptions with a try:
1511 except: statement.
1426 except: statement.
1512
1427
1513 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1428 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1514 any app directly invokes sys.excepthook, it will look to the user like
1429 any app directly invokes sys.excepthook, it will look to the user like
1515 IPython crashed. In order to work around this, we can disable the
1430 IPython crashed. In order to work around this, we can disable the
1516 CrashHandler and replace it with this excepthook instead, which prints a
1431 CrashHandler and replace it with this excepthook instead, which prints a
1517 regular traceback using our InteractiveTB. In this fashion, apps which
1432 regular traceback using our InteractiveTB. In this fashion, apps which
1518 call sys.excepthook will generate a regular-looking exception from
1433 call sys.excepthook will generate a regular-looking exception from
1519 IPython, and the CrashHandler will only be triggered by real IPython
1434 IPython, and the CrashHandler will only be triggered by real IPython
1520 crashes.
1435 crashes.
1521
1436
1522 This hook should be used sparingly, only in places which are not likely
1437 This hook should be used sparingly, only in places which are not likely
1523 to be true IPython errors.
1438 to be true IPython errors.
1524 """
1439 """
1525
1440
1526 self.InteractiveTB(type, value, tb, tb_offset=0)
1441 self.InteractiveTB(type, value, tb, tb_offset=0)
1527 if self.InteractiveTB.call_pdb and self.has_readline:
1442 if self.InteractiveTB.call_pdb and self.has_readline:
1528 self.readline.set_completer(self.Completer.complete)
1443 self.readline.set_completer(self.Completer.complete)
1529
1444
1530 def call_alias(self,alias,rest=''):
1445 def call_alias(self,alias,rest=''):
1531 """Call an alias given its name and the rest of the line.
1446 """Call an alias given its name and the rest of the line.
1532
1447
1533 This function MUST be given a proper alias, because it doesn't make
1448 This function MUST be given a proper alias, because it doesn't make
1534 any checks when looking up into the alias table. The caller is
1449 any checks when looking up into the alias table. The caller is
1535 responsible for invoking it only with a valid alias."""
1450 responsible for invoking it only with a valid alias."""
1536
1451
1537 #print 'ALIAS: <%s>+<%s>' % (alias,rest) # dbg
1452 #print 'ALIAS: <%s>+<%s>' % (alias,rest) # dbg
1538 nargs,cmd = self.alias_table[alias]
1453 nargs,cmd = self.alias_table[alias]
1539 # Expand the %l special to be the user's input line
1454 # Expand the %l special to be the user's input line
1540 if cmd.find('%l') >= 0:
1455 if cmd.find('%l') >= 0:
1541 cmd = cmd.replace('%l',rest)
1456 cmd = cmd.replace('%l',rest)
1542 rest = ''
1457 rest = ''
1543 if nargs==0:
1458 if nargs==0:
1544 # Simple, argument-less aliases
1459 # Simple, argument-less aliases
1545 cmd = '%s %s' % (cmd,rest)
1460 cmd = '%s %s' % (cmd,rest)
1546 else:
1461 else:
1547 # Handle aliases with positional arguments
1462 # Handle aliases with positional arguments
1548 args = rest.split(None,nargs)
1463 args = rest.split(None,nargs)
1549 if len(args)< nargs:
1464 if len(args)< nargs:
1550 error('Alias <%s> requires %s arguments, %s given.' %
1465 error('Alias <%s> requires %s arguments, %s given.' %
1551 (alias,nargs,len(args)))
1466 (alias,nargs,len(args)))
1552 return
1467 return
1553 cmd = '%s %s' % (cmd % tuple(args[:nargs]),' '.join(args[nargs:]))
1468 cmd = '%s %s' % (cmd % tuple(args[:nargs]),' '.join(args[nargs:]))
1554 # Now call the macro, evaluating in the user's namespace
1469 # Now call the macro, evaluating in the user's namespace
1555 try:
1470 try:
1556 self.system(cmd)
1471 self.system(cmd)
1557 except:
1472 except:
1558 self.showtraceback()
1473 self.showtraceback()
1559
1474
1560 def runlines(self,lines):
1475 def runlines(self,lines):
1561 """Run a string of one or more lines of source.
1476 """Run a string of one or more lines of source.
1562
1477
1563 This method is capable of running a string containing multiple source
1478 This method is capable of running a string containing multiple source
1564 lines, as if they had been entered at the IPython prompt. Since it
1479 lines, as if they had been entered at the IPython prompt. Since it
1565 exposes IPython's processing machinery, the given strings can contain
1480 exposes IPython's processing machinery, the given strings can contain
1566 magic calls (%magic), special shell access (!cmd), etc."""
1481 magic calls (%magic), special shell access (!cmd), etc."""
1567
1482
1568 # We must start with a clean buffer, in case this is run from an
1483 # We must start with a clean buffer, in case this is run from an
1569 # interactive IPython session (via a magic, for example).
1484 # interactive IPython session (via a magic, for example).
1570 self.resetbuffer()
1485 self.resetbuffer()
1571 lines = lines.split('\n')
1486 lines = lines.split('\n')
1572 more = 0
1487 more = 0
1573 for line in lines:
1488 for line in lines:
1574 # skip blank lines so we don't mess up the prompt counter, but do
1489 # skip blank lines so we don't mess up the prompt counter, but do
1575 # NOT skip even a blank line if we are in a code block (more is
1490 # NOT skip even a blank line if we are in a code block (more is
1576 # true)
1491 # true)
1577 if line or more:
1492 if line or more:
1578 more = self.push((self.prefilter(line,more)))
1493 more = self.push((self.prefilter(line,more)))
1579 # IPython's runsource returns None if there was an error
1494 # IPython's runsource returns None if there was an error
1580 # compiling the code. This allows us to stop processing right
1495 # compiling the code. This allows us to stop processing right
1581 # away, so the user gets the error message at the right place.
1496 # away, so the user gets the error message at the right place.
1582 if more is None:
1497 if more is None:
1583 break
1498 break
1584 # final newline in case the input didn't have it, so that the code
1499 # final newline in case the input didn't have it, so that the code
1585 # actually does get executed
1500 # actually does get executed
1586 if more:
1501 if more:
1587 self.push('\n')
1502 self.push('\n')
1588
1503
1589 def runsource(self, source, filename="<input>", symbol="single"):
1504 def runsource(self, source, filename="<input>", symbol="single"):
1590 """Compile and run some source in the interpreter.
1505 """Compile and run some source in the interpreter.
1591
1506
1592 Arguments are as for compile_command().
1507 Arguments are as for compile_command().
1593
1508
1594 One several things can happen:
1509 One several things can happen:
1595
1510
1596 1) The input is incorrect; compile_command() raised an
1511 1) The input is incorrect; compile_command() raised an
1597 exception (SyntaxError or OverflowError). A syntax traceback
1512 exception (SyntaxError or OverflowError). A syntax traceback
1598 will be printed by calling the showsyntaxerror() method.
1513 will be printed by calling the showsyntaxerror() method.
1599
1514
1600 2) The input is incomplete, and more input is required;
1515 2) The input is incomplete, and more input is required;
1601 compile_command() returned None. Nothing happens.
1516 compile_command() returned None. Nothing happens.
1602
1517
1603 3) The input is complete; compile_command() returned a code
1518 3) The input is complete; compile_command() returned a code
1604 object. The code is executed by calling self.runcode() (which
1519 object. The code is executed by calling self.runcode() (which
1605 also handles run-time exceptions, except for SystemExit).
1520 also handles run-time exceptions, except for SystemExit).
1606
1521
1607 The return value is:
1522 The return value is:
1608
1523
1609 - True in case 2
1524 - True in case 2
1610
1525
1611 - False in the other cases, unless an exception is raised, where
1526 - False in the other cases, unless an exception is raised, where
1612 None is returned instead. This can be used by external callers to
1527 None is returned instead. This can be used by external callers to
1613 know whether to continue feeding input or not.
1528 know whether to continue feeding input or not.
1614
1529
1615 The return value can be used to decide whether to use sys.ps1 or
1530 The return value can be used to decide whether to use sys.ps1 or
1616 sys.ps2 to prompt the next line."""
1531 sys.ps2 to prompt the next line."""
1617 try:
1532 try:
1618 code = self.compile(source, filename, symbol)
1533 code = self.compile(source, filename, symbol)
1619 except (OverflowError, SyntaxError, ValueError):
1534 except (OverflowError, SyntaxError, ValueError):
1620 # Case 1
1535 # Case 1
1621 self.showsyntaxerror(filename)
1536 self.showsyntaxerror(filename)
1622 return None
1537 return None
1623
1538
1624 if code is None:
1539 if code is None:
1625 # Case 2
1540 # Case 2
1626 return True
1541 return True
1627
1542
1628 # Case 3
1543 # Case 3
1629 # We store the code source and object so that threaded shells and
1544 # We store the code source and object so that threaded shells and
1630 # custom exception handlers can access all this info if needed.
1545 # custom exception handlers can access all this info if needed.
1631 self.code_to_run_src = source
1546 self.code_to_run_src = source
1632 self.code_to_run = code
1547 self.code_to_run = code
1633 # now actually execute the code object
1548 # now actually execute the code object
1634 if self.runcode(code) == 0:
1549 if self.runcode(code) == 0:
1635 return False
1550 return False
1636 else:
1551 else:
1637 return None
1552 return None
1638
1553
1639 def runcode(self,code_obj):
1554 def runcode(self,code_obj):
1640 """Execute a code object.
1555 """Execute a code object.
1641
1556
1642 When an exception occurs, self.showtraceback() is called to display a
1557 When an exception occurs, self.showtraceback() is called to display a
1643 traceback.
1558 traceback.
1644
1559
1645 Return value: a flag indicating whether the code to be run completed
1560 Return value: a flag indicating whether the code to be run completed
1646 successfully:
1561 successfully:
1647
1562
1648 - 0: successful execution.
1563 - 0: successful execution.
1649 - 1: an error occurred.
1564 - 1: an error occurred.
1650 """
1565 """
1651
1566
1652 # Set our own excepthook in case the user code tries to call it
1567 # Set our own excepthook in case the user code tries to call it
1653 # directly, so that the IPython crash handler doesn't get triggered
1568 # directly, so that the IPython crash handler doesn't get triggered
1654 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
1569 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
1655 outflag = 1 # happens in more places, so it's easier as default
1570 outflag = 1 # happens in more places, so it's easier as default
1656 try:
1571 try:
1657 try:
1572 try:
1658 exec code_obj in self.locals
1573 exec code_obj in self.locals
1659 finally:
1574 finally:
1660 # Reset our crash handler in place
1575 # Reset our crash handler in place
1661 sys.excepthook = old_excepthook
1576 sys.excepthook = old_excepthook
1662 except SystemExit:
1577 except SystemExit:
1663 self.resetbuffer()
1578 self.resetbuffer()
1664 self.showtraceback()
1579 self.showtraceback()
1665 warn( __builtin__.exit,level=1)
1580 warn( __builtin__.exit,level=1)
1666 except self.custom_exceptions:
1581 except self.custom_exceptions:
1667 etype,value,tb = sys.exc_info()
1582 etype,value,tb = sys.exc_info()
1668 self.CustomTB(etype,value,tb)
1583 self.CustomTB(etype,value,tb)
1669 except:
1584 except:
1670 self.showtraceback()
1585 self.showtraceback()
1671 else:
1586 else:
1672 outflag = 0
1587 outflag = 0
1673 if code.softspace(sys.stdout, 0):
1588 if code.softspace(sys.stdout, 0):
1674 print
1589 print
1675 # Flush out code object which has been run (and source)
1590 # Flush out code object which has been run (and source)
1676 self.code_to_run = None
1591 self.code_to_run = None
1677 self.code_to_run_src = ''
1592 self.code_to_run_src = ''
1678 return outflag
1593 return outflag
1679
1594
1680 def raw_input(self, prompt=""):
1595 def raw_input(self, prompt=""):
1681 """Write a prompt and read a line.
1596 """Write a prompt and read a line.
1682
1597
1683 The returned line does not include the trailing newline.
1598 The returned line does not include the trailing newline.
1684 When the user enters the EOF key sequence, EOFError is raised.
1599 When the user enters the EOF key sequence, EOFError is raised.
1685
1600
1686 The base implementation uses the built-in function
1601 The base implementation uses the built-in function
1687 raw_input(); a subclass may replace this with a different
1602 raw_input(); a subclass may replace this with a different
1688 implementation.
1603 implementation.
1689 """
1604 """
1690 return self.prefilter(raw_input_original(prompt),
1605 return self.prefilter(raw_input_original(prompt),
1691 prompt==self.outputcache.prompt2)
1606 prompt==self.outputcache.prompt2)
1692
1607
1693 def split_user_input(self,line):
1608 def split_user_input(self,line):
1694 """Split user input into pre-char, function part and rest."""
1609 """Split user input into pre-char, function part and rest."""
1695
1610
1696 lsplit = self.line_split.match(line)
1611 lsplit = self.line_split.match(line)
1697 if lsplit is None: # no regexp match returns None
1612 if lsplit is None: # no regexp match returns None
1698 try:
1613 try:
1699 iFun,theRest = line.split(None,1)
1614 iFun,theRest = line.split(None,1)
1700 except ValueError:
1615 except ValueError:
1701 iFun,theRest = line,''
1616 iFun,theRest = line,''
1702 pre = re.match('^(\s*)(.*)',line).groups()[0]
1617 pre = re.match('^(\s*)(.*)',line).groups()[0]
1703 else:
1618 else:
1704 pre,iFun,theRest = lsplit.groups()
1619 pre,iFun,theRest = lsplit.groups()
1705
1620
1706 #print 'line:<%s>' % line # dbg
1621 #print 'line:<%s>' % line # dbg
1707 #print 'pre <%s> iFun <%s> rest <%s>' % (pre,iFun.strip(),theRest) # dbg
1622 #print 'pre <%s> iFun <%s> rest <%s>' % (pre,iFun.strip(),theRest) # dbg
1708 return pre,iFun.strip(),theRest
1623 return pre,iFun.strip(),theRest
1709
1624
1710 def _prefilter(self, line, continue_prompt):
1625 def _prefilter(self, line, continue_prompt):
1711 """Calls different preprocessors, depending on the form of line."""
1626 """Calls different preprocessors, depending on the form of line."""
1712
1627
1713 # All handlers *must* return a value, even if it's blank ('').
1628 # All handlers *must* return a value, even if it's blank ('').
1714
1629
1715 # Lines are NOT logged here. Handlers should process the line as
1630 # Lines are NOT logged here. Handlers should process the line as
1716 # needed, update the cache AND log it (so that the input cache array
1631 # needed, update the cache AND log it (so that the input cache array
1717 # stays synced).
1632 # stays synced).
1718
1633
1719 # This function is _very_ delicate, and since it's also the one which
1634 # This function is _very_ delicate, and since it's also the one which
1720 # determines IPython's response to user input, it must be as efficient
1635 # determines IPython's response to user input, it must be as efficient
1721 # as possible. For this reason it has _many_ returns in it, trying
1636 # as possible. For this reason it has _many_ returns in it, trying
1722 # always to exit as quickly as it can figure out what it needs to do.
1637 # always to exit as quickly as it can figure out what it needs to do.
1723
1638
1724 # This function is the main responsible for maintaining IPython's
1639 # This function is the main responsible for maintaining IPython's
1725 # behavior respectful of Python's semantics. So be _very_ careful if
1640 # behavior respectful of Python's semantics. So be _very_ careful if
1726 # making changes to anything here.
1641 # making changes to anything here.
1727
1642
1728 #.....................................................................
1643 #.....................................................................
1729 # Code begins
1644 # Code begins
1730
1645
1731 #if line.startswith('%crash'): raise RuntimeError,'Crash now!' # dbg
1646 #if line.startswith('%crash'): raise RuntimeError,'Crash now!' # dbg
1732
1647
1733 # save the line away in case we crash, so the post-mortem handler can
1648 # save the line away in case we crash, so the post-mortem handler can
1734 # record it
1649 # record it
1735 self._last_input_line = line
1650 self._last_input_line = line
1736
1651
1737 #print '***line: <%s>' % line # dbg
1652 #print '***line: <%s>' % line # dbg
1738
1653
1739 # the input history needs to track even empty lines
1654 # the input history needs to track even empty lines
1740 if not line.strip():
1655 if not line.strip():
1741 if not continue_prompt:
1656 if not continue_prompt:
1742 self.outputcache.prompt_count -= 1
1657 self.outputcache.prompt_count -= 1
1743 return self.handle_normal('',continue_prompt)
1658 return self.handle_normal('',continue_prompt)
1744
1659
1745 # print '***cont',continue_prompt # dbg
1660 # print '***cont',continue_prompt # dbg
1746 # special handlers are only allowed for single line statements
1661 # special handlers are only allowed for single line statements
1747 if continue_prompt and not self.rc.multi_line_specials:
1662 if continue_prompt and not self.rc.multi_line_specials:
1748 return self.handle_normal(line,continue_prompt)
1663 return self.handle_normal(line,continue_prompt)
1749
1664
1750 # For the rest, we need the structure of the input
1665 # For the rest, we need the structure of the input
1751 pre,iFun,theRest = self.split_user_input(line)
1666 pre,iFun,theRest = self.split_user_input(line)
1752 #print 'pre <%s> iFun <%s> rest <%s>' % (pre,iFun,theRest) # dbg
1667 #print 'pre <%s> iFun <%s> rest <%s>' % (pre,iFun,theRest) # dbg
1753
1668
1754 # First check for explicit escapes in the last/first character
1669 # First check for explicit escapes in the last/first character
1755 handler = None
1670 handler = None
1756 if line[-1] == self.ESC_HELP:
1671 if line[-1] == self.ESC_HELP:
1757 handler = self.esc_handlers.get(line[-1]) # the ? can be at the end
1672 handler = self.esc_handlers.get(line[-1]) # the ? can be at the end
1758 if handler is None:
1673 if handler is None:
1759 # look at the first character of iFun, NOT of line, so we skip
1674 # look at the first character of iFun, NOT of line, so we skip
1760 # leading whitespace in multiline input
1675 # leading whitespace in multiline input
1761 handler = self.esc_handlers.get(iFun[0:1])
1676 handler = self.esc_handlers.get(iFun[0:1])
1762 if handler is not None:
1677 if handler is not None:
1763 return handler(line,continue_prompt,pre,iFun,theRest)
1678 return handler(line,continue_prompt,pre,iFun,theRest)
1764 # Emacs ipython-mode tags certain input lines
1679 # Emacs ipython-mode tags certain input lines
1765 if line.endswith('# PYTHON-MODE'):
1680 if line.endswith('# PYTHON-MODE'):
1766 return self.handle_emacs(line,continue_prompt)
1681 return self.handle_emacs(line,continue_prompt)
1767
1682
1768 # Next, check if we can automatically execute this thing
1683 # Next, check if we can automatically execute this thing
1769
1684
1770 # Allow ! in multi-line statements if multi_line_specials is on:
1685 # Allow ! in multi-line statements if multi_line_specials is on:
1771 if continue_prompt and self.rc.multi_line_specials and \
1686 if continue_prompt and self.rc.multi_line_specials and \
1772 iFun.startswith(self.ESC_SHELL):
1687 iFun.startswith(self.ESC_SHELL):
1773 return self.handle_shell_escape(line,continue_prompt,
1688 return self.handle_shell_escape(line,continue_prompt,
1774 pre=pre,iFun=iFun,
1689 pre=pre,iFun=iFun,
1775 theRest=theRest)
1690 theRest=theRest)
1776
1691
1777 # Let's try to find if the input line is a magic fn
1692 # Let's try to find if the input line is a magic fn
1778 oinfo = None
1693 oinfo = None
1779 if hasattr(self,'magic_'+iFun):
1694 if hasattr(self,'magic_'+iFun):
1780 oinfo = self._ofind(iFun) # FIXME - _ofind is part of Magic
1695 oinfo = self._ofind(iFun) # FIXME - _ofind is part of Magic
1781 if oinfo['ismagic']:
1696 if oinfo['ismagic']:
1782 # Be careful not to call magics when a variable assignment is
1697 # Be careful not to call magics when a variable assignment is
1783 # being made (ls='hi', for example)
1698 # being made (ls='hi', for example)
1784 if self.rc.automagic and \
1699 if self.rc.automagic and \
1785 (len(theRest)==0 or theRest[0] not in '!=()<>,') and \
1700 (len(theRest)==0 or theRest[0] not in '!=()<>,') and \
1786 (self.rc.multi_line_specials or not continue_prompt):
1701 (self.rc.multi_line_specials or not continue_prompt):
1787 return self.handle_magic(line,continue_prompt,
1702 return self.handle_magic(line,continue_prompt,
1788 pre,iFun,theRest)
1703 pre,iFun,theRest)
1789 else:
1704 else:
1790 return self.handle_normal(line,continue_prompt)
1705 return self.handle_normal(line,continue_prompt)
1791
1706
1792 # If the rest of the line begins with an (in)equality, assginment or
1707 # If the rest of the line begins with an (in)equality, assginment or
1793 # function call, we should not call _ofind but simply execute it.
1708 # function call, we should not call _ofind but simply execute it.
1794 # This avoids spurious geattr() accesses on objects upon assignment.
1709 # This avoids spurious geattr() accesses on objects upon assignment.
1795 #
1710 #
1796 # It also allows users to assign to either alias or magic names true
1711 # It also allows users to assign to either alias or magic names true
1797 # python variables (the magic/alias systems always take second seat to
1712 # python variables (the magic/alias systems always take second seat to
1798 # true python code).
1713 # true python code).
1799 if theRest and theRest[0] in '!=()':
1714 if theRest and theRest[0] in '!=()':
1800 return self.handle_normal(line,continue_prompt)
1715 return self.handle_normal(line,continue_prompt)
1801
1716
1802 if oinfo is None:
1717 if oinfo is None:
1803 oinfo = self._ofind(iFun) # FIXME - _ofind is part of Magic
1718 oinfo = self._ofind(iFun) # FIXME - _ofind is part of Magic
1804
1719
1805 if not oinfo['found']:
1720 if not oinfo['found']:
1806 return self.handle_normal(line,continue_prompt)
1721 return self.handle_normal(line,continue_prompt)
1807 else:
1722 else:
1808 #print 'iFun <%s> rest <%s>' % (iFun,theRest) # dbg
1723 #print 'iFun <%s> rest <%s>' % (iFun,theRest) # dbg
1809 if oinfo['isalias']:
1724 if oinfo['isalias']:
1810 return self.handle_alias(line,continue_prompt,
1725 return self.handle_alias(line,continue_prompt,
1811 pre,iFun,theRest)
1726 pre,iFun,theRest)
1812
1727
1813 if self.rc.autocall and \
1728 if self.rc.autocall and \
1814 not self.re_exclude_auto.match(theRest) and \
1729 not self.re_exclude_auto.match(theRest) and \
1815 self.re_fun_name.match(iFun) and \
1730 self.re_fun_name.match(iFun) and \
1816 callable(oinfo['obj']) :
1731 callable(oinfo['obj']) :
1817 #print 'going auto' # dbg
1732 #print 'going auto' # dbg
1818 return self.handle_auto(line,continue_prompt,pre,iFun,theRest)
1733 return self.handle_auto(line,continue_prompt,pre,iFun,theRest)
1819 else:
1734 else:
1820 #print 'was callable?', callable(oinfo['obj']) # dbg
1735 #print 'was callable?', callable(oinfo['obj']) # dbg
1821 return self.handle_normal(line,continue_prompt)
1736 return self.handle_normal(line,continue_prompt)
1822
1737
1823 # If we get here, we have a normal Python line. Log and return.
1738 # If we get here, we have a normal Python line. Log and return.
1824 return self.handle_normal(line,continue_prompt)
1739 return self.handle_normal(line,continue_prompt)
1825
1740
1826 def _prefilter_dumb(self, line, continue_prompt):
1741 def _prefilter_dumb(self, line, continue_prompt):
1827 """simple prefilter function, for debugging"""
1742 """simple prefilter function, for debugging"""
1828 return self.handle_normal(line,continue_prompt)
1743 return self.handle_normal(line,continue_prompt)
1829
1744
1830 # Set the default prefilter() function (this can be user-overridden)
1745 # Set the default prefilter() function (this can be user-overridden)
1831 prefilter = _prefilter
1746 prefilter = _prefilter
1832
1747
1833 def handle_normal(self,line,continue_prompt=None,
1748 def handle_normal(self,line,continue_prompt=None,
1834 pre=None,iFun=None,theRest=None):
1749 pre=None,iFun=None,theRest=None):
1835 """Handle normal input lines. Use as a template for handlers."""
1750 """Handle normal input lines. Use as a template for handlers."""
1836
1751
1837 self.log(line,continue_prompt)
1752 self.log(line,continue_prompt)
1838 self.update_cache(line)
1753 self.update_cache(line)
1839 return line
1754 return line
1840
1755
1841 def handle_alias(self,line,continue_prompt=None,
1756 def handle_alias(self,line,continue_prompt=None,
1842 pre=None,iFun=None,theRest=None):
1757 pre=None,iFun=None,theRest=None):
1843 """Handle alias input lines. """
1758 """Handle alias input lines. """
1844
1759
1845 theRest = esc_quotes(theRest)
1760 theRest = esc_quotes(theRest)
1846 line_out = "%s%s.call_alias('%s','%s')" % (pre,self.name,iFun,theRest)
1761 line_out = "%s%s.call_alias('%s','%s')" % (pre,self.name,iFun,theRest)
1847 self.log(line_out,continue_prompt)
1762 self.log(line_out,continue_prompt)
1848 self.update_cache(line_out)
1763 self.update_cache(line_out)
1849 return line_out
1764 return line_out
1850
1765
1851 def handle_shell_escape(self, line, continue_prompt=None,
1766 def handle_shell_escape(self, line, continue_prompt=None,
1852 pre=None,iFun=None,theRest=None):
1767 pre=None,iFun=None,theRest=None):
1853 """Execute the line in a shell, empty return value"""
1768 """Execute the line in a shell, empty return value"""
1854
1769
1855 # Example of a special handler. Others follow a similar pattern.
1770 # Example of a special handler. Others follow a similar pattern.
1856 if continue_prompt: # multi-line statements
1771 if continue_prompt: # multi-line statements
1857 if iFun.startswith('!!'):
1772 if iFun.startswith('!!'):
1858 print 'SyntaxError: !! is not allowed in multiline statements'
1773 print 'SyntaxError: !! is not allowed in multiline statements'
1859 return pre
1774 return pre
1860 else:
1775 else:
1861 cmd = ("%s %s" % (iFun[1:],theRest)).replace('"','\\"')
1776 cmd = ("%s %s" % (iFun[1:],theRest)).replace('"','\\"')
1862 line_out = '%s%s.system("%s")' % (pre,self.name,cmd)
1777 line_out = '%s%s.system("%s")' % (pre,self.name,cmd)
1863 else: # single-line input
1778 else: # single-line input
1864 if line.startswith('!!'):
1779 if line.startswith('!!'):
1865 # rewrite iFun/theRest to properly hold the call to %sx and
1780 # rewrite iFun/theRest to properly hold the call to %sx and
1866 # the actual command to be executed, so handle_magic can work
1781 # the actual command to be executed, so handle_magic can work
1867 # correctly
1782 # correctly
1868 theRest = '%s %s' % (iFun[2:],theRest)
1783 theRest = '%s %s' % (iFun[2:],theRest)
1869 iFun = 'sx'
1784 iFun = 'sx'
1870 return self.handle_magic('%ssx %s' % (self.ESC_MAGIC,line[2:]),
1785 return self.handle_magic('%ssx %s' % (self.ESC_MAGIC,line[2:]),
1871 continue_prompt,pre,iFun,theRest)
1786 continue_prompt,pre,iFun,theRest)
1872 else:
1787 else:
1873 cmd = esc_quotes(line[1:])
1788 cmd = esc_quotes(line[1:])
1874 line_out = '%s.system("%s")' % (self.name,cmd)
1789 line_out = '%s.system("%s")' % (self.name,cmd)
1875 # update cache/log and return
1790 # update cache/log and return
1876 self.log(line_out,continue_prompt)
1791 self.log(line_out,continue_prompt)
1877 self.update_cache(line_out) # readline cache gets normal line
1792 self.update_cache(line_out) # readline cache gets normal line
1878 return line_out
1793 return line_out
1879
1794
1880 def handle_magic(self, line, continue_prompt=None,
1795 def handle_magic(self, line, continue_prompt=None,
1881 pre=None,iFun=None,theRest=None):
1796 pre=None,iFun=None,theRest=None):
1882 """Execute magic functions.
1797 """Execute magic functions.
1883
1798
1884 Also log them with a prepended # so the log is clean Python."""
1799 Also log them with a prepended # so the log is clean Python."""
1885
1800
1886 cmd = '%sipmagic("%s")' % (pre,esc_quotes('%s %s' % (iFun,theRest)))
1801 cmd = '%sipmagic("%s")' % (pre,esc_quotes('%s %s' % (iFun,theRest)))
1887 self.log(cmd,continue_prompt)
1802 self.log(cmd,continue_prompt)
1888 self.update_cache(line)
1803 self.update_cache(line)
1889 #print 'in handle_magic, cmd=<%s>' % cmd # dbg
1804 #print 'in handle_magic, cmd=<%s>' % cmd # dbg
1890 return cmd
1805 return cmd
1891
1806
1892 def handle_auto(self, line, continue_prompt=None,
1807 def handle_auto(self, line, continue_prompt=None,
1893 pre=None,iFun=None,theRest=None):
1808 pre=None,iFun=None,theRest=None):
1894 """Hande lines which can be auto-executed, quoting if requested."""
1809 """Hande lines which can be auto-executed, quoting if requested."""
1895
1810
1896 #print 'pre <%s> iFun <%s> rest <%s>' % (pre,iFun,theRest) # dbg
1811 #print 'pre <%s> iFun <%s> rest <%s>' % (pre,iFun,theRest) # dbg
1897
1812
1898 # This should only be active for single-line input!
1813 # This should only be active for single-line input!
1899 if continue_prompt:
1814 if continue_prompt:
1900 return line
1815 return line
1901
1816
1902 if pre == self.ESC_QUOTE:
1817 if pre == self.ESC_QUOTE:
1903 # Auto-quote splitting on whitespace
1818 # Auto-quote splitting on whitespace
1904 newcmd = '%s("%s")\n' % (iFun,'", "'.join(theRest.split()) )
1819 newcmd = '%s("%s")\n' % (iFun,'", "'.join(theRest.split()) )
1905 elif pre == self.ESC_QUOTE2:
1820 elif pre == self.ESC_QUOTE2:
1906 # Auto-quote whole string
1821 # Auto-quote whole string
1907 newcmd = '%s("%s")\n' % (iFun,theRest)
1822 newcmd = '%s("%s")\n' % (iFun,theRest)
1908 else:
1823 else:
1909 # Auto-paren
1824 # Auto-paren
1910 if theRest[0:1] in ('=','['):
1825 if theRest[0:1] in ('=','['):
1911 # Don't autocall in these cases. They can be either
1826 # Don't autocall in these cases. They can be either
1912 # rebindings of an existing callable's name, or item access
1827 # rebindings of an existing callable's name, or item access
1913 # for an object which is BOTH callable and implements
1828 # for an object which is BOTH callable and implements
1914 # __getitem__.
1829 # __getitem__.
1915 return '%s %s\n' % (iFun,theRest)
1830 return '%s %s\n' % (iFun,theRest)
1916 if theRest.endswith(';'):
1831 if theRest.endswith(';'):
1917 newcmd = '%s(%s);\n' % (iFun.rstrip(),theRest[:-1])
1832 newcmd = '%s(%s);\n' % (iFun.rstrip(),theRest[:-1])
1918 else:
1833 else:
1919 newcmd = '%s(%s)\n' % (iFun.rstrip(),theRest)
1834 newcmd = '%s(%s)\n' % (iFun.rstrip(),theRest)
1920
1835
1921 print >>Term.cout, self.outputcache.prompt1.auto_rewrite() + newcmd,
1836 print >>Term.cout, self.outputcache.prompt1.auto_rewrite() + newcmd,
1922 # log what is now valid Python, not the actual user input (without the
1837 # log what is now valid Python, not the actual user input (without the
1923 # final newline)
1838 # final newline)
1924 self.log(newcmd.strip(),continue_prompt)
1839 self.log(newcmd.strip(),continue_prompt)
1925 return newcmd
1840 return newcmd
1926
1841
1927 def handle_help(self, line, continue_prompt=None,
1842 def handle_help(self, line, continue_prompt=None,
1928 pre=None,iFun=None,theRest=None):
1843 pre=None,iFun=None,theRest=None):
1929 """Try to get some help for the object.
1844 """Try to get some help for the object.
1930
1845
1931 obj? or ?obj -> basic information.
1846 obj? or ?obj -> basic information.
1932 obj?? or ??obj -> more details.
1847 obj?? or ??obj -> more details.
1933 """
1848 """
1934
1849
1935 # We need to make sure that we don't process lines which would be
1850 # We need to make sure that we don't process lines which would be
1936 # otherwise valid python, such as "x=1 # what?"
1851 # otherwise valid python, such as "x=1 # what?"
1937 try:
1852 try:
1938 code.compile_command(line)
1853 code.compile_command(line)
1939 except SyntaxError:
1854 except SyntaxError:
1940 # We should only handle as help stuff which is NOT valid syntax
1855 # We should only handle as help stuff which is NOT valid syntax
1941 if line[0]==self.ESC_HELP:
1856 if line[0]==self.ESC_HELP:
1942 line = line[1:]
1857 line = line[1:]
1943 elif line[-1]==self.ESC_HELP:
1858 elif line[-1]==self.ESC_HELP:
1944 line = line[:-1]
1859 line = line[:-1]
1945 self.log('#?'+line)
1860 self.log('#?'+line)
1946 self.update_cache(line)
1861 self.update_cache(line)
1947 if line:
1862 if line:
1948 self.magic_pinfo(line)
1863 self.magic_pinfo(line)
1949 else:
1864 else:
1950 page(self.usage,screen_lines=self.rc.screen_length)
1865 page(self.usage,screen_lines=self.rc.screen_length)
1951 return '' # Empty string is needed here!
1866 return '' # Empty string is needed here!
1952 except:
1867 except:
1953 # Pass any other exceptions through to the normal handler
1868 # Pass any other exceptions through to the normal handler
1954 return self.handle_normal(line,continue_prompt)
1869 return self.handle_normal(line,continue_prompt)
1955 else:
1870 else:
1956 # If the code compiles ok, we should handle it normally
1871 # If the code compiles ok, we should handle it normally
1957 return self.handle_normal(line,continue_prompt)
1872 return self.handle_normal(line,continue_prompt)
1958
1873
1959 def handle_emacs(self,line,continue_prompt=None,
1874 def handle_emacs(self,line,continue_prompt=None,
1960 pre=None,iFun=None,theRest=None):
1875 pre=None,iFun=None,theRest=None):
1961 """Handle input lines marked by python-mode."""
1876 """Handle input lines marked by python-mode."""
1962
1877
1963 # Currently, nothing is done. Later more functionality can be added
1878 # Currently, nothing is done. Later more functionality can be added
1964 # here if needed.
1879 # here if needed.
1965
1880
1966 # The input cache shouldn't be updated
1881 # The input cache shouldn't be updated
1967
1882
1968 return line
1883 return line
1969
1884
1970 def write(self,data):
1885 def write(self,data):
1971 """Write a string to the default output"""
1886 """Write a string to the default output"""
1972 Term.cout.write(data)
1887 Term.cout.write(data)
1973
1888
1974 def write_err(self,data):
1889 def write_err(self,data):
1975 """Write a string to the default error output"""
1890 """Write a string to the default error output"""
1976 Term.cerr.write(data)
1891 Term.cerr.write(data)
1977
1892
1978 def safe_execfile(self,fname,*where,**kw):
1893 def safe_execfile(self,fname,*where,**kw):
1979 fname = os.path.expanduser(fname)
1894 fname = os.path.expanduser(fname)
1980
1895
1981 # find things also in current directory
1896 # find things also in current directory
1982 dname = os.path.dirname(fname)
1897 dname = os.path.dirname(fname)
1983 if not sys.path.count(dname):
1898 if not sys.path.count(dname):
1984 sys.path.append(dname)
1899 sys.path.append(dname)
1985
1900
1986 try:
1901 try:
1987 xfile = open(fname)
1902 xfile = open(fname)
1988 except:
1903 except:
1989 print >> Term.cerr, \
1904 print >> Term.cerr, \
1990 'Could not open file <%s> for safe execution.' % fname
1905 'Could not open file <%s> for safe execution.' % fname
1991 return None
1906 return None
1992
1907
1993 kw.setdefault('islog',0)
1908 kw.setdefault('islog',0)
1994 kw.setdefault('quiet',1)
1909 kw.setdefault('quiet',1)
1995 kw.setdefault('exit_ignore',0)
1910 kw.setdefault('exit_ignore',0)
1996 first = xfile.readline()
1911 first = xfile.readline()
1997 _LOGHEAD = str(self.LOGHEAD).split('\n',1)[0].strip()
1912 _LOGHEAD = str(self.LOGHEAD).split('\n',1)[0].strip()
1998 xfile.close()
1913 xfile.close()
1999 # line by line execution
1914 # line by line execution
2000 if first.startswith(_LOGHEAD) or kw['islog']:
1915 if first.startswith(_LOGHEAD) or kw['islog']:
2001 print 'Loading log file <%s> one line at a time...' % fname
1916 print 'Loading log file <%s> one line at a time...' % fname
2002 if kw['quiet']:
1917 if kw['quiet']:
2003 stdout_save = sys.stdout
1918 stdout_save = sys.stdout
2004 sys.stdout = StringIO.StringIO()
1919 sys.stdout = StringIO.StringIO()
2005 try:
1920 try:
2006 globs,locs = where[0:2]
1921 globs,locs = where[0:2]
2007 except:
1922 except:
2008 try:
1923 try:
2009 globs = locs = where[0]
1924 globs = locs = where[0]
2010 except:
1925 except:
2011 globs = locs = globals()
1926 globs = locs = globals()
2012 badblocks = []
1927 badblocks = []
2013
1928
2014 # we also need to identify indented blocks of code when replaying
1929 # we also need to identify indented blocks of code when replaying
2015 # logs and put them together before passing them to an exec
1930 # logs and put them together before passing them to an exec
2016 # statement. This takes a bit of regexp and look-ahead work in the
1931 # statement. This takes a bit of regexp and look-ahead work in the
2017 # file. It's easiest if we swallow the whole thing in memory
1932 # file. It's easiest if we swallow the whole thing in memory
2018 # first, and manually walk through the lines list moving the
1933 # first, and manually walk through the lines list moving the
2019 # counter ourselves.
1934 # counter ourselves.
2020 indent_re = re.compile('\s+\S')
1935 indent_re = re.compile('\s+\S')
2021 xfile = open(fname)
1936 xfile = open(fname)
2022 filelines = xfile.readlines()
1937 filelines = xfile.readlines()
2023 xfile.close()
1938 xfile.close()
2024 nlines = len(filelines)
1939 nlines = len(filelines)
2025 lnum = 0
1940 lnum = 0
2026 while lnum < nlines:
1941 while lnum < nlines:
2027 line = filelines[lnum]
1942 line = filelines[lnum]
2028 lnum += 1
1943 lnum += 1
2029 # don't re-insert logger status info into cache
1944 # don't re-insert logger status info into cache
2030 if line.startswith('#log#'):
1945 if line.startswith('#log#'):
2031 continue
1946 continue
2032 elif line.startswith('#%s'% self.ESC_MAGIC):
1947 elif line.startswith('#%s'% self.ESC_MAGIC):
2033 self.update_cache(line[1:])
1948 self.update_cache(line[1:])
2034 line = magic2python(line)
1949 line = magic2python(line)
2035 elif line.startswith('#!'):
1950 elif line.startswith('#!'):
2036 self.update_cache(line[1:])
1951 self.update_cache(line[1:])
2037 else:
1952 else:
2038 # build a block of code (maybe a single line) for execution
1953 # build a block of code (maybe a single line) for execution
2039 block = line
1954 block = line
2040 try:
1955 try:
2041 next = filelines[lnum] # lnum has already incremented
1956 next = filelines[lnum] # lnum has already incremented
2042 except:
1957 except:
2043 next = None
1958 next = None
2044 while next and indent_re.match(next):
1959 while next and indent_re.match(next):
2045 block += next
1960 block += next
2046 lnum += 1
1961 lnum += 1
2047 try:
1962 try:
2048 next = filelines[lnum]
1963 next = filelines[lnum]
2049 except:
1964 except:
2050 next = None
1965 next = None
2051 # now execute the block of one or more lines
1966 # now execute the block of one or more lines
2052 try:
1967 try:
2053 exec block in globs,locs
1968 exec block in globs,locs
2054 self.update_cache(block.rstrip())
1969 self.update_cache(block.rstrip())
2055 except SystemExit:
1970 except SystemExit:
2056 pass
1971 pass
2057 except:
1972 except:
2058 badblocks.append(block.rstrip())
1973 badblocks.append(block.rstrip())
2059 if kw['quiet']: # restore stdout
1974 if kw['quiet']: # restore stdout
2060 sys.stdout.close()
1975 sys.stdout.close()
2061 sys.stdout = stdout_save
1976 sys.stdout = stdout_save
2062 print 'Finished replaying log file <%s>' % fname
1977 print 'Finished replaying log file <%s>' % fname
2063 if badblocks:
1978 if badblocks:
2064 print >> sys.stderr, \
1979 print >> sys.stderr, \
2065 '\nThe following lines/blocks in file <%s> reported errors:' \
1980 '\nThe following lines/blocks in file <%s> reported errors:' \
2066 % fname
1981 % fname
2067 for badline in badblocks:
1982 for badline in badblocks:
2068 print >> sys.stderr, badline
1983 print >> sys.stderr, badline
2069 else: # regular file execution
1984 else: # regular file execution
2070 try:
1985 try:
2071 execfile(fname,*where)
1986 execfile(fname,*where)
2072 except SyntaxError:
1987 except SyntaxError:
2073 etype, evalue = sys.exc_info()[0:2]
1988 etype, evalue = sys.exc_info()[0:2]
2074 self.SyntaxTB(etype,evalue,[])
1989 self.SyntaxTB(etype,evalue,[])
2075 warn('Failure executing file: <%s>' % fname)
1990 warn('Failure executing file: <%s>' % fname)
2076 except SystemExit,status:
1991 except SystemExit,status:
2077 if not kw['exit_ignore']:
1992 if not kw['exit_ignore']:
2078 self.InteractiveTB()
1993 self.InteractiveTB()
2079 warn('Failure executing file: <%s>' % fname)
1994 warn('Failure executing file: <%s>' % fname)
2080 except:
1995 except:
2081 self.InteractiveTB()
1996 self.InteractiveTB()
2082 warn('Failure executing file: <%s>' % fname)
1997 warn('Failure executing file: <%s>' % fname)
2083
1998
2084 #************************* end of file <iplib.py> *****************************
1999 #************************* end of file <iplib.py> *****************************
@@ -1,736 +1,725 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 IPython -- An enhanced Interactive Python
3 IPython -- An enhanced Interactive Python
4
4
5 Requires Python 2.1 or better.
5 Requires Python 2.1 or better.
6
6
7 This file contains the main make_IPython() starter function.
7 This file contains the main make_IPython() starter function.
8
8
9 $Id: ipmaker.py 582 2005-05-13 21:20:00Z fperez $"""
9 $Id: ipmaker.py 638 2005-07-18 03:01:41Z fperez $"""
10
10
11 #*****************************************************************************
11 #*****************************************************************************
12 # Copyright (C) 2001-2004 Fernando Perez. <fperez@colorado.edu>
12 # Copyright (C) 2001-2004 Fernando Perez. <fperez@colorado.edu>
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 from IPython import Release
18 from IPython import Release
19 __author__ = '%s <%s>' % Release.authors['Fernando']
19 __author__ = '%s <%s>' % Release.authors['Fernando']
20 __license__ = Release.license
20 __license__ = Release.license
21 __version__ = Release.version
21 __version__ = Release.version
22
22
23 credits._Printer__data = """
23 credits._Printer__data = """
24 Python: %s
24 Python: %s
25
25
26 IPython: Fernando Perez, Janko Hauser, Nathan Gray, and many users.
26 IPython: Fernando Perez, Janko Hauser, Nathan Gray, and many users.
27 See http://ipython.scipy.org for more information.""" \
27 See http://ipython.scipy.org for more information.""" \
28 % credits._Printer__data
28 % credits._Printer__data
29
29
30 copyright._Printer__data += """
30 copyright._Printer__data += """
31
31
32 Copyright (c) 2001-2004 Fernando Perez, Janko Hauser, Nathan Gray.
32 Copyright (c) 2001-2004 Fernando Perez, Janko Hauser, Nathan Gray.
33 All Rights Reserved."""
33 All Rights Reserved."""
34
34
35 #****************************************************************************
35 #****************************************************************************
36 # Required modules
36 # Required modules
37
37
38 # From the standard library
38 # From the standard library
39 import __main__, __builtin__
39 import __main__, __builtin__
40 import os,sys,types,re
40 import os,sys,types,re
41 from pprint import pprint,pformat
41 from pprint import pprint,pformat
42
42
43 # Our own
43 # Our own
44 from IPython import DPyGetOpt
44 from IPython import DPyGetOpt
45 from IPython.Struct import Struct
45 from IPython.Struct import Struct
46 from IPython.OutputTrap import OutputTrap
46 from IPython.OutputTrap import OutputTrap
47 from IPython.ConfigLoader import ConfigLoader
47 from IPython.ConfigLoader import ConfigLoader
48 from IPython.iplib import InteractiveShell,qw_lol,import_fail_info
48 from IPython.iplib import InteractiveShell,qw_lol,import_fail_info
49 from IPython.usage import cmd_line_usage,interactive_usage
49 from IPython.usage import cmd_line_usage,interactive_usage
50 from IPython.Prompts import CachedOutput
50 from IPython.Prompts import CachedOutput
51 from IPython.genutils import *
51 from IPython.genutils import *
52
52
53 #-----------------------------------------------------------------------------
53 #-----------------------------------------------------------------------------
54 def make_IPython(argv=None,user_ns=None,debug=1,rc_override=None,
54 def make_IPython(argv=None,user_ns=None,debug=1,rc_override=None,
55 shell_class=InteractiveShell,embedded=False,**kw):
55 shell_class=InteractiveShell,embedded=False,**kw):
56 """This is a dump of IPython into a single function.
56 """This is a dump of IPython into a single function.
57
57
58 Later it will have to be broken up in a sensible manner.
58 Later it will have to be broken up in a sensible manner.
59
59
60 Arguments:
60 Arguments:
61
61
62 - argv: a list similar to sys.argv[1:]. It should NOT contain the desired
62 - argv: a list similar to sys.argv[1:]. It should NOT contain the desired
63 script name, b/c DPyGetOpt strips the first argument only for the real
63 script name, b/c DPyGetOpt strips the first argument only for the real
64 sys.argv.
64 sys.argv.
65
65
66 - user_ns: a dict to be used as the user's namespace."""
66 - user_ns: a dict to be used as the user's namespace."""
67
67
68 #----------------------------------------------------------------------
68 #----------------------------------------------------------------------
69 # Defaults and initialization
69 # Defaults and initialization
70
70
71 # For developer debugging, deactivates crash handler and uses pdb.
71 # For developer debugging, deactivates crash handler and uses pdb.
72 DEVDEBUG = False
72 DEVDEBUG = False
73
73
74 if argv is None:
74 if argv is None:
75 argv = sys.argv
75 argv = sys.argv
76
76
77 # __IP is the main global that lives throughout and represents the whole
77 # __IP is the main global that lives throughout and represents the whole
78 # application. If the user redefines it, all bets are off as to what
78 # application. If the user redefines it, all bets are off as to what
79 # happens.
79 # happens.
80
80
81 # __IP is the name of he global which the caller will have accessible as
81 # __IP is the name of he global which the caller will have accessible as
82 # __IP.name. We set its name via the first parameter passed to
82 # __IP.name. We set its name via the first parameter passed to
83 # InteractiveShell:
83 # InteractiveShell:
84
84
85 IP = shell_class('__IP',user_ns=user_ns,**kw)
85 IP = shell_class('__IP',user_ns=user_ns,**kw)
86
86
87 # Put 'help' in the user namespace
87 # Put 'help' in the user namespace
88 try:
89 from site import _Helper
88 from site import _Helper
90 except ImportError:
91 # Use the _Helper class from Python 2.2 for older Python versions
92 class _Helper:
93 def __repr__(self):
94 return "Type help() for interactive help, " \
95 "or help(object) for help about object."
96 def __call__(self, *args, **kwds):
97 import pydoc
98 return pydoc.help(*args, **kwds)
99 else:
100 IP.user_ns['help'] = _Helper()
89 IP.user_ns['help'] = _Helper()
101
90
102 if DEVDEBUG:
91 if DEVDEBUG:
103 # For developer debugging only (global flag)
92 # For developer debugging only (global flag)
104 from IPython import ultraTB
93 from IPython import ultraTB
105 sys.excepthook = ultraTB.VerboseTB(call_pdb=1)
94 sys.excepthook = ultraTB.VerboseTB(call_pdb=1)
106 else:
95 else:
107 # IPython itself shouldn't crash. This will produce a detailed
96 # IPython itself shouldn't crash. This will produce a detailed
108 # post-mortem if it does
97 # post-mortem if it does
109 from IPython import CrashHandler
98 from IPython import CrashHandler
110 sys.excepthook = CrashHandler.CrashHandler(IP)
99 sys.excepthook = CrashHandler.CrashHandler(IP)
111
100
112 IP.BANNER_PARTS = ['Python %s\n'
101 IP.BANNER_PARTS = ['Python %s\n'
113 'Type "copyright", "credits" or "license" '
102 'Type "copyright", "credits" or "license" '
114 'for more information.\n'
103 'for more information.\n'
115 % (sys.version.split('\n')[0],),
104 % (sys.version.split('\n')[0],),
116 "IPython %s -- An enhanced Interactive Python."
105 "IPython %s -- An enhanced Interactive Python."
117 % (__version__,),
106 % (__version__,),
118 """? -> Introduction to IPython's features.
107 """? -> Introduction to IPython's features.
119 %magic -> Information about IPython's 'magic' % functions.
108 %magic -> Information about IPython's 'magic' % functions.
120 help -> Python's own help system.
109 help -> Python's own help system.
121 object? -> Details about 'object'. ?object also works, ?? prints more.
110 object? -> Details about 'object'. ?object also works, ?? prints more.
122 """ ]
111 """ ]
123
112
124 IP.usage = interactive_usage
113 IP.usage = interactive_usage
125
114
126 # Platform-dependent suffix and directory names
115 # Platform-dependent suffix and directory names
127 if os.name == 'posix':
116 if os.name == 'posix':
128 rc_suffix = ''
117 rc_suffix = ''
129 ipdir_def = '.ipython'
118 ipdir_def = '.ipython'
130 else:
119 else:
131 rc_suffix = '.ini'
120 rc_suffix = '.ini'
132 ipdir_def = '_ipython'
121 ipdir_def = '_ipython'
133
122
134 # default directory for configuration
123 # default directory for configuration
135 ipythondir = os.path.abspath(os.environ.get('IPYTHONDIR',
124 ipythondir = os.path.abspath(os.environ.get('IPYTHONDIR',
136 os.path.join(IP.home_dir,ipdir_def)))
125 os.path.join(IP.home_dir,ipdir_def)))
137
126
138 # we need the directory where IPython itself is installed
127 # we need the directory where IPython itself is installed
139 import IPython
128 import IPython
140 IPython_dir = os.path.dirname(IPython.__file__)
129 IPython_dir = os.path.dirname(IPython.__file__)
141 del IPython
130 del IPython
142
131
143 #-------------------------------------------------------------------------
132 #-------------------------------------------------------------------------
144 # Command line handling
133 # Command line handling
145
134
146 # Valid command line options (uses DPyGetOpt syntax, like Perl's
135 # Valid command line options (uses DPyGetOpt syntax, like Perl's
147 # GetOpt::Long)
136 # GetOpt::Long)
148
137
149 # Any key not listed here gets deleted even if in the file (like session
138 # Any key not listed here gets deleted even if in the file (like session
150 # or profile). That's deliberate, to maintain the rc namespace clean.
139 # or profile). That's deliberate, to maintain the rc namespace clean.
151
140
152 # Each set of options appears twice: under _conv only the names are
141 # Each set of options appears twice: under _conv only the names are
153 # listed, indicating which type they must be converted to when reading the
142 # listed, indicating which type they must be converted to when reading the
154 # ipythonrc file. And under DPyGetOpt they are listed with the regular
143 # ipythonrc file. And under DPyGetOpt they are listed with the regular
155 # DPyGetOpt syntax (=s,=i,:f,etc).
144 # DPyGetOpt syntax (=s,=i,:f,etc).
156
145
157 # Make sure there's a space before each end of line (they get auto-joined!)
146 # Make sure there's a space before each end of line (they get auto-joined!)
158 cmdline_opts = ('autocall! autoindent! automagic! banner! cache_size|cs=i '
147 cmdline_opts = ('autocall! autoindent! automagic! banner! cache_size|cs=i '
159 'c=s classic|cl color_info! colors=s confirm_exit! '
148 'c=s classic|cl color_info! colors=s confirm_exit! '
160 'debug! deep_reload! editor=s log|l messages! nosep pdb! '
149 'debug! deep_reload! editor=s log|l messages! nosep pdb! '
161 'pprint! prompt_in1|pi1=s prompt_in2|pi2=s prompt_out|po=s '
150 'pprint! prompt_in1|pi1=s prompt_in2|pi2=s prompt_out|po=s '
162 'quick screen_length|sl=i prompts_pad_left=i '
151 'quick screen_length|sl=i prompts_pad_left=i '
163 'logfile|lf=s logplay|lp=s profile|p=s '
152 'logfile|lf=s logplay|lp=s profile|p=s '
164 'readline! readline_merge_completions! '
153 'readline! readline_merge_completions! '
165 'readline_omit__names! '
154 'readline_omit__names! '
166 'rcfile=s separate_in|si=s separate_out|so=s '
155 'rcfile=s separate_in|si=s separate_out|so=s '
167 'separate_out2|so2=s xmode=s '
156 'separate_out2|so2=s xmode=s '
168 'magic_docstrings system_verbose! '
157 'magic_docstrings system_verbose! '
169 'multi_line_specials!')
158 'multi_line_specials!')
170
159
171 # Options that can *only* appear at the cmd line (not in rcfiles).
160 # Options that can *only* appear at the cmd line (not in rcfiles).
172
161
173 # The "ignore" option is a kludge so that Emacs buffers don't crash, since
162 # The "ignore" option is a kludge so that Emacs buffers don't crash, since
174 # the 'C-c !' command in emacs automatically appends a -i option at the end.
163 # the 'C-c !' command in emacs automatically appends a -i option at the end.
175 cmdline_only = ('help ignore|i ipythondir=s Version upgrade '
164 cmdline_only = ('help ignore|i ipythondir=s Version upgrade '
176 'gthread! qthread! wthread! pylab! tk!')
165 'gthread! qthread! wthread! pylab! tk!')
177
166
178 # Build the actual name list to be used by DPyGetOpt
167 # Build the actual name list to be used by DPyGetOpt
179 opts_names = qw(cmdline_opts) + qw(cmdline_only)
168 opts_names = qw(cmdline_opts) + qw(cmdline_only)
180
169
181 # Set sensible command line defaults.
170 # Set sensible command line defaults.
182 # This should have everything from cmdline_opts and cmdline_only
171 # This should have everything from cmdline_opts and cmdline_only
183 opts_def = Struct(autocall = 1,
172 opts_def = Struct(autocall = 1,
184 autoindent=0,
173 autoindent=0,
185 automagic = 1,
174 automagic = 1,
186 banner = 1,
175 banner = 1,
187 cache_size = 1000,
176 cache_size = 1000,
188 c = '',
177 c = '',
189 classic = 0,
178 classic = 0,
190 colors = 'NoColor',
179 colors = 'NoColor',
191 color_info = 0,
180 color_info = 0,
192 confirm_exit = 1,
181 confirm_exit = 1,
193 debug = 0,
182 debug = 0,
194 deep_reload = 0,
183 deep_reload = 0,
195 editor = '0',
184 editor = '0',
196 help = 0,
185 help = 0,
197 ignore = 0,
186 ignore = 0,
198 ipythondir = ipythondir,
187 ipythondir = ipythondir,
199 log = 0,
188 log = 0,
200 logfile = '',
189 logfile = '',
201 logplay = '',
190 logplay = '',
202 multi_line_specials = 1,
191 multi_line_specials = 1,
203 messages = 1,
192 messages = 1,
204 nosep = 0,
193 nosep = 0,
205 pdb = 0,
194 pdb = 0,
206 pprint = 0,
195 pprint = 0,
207 profile = '',
196 profile = '',
208 prompt_in1 = 'In [\\#]:',
197 prompt_in1 = 'In [\\#]:',
209 prompt_in2 = ' .\\D.:',
198 prompt_in2 = ' .\\D.:',
210 prompt_out = 'Out[\\#]:',
199 prompt_out = 'Out[\\#]:',
211 prompts_pad_left = 1,
200 prompts_pad_left = 1,
212 quick = 0,
201 quick = 0,
213 readline = 1,
202 readline = 1,
214 readline_merge_completions = 1,
203 readline_merge_completions = 1,
215 readline_omit__names = 0,
204 readline_omit__names = 0,
216 rcfile = 'ipythonrc' + rc_suffix,
205 rcfile = 'ipythonrc' + rc_suffix,
217 screen_length = 0,
206 screen_length = 0,
218 separate_in = '\n',
207 separate_in = '\n',
219 separate_out = '\n',
208 separate_out = '\n',
220 separate_out2 = '',
209 separate_out2 = '',
221 system_verbose = 0,
210 system_verbose = 0,
222 gthread = 0,
211 gthread = 0,
223 qthread = 0,
212 qthread = 0,
224 wthread = 0,
213 wthread = 0,
225 pylab = 0,
214 pylab = 0,
226 tk = 0,
215 tk = 0,
227 upgrade = 0,
216 upgrade = 0,
228 Version = 0,
217 Version = 0,
229 xmode = 'Verbose',
218 xmode = 'Verbose',
230 magic_docstrings = 0, # undocumented, for doc generation
219 magic_docstrings = 0, # undocumented, for doc generation
231 )
220 )
232
221
233 # Things that will *only* appear in rcfiles (not at the command line).
222 # Things that will *only* appear in rcfiles (not at the command line).
234 # Make sure there's a space before each end of line (they get auto-joined!)
223 # Make sure there's a space before each end of line (they get auto-joined!)
235 rcfile_opts = { qwflat: 'include import_mod import_all execfile ',
224 rcfile_opts = { qwflat: 'include import_mod import_all execfile ',
236 qw_lol: 'import_some ',
225 qw_lol: 'import_some ',
237 # for things with embedded whitespace:
226 # for things with embedded whitespace:
238 list_strings:'execute alias readline_parse_and_bind ',
227 list_strings:'execute alias readline_parse_and_bind ',
239 # Regular strings need no conversion:
228 # Regular strings need no conversion:
240 None:'readline_remove_delims ',
229 None:'readline_remove_delims ',
241 }
230 }
242 # Default values for these
231 # Default values for these
243 rc_def = Struct(include = [],
232 rc_def = Struct(include = [],
244 import_mod = [],
233 import_mod = [],
245 import_all = [],
234 import_all = [],
246 import_some = [[]],
235 import_some = [[]],
247 execute = [],
236 execute = [],
248 execfile = [],
237 execfile = [],
249 alias = [],
238 alias = [],
250 readline_parse_and_bind = [],
239 readline_parse_and_bind = [],
251 readline_remove_delims = '',
240 readline_remove_delims = '',
252 )
241 )
253
242
254 # Build the type conversion dictionary from the above tables:
243 # Build the type conversion dictionary from the above tables:
255 typeconv = rcfile_opts.copy()
244 typeconv = rcfile_opts.copy()
256 typeconv.update(optstr2types(cmdline_opts))
245 typeconv.update(optstr2types(cmdline_opts))
257
246
258 # FIXME: the None key appears in both, put that back together by hand. Ugly!
247 # FIXME: the None key appears in both, put that back together by hand. Ugly!
259 typeconv[None] += ' ' + rcfile_opts[None]
248 typeconv[None] += ' ' + rcfile_opts[None]
260
249
261 # Remove quotes at ends of all strings (used to protect spaces)
250 # Remove quotes at ends of all strings (used to protect spaces)
262 typeconv[unquote_ends] = typeconv[None]
251 typeconv[unquote_ends] = typeconv[None]
263 del typeconv[None]
252 del typeconv[None]
264
253
265 # Build the list we'll use to make all config decisions with defaults:
254 # Build the list we'll use to make all config decisions with defaults:
266 opts_all = opts_def.copy()
255 opts_all = opts_def.copy()
267 opts_all.update(rc_def)
256 opts_all.update(rc_def)
268
257
269 # Build conflict resolver for recursive loading of config files:
258 # Build conflict resolver for recursive loading of config files:
270 # - preserve means the outermost file maintains the value, it is not
259 # - preserve means the outermost file maintains the value, it is not
271 # overwritten if an included file has the same key.
260 # overwritten if an included file has the same key.
272 # - add_flip applies + to the two values, so it better make sense to add
261 # - add_flip applies + to the two values, so it better make sense to add
273 # those types of keys. But it flips them first so that things loaded
262 # those types of keys. But it flips them first so that things loaded
274 # deeper in the inclusion chain have lower precedence.
263 # deeper in the inclusion chain have lower precedence.
275 conflict = {'preserve': ' '.join([ typeconv[int],
264 conflict = {'preserve': ' '.join([ typeconv[int],
276 typeconv[unquote_ends] ]),
265 typeconv[unquote_ends] ]),
277 'add_flip': ' '.join([ typeconv[qwflat],
266 'add_flip': ' '.join([ typeconv[qwflat],
278 typeconv[qw_lol],
267 typeconv[qw_lol],
279 typeconv[list_strings] ])
268 typeconv[list_strings] ])
280 }
269 }
281
270
282 # Now actually process the command line
271 # Now actually process the command line
283 getopt = DPyGetOpt.DPyGetOpt()
272 getopt = DPyGetOpt.DPyGetOpt()
284 getopt.setIgnoreCase(0)
273 getopt.setIgnoreCase(0)
285
274
286 getopt.parseConfiguration(opts_names)
275 getopt.parseConfiguration(opts_names)
287
276
288 try:
277 try:
289 getopt.processArguments(argv)
278 getopt.processArguments(argv)
290 except:
279 except:
291 print cmd_line_usage
280 print cmd_line_usage
292 warn('\nError in Arguments: ' + `sys.exc_value`)
281 warn('\nError in Arguments: ' + `sys.exc_value`)
293 sys.exit()
282 sys.exit()
294
283
295 # convert the options dict to a struct for much lighter syntax later
284 # convert the options dict to a struct for much lighter syntax later
296 opts = Struct(getopt.optionValues)
285 opts = Struct(getopt.optionValues)
297 args = getopt.freeValues
286 args = getopt.freeValues
298
287
299 # this is the struct (which has default values at this point) with which
288 # this is the struct (which has default values at this point) with which
300 # we make all decisions:
289 # we make all decisions:
301 opts_all.update(opts)
290 opts_all.update(opts)
302
291
303 # Options that force an immediate exit
292 # Options that force an immediate exit
304 if opts_all.help:
293 if opts_all.help:
305 page(cmd_line_usage)
294 page(cmd_line_usage)
306 sys.exit()
295 sys.exit()
307
296
308 if opts_all.Version:
297 if opts_all.Version:
309 print __version__
298 print __version__
310 sys.exit()
299 sys.exit()
311
300
312 if opts_all.magic_docstrings:
301 if opts_all.magic_docstrings:
313 IP.magic_magic('-latex')
302 IP.magic_magic('-latex')
314 sys.exit()
303 sys.exit()
315
304
316 # Create user config directory if it doesn't exist. This must be done
305 # Create user config directory if it doesn't exist. This must be done
317 # *after* getting the cmd line options.
306 # *after* getting the cmd line options.
318 if not os.path.isdir(opts_all.ipythondir):
307 if not os.path.isdir(opts_all.ipythondir):
319 IP.user_setup(opts_all.ipythondir,rc_suffix,'install')
308 IP.user_setup(opts_all.ipythondir,rc_suffix,'install')
320
309
321 # upgrade user config files while preserving a copy of the originals
310 # upgrade user config files while preserving a copy of the originals
322 if opts_all.upgrade:
311 if opts_all.upgrade:
323 IP.user_setup(opts_all.ipythondir,rc_suffix,'upgrade')
312 IP.user_setup(opts_all.ipythondir,rc_suffix,'upgrade')
324
313
325 # check mutually exclusive options in the *original* command line
314 # check mutually exclusive options in the *original* command line
326 mutex_opts(opts,[qw('log logfile'),qw('rcfile profile'),
315 mutex_opts(opts,[qw('log logfile'),qw('rcfile profile'),
327 qw('classic profile'),qw('classic rcfile')])
316 qw('classic profile'),qw('classic rcfile')])
328
317
329 # default logfilename used when -log is called.
318 # default logfilename used when -log is called.
330 IP.LOGDEF = 'ipython.log'
319 IP.LOGDEF = 'ipython.log'
331
320
332 #---------------------------------------------------------------------------
321 #---------------------------------------------------------------------------
333 # Log replay
322 # Log replay
334
323
335 # if -logplay, we need to 'become' the other session. That basically means
324 # if -logplay, we need to 'become' the other session. That basically means
336 # replacing the current command line environment with that of the old
325 # replacing the current command line environment with that of the old
337 # session and moving on.
326 # session and moving on.
338
327
339 # this is needed so that later we know we're in session reload mode, as
328 # this is needed so that later we know we're in session reload mode, as
340 # opts_all will get overwritten:
329 # opts_all will get overwritten:
341 load_logplay = 0
330 load_logplay = 0
342
331
343 if opts_all.logplay:
332 if opts_all.logplay:
344 load_logplay = opts_all.logplay
333 load_logplay = opts_all.logplay
345 opts_debug_save = opts_all.debug
334 opts_debug_save = opts_all.debug
346 try:
335 try:
347 logplay = open(opts_all.logplay)
336 logplay = open(opts_all.logplay)
348 except IOError:
337 except IOError:
349 if opts_all.debug: IP.InteractiveTB()
338 if opts_all.debug: IP.InteractiveTB()
350 warn('Could not open logplay file '+`opts_all.logplay`)
339 warn('Could not open logplay file '+`opts_all.logplay`)
351 # restore state as if nothing had happened and move on, but make
340 # restore state as if nothing had happened and move on, but make
352 # sure that later we don't try to actually load the session file
341 # sure that later we don't try to actually load the session file
353 logplay = None
342 logplay = None
354 load_logplay = 0
343 load_logplay = 0
355 del opts_all.logplay
344 del opts_all.logplay
356 else:
345 else:
357 try:
346 try:
358 logplay.readline()
347 logplay.readline()
359 logplay.readline();
348 logplay.readline();
360 # this reloads that session's command line
349 # this reloads that session's command line
361 cmd = logplay.readline()[6:]
350 cmd = logplay.readline()[6:]
362 exec cmd
351 exec cmd
363 # restore the true debug flag given so that the process of
352 # restore the true debug flag given so that the process of
364 # session loading itself can be monitored.
353 # session loading itself can be monitored.
365 opts.debug = opts_debug_save
354 opts.debug = opts_debug_save
366 # save the logplay flag so later we don't overwrite the log
355 # save the logplay flag so later we don't overwrite the log
367 opts.logplay = load_logplay
356 opts.logplay = load_logplay
368 # now we must update our own structure with defaults
357 # now we must update our own structure with defaults
369 opts_all.update(opts)
358 opts_all.update(opts)
370 # now load args
359 # now load args
371 cmd = logplay.readline()[6:]
360 cmd = logplay.readline()[6:]
372 exec cmd
361 exec cmd
373 logplay.close()
362 logplay.close()
374 except:
363 except:
375 logplay.close()
364 logplay.close()
376 if opts_all.debug: IP.InteractiveTB()
365 if opts_all.debug: IP.InteractiveTB()
377 warn("Logplay file lacking full configuration information.\n"
366 warn("Logplay file lacking full configuration information.\n"
378 "I'll try to read it, but some things may not work.")
367 "I'll try to read it, but some things may not work.")
379
368
380 #-------------------------------------------------------------------------
369 #-------------------------------------------------------------------------
381 # set up output traps: catch all output from files, being run, modules
370 # set up output traps: catch all output from files, being run, modules
382 # loaded, etc. Then give it to the user in a clean form at the end.
371 # loaded, etc. Then give it to the user in a clean form at the end.
383
372
384 msg_out = 'Output messages. '
373 msg_out = 'Output messages. '
385 msg_err = 'Error messages. '
374 msg_err = 'Error messages. '
386 msg_sep = '\n'
375 msg_sep = '\n'
387 msg = Struct(config = OutputTrap('Configuration Loader',msg_out,
376 msg = Struct(config = OutputTrap('Configuration Loader',msg_out,
388 msg_err,msg_sep,debug,
377 msg_err,msg_sep,debug,
389 quiet_out=1),
378 quiet_out=1),
390 user_exec = OutputTrap('User File Execution',msg_out,
379 user_exec = OutputTrap('User File Execution',msg_out,
391 msg_err,msg_sep,debug),
380 msg_err,msg_sep,debug),
392 logplay = OutputTrap('Log Loader',msg_out,
381 logplay = OutputTrap('Log Loader',msg_out,
393 msg_err,msg_sep,debug),
382 msg_err,msg_sep,debug),
394 summary = ''
383 summary = ''
395 )
384 )
396
385
397 #-------------------------------------------------------------------------
386 #-------------------------------------------------------------------------
398 # Process user ipythonrc-type configuration files
387 # Process user ipythonrc-type configuration files
399
388
400 # turn on output trapping and log to msg.config
389 # turn on output trapping and log to msg.config
401 # remember that with debug on, trapping is actually disabled
390 # remember that with debug on, trapping is actually disabled
402 msg.config.trap_all()
391 msg.config.trap_all()
403
392
404 # look for rcfile in current or default directory
393 # look for rcfile in current or default directory
405 try:
394 try:
406 opts_all.rcfile = filefind(opts_all.rcfile,opts_all.ipythondir)
395 opts_all.rcfile = filefind(opts_all.rcfile,opts_all.ipythondir)
407 except IOError:
396 except IOError:
408 if opts_all.debug: IP.InteractiveTB()
397 if opts_all.debug: IP.InteractiveTB()
409 warn('Configuration file %s not found. Ignoring request.'
398 warn('Configuration file %s not found. Ignoring request.'
410 % (opts_all.rcfile) )
399 % (opts_all.rcfile) )
411
400
412 # 'profiles' are a shorthand notation for config filenames
401 # 'profiles' are a shorthand notation for config filenames
413 if opts_all.profile:
402 if opts_all.profile:
414 try:
403 try:
415 opts_all.rcfile = filefind('ipythonrc-' + opts_all.profile
404 opts_all.rcfile = filefind('ipythonrc-' + opts_all.profile
416 + rc_suffix,
405 + rc_suffix,
417 opts_all.ipythondir)
406 opts_all.ipythondir)
418 except IOError:
407 except IOError:
419 if opts_all.debug: IP.InteractiveTB()
408 if opts_all.debug: IP.InteractiveTB()
420 opts.profile = '' # remove profile from options if invalid
409 opts.profile = '' # remove profile from options if invalid
421 warn('Profile configuration file %s not found. Ignoring request.'
410 warn('Profile configuration file %s not found. Ignoring request.'
422 % (opts_all.profile) )
411 % (opts_all.profile) )
423
412
424 # load the config file
413 # load the config file
425 rcfiledata = None
414 rcfiledata = None
426 if opts_all.quick:
415 if opts_all.quick:
427 print 'Launching IPython in quick mode. No config file read.'
416 print 'Launching IPython in quick mode. No config file read.'
428 elif opts_all.classic:
417 elif opts_all.classic:
429 print 'Launching IPython in classic mode. No config file read.'
418 print 'Launching IPython in classic mode. No config file read.'
430 elif opts_all.rcfile:
419 elif opts_all.rcfile:
431 try:
420 try:
432 cfg_loader = ConfigLoader(conflict)
421 cfg_loader = ConfigLoader(conflict)
433 rcfiledata = cfg_loader.load(opts_all.rcfile,typeconv,
422 rcfiledata = cfg_loader.load(opts_all.rcfile,typeconv,
434 'include',opts_all.ipythondir,
423 'include',opts_all.ipythondir,
435 purge = 1,
424 purge = 1,
436 unique = conflict['preserve'])
425 unique = conflict['preserve'])
437 except:
426 except:
438 IP.InteractiveTB()
427 IP.InteractiveTB()
439 warn('Problems loading configuration file '+
428 warn('Problems loading configuration file '+
440 `opts_all.rcfile`+
429 `opts_all.rcfile`+
441 '\nStarting with default -bare bones- configuration.')
430 '\nStarting with default -bare bones- configuration.')
442 else:
431 else:
443 warn('No valid configuration file found in either currrent directory\n'+
432 warn('No valid configuration file found in either currrent directory\n'+
444 'or in the IPython config. directory: '+`opts_all.ipythondir`+
433 'or in the IPython config. directory: '+`opts_all.ipythondir`+
445 '\nProceeding with internal defaults.')
434 '\nProceeding with internal defaults.')
446
435
447 #------------------------------------------------------------------------
436 #------------------------------------------------------------------------
448 # Set exception handlers in mode requested by user.
437 # Set exception handlers in mode requested by user.
449 otrap = OutputTrap(trap_out=1) # trap messages from magic_xmode
438 otrap = OutputTrap(trap_out=1) # trap messages from magic_xmode
450 IP.magic_xmode(opts_all.xmode)
439 IP.magic_xmode(opts_all.xmode)
451 otrap.release_out()
440 otrap.release_out()
452
441
453 #------------------------------------------------------------------------
442 #------------------------------------------------------------------------
454 # Execute user config
443 # Execute user config
455
444
456 # first, create a valid config structure with the right precedence order:
445 # first, create a valid config structure with the right precedence order:
457 # defaults < rcfile < command line
446 # defaults < rcfile < command line
458 IP.rc = rc_def.copy()
447 IP.rc = rc_def.copy()
459 IP.rc.update(opts_def)
448 IP.rc.update(opts_def)
460 if rcfiledata:
449 if rcfiledata:
461 # now we can update
450 # now we can update
462 IP.rc.update(rcfiledata)
451 IP.rc.update(rcfiledata)
463 IP.rc.update(opts)
452 IP.rc.update(opts)
464 IP.rc.update(rc_override)
453 IP.rc.update(rc_override)
465
454
466 # Store the original cmd line for reference:
455 # Store the original cmd line for reference:
467 IP.rc.opts = opts
456 IP.rc.opts = opts
468 IP.rc.args = args
457 IP.rc.args = args
469
458
470 # create a *runtime* Struct like rc for holding parameters which may be
459 # create a *runtime* Struct like rc for holding parameters which may be
471 # created and/or modified by runtime user extensions.
460 # created and/or modified by runtime user extensions.
472 IP.runtime_rc = Struct()
461 IP.runtime_rc = Struct()
473
462
474 # from this point on, all config should be handled through IP.rc,
463 # from this point on, all config should be handled through IP.rc,
475 # opts* shouldn't be used anymore.
464 # opts* shouldn't be used anymore.
476
465
477 # add personal .ipython dir to sys.path so that users can put things in
466 # add personal .ipython dir to sys.path so that users can put things in
478 # there for customization
467 # there for customization
479 sys.path.append(IP.rc.ipythondir)
468 sys.path.append(IP.rc.ipythondir)
480 sys.path.insert(0, '') # add . to sys.path. Fix from Prabhu Ramachandran
469 sys.path.insert(0, '') # add . to sys.path. Fix from Prabhu Ramachandran
481
470
482 # update IP.rc with some special things that need manual
471 # update IP.rc with some special things that need manual
483 # tweaks. Basically options which affect other options. I guess this
472 # tweaks. Basically options which affect other options. I guess this
484 # should just be written so that options are fully orthogonal and we
473 # should just be written so that options are fully orthogonal and we
485 # wouldn't worry about this stuff!
474 # wouldn't worry about this stuff!
486
475
487 if IP.rc.classic:
476 if IP.rc.classic:
488 IP.rc.quick = 1
477 IP.rc.quick = 1
489 IP.rc.cache_size = 0
478 IP.rc.cache_size = 0
490 IP.rc.pprint = 0
479 IP.rc.pprint = 0
491 IP.rc.prompt_in1 = '>>> '
480 IP.rc.prompt_in1 = '>>> '
492 IP.rc.prompt_in2 = '... '
481 IP.rc.prompt_in2 = '... '
493 IP.rc.prompt_out = ''
482 IP.rc.prompt_out = ''
494 IP.rc.separate_in = IP.rc.separate_out = IP.rc.separate_out2 = '0'
483 IP.rc.separate_in = IP.rc.separate_out = IP.rc.separate_out2 = '0'
495 IP.rc.colors = 'NoColor'
484 IP.rc.colors = 'NoColor'
496 IP.rc.xmode = 'Plain'
485 IP.rc.xmode = 'Plain'
497
486
498 # configure readline
487 # configure readline
499 # Define the history file for saving commands in between sessions
488 # Define the history file for saving commands in between sessions
500 if IP.rc.profile:
489 if IP.rc.profile:
501 histfname = 'history-%s' % IP.rc.profile
490 histfname = 'history-%s' % IP.rc.profile
502 else:
491 else:
503 histfname = 'history'
492 histfname = 'history'
504 IP.histfile = os.path.join(opts_all.ipythondir,histfname)
493 IP.histfile = os.path.join(opts_all.ipythondir,histfname)
505 # Load readline proper
494 # Load readline proper
506 if IP.rc.readline:
495 if IP.rc.readline:
507 IP.init_readline()
496 IP.init_readline()
508
497
509 # update exception handlers with rc file status
498 # update exception handlers with rc file status
510 otrap.trap_out() # I don't want these messages ever.
499 otrap.trap_out() # I don't want these messages ever.
511 IP.magic_xmode(IP.rc.xmode)
500 IP.magic_xmode(IP.rc.xmode)
512 otrap.release_out()
501 otrap.release_out()
513
502
514 # activate logging if requested and not reloading a log
503 # activate logging if requested and not reloading a log
515 if IP.rc.logplay:
504 if IP.rc.logplay:
516 IP.magic_logstart(IP.rc.logplay + ' append')
505 IP.magic_logstart(IP.rc.logplay + ' append')
517 elif IP.rc.logfile:
506 elif IP.rc.logfile:
518 IP.magic_logstart(IP.rc.logfile)
507 IP.magic_logstart(IP.rc.logfile)
519 elif IP.rc.log:
508 elif IP.rc.log:
520 IP.magic_logstart()
509 IP.magic_logstart()
521
510
522 # find user editor so that it we don't have to look it up constantly
511 # find user editor so that it we don't have to look it up constantly
523 if IP.rc.editor.strip()=='0':
512 if IP.rc.editor.strip()=='0':
524 try:
513 try:
525 ed = os.environ['EDITOR']
514 ed = os.environ['EDITOR']
526 except KeyError:
515 except KeyError:
527 if os.name == 'posix':
516 if os.name == 'posix':
528 ed = 'vi' # the only one guaranteed to be there!
517 ed = 'vi' # the only one guaranteed to be there!
529 else:
518 else:
530 ed = 'notepad' # same in Windows!
519 ed = 'notepad' # same in Windows!
531 IP.rc.editor = ed
520 IP.rc.editor = ed
532
521
533 # Recursive reload
522 # Recursive reload
534 try:
523 try:
535 from IPython import deep_reload
524 from IPython import deep_reload
536 if IP.rc.deep_reload:
525 if IP.rc.deep_reload:
537 __builtin__.reload = deep_reload.reload
526 __builtin__.reload = deep_reload.reload
538 else:
527 else:
539 __builtin__.dreload = deep_reload.reload
528 __builtin__.dreload = deep_reload.reload
540 del deep_reload
529 del deep_reload
541 except ImportError:
530 except ImportError:
542 pass
531 pass
543
532
544 # Save the current state of our namespace so that the interactive shell
533 # Save the current state of our namespace so that the interactive shell
545 # can later know which variables have been created by us from config files
534 # can later know which variables have been created by us from config files
546 # and loading. This way, loading a file (in any way) is treated just like
535 # and loading. This way, loading a file (in any way) is treated just like
547 # defining things on the command line, and %who works as expected.
536 # defining things on the command line, and %who works as expected.
548
537
549 # DON'T do anything that affects the namespace beyond this point!
538 # DON'T do anything that affects the namespace beyond this point!
550 IP.internal_ns = __main__.__dict__.copy()
539 IP.internal_ns = __main__.__dict__.copy()
551
540
552 #IP.internal_ns.update(locals()) # so our stuff doesn't show up in %who
541 #IP.internal_ns.update(locals()) # so our stuff doesn't show up in %who
553
542
554 # Now run through the different sections of the users's config
543 # Now run through the different sections of the users's config
555 if IP.rc.debug:
544 if IP.rc.debug:
556 print 'Trying to execute the following configuration structure:'
545 print 'Trying to execute the following configuration structure:'
557 print '(Things listed first are deeper in the inclusion tree and get'
546 print '(Things listed first are deeper in the inclusion tree and get'
558 print 'loaded first).\n'
547 print 'loaded first).\n'
559 pprint(IP.rc.__dict__)
548 pprint(IP.rc.__dict__)
560
549
561 for mod in IP.rc.import_mod:
550 for mod in IP.rc.import_mod:
562 try:
551 try:
563 exec 'import '+mod in IP.user_ns
552 exec 'import '+mod in IP.user_ns
564 except :
553 except :
565 IP.InteractiveTB()
554 IP.InteractiveTB()
566 import_fail_info(mod)
555 import_fail_info(mod)
567
556
568 for mod_fn in IP.rc.import_some:
557 for mod_fn in IP.rc.import_some:
569 if mod_fn == []: break
558 if mod_fn == []: break
570 mod,fn = mod_fn[0],','.join(mod_fn[1:])
559 mod,fn = mod_fn[0],','.join(mod_fn[1:])
571 try:
560 try:
572 exec 'from '+mod+' import '+fn in IP.user_ns
561 exec 'from '+mod+' import '+fn in IP.user_ns
573 except :
562 except :
574 IP.InteractiveTB()
563 IP.InteractiveTB()
575 import_fail_info(mod,fn)
564 import_fail_info(mod,fn)
576
565
577 for mod in IP.rc.import_all:
566 for mod in IP.rc.import_all:
578 try:
567 try:
579 exec 'from '+mod+' import *' in IP.user_ns
568 exec 'from '+mod+' import *' in IP.user_ns
580 except :
569 except :
581 IP.InteractiveTB()
570 IP.InteractiveTB()
582 import_fail_info(mod)
571 import_fail_info(mod)
583
572
584 for code in IP.rc.execute:
573 for code in IP.rc.execute:
585 try:
574 try:
586 exec code in IP.user_ns
575 exec code in IP.user_ns
587 except:
576 except:
588 IP.InteractiveTB()
577 IP.InteractiveTB()
589 warn('Failure executing code: ' + `code`)
578 warn('Failure executing code: ' + `code`)
590
579
591 # Execute the files the user wants in ipythonrc
580 # Execute the files the user wants in ipythonrc
592 for file in IP.rc.execfile:
581 for file in IP.rc.execfile:
593 try:
582 try:
594 file = filefind(file,sys.path+[IPython_dir])
583 file = filefind(file,sys.path+[IPython_dir])
595 except IOError:
584 except IOError:
596 warn(itpl('File $file not found. Skipping it.'))
585 warn(itpl('File $file not found. Skipping it.'))
597 else:
586 else:
598 IP.safe_execfile(os.path.expanduser(file),IP.user_ns)
587 IP.safe_execfile(os.path.expanduser(file),IP.user_ns)
599
588
600 # Load user aliases
589 # Load user aliases
601 for alias in IP.rc.alias:
590 for alias in IP.rc.alias:
602 IP.magic_alias(alias)
591 IP.magic_alias(alias)
603
592
604 # release stdout and stderr and save config log into a global summary
593 # release stdout and stderr and save config log into a global summary
605 msg.config.release_all()
594 msg.config.release_all()
606 if IP.rc.messages:
595 if IP.rc.messages:
607 msg.summary += msg.config.summary_all()
596 msg.summary += msg.config.summary_all()
608
597
609 #------------------------------------------------------------------------
598 #------------------------------------------------------------------------
610 # Setup interactive session
599 # Setup interactive session
611
600
612 # Now we should be fully configured. We can then execute files or load
601 # Now we should be fully configured. We can then execute files or load
613 # things only needed for interactive use. Then we'll open the shell.
602 # things only needed for interactive use. Then we'll open the shell.
614
603
615 # Take a snapshot of the user namespace before opening the shell. That way
604 # Take a snapshot of the user namespace before opening the shell. That way
616 # we'll be able to identify which things were interactively defined and
605 # we'll be able to identify which things were interactively defined and
617 # which were defined through config files.
606 # which were defined through config files.
618 IP.user_config_ns = IP.user_ns.copy()
607 IP.user_config_ns = IP.user_ns.copy()
619
608
620 # Force reading a file as if it were a session log. Slower but safer.
609 # Force reading a file as if it were a session log. Slower but safer.
621 if load_logplay:
610 if load_logplay:
622 print 'Replaying log...'
611 print 'Replaying log...'
623 try:
612 try:
624 if IP.rc.debug:
613 if IP.rc.debug:
625 logplay_quiet = 0
614 logplay_quiet = 0
626 else:
615 else:
627 logplay_quiet = 1
616 logplay_quiet = 1
628
617
629 msg.logplay.trap_all()
618 msg.logplay.trap_all()
630 IP.safe_execfile(load_logplay,IP.user_ns,
619 IP.safe_execfile(load_logplay,IP.user_ns,
631 islog = 1, quiet = logplay_quiet)
620 islog = 1, quiet = logplay_quiet)
632 msg.logplay.release_all()
621 msg.logplay.release_all()
633 if IP.rc.messages:
622 if IP.rc.messages:
634 msg.summary += msg.logplay.summary_all()
623 msg.summary += msg.logplay.summary_all()
635 except:
624 except:
636 warn('Problems replaying logfile %s.' % load_logplay)
625 warn('Problems replaying logfile %s.' % load_logplay)
637 IP.InteractiveTB()
626 IP.InteractiveTB()
638
627
639 # Load remaining files in command line
628 # Load remaining files in command line
640 msg.user_exec.trap_all()
629 msg.user_exec.trap_all()
641
630
642 # Do NOT execute files named in the command line as scripts to be loaded
631 # Do NOT execute files named in the command line as scripts to be loaded
643 # by embedded instances. Doing so has the potential for an infinite
632 # by embedded instances. Doing so has the potential for an infinite
644 # recursion if there are exceptions thrown in the process.
633 # recursion if there are exceptions thrown in the process.
645
634
646 # XXX FIXME: the execution of user files should be moved out to after
635 # XXX FIXME: the execution of user files should be moved out to after
647 # ipython is fully initialized, just as if they were run via %run at the
636 # ipython is fully initialized, just as if they were run via %run at the
648 # ipython prompt. This would also give them the benefit of ipython's
637 # ipython prompt. This would also give them the benefit of ipython's
649 # nice tracebacks.
638 # nice tracebacks.
650
639
651 if not embedded and IP.rc.args:
640 if not embedded and IP.rc.args:
652 name_save = IP.user_ns['__name__']
641 name_save = IP.user_ns['__name__']
653 IP.user_ns['__name__'] = '__main__'
642 IP.user_ns['__name__'] = '__main__'
654 try:
643 try:
655 # Set our own excepthook in case the user code tries to call it
644 # Set our own excepthook in case the user code tries to call it
656 # directly. This prevents triggering the IPython crash handler.
645 # directly. This prevents triggering the IPython crash handler.
657 old_excepthook,sys.excepthook = sys.excepthook, IP.excepthook
646 old_excepthook,sys.excepthook = sys.excepthook, IP.excepthook
658 for run in args:
647 for run in args:
659 IP.safe_execfile(run,IP.user_ns)
648 IP.safe_execfile(run,IP.user_ns)
660 finally:
649 finally:
661 # Reset our crash handler in place
650 # Reset our crash handler in place
662 sys.excepthook = old_excepthook
651 sys.excepthook = old_excepthook
663
652
664 IP.user_ns['__name__'] = name_save
653 IP.user_ns['__name__'] = name_save
665
654
666 msg.user_exec.release_all()
655 msg.user_exec.release_all()
667 if IP.rc.messages:
656 if IP.rc.messages:
668 msg.summary += msg.user_exec.summary_all()
657 msg.summary += msg.user_exec.summary_all()
669
658
670 # since we can't specify a null string on the cmd line, 0 is the equivalent:
659 # since we can't specify a null string on the cmd line, 0 is the equivalent:
671 if IP.rc.nosep:
660 if IP.rc.nosep:
672 IP.rc.separate_in = IP.rc.separate_out = IP.rc.separate_out2 = '0'
661 IP.rc.separate_in = IP.rc.separate_out = IP.rc.separate_out2 = '0'
673 if IP.rc.separate_in == '0': IP.rc.separate_in = ''
662 if IP.rc.separate_in == '0': IP.rc.separate_in = ''
674 if IP.rc.separate_out == '0': IP.rc.separate_out = ''
663 if IP.rc.separate_out == '0': IP.rc.separate_out = ''
675 if IP.rc.separate_out2 == '0': IP.rc.separate_out2 = ''
664 if IP.rc.separate_out2 == '0': IP.rc.separate_out2 = ''
676 IP.rc.separate_in = IP.rc.separate_in.replace('\\n','\n')
665 IP.rc.separate_in = IP.rc.separate_in.replace('\\n','\n')
677 IP.rc.separate_out = IP.rc.separate_out.replace('\\n','\n')
666 IP.rc.separate_out = IP.rc.separate_out.replace('\\n','\n')
678 IP.rc.separate_out2 = IP.rc.separate_out2.replace('\\n','\n')
667 IP.rc.separate_out2 = IP.rc.separate_out2.replace('\\n','\n')
679
668
680 # Determine how many lines at the bottom of the screen are needed for
669 # Determine how many lines at the bottom of the screen are needed for
681 # showing prompts, so we can know wheter long strings are to be printed or
670 # showing prompts, so we can know wheter long strings are to be printed or
682 # paged:
671 # paged:
683 num_lines_bot = IP.rc.separate_in.count('\n')+1
672 num_lines_bot = IP.rc.separate_in.count('\n')+1
684 IP.rc.screen_length = IP.rc.screen_length - num_lines_bot
673 IP.rc.screen_length = IP.rc.screen_length - num_lines_bot
685 # Initialize cache, set in/out prompts and printing system
674 # Initialize cache, set in/out prompts and printing system
686 IP.outputcache = CachedOutput(IP.rc.cache_size,
675 IP.outputcache = CachedOutput(IP.rc.cache_size,
687 IP.rc.pprint,
676 IP.rc.pprint,
688 input_sep = IP.rc.separate_in,
677 input_sep = IP.rc.separate_in,
689 output_sep = IP.rc.separate_out,
678 output_sep = IP.rc.separate_out,
690 output_sep2 = IP.rc.separate_out2,
679 output_sep2 = IP.rc.separate_out2,
691 ps1 = IP.rc.prompt_in1,
680 ps1 = IP.rc.prompt_in1,
692 ps2 = IP.rc.prompt_in2,
681 ps2 = IP.rc.prompt_in2,
693 ps_out = IP.rc.prompt_out,
682 ps_out = IP.rc.prompt_out,
694 user_ns = IP.user_ns,
683 user_ns = IP.user_ns,
695 input_hist = IP.input_hist,
684 input_hist = IP.input_hist,
696 pad_left = IP.rc.prompts_pad_left)
685 pad_left = IP.rc.prompts_pad_left)
697
686
698 # Set user colors (don't do it in the constructor above so that it doesn't
687 # Set user colors (don't do it in the constructor above so that it doesn't
699 # crash if colors option is invalid)
688 # crash if colors option is invalid)
700 IP.magic_colors(IP.rc.colors)
689 IP.magic_colors(IP.rc.colors)
701
690
702 # user may have over-ridden the default print hook:
691 # user may have over-ridden the default print hook:
703 try:
692 try:
704 IP.outputcache.__class__.display = IP.hooks.display
693 IP.outputcache.__class__.display = IP.hooks.display
705 except AttributeError:
694 except AttributeError:
706 pass
695 pass
707
696
708 # Set calling of pdb on exceptions
697 # Set calling of pdb on exceptions
709 IP.InteractiveTB.call_pdb = IP.rc.pdb
698 IP.InteractiveTB.call_pdb = IP.rc.pdb
710
699
711 # I don't like assigning globally to sys, because it means when embedding
700 # I don't like assigning globally to sys, because it means when embedding
712 # instances, each embedded instance overrides the previous choice. But
701 # instances, each embedded instance overrides the previous choice. But
713 # sys.displayhook seems to be called internally by exec, so I don't see a
702 # sys.displayhook seems to be called internally by exec, so I don't see a
714 # way around it.
703 # way around it.
715 sys.displayhook = IP.outputcache
704 sys.displayhook = IP.outputcache
716
705
717 # we need to know globally if we're caching i/o or not
706 # we need to know globally if we're caching i/o or not
718 IP.do_full_cache = IP.outputcache.do_full_cache
707 IP.do_full_cache = IP.outputcache.do_full_cache
719
708
720 # configure startup banner
709 # configure startup banner
721 if IP.rc.c: # regular python doesn't print the banner with -c
710 if IP.rc.c: # regular python doesn't print the banner with -c
722 IP.rc.banner = 0
711 IP.rc.banner = 0
723 if IP.rc.banner:
712 if IP.rc.banner:
724 IP.BANNER = '\n'.join(IP.BANNER_PARTS)
713 IP.BANNER = '\n'.join(IP.BANNER_PARTS)
725 else:
714 else:
726 IP.BANNER = ''
715 IP.BANNER = ''
727
716
728 if IP.rc.profile: IP.BANNER += '\nIPython profile: '+IP.rc.profile+'\n'
717 if IP.rc.profile: IP.BANNER += '\nIPython profile: '+IP.rc.profile+'\n'
729
718
730 # add message log (possibly empty)
719 # add message log (possibly empty)
731 IP.BANNER += msg.summary
720 IP.BANNER += msg.summary
732
721
733 IP.post_config_initialization()
722 IP.post_config_initialization()
734
723
735 return IP
724 return IP
736 #************************ end of file <ipmaker.py> **************************
725 #************************ end of file <ipmaker.py> **************************
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