##// END OF EJS Templates
iplib.py => core/iplib.py and updated tests and imports.
Brian Granger -
Show More
@@ -1,253 +1,253 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
8
9 #*****************************************************************************
9 #*****************************************************************************
10 # Copyright (C) 2004 W.J. van der Laan <gnufnork@hetdigitalegat.nl>
10 # Copyright (C) 2004 W.J. van der Laan <gnufnork@hetdigitalegat.nl>
11 # Copyright (C) 2004-2006 Fernando Perez <fperez@colorado.edu>
11 # Copyright (C) 2004-2006 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 # TODO: deprecated
17 # TODO: deprecated
18 def prefilter_shell(self,line,continuation):
18 def prefilter_shell(self,line,continuation):
19 """Alternate prefilter, modified for shell-like functionality.
19 """Alternate prefilter, modified for shell-like functionality.
20
20
21 - Execute all lines beginning with '~', '/' or '.'
21 - Execute all lines beginning with '~', '/' or '.'
22 - $var=cmd <=> %sc var=cmd
22 - $var=cmd <=> %sc var=cmd
23 - $$var=cmd <=> %sc -l var=cmd
23 - $$var=cmd <=> %sc -l var=cmd
24 """
24 """
25
25
26 if line:
26 if line:
27 l0 = line[0]
27 l0 = line[0]
28 if l0 in '~/.':
28 if l0 in '~/.':
29 return self._prefilter("!%s"%line,continuation)
29 return self._prefilter("!%s"%line,continuation)
30 elif l0=='$':
30 elif l0=='$':
31 lrest = line[1:]
31 lrest = line[1:]
32 if lrest.startswith('$'):
32 if lrest.startswith('$'):
33 # $$var=cmd <=> %sc -l var=cmd
33 # $$var=cmd <=> %sc -l var=cmd
34 return self._prefilter("%ssc -l %s" % (self.ESC_MAGIC,lrest[1:]),
34 return self._prefilter("%ssc -l %s" % (self.ESC_MAGIC,lrest[1:]),
35 continuation)
35 continuation)
36 else:
36 else:
37 # $var=cmd <=> %sc var=cmd
37 # $var=cmd <=> %sc var=cmd
38 return self._prefilter("%ssc %s" % (self.ESC_MAGIC,lrest),
38 return self._prefilter("%ssc %s" % (self.ESC_MAGIC,lrest),
39 continuation)
39 continuation)
40 else:
40 else:
41 return self._prefilter(line,continuation)
41 return self._prefilter(line,continuation)
42 else:
42 else:
43 return self._prefilter(line,continuation)
43 return self._prefilter(line,continuation)
44
44
45 # Rebind this to be the new IPython prefilter:
45 # Rebind this to be the new IPython prefilter:
46 from IPython.iplib import InteractiveShell
46 from IPython.core.iplib import InteractiveShell
47 InteractiveShell.prefilter = prefilter_shell
47 InteractiveShell.prefilter = prefilter_shell
48 # Clean up the namespace.
48 # Clean up the namespace.
49 del InteractiveShell,prefilter_shell
49 del InteractiveShell,prefilter_shell
50
50
51 # Provide pysh and further shell-oriented services
51 # Provide pysh and further shell-oriented services
52 import os,sys,shutil
52 import os,sys,shutil
53 from IPython.utils.genutils import system,shell,getoutput,getoutputerror
53 from IPython.utils.genutils import system,shell,getoutput,getoutputerror
54
54
55 # Short aliases for getting shell output as a string and a list
55 # Short aliases for getting shell output as a string and a list
56 sout = getoutput
56 sout = getoutput
57 lout = lambda cmd: getoutput(cmd,split=1)
57 lout = lambda cmd: getoutput(cmd,split=1)
58
58
59 # Empty function, meant as a docstring holder so help(pysh) works.
59 # Empty function, meant as a docstring holder so help(pysh) works.
60 def pysh():
60 def pysh():
61 """Pysh is a set of modules and extensions to IPython which make shell-like
61 """Pysh is a set of modules and extensions to IPython which make shell-like
62 usage with Python syntax more convenient. Keep in mind that pysh is NOT a
62 usage with Python syntax more convenient. Keep in mind that pysh is NOT a
63 full-blown shell, so don't try to make it your /etc/passwd entry!
63 full-blown shell, so don't try to make it your /etc/passwd entry!
64
64
65 In particular, it has no job control, so if you type Ctrl-Z (under Unix),
65 In particular, it has no job control, so if you type Ctrl-Z (under Unix),
66 you'll suspend pysh itself, not the process you just started.
66 you'll suspend pysh itself, not the process you just started.
67
67
68 Since pysh is really nothing but a customized IPython, you should
68 Since pysh is really nothing but a customized IPython, you should
69 familiarize yourself with IPython's features. This brief help mainly
69 familiarize yourself with IPython's features. This brief help mainly
70 documents areas in which pysh differs from the normal IPython.
70 documents areas in which pysh differs from the normal IPython.
71
71
72 ALIASES
72 ALIASES
73 -------
73 -------
74 All of your $PATH has been loaded as IPython aliases, so you should be
74 All of your $PATH has been loaded as IPython aliases, so you should be
75 able to type any normal system command and have it executed. See %alias?
75 able to type any normal system command and have it executed. See %alias?
76 and %unalias? for details on the alias facilities.
76 and %unalias? for details on the alias facilities.
77
77
78 SPECIAL SYNTAX
78 SPECIAL SYNTAX
79 --------------
79 --------------
80 Any lines which begin with '~', '/' and '.' will be executed as shell
80 Any lines which begin with '~', '/' and '.' will be executed as shell
81 commands instead of as Python code. The special escapes below are also
81 commands instead of as Python code. The special escapes below are also
82 recognized. !cmd is valid in single or multi-line input, all others are
82 recognized. !cmd is valid in single or multi-line input, all others are
83 only valid in single-line input:
83 only valid in single-line input:
84
84
85 !cmd - pass 'cmd' directly to the shell
85 !cmd - pass 'cmd' directly to the shell
86 !!cmd - execute 'cmd' and return output as a list (split on '\\n')
86 !!cmd - execute 'cmd' and return output as a list (split on '\\n')
87 $var=cmd - capture output of cmd into var, as a string
87 $var=cmd - capture output of cmd into var, as a string
88 $$var=cmd - capture output of cmd into var, as a list (split on '\\n')
88 $$var=cmd - capture output of cmd into var, as a list (split on '\\n')
89
89
90 The $/$$ syntaxes make Python variables from system output, which you can
90 The $/$$ syntaxes make Python variables from system output, which you can
91 later use for further scripting. The converse is also possible: when
91 later use for further scripting. The converse is also possible: when
92 executing an alias or calling to the system via !/!!, you can expand any
92 executing an alias or calling to the system via !/!!, you can expand any
93 python variable or expression by prepending it with $. Full details of
93 python variable or expression by prepending it with $. Full details of
94 the allowed syntax can be found in Python's PEP 215.
94 the allowed syntax can be found in Python's PEP 215.
95
95
96 A few brief examples will illustrate these:
96 A few brief examples will illustrate these:
97
97
98 fperez[~/test]|3> !ls *s.py
98 fperez[~/test]|3> !ls *s.py
99 scopes.py strings.py
99 scopes.py strings.py
100
100
101 ls is an internal alias, so there's no need to use !:
101 ls is an internal alias, so there's no need to use !:
102 fperez[~/test]|4> ls *s.py
102 fperez[~/test]|4> ls *s.py
103 scopes.py* strings.py
103 scopes.py* strings.py
104
104
105 !!ls will return the output into a Python variable:
105 !!ls will return the output into a Python variable:
106 fperez[~/test]|5> !!ls *s.py
106 fperez[~/test]|5> !!ls *s.py
107 <5> ['scopes.py', 'strings.py']
107 <5> ['scopes.py', 'strings.py']
108 fperez[~/test]|6> print _5
108 fperez[~/test]|6> print _5
109 ['scopes.py', 'strings.py']
109 ['scopes.py', 'strings.py']
110
110
111 $ and $$ allow direct capture to named variables:
111 $ and $$ allow direct capture to named variables:
112 fperez[~/test]|7> $astr = ls *s.py
112 fperez[~/test]|7> $astr = ls *s.py
113 fperez[~/test]|8> astr
113 fperez[~/test]|8> astr
114 <8> 'scopes.py\\nstrings.py'
114 <8> 'scopes.py\\nstrings.py'
115
115
116 fperez[~/test]|9> $$alist = ls *s.py
116 fperez[~/test]|9> $$alist = ls *s.py
117 fperez[~/test]|10> alist
117 fperez[~/test]|10> alist
118 <10> ['scopes.py', 'strings.py']
118 <10> ['scopes.py', 'strings.py']
119
119
120 alist is now a normal python list you can loop over. Using $ will expand
120 alist is now a normal python list you can loop over. Using $ will expand
121 back the python values when alias calls are made:
121 back the python values when alias calls are made:
122 fperez[~/test]|11> for f in alist:
122 fperez[~/test]|11> for f in alist:
123 |..> print 'file',f,
123 |..> print 'file',f,
124 |..> wc -l $f
124 |..> wc -l $f
125 |..>
125 |..>
126 file scopes.py 13 scopes.py
126 file scopes.py 13 scopes.py
127 file strings.py 4 strings.py
127 file strings.py 4 strings.py
128
128
129 Note that you may need to protect your variables with braces if you want
129 Note that you may need to protect your variables with braces if you want
130 to append strings to their names. To copy all files in alist to .bak
130 to append strings to their names. To copy all files in alist to .bak
131 extensions, you must use:
131 extensions, you must use:
132 fperez[~/test]|12> for f in alist:
132 fperez[~/test]|12> for f in alist:
133 |..> cp $f ${f}.bak
133 |..> cp $f ${f}.bak
134
134
135 If you try using $f.bak, you'll get an AttributeError exception saying
135 If you try using $f.bak, you'll get an AttributeError exception saying
136 that your string object doesn't have a .bak attribute. This is because
136 that your string object doesn't have a .bak attribute. This is because
137 the $ expansion mechanism allows you to expand full Python expressions:
137 the $ expansion mechanism allows you to expand full Python expressions:
138 fperez[~/test]|13> echo "sys.platform is: $sys.platform"
138 fperez[~/test]|13> echo "sys.platform is: $sys.platform"
139 sys.platform is: linux2
139 sys.platform is: linux2
140
140
141 IPython's input history handling is still active, which allows you to
141 IPython's input history handling is still active, which allows you to
142 rerun a single block of multi-line input by simply using exec:
142 rerun a single block of multi-line input by simply using exec:
143 fperez[~/test]|14> $$alist = ls *.eps
143 fperez[~/test]|14> $$alist = ls *.eps
144 fperez[~/test]|15> exec _i11
144 fperez[~/test]|15> exec _i11
145 file image2.eps 921 image2.eps
145 file image2.eps 921 image2.eps
146 file image.eps 921 image.eps
146 file image.eps 921 image.eps
147
147
148 While these are new special-case syntaxes, they are designed to allow very
148 While these are new special-case syntaxes, they are designed to allow very
149 efficient use of the shell with minimal typing. At an interactive shell
149 efficient use of the shell with minimal typing. At an interactive shell
150 prompt, conciseness of expression wins over readability.
150 prompt, conciseness of expression wins over readability.
151
151
152 USEFUL FUNCTIONS AND MODULES
152 USEFUL FUNCTIONS AND MODULES
153 ----------------------------
153 ----------------------------
154 The os, sys and shutil modules from the Python standard library are
154 The os, sys and shutil modules from the Python standard library are
155 automatically loaded. Some additional functions, useful for shell usage,
155 automatically loaded. Some additional functions, useful for shell usage,
156 are listed below. You can request more help about them with '?'.
156 are listed below. You can request more help about them with '?'.
157
157
158 shell - execute a command in the underlying system shell
158 shell - execute a command in the underlying system shell
159 system - like shell(), but return the exit status of the command
159 system - like shell(), but return the exit status of the command
160 sout - capture the output of a command as a string
160 sout - capture the output of a command as a string
161 lout - capture the output of a command as a list (split on '\\n')
161 lout - capture the output of a command as a list (split on '\\n')
162 getoutputerror - capture (output,error) of a shell command
162 getoutputerror - capture (output,error) of a shell command
163
163
164 sout/lout are the functional equivalents of $/$$. They are provided to
164 sout/lout are the functional equivalents of $/$$. They are provided to
165 allow you to capture system output in the middle of true python code,
165 allow you to capture system output in the middle of true python code,
166 function definitions, etc (where $ and $$ are invalid).
166 function definitions, etc (where $ and $$ are invalid).
167
167
168 DIRECTORY MANAGEMENT
168 DIRECTORY MANAGEMENT
169 --------------------
169 --------------------
170 Since each command passed by pysh to the underlying system is executed in
170 Since each command passed by pysh to the underlying system is executed in
171 a subshell which exits immediately, you can NOT use !cd to navigate the
171 a subshell which exits immediately, you can NOT use !cd to navigate the
172 filesystem.
172 filesystem.
173
173
174 Pysh provides its own builtin '%cd' magic command to move in the
174 Pysh provides its own builtin '%cd' magic command to move in the
175 filesystem (the % is not required with automagic on). It also maintains a
175 filesystem (the % is not required with automagic on). It also maintains a
176 list of visited directories (use %dhist to see it) and allows direct
176 list of visited directories (use %dhist to see it) and allows direct
177 switching to any of them. Type 'cd?' for more details.
177 switching to any of them. Type 'cd?' for more details.
178
178
179 %pushd, %popd and %dirs are provided for directory stack handling.
179 %pushd, %popd and %dirs are provided for directory stack handling.
180
180
181 PROMPT CUSTOMIZATION
181 PROMPT CUSTOMIZATION
182 --------------------
182 --------------------
183
183
184 The supplied ipythonrc-pysh profile comes with an example of a very
184 The supplied ipythonrc-pysh profile comes with an example of a very
185 colored and detailed prompt, mainly to serve as an illustration. The
185 colored and detailed prompt, mainly to serve as an illustration. The
186 valid escape sequences, besides color names, are:
186 valid escape sequences, besides color names, are:
187
187
188 \\# - Prompt number.
188 \\# - Prompt number.
189 \\D - Dots, as many as there are digits in \\# (so they align).
189 \\D - Dots, as many as there are digits in \\# (so they align).
190 \\w - Current working directory (cwd).
190 \\w - Current working directory (cwd).
191 \\W - Basename of current working directory.
191 \\W - Basename of current working directory.
192 \\XN - Where N=0..5. N terms of the cwd, with $HOME written as ~.
192 \\XN - Where N=0..5. N terms of the cwd, with $HOME written as ~.
193 \\YN - Where N=0..5. Like XN, but if ~ is term N+1 it's also shown.
193 \\YN - Where N=0..5. Like XN, but if ~ is term N+1 it's also shown.
194 \\u - Username.
194 \\u - Username.
195 \\H - Full hostname.
195 \\H - Full hostname.
196 \\h - Hostname up to first '.'
196 \\h - Hostname up to first '.'
197 \\$ - Root symbol ($ or #).
197 \\$ - Root symbol ($ or #).
198 \\t - Current time, in H:M:S format.
198 \\t - Current time, in H:M:S format.
199 \\v - IPython release version.
199 \\v - IPython release version.
200 \\n - Newline.
200 \\n - Newline.
201 \\r - Carriage return.
201 \\r - Carriage return.
202 \\\\ - An explicitly escaped '\\'.
202 \\\\ - An explicitly escaped '\\'.
203
203
204 You can configure your prompt colors using any ANSI color escape. Each
204 You can configure your prompt colors using any ANSI color escape. Each
205 color escape sets the color for any subsequent text, until another escape
205 color escape sets the color for any subsequent text, until another escape
206 comes in and changes things. The valid color escapes are:
206 comes in and changes things. The valid color escapes are:
207
207
208 \\C_Black
208 \\C_Black
209 \\C_Blue
209 \\C_Blue
210 \\C_Brown
210 \\C_Brown
211 \\C_Cyan
211 \\C_Cyan
212 \\C_DarkGray
212 \\C_DarkGray
213 \\C_Green
213 \\C_Green
214 \\C_LightBlue
214 \\C_LightBlue
215 \\C_LightCyan
215 \\C_LightCyan
216 \\C_LightGray
216 \\C_LightGray
217 \\C_LightGreen
217 \\C_LightGreen
218 \\C_LightPurple
218 \\C_LightPurple
219 \\C_LightRed
219 \\C_LightRed
220 \\C_Purple
220 \\C_Purple
221 \\C_Red
221 \\C_Red
222 \\C_White
222 \\C_White
223 \\C_Yellow
223 \\C_Yellow
224 \\C_Normal - Stop coloring, defaults to your terminal settings.
224 \\C_Normal - Stop coloring, defaults to your terminal settings.
225 """
225 """
226 pass
226 pass
227
227
228 # Configure a few things. Much of this is fairly hackish, since IPython
228 # Configure a few things. Much of this is fairly hackish, since IPython
229 # doesn't really expose a clean API for it. Be careful if you start making
229 # doesn't really expose a clean API for it. Be careful if you start making
230 # many modifications here.
230 # many modifications here.
231
231
232
232
233 # Set the 'cd' command to quiet mode, a more shell-like behavior
233 # Set the 'cd' command to quiet mode, a more shell-like behavior
234 __IPYTHON__.default_option('cd','-q')
234 __IPYTHON__.default_option('cd','-q')
235
235
236 # This is redundant, ipy_user_conf.py will determine this
236 # This is redundant, ipy_user_conf.py will determine this
237 # Load all of $PATH as aliases
237 # Load all of $PATH as aliases
238 __IPYTHON__.magic_rehashx()
238 __IPYTHON__.magic_rehashx()
239
239
240 # Remove %sc,%sx if present as aliases
240 # Remove %sc,%sx if present as aliases
241 __IPYTHON__.magic_unalias('sc')
241 __IPYTHON__.magic_unalias('sc')
242 __IPYTHON__.magic_unalias('sx')
242 __IPYTHON__.magic_unalias('sx')
243
243
244 # We need different criteria for line-splitting, so that aliases such as
244 # We need different criteria for line-splitting, so that aliases such as
245 # 'gnome-terminal' are interpreted as a single alias instead of variable
245 # 'gnome-terminal' are interpreted as a single alias instead of variable
246 # 'gnome' minus variable 'terminal'.
246 # 'gnome' minus variable 'terminal'.
247 import re
247 import re
248 __IPYTHON__.line_split = re.compile(r'^([\s*,;/])'
248 __IPYTHON__.line_split = re.compile(r'^([\s*,;/])'
249 r'([\?\w\.\-\+]+\w*\s*)'
249 r'([\?\w\.\-\+]+\w*\s*)'
250 r'(\(?.*$)')
250 r'(\(?.*$)')
251
251
252 # Namespace cleanup
252 # Namespace cleanup
253 del re
253 del re
@@ -1,124 +1,124 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Modified input prompt for entering text with >>> or ... at the start.
2 """Modified input prompt for entering text with >>> or ... at the start.
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 '... '. These two strings, if present at the start of the input
5 '>>> ' or '... '. These two strings, if present at the start of the input
6 line, are stripped. This allows for direct pasting of code from examples such
6 line, are stripped. This allows for direct pasting of code from examples such
7 as those available in the standard Python tutorial.
7 as those available in the standard Python tutorial.
8
8
9 Normally pasting such code is one chunk is impossible because of the
9 Normally pasting such code is one chunk is impossible because of the
10 extraneous >>> and ..., requiring one to do a line by line paste with careful
10 extraneous >>> and ..., requiring one to do a line by line paste with careful
11 removal of those characters. This module allows pasting that kind of
11 removal of those characters. This module allows pasting that kind of
12 multi-line examples in one pass.
12 multi-line examples in one pass.
13
13
14 Here is an 'screenshot' of a section of the tutorial pasted into IPython with
14 Here is an 'screenshot' of a section of the tutorial pasted into IPython with
15 this feature enabled:
15 this feature enabled:
16
16
17 In [1]: >>> def fib2(n): # return Fibonacci series up to n
17 In [1]: >>> def fib2(n): # return Fibonacci series up to n
18 ...: ... '''Return a list containing the Fibonacci series up to n.'''
18 ...: ... '''Return a list containing the Fibonacci series up to n.'''
19 ...: ... result = []
19 ...: ... result = []
20 ...: ... a, b = 0, 1
20 ...: ... a, b = 0, 1
21 ...: ... while b < n:
21 ...: ... while b < n:
22 ...: ... result.append(b) # see below
22 ...: ... result.append(b) # see below
23 ...: ... a, b = b, a+b
23 ...: ... a, b = b, a+b
24 ...: ... return result
24 ...: ... return result
25 ...:
25 ...:
26
26
27 In [2]: fib2(10)
27 In [2]: fib2(10)
28 Out[2]: [1, 1, 2, 3, 5, 8]
28 Out[2]: [1, 1, 2, 3, 5, 8]
29
29
30 The >>> and ... are stripped from the input so that the python interpreter
30 The >>> and ... are stripped from the input so that the python interpreter
31 only sees the real part of the code.
31 only sees the real part of the code.
32
32
33 All other input is processed normally.
33 All other input is processed normally.
34
34
35 Notes
35 Notes
36 =====
36 =====
37
37
38 * You can even paste code that has extra initial spaces, such as is common in
38 * You can even paste code that has extra initial spaces, such as is common in
39 doctests:
39 doctests:
40
40
41 In [3]: >>> a = ['Mary', 'had', 'a', 'little', 'lamb']
41 In [3]: >>> a = ['Mary', 'had', 'a', 'little', 'lamb']
42
42
43 In [4]: >>> for i in range(len(a)):
43 In [4]: >>> for i in range(len(a)):
44 ...: ... print i, a[i]
44 ...: ... print i, a[i]
45 ...: ...
45 ...: ...
46 0 Mary
46 0 Mary
47 1 had
47 1 had
48 2 a
48 2 a
49 3 little
49 3 little
50 4 lamb
50 4 lamb
51
51
52
52
53 Authors
53 Authors
54 -------
54 -------
55 - Fernando Perez <Fernando.Perez@berkeley.edu>
55 - Fernando Perez <Fernando.Perez@berkeley.edu>
56 """
56 """
57
57
58 #*****************************************************************************
58 #*****************************************************************************
59 # Copyright (C) 2008-2009 The IPython Development Team
59 # Copyright (C) 2008-2009 The IPython Development Team
60 # Copyright (C) 2001-2007 Fernando Perez <fperez@colorado.edu>
60 # Copyright (C) 2001-2007 Fernando Perez <fperez@colorado.edu>
61 #
61 #
62 # Distributed under the terms of the BSD License. The full license is in
62 # Distributed under the terms of the BSD License. The full license is in
63 # the file COPYING, distributed as part of this software.
63 # the file COPYING, distributed as part of this software.
64 #*****************************************************************************
64 #*****************************************************************************
65
65
66 # This file is an example of how to modify IPython's line-processing behavior
66 # This file is an example of how to modify IPython's line-processing behavior
67 # without touching the internal code. We'll define an alternate pre-processing
67 # without touching the internal code. We'll define an alternate pre-processing
68 # stage which allows a special form of input (which is invalid Python syntax)
68 # stage which allows a special form of input (which is invalid Python syntax)
69 # for certain quantities, rewrites a line of proper Python in those cases, and
69 # for certain quantities, rewrites a line of proper Python in those cases, and
70 # then passes it off to IPython's normal processor for further work.
70 # then passes it off to IPython's normal processor for further work.
71
71
72 # With this kind of customization, IPython can be adapted for many
72 # With this kind of customization, IPython can be adapted for many
73 # special-purpose scenarios providing alternate input syntaxes.
73 # special-purpose scenarios providing alternate input syntaxes.
74
74
75 # This file can be imported like a regular module.
75 # This file can be imported like a regular module.
76
76
77 # IPython has a prefilter() function that analyzes each input line. We redefine
77 # IPython has a prefilter() function that analyzes each input line. We redefine
78 # it here to first pre-process certain forms of input
78 # it here to first pre-process certain forms of input
79
79
80 # The prototype of any alternate prefilter must be like this one (the name
80 # The prototype of any alternate prefilter must be like this one (the name
81 # doesn't matter):
81 # doesn't matter):
82 # - line is a string containing the user input line.
82 # - line is a string containing the user input line.
83 # - continuation is a parameter which tells us if we are processing a first
83 # - continuation is a parameter which tells us if we are processing a first
84 # line of user input or the second or higher of a multi-line statement.
84 # line of user input or the second or higher of a multi-line statement.
85
85
86 import re
86 import re
87
87
88 from IPython.iplib import InteractiveShell
88 from IPython.core.iplib import InteractiveShell
89
89
90 PROMPT_RE = re.compile(r'(^[ \t]*>>> |^[ \t]*\.\.\. )')
90 PROMPT_RE = re.compile(r'(^[ \t]*>>> |^[ \t]*\.\.\. )')
91
91
92 def prefilter_paste(self,line,continuation):
92 def prefilter_paste(self,line,continuation):
93 """Alternate prefilter for input of pasted code from an interpreter.
93 """Alternate prefilter for input of pasted code from an interpreter.
94 """
94 """
95 if not line:
95 if not line:
96 return ''
96 return ''
97 m = PROMPT_RE.match(line)
97 m = PROMPT_RE.match(line)
98 if m:
98 if m:
99 # In the end, always call the default IPython _prefilter() function.
99 # In the end, always call the default IPython _prefilter() function.
100 # Note that self must be passed explicitly, b/c we're calling the
100 # Note that self must be passed explicitly, b/c we're calling the
101 # unbound class method (since this method will overwrite the instance
101 # unbound class method (since this method will overwrite the instance
102 # prefilter())
102 # prefilter())
103 return self._prefilter(line[len(m.group(0)):],continuation)
103 return self._prefilter(line[len(m.group(0)):],continuation)
104 elif line.strip() == '...':
104 elif line.strip() == '...':
105 return self._prefilter('',continuation)
105 return self._prefilter('',continuation)
106 elif line.isspace():
106 elif line.isspace():
107 # This allows us to recognize multiple input prompts separated by blank
107 # This allows us to recognize multiple input prompts separated by blank
108 # lines and pasted in a single chunk, very common when pasting doctests
108 # lines and pasted in a single chunk, very common when pasting doctests
109 # or long tutorial passages.
109 # or long tutorial passages.
110 return ''
110 return ''
111 else:
111 else:
112 return self._prefilter(line,continuation)
112 return self._prefilter(line,continuation)
113
113
114 def activate_prefilter():
114 def activate_prefilter():
115 """Rebind the input-pasting filter to be the new IPython prefilter"""
115 """Rebind the input-pasting filter to be the new IPython prefilter"""
116 InteractiveShell.prefilter = prefilter_paste
116 InteractiveShell.prefilter = prefilter_paste
117
117
118 def deactivate_prefilter():
118 def deactivate_prefilter():
119 """Reset the filter."""
119 """Reset the filter."""
120 InteractiveShell.prefilter = InteractiveShell._prefilter
120 InteractiveShell.prefilter = InteractiveShell._prefilter
121
121
122 # Just a heads up at the console
122 # Just a heads up at the console
123 activate_prefilter()
123 activate_prefilter()
124 print '*** Pasting of code with ">>>" or "..." has been enabled.'
124 print '*** Pasting of code with ">>>" or "..." has been enabled.'
@@ -1,84 +1,84 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Modified input prompt for entering quantities with units.
2 """Modified input prompt for entering quantities with units.
3
3
4 Modify the behavior of the interactive interpreter to allow direct input of
4 Modify the behavior of the interactive interpreter to allow direct input of
5 quantities with units without having to make a function call.
5 quantities with units without having to make a function call.
6
6
7 Now the following forms are accepted:
7 Now the following forms are accepted:
8
8
9 x = 4 m
9 x = 4 m
10 y = -.45e3 m/s
10 y = -.45e3 m/s
11 g = 9.8 m/s**2
11 g = 9.8 m/s**2
12 a = 2.3 m/s^2 # ^ -> ** automatically
12 a = 2.3 m/s^2 # ^ -> ** automatically
13
13
14 All other input is processed normally.
14 All other input is processed normally.
15
15
16 Authors
16 Authors
17 -------
17 -------
18 - Fernando Perez <Fernando.Perez@berkeley.edu>
18 - Fernando Perez <Fernando.Perez@berkeley.edu>
19 """
19 """
20 #*****************************************************************************
20 #*****************************************************************************
21 # Copyright (C) 2008-2009 The IPython Development Team
21 # Copyright (C) 2008-2009 The IPython Development Team
22 # Copyright (C) 2001-2007 Fernando Perez <fperez@colorado.edu>
22 # Copyright (C) 2001-2007 Fernando Perez <fperez@colorado.edu>
23 #
23 #
24 # Distributed under the terms of the BSD License. The full license is in
24 # Distributed under the terms of the BSD License. The full license is in
25 # the file COPYING, distributed as part of this software.
25 # the file COPYING, distributed as part of this software.
26 #*****************************************************************************
26 #*****************************************************************************
27
27
28 # This file is an example of how to modify IPython's line-processing behavior
28 # This file is an example of how to modify IPython's line-processing behavior
29 # without touching the internal code. We'll define an alternate pre-processing
29 # without touching the internal code. We'll define an alternate pre-processing
30 # stage which allows a special form of input (which is invalid Python syntax)
30 # stage which allows a special form of input (which is invalid Python syntax)
31 # for certain quantities, rewrites a line of proper Python in those cases, and
31 # for certain quantities, rewrites a line of proper Python in those cases, and
32 # then passes it off to IPython's normal processor for further work.
32 # then passes it off to IPython's normal processor for further work.
33
33
34 # With this kind of customization, IPython can be adapted for many
34 # With this kind of customization, IPython can be adapted for many
35 # special-purpose scenarios providing alternate input syntaxes.
35 # special-purpose scenarios providing alternate input syntaxes.
36
36
37 # This file can be imported like a regular module.
37 # This file can be imported like a regular module.
38
38
39 # IPython has a prefilter() function that analyzes each input line. We redefine
39 # IPython has a prefilter() function that analyzes each input line. We redefine
40 # it here to first pre-process certain forms of input
40 # it here to first pre-process certain forms of input
41
41
42 # The prototype of any alternate prefilter must be like this one (the name
42 # The prototype of any alternate prefilter must be like this one (the name
43 # doesn't matter):
43 # doesn't matter):
44 # - line is a string containing the user input line.
44 # - line is a string containing the user input line.
45 # - continuation is a parameter which tells us if we are processing a first line of
45 # - continuation is a parameter which tells us if we are processing a first line of
46 # user input or the second or higher of a multi-line statement.
46 # user input or the second or higher of a multi-line statement.
47
47
48 def prefilter_PQ(self,line,continuation):
48 def prefilter_PQ(self,line,continuation):
49 """Alternate prefilter for input of PhysicalQuantityInteractive objects.
49 """Alternate prefilter for input of PhysicalQuantityInteractive objects.
50
50
51 This assumes that the function PhysicalQuantityInteractive() has been
51 This assumes that the function PhysicalQuantityInteractive() has been
52 imported."""
52 imported."""
53
53
54 from re import match
54 from re import match
55 from IPython.iplib import InteractiveShell
55 from IPython.core.iplib import InteractiveShell
56
56
57 # This regexp is what does the real work
57 # This regexp is what does the real work
58 unit_split = match(r'\s*(\w+)\s*=\s*(-?\d*\.?\d*[eE]?-?\d*)\s+([a-zA-Z].*)',
58 unit_split = match(r'\s*(\w+)\s*=\s*(-?\d*\.?\d*[eE]?-?\d*)\s+([a-zA-Z].*)',
59 line)
59 line)
60
60
61 # If special input was ecnountered, process it:
61 # If special input was ecnountered, process it:
62 if unit_split:
62 if unit_split:
63 var,val,units = unit_split.groups()
63 var,val,units = unit_split.groups()
64 if var and val and units:
64 if var and val and units:
65 units = units.replace('^','**')
65 units = units.replace('^','**')
66 # Now a valid line needs to be constructed for IPython to process:
66 # Now a valid line needs to be constructed for IPython to process:
67 line = var +" = PhysicalQuantityInteractive(" + val + ", '" + \
67 line = var +" = PhysicalQuantityInteractive(" + val + ", '" + \
68 units + "')"
68 units + "')"
69 #print 'New line:',line # dbg
69 #print 'New line:',line # dbg
70
70
71 # In the end, always call the default IPython _prefilter() function. Note
71 # In the end, always call the default IPython _prefilter() function. Note
72 # that self must be passed explicitly, b/c we're calling the unbound class
72 # that self must be passed explicitly, b/c we're calling the unbound class
73 # method (since this method will overwrite the instance prefilter())
73 # method (since this method will overwrite the instance prefilter())
74 return InteractiveShell._prefilter(self,line,continuation)
74 return InteractiveShell._prefilter(self,line,continuation)
75
75
76 # Rebind this to be the new IPython prefilter:
76 # Rebind this to be the new IPython prefilter:
77 from IPython.iplib import InteractiveShell
77 from IPython.core.iplib import InteractiveShell
78 InteractiveShell.prefilter = prefilter_PQ
78 InteractiveShell.prefilter = prefilter_PQ
79
79
80 # Clean up the namespace.
80 # Clean up the namespace.
81 del InteractiveShell,prefilter_PQ
81 del InteractiveShell,prefilter_PQ
82
82
83 # Just a heads up at the console
83 # Just a heads up at the console
84 print '*** Simplified input for physical quantities enabled.'
84 print '*** Simplified input for physical quantities enabled.'
@@ -1,3457 +1,3457 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Magic functions for InteractiveShell.
2 """Magic functions for InteractiveShell.
3 """
3 """
4
4
5 #*****************************************************************************
5 #*****************************************************************************
6 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and
6 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and
7 # Copyright (C) 2001-2006 Fernando Perez <fperez@colorado.edu>
7 # Copyright (C) 2001-2006 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 #****************************************************************************
13 #****************************************************************************
14 # Modules and globals
14 # Modules and globals
15
15
16 # Python standard modules
16 # Python standard modules
17 import __builtin__
17 import __builtin__
18 import bdb
18 import bdb
19 import inspect
19 import inspect
20 import os
20 import os
21 import pdb
21 import pdb
22 import pydoc
22 import pydoc
23 import sys
23 import sys
24 import re
24 import re
25 import tempfile
25 import tempfile
26 import time
26 import time
27 import cPickle as pickle
27 import cPickle as pickle
28 import textwrap
28 import textwrap
29 from cStringIO import StringIO
29 from cStringIO import StringIO
30 from getopt import getopt,GetoptError
30 from getopt import getopt,GetoptError
31 from pprint import pprint, pformat
31 from pprint import pprint, pformat
32
32
33 # cProfile was added in Python2.5
33 # cProfile was added in Python2.5
34 try:
34 try:
35 import cProfile as profile
35 import cProfile as profile
36 import pstats
36 import pstats
37 except ImportError:
37 except ImportError:
38 # profile isn't bundled by default in Debian for license reasons
38 # profile isn't bundled by default in Debian for license reasons
39 try:
39 try:
40 import profile,pstats
40 import profile,pstats
41 except ImportError:
41 except ImportError:
42 profile = pstats = None
42 profile = pstats = None
43
43
44 # Homebrewed
44 # Homebrewed
45 import IPython
45 import IPython
46 from IPython import OInspect, wildcard
46 from IPython import OInspect, wildcard
47 from IPython.core import debugger
47 from IPython.core import debugger
48 from IPython.core.fakemodule import FakeModule
48 from IPython.core.fakemodule import FakeModule
49 from IPython.Itpl import Itpl, itpl, printpl,itplns
49 from IPython.Itpl import Itpl, itpl, printpl,itplns
50 from IPython.PyColorize import Parser
50 from IPython.PyColorize import Parser
51 from IPython.ipstruct import Struct
51 from IPython.ipstruct import Struct
52 from IPython.macro import Macro
52 from IPython.macro import Macro
53 from IPython.utils.genutils import *
53 from IPython.utils.genutils import *
54 from IPython import platutils
54 from IPython import platutils
55 import IPython.utils.generics
55 import IPython.utils.generics
56 from IPython.core import ipapi
56 from IPython.core import ipapi
57 from IPython.core.ipapi import UsageError
57 from IPython.core.ipapi import UsageError
58 from IPython.testing import decorators as testdec
58 from IPython.testing import decorators as testdec
59
59
60 #***************************************************************************
60 #***************************************************************************
61 # Utility functions
61 # Utility functions
62 def on_off(tag):
62 def on_off(tag):
63 """Return an ON/OFF string for a 1/0 input. Simple utility function."""
63 """Return an ON/OFF string for a 1/0 input. Simple utility function."""
64 return ['OFF','ON'][tag]
64 return ['OFF','ON'][tag]
65
65
66 class Bunch: pass
66 class Bunch: pass
67
67
68 def compress_dhist(dh):
68 def compress_dhist(dh):
69 head, tail = dh[:-10], dh[-10:]
69 head, tail = dh[:-10], dh[-10:]
70
70
71 newhead = []
71 newhead = []
72 done = set()
72 done = set()
73 for h in head:
73 for h in head:
74 if h in done:
74 if h in done:
75 continue
75 continue
76 newhead.append(h)
76 newhead.append(h)
77 done.add(h)
77 done.add(h)
78
78
79 return newhead + tail
79 return newhead + tail
80
80
81
81
82 #***************************************************************************
82 #***************************************************************************
83 # Main class implementing Magic functionality
83 # Main class implementing Magic functionality
84 class Magic:
84 class Magic:
85 """Magic functions for InteractiveShell.
85 """Magic functions for InteractiveShell.
86
86
87 Shell functions which can be reached as %function_name. All magic
87 Shell functions which can be reached as %function_name. All magic
88 functions should accept a string, which they can parse for their own
88 functions should accept a string, which they can parse for their own
89 needs. This can make some functions easier to type, eg `%cd ../`
89 needs. This can make some functions easier to type, eg `%cd ../`
90 vs. `%cd("../")`
90 vs. `%cd("../")`
91
91
92 ALL definitions MUST begin with the prefix magic_. The user won't need it
92 ALL definitions MUST begin with the prefix magic_. The user won't need it
93 at the command line, but it is is needed in the definition. """
93 at the command line, but it is is needed in the definition. """
94
94
95 # class globals
95 # class globals
96 auto_status = ['Automagic is OFF, % prefix IS needed for magic functions.',
96 auto_status = ['Automagic is OFF, % prefix IS needed for magic functions.',
97 'Automagic is ON, % prefix NOT needed for magic functions.']
97 'Automagic is ON, % prefix NOT needed for magic functions.']
98
98
99 #......................................................................
99 #......................................................................
100 # some utility functions
100 # some utility functions
101
101
102 def __init__(self,shell):
102 def __init__(self,shell):
103
103
104 self.options_table = {}
104 self.options_table = {}
105 if profile is None:
105 if profile is None:
106 self.magic_prun = self.profile_missing_notice
106 self.magic_prun = self.profile_missing_notice
107 self.shell = shell
107 self.shell = shell
108
108
109 # namespace for holding state we may need
109 # namespace for holding state we may need
110 self._magic_state = Bunch()
110 self._magic_state = Bunch()
111
111
112 def profile_missing_notice(self, *args, **kwargs):
112 def profile_missing_notice(self, *args, **kwargs):
113 error("""\
113 error("""\
114 The profile module could not be found. It has been removed from the standard
114 The profile module could not be found. It has been removed from the standard
115 python packages because of its non-free license. To use profiling, install the
115 python packages because of its non-free license. To use profiling, install the
116 python-profiler package from non-free.""")
116 python-profiler package from non-free.""")
117
117
118 def default_option(self,fn,optstr):
118 def default_option(self,fn,optstr):
119 """Make an entry in the options_table for fn, with value optstr"""
119 """Make an entry in the options_table for fn, with value optstr"""
120
120
121 if fn not in self.lsmagic():
121 if fn not in self.lsmagic():
122 error("%s is not a magic function" % fn)
122 error("%s is not a magic function" % fn)
123 self.options_table[fn] = optstr
123 self.options_table[fn] = optstr
124
124
125 def lsmagic(self):
125 def lsmagic(self):
126 """Return a list of currently available magic functions.
126 """Return a list of currently available magic functions.
127
127
128 Gives a list of the bare names after mangling (['ls','cd', ...], not
128 Gives a list of the bare names after mangling (['ls','cd', ...], not
129 ['magic_ls','magic_cd',...]"""
129 ['magic_ls','magic_cd',...]"""
130
130
131 # FIXME. This needs a cleanup, in the way the magics list is built.
131 # FIXME. This needs a cleanup, in the way the magics list is built.
132
132
133 # magics in class definition
133 # magics in class definition
134 class_magic = lambda fn: fn.startswith('magic_') and \
134 class_magic = lambda fn: fn.startswith('magic_') and \
135 callable(Magic.__dict__[fn])
135 callable(Magic.__dict__[fn])
136 # in instance namespace (run-time user additions)
136 # in instance namespace (run-time user additions)
137 inst_magic = lambda fn: fn.startswith('magic_') and \
137 inst_magic = lambda fn: fn.startswith('magic_') and \
138 callable(self.__dict__[fn])
138 callable(self.__dict__[fn])
139 # and bound magics by user (so they can access self):
139 # and bound magics by user (so they can access self):
140 inst_bound_magic = lambda fn: fn.startswith('magic_') and \
140 inst_bound_magic = lambda fn: fn.startswith('magic_') and \
141 callable(self.__class__.__dict__[fn])
141 callable(self.__class__.__dict__[fn])
142 magics = filter(class_magic,Magic.__dict__.keys()) + \
142 magics = filter(class_magic,Magic.__dict__.keys()) + \
143 filter(inst_magic,self.__dict__.keys()) + \
143 filter(inst_magic,self.__dict__.keys()) + \
144 filter(inst_bound_magic,self.__class__.__dict__.keys())
144 filter(inst_bound_magic,self.__class__.__dict__.keys())
145 out = []
145 out = []
146 for fn in set(magics):
146 for fn in set(magics):
147 out.append(fn.replace('magic_','',1))
147 out.append(fn.replace('magic_','',1))
148 out.sort()
148 out.sort()
149 return out
149 return out
150
150
151 def extract_input_slices(self,slices,raw=False):
151 def extract_input_slices(self,slices,raw=False):
152 """Return as a string a set of input history slices.
152 """Return as a string a set of input history slices.
153
153
154 Inputs:
154 Inputs:
155
155
156 - slices: the set of slices is given as a list of strings (like
156 - slices: the set of slices is given as a list of strings (like
157 ['1','4:8','9'], since this function is for use by magic functions
157 ['1','4:8','9'], since this function is for use by magic functions
158 which get their arguments as strings.
158 which get their arguments as strings.
159
159
160 Optional inputs:
160 Optional inputs:
161
161
162 - raw(False): by default, the processed input is used. If this is
162 - raw(False): by default, the processed input is used. If this is
163 true, the raw input history is used instead.
163 true, the raw input history is used instead.
164
164
165 Note that slices can be called with two notations:
165 Note that slices can be called with two notations:
166
166
167 N:M -> standard python form, means including items N...(M-1).
167 N:M -> standard python form, means including items N...(M-1).
168
168
169 N-M -> include items N..M (closed endpoint)."""
169 N-M -> include items N..M (closed endpoint)."""
170
170
171 if raw:
171 if raw:
172 hist = self.shell.input_hist_raw
172 hist = self.shell.input_hist_raw
173 else:
173 else:
174 hist = self.shell.input_hist
174 hist = self.shell.input_hist
175
175
176 cmds = []
176 cmds = []
177 for chunk in slices:
177 for chunk in slices:
178 if ':' in chunk:
178 if ':' in chunk:
179 ini,fin = map(int,chunk.split(':'))
179 ini,fin = map(int,chunk.split(':'))
180 elif '-' in chunk:
180 elif '-' in chunk:
181 ini,fin = map(int,chunk.split('-'))
181 ini,fin = map(int,chunk.split('-'))
182 fin += 1
182 fin += 1
183 else:
183 else:
184 ini = int(chunk)
184 ini = int(chunk)
185 fin = ini+1
185 fin = ini+1
186 cmds.append(hist[ini:fin])
186 cmds.append(hist[ini:fin])
187 return cmds
187 return cmds
188
188
189 def _ofind(self, oname, namespaces=None):
189 def _ofind(self, oname, namespaces=None):
190 """Find an object in the available namespaces.
190 """Find an object in the available namespaces.
191
191
192 self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
192 self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
193
193
194 Has special code to detect magic functions.
194 Has special code to detect magic functions.
195 """
195 """
196
196
197 oname = oname.strip()
197 oname = oname.strip()
198
198
199 alias_ns = None
199 alias_ns = None
200 if namespaces is None:
200 if namespaces is None:
201 # Namespaces to search in:
201 # Namespaces to search in:
202 # Put them in a list. The order is important so that we
202 # Put them in a list. The order is important so that we
203 # find things in the same order that Python finds them.
203 # find things in the same order that Python finds them.
204 namespaces = [ ('Interactive', self.shell.user_ns),
204 namespaces = [ ('Interactive', self.shell.user_ns),
205 ('IPython internal', self.shell.internal_ns),
205 ('IPython internal', self.shell.internal_ns),
206 ('Python builtin', __builtin__.__dict__),
206 ('Python builtin', __builtin__.__dict__),
207 ('Alias', self.shell.alias_table),
207 ('Alias', self.shell.alias_table),
208 ]
208 ]
209 alias_ns = self.shell.alias_table
209 alias_ns = self.shell.alias_table
210
210
211 # initialize results to 'null'
211 # initialize results to 'null'
212 found = 0; obj = None; ospace = None; ds = None;
212 found = 0; obj = None; ospace = None; ds = None;
213 ismagic = 0; isalias = 0; parent = None
213 ismagic = 0; isalias = 0; parent = None
214
214
215 # Look for the given name by splitting it in parts. If the head is
215 # Look for the given name by splitting it in parts. If the head is
216 # found, then we look for all the remaining parts as members, and only
216 # found, then we look for all the remaining parts as members, and only
217 # declare success if we can find them all.
217 # declare success if we can find them all.
218 oname_parts = oname.split('.')
218 oname_parts = oname.split('.')
219 oname_head, oname_rest = oname_parts[0],oname_parts[1:]
219 oname_head, oname_rest = oname_parts[0],oname_parts[1:]
220 for nsname,ns in namespaces:
220 for nsname,ns in namespaces:
221 try:
221 try:
222 obj = ns[oname_head]
222 obj = ns[oname_head]
223 except KeyError:
223 except KeyError:
224 continue
224 continue
225 else:
225 else:
226 #print 'oname_rest:', oname_rest # dbg
226 #print 'oname_rest:', oname_rest # dbg
227 for part in oname_rest:
227 for part in oname_rest:
228 try:
228 try:
229 parent = obj
229 parent = obj
230 obj = getattr(obj,part)
230 obj = getattr(obj,part)
231 except:
231 except:
232 # Blanket except b/c some badly implemented objects
232 # Blanket except b/c some badly implemented objects
233 # allow __getattr__ to raise exceptions other than
233 # allow __getattr__ to raise exceptions other than
234 # AttributeError, which then crashes IPython.
234 # AttributeError, which then crashes IPython.
235 break
235 break
236 else:
236 else:
237 # If we finish the for loop (no break), we got all members
237 # If we finish the for loop (no break), we got all members
238 found = 1
238 found = 1
239 ospace = nsname
239 ospace = nsname
240 if ns == alias_ns:
240 if ns == alias_ns:
241 isalias = 1
241 isalias = 1
242 break # namespace loop
242 break # namespace loop
243
243
244 # Try to see if it's magic
244 # Try to see if it's magic
245 if not found:
245 if not found:
246 if oname.startswith(self.shell.ESC_MAGIC):
246 if oname.startswith(self.shell.ESC_MAGIC):
247 oname = oname[1:]
247 oname = oname[1:]
248 obj = getattr(self,'magic_'+oname,None)
248 obj = getattr(self,'magic_'+oname,None)
249 if obj is not None:
249 if obj is not None:
250 found = 1
250 found = 1
251 ospace = 'IPython internal'
251 ospace = 'IPython internal'
252 ismagic = 1
252 ismagic = 1
253
253
254 # Last try: special-case some literals like '', [], {}, etc:
254 # Last try: special-case some literals like '', [], {}, etc:
255 if not found and oname_head in ["''",'""','[]','{}','()']:
255 if not found and oname_head in ["''",'""','[]','{}','()']:
256 obj = eval(oname_head)
256 obj = eval(oname_head)
257 found = 1
257 found = 1
258 ospace = 'Interactive'
258 ospace = 'Interactive'
259
259
260 return {'found':found, 'obj':obj, 'namespace':ospace,
260 return {'found':found, 'obj':obj, 'namespace':ospace,
261 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
261 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
262
262
263 def arg_err(self,func):
263 def arg_err(self,func):
264 """Print docstring if incorrect arguments were passed"""
264 """Print docstring if incorrect arguments were passed"""
265 print 'Error in arguments:'
265 print 'Error in arguments:'
266 print OInspect.getdoc(func)
266 print OInspect.getdoc(func)
267
267
268 def format_latex(self,strng):
268 def format_latex(self,strng):
269 """Format a string for latex inclusion."""
269 """Format a string for latex inclusion."""
270
270
271 # Characters that need to be escaped for latex:
271 # Characters that need to be escaped for latex:
272 escape_re = re.compile(r'(%|_|\$|#|&)',re.MULTILINE)
272 escape_re = re.compile(r'(%|_|\$|#|&)',re.MULTILINE)
273 # Magic command names as headers:
273 # Magic command names as headers:
274 cmd_name_re = re.compile(r'^(%s.*?):' % self.shell.ESC_MAGIC,
274 cmd_name_re = re.compile(r'^(%s.*?):' % self.shell.ESC_MAGIC,
275 re.MULTILINE)
275 re.MULTILINE)
276 # Magic commands
276 # Magic commands
277 cmd_re = re.compile(r'(?P<cmd>%s.+?\b)(?!\}\}:)' % self.shell.ESC_MAGIC,
277 cmd_re = re.compile(r'(?P<cmd>%s.+?\b)(?!\}\}:)' % self.shell.ESC_MAGIC,
278 re.MULTILINE)
278 re.MULTILINE)
279 # Paragraph continue
279 # Paragraph continue
280 par_re = re.compile(r'\\$',re.MULTILINE)
280 par_re = re.compile(r'\\$',re.MULTILINE)
281
281
282 # The "\n" symbol
282 # The "\n" symbol
283 newline_re = re.compile(r'\\n')
283 newline_re = re.compile(r'\\n')
284
284
285 # Now build the string for output:
285 # Now build the string for output:
286 #strng = cmd_name_re.sub(r'\n\\texttt{\\textsl{\\large \1}}:',strng)
286 #strng = cmd_name_re.sub(r'\n\\texttt{\\textsl{\\large \1}}:',strng)
287 strng = cmd_name_re.sub(r'\n\\bigskip\n\\texttt{\\textbf{ \1}}:',
287 strng = cmd_name_re.sub(r'\n\\bigskip\n\\texttt{\\textbf{ \1}}:',
288 strng)
288 strng)
289 strng = cmd_re.sub(r'\\texttt{\g<cmd>}',strng)
289 strng = cmd_re.sub(r'\\texttt{\g<cmd>}',strng)
290 strng = par_re.sub(r'\\\\',strng)
290 strng = par_re.sub(r'\\\\',strng)
291 strng = escape_re.sub(r'\\\1',strng)
291 strng = escape_re.sub(r'\\\1',strng)
292 strng = newline_re.sub(r'\\textbackslash{}n',strng)
292 strng = newline_re.sub(r'\\textbackslash{}n',strng)
293 return strng
293 return strng
294
294
295 def format_screen(self,strng):
295 def format_screen(self,strng):
296 """Format a string for screen printing.
296 """Format a string for screen printing.
297
297
298 This removes some latex-type format codes."""
298 This removes some latex-type format codes."""
299 # Paragraph continue
299 # Paragraph continue
300 par_re = re.compile(r'\\$',re.MULTILINE)
300 par_re = re.compile(r'\\$',re.MULTILINE)
301 strng = par_re.sub('',strng)
301 strng = par_re.sub('',strng)
302 return strng
302 return strng
303
303
304 def parse_options(self,arg_str,opt_str,*long_opts,**kw):
304 def parse_options(self,arg_str,opt_str,*long_opts,**kw):
305 """Parse options passed to an argument string.
305 """Parse options passed to an argument string.
306
306
307 The interface is similar to that of getopt(), but it returns back a
307 The interface is similar to that of getopt(), but it returns back a
308 Struct with the options as keys and the stripped argument string still
308 Struct with the options as keys and the stripped argument string still
309 as a string.
309 as a string.
310
310
311 arg_str is quoted as a true sys.argv vector by using shlex.split.
311 arg_str is quoted as a true sys.argv vector by using shlex.split.
312 This allows us to easily expand variables, glob files, quote
312 This allows us to easily expand variables, glob files, quote
313 arguments, etc.
313 arguments, etc.
314
314
315 Options:
315 Options:
316 -mode: default 'string'. If given as 'list', the argument string is
316 -mode: default 'string'. If given as 'list', the argument string is
317 returned as a list (split on whitespace) instead of a string.
317 returned as a list (split on whitespace) instead of a string.
318
318
319 -list_all: put all option values in lists. Normally only options
319 -list_all: put all option values in lists. Normally only options
320 appearing more than once are put in a list.
320 appearing more than once are put in a list.
321
321
322 -posix (True): whether to split the input line in POSIX mode or not,
322 -posix (True): whether to split the input line in POSIX mode or not,
323 as per the conventions outlined in the shlex module from the
323 as per the conventions outlined in the shlex module from the
324 standard library."""
324 standard library."""
325
325
326 # inject default options at the beginning of the input line
326 # inject default options at the beginning of the input line
327 caller = sys._getframe(1).f_code.co_name.replace('magic_','')
327 caller = sys._getframe(1).f_code.co_name.replace('magic_','')
328 arg_str = '%s %s' % (self.options_table.get(caller,''),arg_str)
328 arg_str = '%s %s' % (self.options_table.get(caller,''),arg_str)
329
329
330 mode = kw.get('mode','string')
330 mode = kw.get('mode','string')
331 if mode not in ['string','list']:
331 if mode not in ['string','list']:
332 raise ValueError,'incorrect mode given: %s' % mode
332 raise ValueError,'incorrect mode given: %s' % mode
333 # Get options
333 # Get options
334 list_all = kw.get('list_all',0)
334 list_all = kw.get('list_all',0)
335 posix = kw.get('posix',True)
335 posix = kw.get('posix',True)
336
336
337 # Check if we have more than one argument to warrant extra processing:
337 # Check if we have more than one argument to warrant extra processing:
338 odict = {} # Dictionary with options
338 odict = {} # Dictionary with options
339 args = arg_str.split()
339 args = arg_str.split()
340 if len(args) >= 1:
340 if len(args) >= 1:
341 # If the list of inputs only has 0 or 1 thing in it, there's no
341 # If the list of inputs only has 0 or 1 thing in it, there's no
342 # need to look for options
342 # need to look for options
343 argv = arg_split(arg_str,posix)
343 argv = arg_split(arg_str,posix)
344 # Do regular option processing
344 # Do regular option processing
345 try:
345 try:
346 opts,args = getopt(argv,opt_str,*long_opts)
346 opts,args = getopt(argv,opt_str,*long_opts)
347 except GetoptError,e:
347 except GetoptError,e:
348 raise UsageError('%s ( allowed: "%s" %s)' % (e.msg,opt_str,
348 raise UsageError('%s ( allowed: "%s" %s)' % (e.msg,opt_str,
349 " ".join(long_opts)))
349 " ".join(long_opts)))
350 for o,a in opts:
350 for o,a in opts:
351 if o.startswith('--'):
351 if o.startswith('--'):
352 o = o[2:]
352 o = o[2:]
353 else:
353 else:
354 o = o[1:]
354 o = o[1:]
355 try:
355 try:
356 odict[o].append(a)
356 odict[o].append(a)
357 except AttributeError:
357 except AttributeError:
358 odict[o] = [odict[o],a]
358 odict[o] = [odict[o],a]
359 except KeyError:
359 except KeyError:
360 if list_all:
360 if list_all:
361 odict[o] = [a]
361 odict[o] = [a]
362 else:
362 else:
363 odict[o] = a
363 odict[o] = a
364
364
365 # Prepare opts,args for return
365 # Prepare opts,args for return
366 opts = Struct(odict)
366 opts = Struct(odict)
367 if mode == 'string':
367 if mode == 'string':
368 args = ' '.join(args)
368 args = ' '.join(args)
369
369
370 return opts,args
370 return opts,args
371
371
372 #......................................................................
372 #......................................................................
373 # And now the actual magic functions
373 # And now the actual magic functions
374
374
375 # Functions for IPython shell work (vars,funcs, config, etc)
375 # Functions for IPython shell work (vars,funcs, config, etc)
376 def magic_lsmagic(self, parameter_s = ''):
376 def magic_lsmagic(self, parameter_s = ''):
377 """List currently available magic functions."""
377 """List currently available magic functions."""
378 mesc = self.shell.ESC_MAGIC
378 mesc = self.shell.ESC_MAGIC
379 print 'Available magic functions:\n'+mesc+\
379 print 'Available magic functions:\n'+mesc+\
380 (' '+mesc).join(self.lsmagic())
380 (' '+mesc).join(self.lsmagic())
381 print '\n' + Magic.auto_status[self.shell.rc.automagic]
381 print '\n' + Magic.auto_status[self.shell.rc.automagic]
382 return None
382 return None
383
383
384 def magic_magic(self, parameter_s = ''):
384 def magic_magic(self, parameter_s = ''):
385 """Print information about the magic function system.
385 """Print information about the magic function system.
386
386
387 Supported formats: -latex, -brief, -rest
387 Supported formats: -latex, -brief, -rest
388 """
388 """
389
389
390 mode = ''
390 mode = ''
391 try:
391 try:
392 if parameter_s.split()[0] == '-latex':
392 if parameter_s.split()[0] == '-latex':
393 mode = 'latex'
393 mode = 'latex'
394 if parameter_s.split()[0] == '-brief':
394 if parameter_s.split()[0] == '-brief':
395 mode = 'brief'
395 mode = 'brief'
396 if parameter_s.split()[0] == '-rest':
396 if parameter_s.split()[0] == '-rest':
397 mode = 'rest'
397 mode = 'rest'
398 rest_docs = []
398 rest_docs = []
399 except:
399 except:
400 pass
400 pass
401
401
402 magic_docs = []
402 magic_docs = []
403 for fname in self.lsmagic():
403 for fname in self.lsmagic():
404 mname = 'magic_' + fname
404 mname = 'magic_' + fname
405 for space in (Magic,self,self.__class__):
405 for space in (Magic,self,self.__class__):
406 try:
406 try:
407 fn = space.__dict__[mname]
407 fn = space.__dict__[mname]
408 except KeyError:
408 except KeyError:
409 pass
409 pass
410 else:
410 else:
411 break
411 break
412 if mode == 'brief':
412 if mode == 'brief':
413 # only first line
413 # only first line
414 if fn.__doc__:
414 if fn.__doc__:
415 fndoc = fn.__doc__.split('\n',1)[0]
415 fndoc = fn.__doc__.split('\n',1)[0]
416 else:
416 else:
417 fndoc = 'No documentation'
417 fndoc = 'No documentation'
418 else:
418 else:
419 if fn.__doc__:
419 if fn.__doc__:
420 fndoc = fn.__doc__.rstrip()
420 fndoc = fn.__doc__.rstrip()
421 else:
421 else:
422 fndoc = 'No documentation'
422 fndoc = 'No documentation'
423
423
424
424
425 if mode == 'rest':
425 if mode == 'rest':
426 rest_docs.append('**%s%s**::\n\n\t%s\n\n' %(self.shell.ESC_MAGIC,
426 rest_docs.append('**%s%s**::\n\n\t%s\n\n' %(self.shell.ESC_MAGIC,
427 fname,fndoc))
427 fname,fndoc))
428
428
429 else:
429 else:
430 magic_docs.append('%s%s:\n\t%s\n' %(self.shell.ESC_MAGIC,
430 magic_docs.append('%s%s:\n\t%s\n' %(self.shell.ESC_MAGIC,
431 fname,fndoc))
431 fname,fndoc))
432
432
433 magic_docs = ''.join(magic_docs)
433 magic_docs = ''.join(magic_docs)
434
434
435 if mode == 'rest':
435 if mode == 'rest':
436 return "".join(rest_docs)
436 return "".join(rest_docs)
437
437
438 if mode == 'latex':
438 if mode == 'latex':
439 print self.format_latex(magic_docs)
439 print self.format_latex(magic_docs)
440 return
440 return
441 else:
441 else:
442 magic_docs = self.format_screen(magic_docs)
442 magic_docs = self.format_screen(magic_docs)
443 if mode == 'brief':
443 if mode == 'brief':
444 return magic_docs
444 return magic_docs
445
445
446 outmsg = """
446 outmsg = """
447 IPython's 'magic' functions
447 IPython's 'magic' functions
448 ===========================
448 ===========================
449
449
450 The magic function system provides a series of functions which allow you to
450 The magic function system provides a series of functions which allow you to
451 control the behavior of IPython itself, plus a lot of system-type
451 control the behavior of IPython itself, plus a lot of system-type
452 features. All these functions are prefixed with a % character, but parameters
452 features. All these functions are prefixed with a % character, but parameters
453 are given without parentheses or quotes.
453 are given without parentheses or quotes.
454
454
455 NOTE: If you have 'automagic' enabled (via the command line option or with the
455 NOTE: If you have 'automagic' enabled (via the command line option or with the
456 %automagic function), you don't need to type in the % explicitly. By default,
456 %automagic function), you don't need to type in the % explicitly. By default,
457 IPython ships with automagic on, so you should only rarely need the % escape.
457 IPython ships with automagic on, so you should only rarely need the % escape.
458
458
459 Example: typing '%cd mydir' (without the quotes) changes you working directory
459 Example: typing '%cd mydir' (without the quotes) changes you working directory
460 to 'mydir', if it exists.
460 to 'mydir', if it exists.
461
461
462 You can define your own magic functions to extend the system. See the supplied
462 You can define your own magic functions to extend the system. See the supplied
463 ipythonrc and example-magic.py files for details (in your ipython
463 ipythonrc and example-magic.py files for details (in your ipython
464 configuration directory, typically $HOME/.ipython/).
464 configuration directory, typically $HOME/.ipython/).
465
465
466 You can also define your own aliased names for magic functions. In your
466 You can also define your own aliased names for magic functions. In your
467 ipythonrc file, placing a line like:
467 ipythonrc file, placing a line like:
468
468
469 execute __IPYTHON__.magic_pf = __IPYTHON__.magic_profile
469 execute __IPYTHON__.magic_pf = __IPYTHON__.magic_profile
470
470
471 will define %pf as a new name for %profile.
471 will define %pf as a new name for %profile.
472
472
473 You can also call magics in code using the ipmagic() function, which IPython
473 You can also call magics in code using the ipmagic() function, which IPython
474 automatically adds to the builtin namespace. Type 'ipmagic?' for details.
474 automatically adds to the builtin namespace. Type 'ipmagic?' for details.
475
475
476 For a list of the available magic functions, use %lsmagic. For a description
476 For a list of the available magic functions, use %lsmagic. For a description
477 of any of them, type %magic_name?, e.g. '%cd?'.
477 of any of them, type %magic_name?, e.g. '%cd?'.
478
478
479 Currently the magic system has the following functions:\n"""
479 Currently the magic system has the following functions:\n"""
480
480
481 mesc = self.shell.ESC_MAGIC
481 mesc = self.shell.ESC_MAGIC
482 outmsg = ("%s\n%s\n\nSummary of magic functions (from %slsmagic):"
482 outmsg = ("%s\n%s\n\nSummary of magic functions (from %slsmagic):"
483 "\n\n%s%s\n\n%s" % (outmsg,
483 "\n\n%s%s\n\n%s" % (outmsg,
484 magic_docs,mesc,mesc,
484 magic_docs,mesc,mesc,
485 (' '+mesc).join(self.lsmagic()),
485 (' '+mesc).join(self.lsmagic()),
486 Magic.auto_status[self.shell.rc.automagic] ) )
486 Magic.auto_status[self.shell.rc.automagic] ) )
487
487
488 page(outmsg,screen_lines=self.shell.rc.screen_length)
488 page(outmsg,screen_lines=self.shell.rc.screen_length)
489
489
490
490
491 def magic_autoindent(self, parameter_s = ''):
491 def magic_autoindent(self, parameter_s = ''):
492 """Toggle autoindent on/off (if available)."""
492 """Toggle autoindent on/off (if available)."""
493
493
494 self.shell.set_autoindent()
494 self.shell.set_autoindent()
495 print "Automatic indentation is:",['OFF','ON'][self.shell.autoindent]
495 print "Automatic indentation is:",['OFF','ON'][self.shell.autoindent]
496
496
497
497
498 def magic_automagic(self, parameter_s = ''):
498 def magic_automagic(self, parameter_s = ''):
499 """Make magic functions callable without having to type the initial %.
499 """Make magic functions callable without having to type the initial %.
500
500
501 Without argumentsl toggles on/off (when off, you must call it as
501 Without argumentsl toggles on/off (when off, you must call it as
502 %automagic, of course). With arguments it sets the value, and you can
502 %automagic, of course). With arguments it sets the value, and you can
503 use any of (case insensitive):
503 use any of (case insensitive):
504
504
505 - on,1,True: to activate
505 - on,1,True: to activate
506
506
507 - off,0,False: to deactivate.
507 - off,0,False: to deactivate.
508
508
509 Note that magic functions have lowest priority, so if there's a
509 Note that magic functions have lowest priority, so if there's a
510 variable whose name collides with that of a magic fn, automagic won't
510 variable whose name collides with that of a magic fn, automagic won't
511 work for that function (you get the variable instead). However, if you
511 work for that function (you get the variable instead). However, if you
512 delete the variable (del var), the previously shadowed magic function
512 delete the variable (del var), the previously shadowed magic function
513 becomes visible to automagic again."""
513 becomes visible to automagic again."""
514
514
515 rc = self.shell.rc
515 rc = self.shell.rc
516 arg = parameter_s.lower()
516 arg = parameter_s.lower()
517 if parameter_s in ('on','1','true'):
517 if parameter_s in ('on','1','true'):
518 rc.automagic = True
518 rc.automagic = True
519 elif parameter_s in ('off','0','false'):
519 elif parameter_s in ('off','0','false'):
520 rc.automagic = False
520 rc.automagic = False
521 else:
521 else:
522 rc.automagic = not rc.automagic
522 rc.automagic = not rc.automagic
523 print '\n' + Magic.auto_status[rc.automagic]
523 print '\n' + Magic.auto_status[rc.automagic]
524
524
525 @testdec.skip_doctest
525 @testdec.skip_doctest
526 def magic_autocall(self, parameter_s = ''):
526 def magic_autocall(self, parameter_s = ''):
527 """Make functions callable without having to type parentheses.
527 """Make functions callable without having to type parentheses.
528
528
529 Usage:
529 Usage:
530
530
531 %autocall [mode]
531 %autocall [mode]
532
532
533 The mode can be one of: 0->Off, 1->Smart, 2->Full. If not given, the
533 The mode can be one of: 0->Off, 1->Smart, 2->Full. If not given, the
534 value is toggled on and off (remembering the previous state).
534 value is toggled on and off (remembering the previous state).
535
535
536 In more detail, these values mean:
536 In more detail, these values mean:
537
537
538 0 -> fully disabled
538 0 -> fully disabled
539
539
540 1 -> active, but do not apply if there are no arguments on the line.
540 1 -> active, but do not apply if there are no arguments on the line.
541
541
542 In this mode, you get:
542 In this mode, you get:
543
543
544 In [1]: callable
544 In [1]: callable
545 Out[1]: <built-in function callable>
545 Out[1]: <built-in function callable>
546
546
547 In [2]: callable 'hello'
547 In [2]: callable 'hello'
548 ------> callable('hello')
548 ------> callable('hello')
549 Out[2]: False
549 Out[2]: False
550
550
551 2 -> Active always. Even if no arguments are present, the callable
551 2 -> Active always. Even if no arguments are present, the callable
552 object is called:
552 object is called:
553
553
554 In [2]: float
554 In [2]: float
555 ------> float()
555 ------> float()
556 Out[2]: 0.0
556 Out[2]: 0.0
557
557
558 Note that even with autocall off, you can still use '/' at the start of
558 Note that even with autocall off, you can still use '/' at the start of
559 a line to treat the first argument on the command line as a function
559 a line to treat the first argument on the command line as a function
560 and add parentheses to it:
560 and add parentheses to it:
561
561
562 In [8]: /str 43
562 In [8]: /str 43
563 ------> str(43)
563 ------> str(43)
564 Out[8]: '43'
564 Out[8]: '43'
565
565
566 # all-random (note for auto-testing)
566 # all-random (note for auto-testing)
567 """
567 """
568
568
569 rc = self.shell.rc
569 rc = self.shell.rc
570
570
571 if parameter_s:
571 if parameter_s:
572 arg = int(parameter_s)
572 arg = int(parameter_s)
573 else:
573 else:
574 arg = 'toggle'
574 arg = 'toggle'
575
575
576 if not arg in (0,1,2,'toggle'):
576 if not arg in (0,1,2,'toggle'):
577 error('Valid modes: (0->Off, 1->Smart, 2->Full')
577 error('Valid modes: (0->Off, 1->Smart, 2->Full')
578 return
578 return
579
579
580 if arg in (0,1,2):
580 if arg in (0,1,2):
581 rc.autocall = arg
581 rc.autocall = arg
582 else: # toggle
582 else: # toggle
583 if rc.autocall:
583 if rc.autocall:
584 self._magic_state.autocall_save = rc.autocall
584 self._magic_state.autocall_save = rc.autocall
585 rc.autocall = 0
585 rc.autocall = 0
586 else:
586 else:
587 try:
587 try:
588 rc.autocall = self._magic_state.autocall_save
588 rc.autocall = self._magic_state.autocall_save
589 except AttributeError:
589 except AttributeError:
590 rc.autocall = self._magic_state.autocall_save = 1
590 rc.autocall = self._magic_state.autocall_save = 1
591
591
592 print "Automatic calling is:",['OFF','Smart','Full'][rc.autocall]
592 print "Automatic calling is:",['OFF','Smart','Full'][rc.autocall]
593
593
594 def magic_system_verbose(self, parameter_s = ''):
594 def magic_system_verbose(self, parameter_s = ''):
595 """Set verbose printing of system calls.
595 """Set verbose printing of system calls.
596
596
597 If called without an argument, act as a toggle"""
597 If called without an argument, act as a toggle"""
598
598
599 if parameter_s:
599 if parameter_s:
600 val = bool(eval(parameter_s))
600 val = bool(eval(parameter_s))
601 else:
601 else:
602 val = None
602 val = None
603
603
604 self.shell.rc_set_toggle('system_verbose',val)
604 self.shell.rc_set_toggle('system_verbose',val)
605 print "System verbose printing is:",\
605 print "System verbose printing is:",\
606 ['OFF','ON'][self.shell.rc.system_verbose]
606 ['OFF','ON'][self.shell.rc.system_verbose]
607
607
608
608
609 def magic_page(self, parameter_s=''):
609 def magic_page(self, parameter_s=''):
610 """Pretty print the object and display it through a pager.
610 """Pretty print the object and display it through a pager.
611
611
612 %page [options] OBJECT
612 %page [options] OBJECT
613
613
614 If no object is given, use _ (last output).
614 If no object is given, use _ (last output).
615
615
616 Options:
616 Options:
617
617
618 -r: page str(object), don't pretty-print it."""
618 -r: page str(object), don't pretty-print it."""
619
619
620 # After a function contributed by Olivier Aubert, slightly modified.
620 # After a function contributed by Olivier Aubert, slightly modified.
621
621
622 # Process options/args
622 # Process options/args
623 opts,args = self.parse_options(parameter_s,'r')
623 opts,args = self.parse_options(parameter_s,'r')
624 raw = 'r' in opts
624 raw = 'r' in opts
625
625
626 oname = args and args or '_'
626 oname = args and args or '_'
627 info = self._ofind(oname)
627 info = self._ofind(oname)
628 if info['found']:
628 if info['found']:
629 txt = (raw and str or pformat)( info['obj'] )
629 txt = (raw and str or pformat)( info['obj'] )
630 page(txt)
630 page(txt)
631 else:
631 else:
632 print 'Object `%s` not found' % oname
632 print 'Object `%s` not found' % oname
633
633
634 def magic_profile(self, parameter_s=''):
634 def magic_profile(self, parameter_s=''):
635 """Print your currently active IPyhton profile."""
635 """Print your currently active IPyhton profile."""
636 if self.shell.rc.profile:
636 if self.shell.rc.profile:
637 printpl('Current IPython profile: $self.shell.rc.profile.')
637 printpl('Current IPython profile: $self.shell.rc.profile.')
638 else:
638 else:
639 print 'No profile active.'
639 print 'No profile active.'
640
640
641 def magic_pinfo(self, parameter_s='', namespaces=None):
641 def magic_pinfo(self, parameter_s='', namespaces=None):
642 """Provide detailed information about an object.
642 """Provide detailed information about an object.
643
643
644 '%pinfo object' is just a synonym for object? or ?object."""
644 '%pinfo object' is just a synonym for object? or ?object."""
645
645
646 #print 'pinfo par: <%s>' % parameter_s # dbg
646 #print 'pinfo par: <%s>' % parameter_s # dbg
647
647
648
648
649 # detail_level: 0 -> obj? , 1 -> obj??
649 # detail_level: 0 -> obj? , 1 -> obj??
650 detail_level = 0
650 detail_level = 0
651 # We need to detect if we got called as 'pinfo pinfo foo', which can
651 # We need to detect if we got called as 'pinfo pinfo foo', which can
652 # happen if the user types 'pinfo foo?' at the cmd line.
652 # happen if the user types 'pinfo foo?' at the cmd line.
653 pinfo,qmark1,oname,qmark2 = \
653 pinfo,qmark1,oname,qmark2 = \
654 re.match('(pinfo )?(\?*)(.*?)(\??$)',parameter_s).groups()
654 re.match('(pinfo )?(\?*)(.*?)(\??$)',parameter_s).groups()
655 if pinfo or qmark1 or qmark2:
655 if pinfo or qmark1 or qmark2:
656 detail_level = 1
656 detail_level = 1
657 if "*" in oname:
657 if "*" in oname:
658 self.magic_psearch(oname)
658 self.magic_psearch(oname)
659 else:
659 else:
660 self._inspect('pinfo', oname, detail_level=detail_level,
660 self._inspect('pinfo', oname, detail_level=detail_level,
661 namespaces=namespaces)
661 namespaces=namespaces)
662
662
663 def magic_pdef(self, parameter_s='', namespaces=None):
663 def magic_pdef(self, parameter_s='', namespaces=None):
664 """Print the definition header for any callable object.
664 """Print the definition header for any callable object.
665
665
666 If the object is a class, print the constructor information."""
666 If the object is a class, print the constructor information."""
667 self._inspect('pdef',parameter_s, namespaces)
667 self._inspect('pdef',parameter_s, namespaces)
668
668
669 def magic_pdoc(self, parameter_s='', namespaces=None):
669 def magic_pdoc(self, parameter_s='', namespaces=None):
670 """Print the docstring for an object.
670 """Print the docstring for an object.
671
671
672 If the given object is a class, it will print both the class and the
672 If the given object is a class, it will print both the class and the
673 constructor docstrings."""
673 constructor docstrings."""
674 self._inspect('pdoc',parameter_s, namespaces)
674 self._inspect('pdoc',parameter_s, namespaces)
675
675
676 def magic_psource(self, parameter_s='', namespaces=None):
676 def magic_psource(self, parameter_s='', namespaces=None):
677 """Print (or run through pager) the source code for an object."""
677 """Print (or run through pager) the source code for an object."""
678 self._inspect('psource',parameter_s, namespaces)
678 self._inspect('psource',parameter_s, namespaces)
679
679
680 def magic_pfile(self, parameter_s=''):
680 def magic_pfile(self, parameter_s=''):
681 """Print (or run through pager) the file where an object is defined.
681 """Print (or run through pager) the file where an object is defined.
682
682
683 The file opens at the line where the object definition begins. IPython
683 The file opens at the line where the object definition begins. IPython
684 will honor the environment variable PAGER if set, and otherwise will
684 will honor the environment variable PAGER if set, and otherwise will
685 do its best to print the file in a convenient form.
685 do its best to print the file in a convenient form.
686
686
687 If the given argument is not an object currently defined, IPython will
687 If the given argument is not an object currently defined, IPython will
688 try to interpret it as a filename (automatically adding a .py extension
688 try to interpret it as a filename (automatically adding a .py extension
689 if needed). You can thus use %pfile as a syntax highlighting code
689 if needed). You can thus use %pfile as a syntax highlighting code
690 viewer."""
690 viewer."""
691
691
692 # first interpret argument as an object name
692 # first interpret argument as an object name
693 out = self._inspect('pfile',parameter_s)
693 out = self._inspect('pfile',parameter_s)
694 # if not, try the input as a filename
694 # if not, try the input as a filename
695 if out == 'not found':
695 if out == 'not found':
696 try:
696 try:
697 filename = get_py_filename(parameter_s)
697 filename = get_py_filename(parameter_s)
698 except IOError,msg:
698 except IOError,msg:
699 print msg
699 print msg
700 return
700 return
701 page(self.shell.inspector.format(file(filename).read()))
701 page(self.shell.inspector.format(file(filename).read()))
702
702
703 def _inspect(self,meth,oname,namespaces=None,**kw):
703 def _inspect(self,meth,oname,namespaces=None,**kw):
704 """Generic interface to the inspector system.
704 """Generic interface to the inspector system.
705
705
706 This function is meant to be called by pdef, pdoc & friends."""
706 This function is meant to be called by pdef, pdoc & friends."""
707
707
708 #oname = oname.strip()
708 #oname = oname.strip()
709 #print '1- oname: <%r>' % oname # dbg
709 #print '1- oname: <%r>' % oname # dbg
710 try:
710 try:
711 oname = oname.strip().encode('ascii')
711 oname = oname.strip().encode('ascii')
712 #print '2- oname: <%r>' % oname # dbg
712 #print '2- oname: <%r>' % oname # dbg
713 except UnicodeEncodeError:
713 except UnicodeEncodeError:
714 print 'Python identifiers can only contain ascii characters.'
714 print 'Python identifiers can only contain ascii characters.'
715 return 'not found'
715 return 'not found'
716
716
717 info = Struct(self._ofind(oname, namespaces))
717 info = Struct(self._ofind(oname, namespaces))
718
718
719 if info.found:
719 if info.found:
720 try:
720 try:
721 IPython.utils.generics.inspect_object(info.obj)
721 IPython.utils.generics.inspect_object(info.obj)
722 return
722 return
723 except ipapi.TryNext:
723 except ipapi.TryNext:
724 pass
724 pass
725 # Get the docstring of the class property if it exists.
725 # Get the docstring of the class property if it exists.
726 path = oname.split('.')
726 path = oname.split('.')
727 root = '.'.join(path[:-1])
727 root = '.'.join(path[:-1])
728 if info.parent is not None:
728 if info.parent is not None:
729 try:
729 try:
730 target = getattr(info.parent, '__class__')
730 target = getattr(info.parent, '__class__')
731 # The object belongs to a class instance.
731 # The object belongs to a class instance.
732 try:
732 try:
733 target = getattr(target, path[-1])
733 target = getattr(target, path[-1])
734 # The class defines the object.
734 # The class defines the object.
735 if isinstance(target, property):
735 if isinstance(target, property):
736 oname = root + '.__class__.' + path[-1]
736 oname = root + '.__class__.' + path[-1]
737 info = Struct(self._ofind(oname))
737 info = Struct(self._ofind(oname))
738 except AttributeError: pass
738 except AttributeError: pass
739 except AttributeError: pass
739 except AttributeError: pass
740
740
741 pmethod = getattr(self.shell.inspector,meth)
741 pmethod = getattr(self.shell.inspector,meth)
742 formatter = info.ismagic and self.format_screen or None
742 formatter = info.ismagic and self.format_screen or None
743 if meth == 'pdoc':
743 if meth == 'pdoc':
744 pmethod(info.obj,oname,formatter)
744 pmethod(info.obj,oname,formatter)
745 elif meth == 'pinfo':
745 elif meth == 'pinfo':
746 pmethod(info.obj,oname,formatter,info,**kw)
746 pmethod(info.obj,oname,formatter,info,**kw)
747 else:
747 else:
748 pmethod(info.obj,oname)
748 pmethod(info.obj,oname)
749 else:
749 else:
750 print 'Object `%s` not found.' % oname
750 print 'Object `%s` not found.' % oname
751 return 'not found' # so callers can take other action
751 return 'not found' # so callers can take other action
752
752
753 def magic_psearch(self, parameter_s=''):
753 def magic_psearch(self, parameter_s=''):
754 """Search for object in namespaces by wildcard.
754 """Search for object in namespaces by wildcard.
755
755
756 %psearch [options] PATTERN [OBJECT TYPE]
756 %psearch [options] PATTERN [OBJECT TYPE]
757
757
758 Note: ? can be used as a synonym for %psearch, at the beginning or at
758 Note: ? can be used as a synonym for %psearch, at the beginning or at
759 the end: both a*? and ?a* are equivalent to '%psearch a*'. Still, the
759 the end: both a*? and ?a* are equivalent to '%psearch a*'. Still, the
760 rest of the command line must be unchanged (options come first), so
760 rest of the command line must be unchanged (options come first), so
761 for example the following forms are equivalent
761 for example the following forms are equivalent
762
762
763 %psearch -i a* function
763 %psearch -i a* function
764 -i a* function?
764 -i a* function?
765 ?-i a* function
765 ?-i a* function
766
766
767 Arguments:
767 Arguments:
768
768
769 PATTERN
769 PATTERN
770
770
771 where PATTERN is a string containing * as a wildcard similar to its
771 where PATTERN is a string containing * as a wildcard similar to its
772 use in a shell. The pattern is matched in all namespaces on the
772 use in a shell. The pattern is matched in all namespaces on the
773 search path. By default objects starting with a single _ are not
773 search path. By default objects starting with a single _ are not
774 matched, many IPython generated objects have a single
774 matched, many IPython generated objects have a single
775 underscore. The default is case insensitive matching. Matching is
775 underscore. The default is case insensitive matching. Matching is
776 also done on the attributes of objects and not only on the objects
776 also done on the attributes of objects and not only on the objects
777 in a module.
777 in a module.
778
778
779 [OBJECT TYPE]
779 [OBJECT TYPE]
780
780
781 Is the name of a python type from the types module. The name is
781 Is the name of a python type from the types module. The name is
782 given in lowercase without the ending type, ex. StringType is
782 given in lowercase without the ending type, ex. StringType is
783 written string. By adding a type here only objects matching the
783 written string. By adding a type here only objects matching the
784 given type are matched. Using all here makes the pattern match all
784 given type are matched. Using all here makes the pattern match all
785 types (this is the default).
785 types (this is the default).
786
786
787 Options:
787 Options:
788
788
789 -a: makes the pattern match even objects whose names start with a
789 -a: makes the pattern match even objects whose names start with a
790 single underscore. These names are normally ommitted from the
790 single underscore. These names are normally ommitted from the
791 search.
791 search.
792
792
793 -i/-c: make the pattern case insensitive/sensitive. If neither of
793 -i/-c: make the pattern case insensitive/sensitive. If neither of
794 these options is given, the default is read from your ipythonrc
794 these options is given, the default is read from your ipythonrc
795 file. The option name which sets this value is
795 file. The option name which sets this value is
796 'wildcards_case_sensitive'. If this option is not specified in your
796 'wildcards_case_sensitive'. If this option is not specified in your
797 ipythonrc file, IPython's internal default is to do a case sensitive
797 ipythonrc file, IPython's internal default is to do a case sensitive
798 search.
798 search.
799
799
800 -e/-s NAMESPACE: exclude/search a given namespace. The pattern you
800 -e/-s NAMESPACE: exclude/search a given namespace. The pattern you
801 specifiy can be searched in any of the following namespaces:
801 specifiy can be searched in any of the following namespaces:
802 'builtin', 'user', 'user_global','internal', 'alias', where
802 'builtin', 'user', 'user_global','internal', 'alias', where
803 'builtin' and 'user' are the search defaults. Note that you should
803 'builtin' and 'user' are the search defaults. Note that you should
804 not use quotes when specifying namespaces.
804 not use quotes when specifying namespaces.
805
805
806 'Builtin' contains the python module builtin, 'user' contains all
806 'Builtin' contains the python module builtin, 'user' contains all
807 user data, 'alias' only contain the shell aliases and no python
807 user data, 'alias' only contain the shell aliases and no python
808 objects, 'internal' contains objects used by IPython. The
808 objects, 'internal' contains objects used by IPython. The
809 'user_global' namespace is only used by embedded IPython instances,
809 'user_global' namespace is only used by embedded IPython instances,
810 and it contains module-level globals. You can add namespaces to the
810 and it contains module-level globals. You can add namespaces to the
811 search with -s or exclude them with -e (these options can be given
811 search with -s or exclude them with -e (these options can be given
812 more than once).
812 more than once).
813
813
814 Examples:
814 Examples:
815
815
816 %psearch a* -> objects beginning with an a
816 %psearch a* -> objects beginning with an a
817 %psearch -e builtin a* -> objects NOT in the builtin space starting in a
817 %psearch -e builtin a* -> objects NOT in the builtin space starting in a
818 %psearch a* function -> all functions beginning with an a
818 %psearch a* function -> all functions beginning with an a
819 %psearch re.e* -> objects beginning with an e in module re
819 %psearch re.e* -> objects beginning with an e in module re
820 %psearch r*.e* -> objects that start with e in modules starting in r
820 %psearch r*.e* -> objects that start with e in modules starting in r
821 %psearch r*.* string -> all strings in modules beginning with r
821 %psearch r*.* string -> all strings in modules beginning with r
822
822
823 Case sensitve search:
823 Case sensitve search:
824
824
825 %psearch -c a* list all object beginning with lower case a
825 %psearch -c a* list all object beginning with lower case a
826
826
827 Show objects beginning with a single _:
827 Show objects beginning with a single _:
828
828
829 %psearch -a _* list objects beginning with a single underscore"""
829 %psearch -a _* list objects beginning with a single underscore"""
830 try:
830 try:
831 parameter_s = parameter_s.encode('ascii')
831 parameter_s = parameter_s.encode('ascii')
832 except UnicodeEncodeError:
832 except UnicodeEncodeError:
833 print 'Python identifiers can only contain ascii characters.'
833 print 'Python identifiers can only contain ascii characters.'
834 return
834 return
835
835
836 # default namespaces to be searched
836 # default namespaces to be searched
837 def_search = ['user','builtin']
837 def_search = ['user','builtin']
838
838
839 # Process options/args
839 # Process options/args
840 opts,args = self.parse_options(parameter_s,'cias:e:',list_all=True)
840 opts,args = self.parse_options(parameter_s,'cias:e:',list_all=True)
841 opt = opts.get
841 opt = opts.get
842 shell = self.shell
842 shell = self.shell
843 psearch = shell.inspector.psearch
843 psearch = shell.inspector.psearch
844
844
845 # select case options
845 # select case options
846 if opts.has_key('i'):
846 if opts.has_key('i'):
847 ignore_case = True
847 ignore_case = True
848 elif opts.has_key('c'):
848 elif opts.has_key('c'):
849 ignore_case = False
849 ignore_case = False
850 else:
850 else:
851 ignore_case = not shell.rc.wildcards_case_sensitive
851 ignore_case = not shell.rc.wildcards_case_sensitive
852
852
853 # Build list of namespaces to search from user options
853 # Build list of namespaces to search from user options
854 def_search.extend(opt('s',[]))
854 def_search.extend(opt('s',[]))
855 ns_exclude = ns_exclude=opt('e',[])
855 ns_exclude = ns_exclude=opt('e',[])
856 ns_search = [nm for nm in def_search if nm not in ns_exclude]
856 ns_search = [nm for nm in def_search if nm not in ns_exclude]
857
857
858 # Call the actual search
858 # Call the actual search
859 try:
859 try:
860 psearch(args,shell.ns_table,ns_search,
860 psearch(args,shell.ns_table,ns_search,
861 show_all=opt('a'),ignore_case=ignore_case)
861 show_all=opt('a'),ignore_case=ignore_case)
862 except:
862 except:
863 shell.showtraceback()
863 shell.showtraceback()
864
864
865 def magic_who_ls(self, parameter_s=''):
865 def magic_who_ls(self, parameter_s=''):
866 """Return a sorted list of all interactive variables.
866 """Return a sorted list of all interactive variables.
867
867
868 If arguments are given, only variables of types matching these
868 If arguments are given, only variables of types matching these
869 arguments are returned."""
869 arguments are returned."""
870
870
871 user_ns = self.shell.user_ns
871 user_ns = self.shell.user_ns
872 internal_ns = self.shell.internal_ns
872 internal_ns = self.shell.internal_ns
873 user_config_ns = self.shell.user_config_ns
873 user_config_ns = self.shell.user_config_ns
874 out = []
874 out = []
875 typelist = parameter_s.split()
875 typelist = parameter_s.split()
876
876
877 for i in user_ns:
877 for i in user_ns:
878 if not (i.startswith('_') or i.startswith('_i')) \
878 if not (i.startswith('_') or i.startswith('_i')) \
879 and not (i in internal_ns or i in user_config_ns):
879 and not (i in internal_ns or i in user_config_ns):
880 if typelist:
880 if typelist:
881 if type(user_ns[i]).__name__ in typelist:
881 if type(user_ns[i]).__name__ in typelist:
882 out.append(i)
882 out.append(i)
883 else:
883 else:
884 out.append(i)
884 out.append(i)
885 out.sort()
885 out.sort()
886 return out
886 return out
887
887
888 def magic_who(self, parameter_s=''):
888 def magic_who(self, parameter_s=''):
889 """Print all interactive variables, with some minimal formatting.
889 """Print all interactive variables, with some minimal formatting.
890
890
891 If any arguments are given, only variables whose type matches one of
891 If any arguments are given, only variables whose type matches one of
892 these are printed. For example:
892 these are printed. For example:
893
893
894 %who function str
894 %who function str
895
895
896 will only list functions and strings, excluding all other types of
896 will only list functions and strings, excluding all other types of
897 variables. To find the proper type names, simply use type(var) at a
897 variables. To find the proper type names, simply use type(var) at a
898 command line to see how python prints type names. For example:
898 command line to see how python prints type names. For example:
899
899
900 In [1]: type('hello')\\
900 In [1]: type('hello')\\
901 Out[1]: <type 'str'>
901 Out[1]: <type 'str'>
902
902
903 indicates that the type name for strings is 'str'.
903 indicates that the type name for strings is 'str'.
904
904
905 %who always excludes executed names loaded through your configuration
905 %who always excludes executed names loaded through your configuration
906 file and things which are internal to IPython.
906 file and things which are internal to IPython.
907
907
908 This is deliberate, as typically you may load many modules and the
908 This is deliberate, as typically you may load many modules and the
909 purpose of %who is to show you only what you've manually defined."""
909 purpose of %who is to show you only what you've manually defined."""
910
910
911 varlist = self.magic_who_ls(parameter_s)
911 varlist = self.magic_who_ls(parameter_s)
912 if not varlist:
912 if not varlist:
913 if parameter_s:
913 if parameter_s:
914 print 'No variables match your requested type.'
914 print 'No variables match your requested type.'
915 else:
915 else:
916 print 'Interactive namespace is empty.'
916 print 'Interactive namespace is empty.'
917 return
917 return
918
918
919 # if we have variables, move on...
919 # if we have variables, move on...
920 count = 0
920 count = 0
921 for i in varlist:
921 for i in varlist:
922 print i+'\t',
922 print i+'\t',
923 count += 1
923 count += 1
924 if count > 8:
924 if count > 8:
925 count = 0
925 count = 0
926 print
926 print
927 print
927 print
928
928
929 def magic_whos(self, parameter_s=''):
929 def magic_whos(self, parameter_s=''):
930 """Like %who, but gives some extra information about each variable.
930 """Like %who, but gives some extra information about each variable.
931
931
932 The same type filtering of %who can be applied here.
932 The same type filtering of %who can be applied here.
933
933
934 For all variables, the type is printed. Additionally it prints:
934 For all variables, the type is printed. Additionally it prints:
935
935
936 - For {},[],(): their length.
936 - For {},[],(): their length.
937
937
938 - For numpy and Numeric arrays, a summary with shape, number of
938 - For numpy and Numeric arrays, a summary with shape, number of
939 elements, typecode and size in memory.
939 elements, typecode and size in memory.
940
940
941 - Everything else: a string representation, snipping their middle if
941 - Everything else: a string representation, snipping their middle if
942 too long."""
942 too long."""
943
943
944 varnames = self.magic_who_ls(parameter_s)
944 varnames = self.magic_who_ls(parameter_s)
945 if not varnames:
945 if not varnames:
946 if parameter_s:
946 if parameter_s:
947 print 'No variables match your requested type.'
947 print 'No variables match your requested type.'
948 else:
948 else:
949 print 'Interactive namespace is empty.'
949 print 'Interactive namespace is empty.'
950 return
950 return
951
951
952 # if we have variables, move on...
952 # if we have variables, move on...
953
953
954 # for these types, show len() instead of data:
954 # for these types, show len() instead of data:
955 seq_types = [types.DictType,types.ListType,types.TupleType]
955 seq_types = [types.DictType,types.ListType,types.TupleType]
956
956
957 # for numpy/Numeric arrays, display summary info
957 # for numpy/Numeric arrays, display summary info
958 try:
958 try:
959 import numpy
959 import numpy
960 except ImportError:
960 except ImportError:
961 ndarray_type = None
961 ndarray_type = None
962 else:
962 else:
963 ndarray_type = numpy.ndarray.__name__
963 ndarray_type = numpy.ndarray.__name__
964 try:
964 try:
965 import Numeric
965 import Numeric
966 except ImportError:
966 except ImportError:
967 array_type = None
967 array_type = None
968 else:
968 else:
969 array_type = Numeric.ArrayType.__name__
969 array_type = Numeric.ArrayType.__name__
970
970
971 # Find all variable names and types so we can figure out column sizes
971 # Find all variable names and types so we can figure out column sizes
972 def get_vars(i):
972 def get_vars(i):
973 return self.shell.user_ns[i]
973 return self.shell.user_ns[i]
974
974
975 # some types are well known and can be shorter
975 # some types are well known and can be shorter
976 abbrevs = {'IPython.macro.Macro' : 'Macro'}
976 abbrevs = {'IPython.macro.Macro' : 'Macro'}
977 def type_name(v):
977 def type_name(v):
978 tn = type(v).__name__
978 tn = type(v).__name__
979 return abbrevs.get(tn,tn)
979 return abbrevs.get(tn,tn)
980
980
981 varlist = map(get_vars,varnames)
981 varlist = map(get_vars,varnames)
982
982
983 typelist = []
983 typelist = []
984 for vv in varlist:
984 for vv in varlist:
985 tt = type_name(vv)
985 tt = type_name(vv)
986
986
987 if tt=='instance':
987 if tt=='instance':
988 typelist.append( abbrevs.get(str(vv.__class__),
988 typelist.append( abbrevs.get(str(vv.__class__),
989 str(vv.__class__)))
989 str(vv.__class__)))
990 else:
990 else:
991 typelist.append(tt)
991 typelist.append(tt)
992
992
993 # column labels and # of spaces as separator
993 # column labels and # of spaces as separator
994 varlabel = 'Variable'
994 varlabel = 'Variable'
995 typelabel = 'Type'
995 typelabel = 'Type'
996 datalabel = 'Data/Info'
996 datalabel = 'Data/Info'
997 colsep = 3
997 colsep = 3
998 # variable format strings
998 # variable format strings
999 vformat = "$vname.ljust(varwidth)$vtype.ljust(typewidth)"
999 vformat = "$vname.ljust(varwidth)$vtype.ljust(typewidth)"
1000 vfmt_short = '$vstr[:25]<...>$vstr[-25:]'
1000 vfmt_short = '$vstr[:25]<...>$vstr[-25:]'
1001 aformat = "%s: %s elems, type `%s`, %s bytes"
1001 aformat = "%s: %s elems, type `%s`, %s bytes"
1002 # find the size of the columns to format the output nicely
1002 # find the size of the columns to format the output nicely
1003 varwidth = max(max(map(len,varnames)), len(varlabel)) + colsep
1003 varwidth = max(max(map(len,varnames)), len(varlabel)) + colsep
1004 typewidth = max(max(map(len,typelist)), len(typelabel)) + colsep
1004 typewidth = max(max(map(len,typelist)), len(typelabel)) + colsep
1005 # table header
1005 # table header
1006 print varlabel.ljust(varwidth) + typelabel.ljust(typewidth) + \
1006 print varlabel.ljust(varwidth) + typelabel.ljust(typewidth) + \
1007 ' '+datalabel+'\n' + '-'*(varwidth+typewidth+len(datalabel)+1)
1007 ' '+datalabel+'\n' + '-'*(varwidth+typewidth+len(datalabel)+1)
1008 # and the table itself
1008 # and the table itself
1009 kb = 1024
1009 kb = 1024
1010 Mb = 1048576 # kb**2
1010 Mb = 1048576 # kb**2
1011 for vname,var,vtype in zip(varnames,varlist,typelist):
1011 for vname,var,vtype in zip(varnames,varlist,typelist):
1012 print itpl(vformat),
1012 print itpl(vformat),
1013 if vtype in seq_types:
1013 if vtype in seq_types:
1014 print len(var)
1014 print len(var)
1015 elif vtype in [array_type,ndarray_type]:
1015 elif vtype in [array_type,ndarray_type]:
1016 vshape = str(var.shape).replace(',','').replace(' ','x')[1:-1]
1016 vshape = str(var.shape).replace(',','').replace(' ','x')[1:-1]
1017 if vtype==ndarray_type:
1017 if vtype==ndarray_type:
1018 # numpy
1018 # numpy
1019 vsize = var.size
1019 vsize = var.size
1020 vbytes = vsize*var.itemsize
1020 vbytes = vsize*var.itemsize
1021 vdtype = var.dtype
1021 vdtype = var.dtype
1022 else:
1022 else:
1023 # Numeric
1023 # Numeric
1024 vsize = Numeric.size(var)
1024 vsize = Numeric.size(var)
1025 vbytes = vsize*var.itemsize()
1025 vbytes = vsize*var.itemsize()
1026 vdtype = var.typecode()
1026 vdtype = var.typecode()
1027
1027
1028 if vbytes < 100000:
1028 if vbytes < 100000:
1029 print aformat % (vshape,vsize,vdtype,vbytes)
1029 print aformat % (vshape,vsize,vdtype,vbytes)
1030 else:
1030 else:
1031 print aformat % (vshape,vsize,vdtype,vbytes),
1031 print aformat % (vshape,vsize,vdtype,vbytes),
1032 if vbytes < Mb:
1032 if vbytes < Mb:
1033 print '(%s kb)' % (vbytes/kb,)
1033 print '(%s kb)' % (vbytes/kb,)
1034 else:
1034 else:
1035 print '(%s Mb)' % (vbytes/Mb,)
1035 print '(%s Mb)' % (vbytes/Mb,)
1036 else:
1036 else:
1037 try:
1037 try:
1038 vstr = str(var)
1038 vstr = str(var)
1039 except UnicodeEncodeError:
1039 except UnicodeEncodeError:
1040 vstr = unicode(var).encode(sys.getdefaultencoding(),
1040 vstr = unicode(var).encode(sys.getdefaultencoding(),
1041 'backslashreplace')
1041 'backslashreplace')
1042 vstr = vstr.replace('\n','\\n')
1042 vstr = vstr.replace('\n','\\n')
1043 if len(vstr) < 50:
1043 if len(vstr) < 50:
1044 print vstr
1044 print vstr
1045 else:
1045 else:
1046 printpl(vfmt_short)
1046 printpl(vfmt_short)
1047
1047
1048 def magic_reset(self, parameter_s=''):
1048 def magic_reset(self, parameter_s=''):
1049 """Resets the namespace by removing all names defined by the user.
1049 """Resets the namespace by removing all names defined by the user.
1050
1050
1051 Input/Output history are left around in case you need them.
1051 Input/Output history are left around in case you need them.
1052
1052
1053 Parameters
1053 Parameters
1054 ----------
1054 ----------
1055 -y : force reset without asking for confirmation.
1055 -y : force reset without asking for confirmation.
1056
1056
1057 Examples
1057 Examples
1058 --------
1058 --------
1059 In [6]: a = 1
1059 In [6]: a = 1
1060
1060
1061 In [7]: a
1061 In [7]: a
1062 Out[7]: 1
1062 Out[7]: 1
1063
1063
1064 In [8]: 'a' in _ip.user_ns
1064 In [8]: 'a' in _ip.user_ns
1065 Out[8]: True
1065 Out[8]: True
1066
1066
1067 In [9]: %reset -f
1067 In [9]: %reset -f
1068
1068
1069 In [10]: 'a' in _ip.user_ns
1069 In [10]: 'a' in _ip.user_ns
1070 Out[10]: False
1070 Out[10]: False
1071 """
1071 """
1072
1072
1073 if parameter_s == '-f':
1073 if parameter_s == '-f':
1074 ans = True
1074 ans = True
1075 else:
1075 else:
1076 ans = self.shell.ask_yes_no(
1076 ans = self.shell.ask_yes_no(
1077 "Once deleted, variables cannot be recovered. Proceed (y/[n])? ")
1077 "Once deleted, variables cannot be recovered. Proceed (y/[n])? ")
1078 if not ans:
1078 if not ans:
1079 print 'Nothing done.'
1079 print 'Nothing done.'
1080 return
1080 return
1081 user_ns = self.shell.user_ns
1081 user_ns = self.shell.user_ns
1082 for i in self.magic_who_ls():
1082 for i in self.magic_who_ls():
1083 del(user_ns[i])
1083 del(user_ns[i])
1084
1084
1085 # Also flush the private list of module references kept for script
1085 # Also flush the private list of module references kept for script
1086 # execution protection
1086 # execution protection
1087 self.shell.clear_main_mod_cache()
1087 self.shell.clear_main_mod_cache()
1088
1088
1089 def magic_logstart(self,parameter_s=''):
1089 def magic_logstart(self,parameter_s=''):
1090 """Start logging anywhere in a session.
1090 """Start logging anywhere in a session.
1091
1091
1092 %logstart [-o|-r|-t] [log_name [log_mode]]
1092 %logstart [-o|-r|-t] [log_name [log_mode]]
1093
1093
1094 If no name is given, it defaults to a file named 'ipython_log.py' in your
1094 If no name is given, it defaults to a file named 'ipython_log.py' in your
1095 current directory, in 'rotate' mode (see below).
1095 current directory, in 'rotate' mode (see below).
1096
1096
1097 '%logstart name' saves to file 'name' in 'backup' mode. It saves your
1097 '%logstart name' saves to file 'name' in 'backup' mode. It saves your
1098 history up to that point and then continues logging.
1098 history up to that point and then continues logging.
1099
1099
1100 %logstart takes a second optional parameter: logging mode. This can be one
1100 %logstart takes a second optional parameter: logging mode. This can be one
1101 of (note that the modes are given unquoted):\\
1101 of (note that the modes are given unquoted):\\
1102 append: well, that says it.\\
1102 append: well, that says it.\\
1103 backup: rename (if exists) to name~ and start name.\\
1103 backup: rename (if exists) to name~ and start name.\\
1104 global: single logfile in your home dir, appended to.\\
1104 global: single logfile in your home dir, appended to.\\
1105 over : overwrite existing log.\\
1105 over : overwrite existing log.\\
1106 rotate: create rotating logs name.1~, name.2~, etc.
1106 rotate: create rotating logs name.1~, name.2~, etc.
1107
1107
1108 Options:
1108 Options:
1109
1109
1110 -o: log also IPython's output. In this mode, all commands which
1110 -o: log also IPython's output. In this mode, all commands which
1111 generate an Out[NN] prompt are recorded to the logfile, right after
1111 generate an Out[NN] prompt are recorded to the logfile, right after
1112 their corresponding input line. The output lines are always
1112 their corresponding input line. The output lines are always
1113 prepended with a '#[Out]# ' marker, so that the log remains valid
1113 prepended with a '#[Out]# ' marker, so that the log remains valid
1114 Python code.
1114 Python code.
1115
1115
1116 Since this marker is always the same, filtering only the output from
1116 Since this marker is always the same, filtering only the output from
1117 a log is very easy, using for example a simple awk call:
1117 a log is very easy, using for example a simple awk call:
1118
1118
1119 awk -F'#\\[Out\\]# ' '{if($2) {print $2}}' ipython_log.py
1119 awk -F'#\\[Out\\]# ' '{if($2) {print $2}}' ipython_log.py
1120
1120
1121 -r: log 'raw' input. Normally, IPython's logs contain the processed
1121 -r: log 'raw' input. Normally, IPython's logs contain the processed
1122 input, so that user lines are logged in their final form, converted
1122 input, so that user lines are logged in their final form, converted
1123 into valid Python. For example, %Exit is logged as
1123 into valid Python. For example, %Exit is logged as
1124 '_ip.magic("Exit"). If the -r flag is given, all input is logged
1124 '_ip.magic("Exit"). If the -r flag is given, all input is logged
1125 exactly as typed, with no transformations applied.
1125 exactly as typed, with no transformations applied.
1126
1126
1127 -t: put timestamps before each input line logged (these are put in
1127 -t: put timestamps before each input line logged (these are put in
1128 comments)."""
1128 comments)."""
1129
1129
1130 opts,par = self.parse_options(parameter_s,'ort')
1130 opts,par = self.parse_options(parameter_s,'ort')
1131 log_output = 'o' in opts
1131 log_output = 'o' in opts
1132 log_raw_input = 'r' in opts
1132 log_raw_input = 'r' in opts
1133 timestamp = 't' in opts
1133 timestamp = 't' in opts
1134
1134
1135 rc = self.shell.rc
1135 rc = self.shell.rc
1136 logger = self.shell.logger
1136 logger = self.shell.logger
1137
1137
1138 # if no args are given, the defaults set in the logger constructor by
1138 # if no args are given, the defaults set in the logger constructor by
1139 # ipytohn remain valid
1139 # ipytohn remain valid
1140 if par:
1140 if par:
1141 try:
1141 try:
1142 logfname,logmode = par.split()
1142 logfname,logmode = par.split()
1143 except:
1143 except:
1144 logfname = par
1144 logfname = par
1145 logmode = 'backup'
1145 logmode = 'backup'
1146 else:
1146 else:
1147 logfname = logger.logfname
1147 logfname = logger.logfname
1148 logmode = logger.logmode
1148 logmode = logger.logmode
1149 # put logfname into rc struct as if it had been called on the command
1149 # put logfname into rc struct as if it had been called on the command
1150 # line, so it ends up saved in the log header Save it in case we need
1150 # line, so it ends up saved in the log header Save it in case we need
1151 # to restore it...
1151 # to restore it...
1152 old_logfile = rc.opts.get('logfile','')
1152 old_logfile = rc.opts.get('logfile','')
1153 if logfname:
1153 if logfname:
1154 logfname = os.path.expanduser(logfname)
1154 logfname = os.path.expanduser(logfname)
1155 rc.opts.logfile = logfname
1155 rc.opts.logfile = logfname
1156 loghead = self.shell.loghead_tpl % (rc.opts,rc.args)
1156 loghead = self.shell.loghead_tpl % (rc.opts,rc.args)
1157 try:
1157 try:
1158 started = logger.logstart(logfname,loghead,logmode,
1158 started = logger.logstart(logfname,loghead,logmode,
1159 log_output,timestamp,log_raw_input)
1159 log_output,timestamp,log_raw_input)
1160 except:
1160 except:
1161 rc.opts.logfile = old_logfile
1161 rc.opts.logfile = old_logfile
1162 warn("Couldn't start log: %s" % sys.exc_info()[1])
1162 warn("Couldn't start log: %s" % sys.exc_info()[1])
1163 else:
1163 else:
1164 # log input history up to this point, optionally interleaving
1164 # log input history up to this point, optionally interleaving
1165 # output if requested
1165 # output if requested
1166
1166
1167 if timestamp:
1167 if timestamp:
1168 # disable timestamping for the previous history, since we've
1168 # disable timestamping for the previous history, since we've
1169 # lost those already (no time machine here).
1169 # lost those already (no time machine here).
1170 logger.timestamp = False
1170 logger.timestamp = False
1171
1171
1172 if log_raw_input:
1172 if log_raw_input:
1173 input_hist = self.shell.input_hist_raw
1173 input_hist = self.shell.input_hist_raw
1174 else:
1174 else:
1175 input_hist = self.shell.input_hist
1175 input_hist = self.shell.input_hist
1176
1176
1177 if log_output:
1177 if log_output:
1178 log_write = logger.log_write
1178 log_write = logger.log_write
1179 output_hist = self.shell.output_hist
1179 output_hist = self.shell.output_hist
1180 for n in range(1,len(input_hist)-1):
1180 for n in range(1,len(input_hist)-1):
1181 log_write(input_hist[n].rstrip())
1181 log_write(input_hist[n].rstrip())
1182 if n in output_hist:
1182 if n in output_hist:
1183 log_write(repr(output_hist[n]),'output')
1183 log_write(repr(output_hist[n]),'output')
1184 else:
1184 else:
1185 logger.log_write(input_hist[1:])
1185 logger.log_write(input_hist[1:])
1186 if timestamp:
1186 if timestamp:
1187 # re-enable timestamping
1187 # re-enable timestamping
1188 logger.timestamp = True
1188 logger.timestamp = True
1189
1189
1190 print ('Activating auto-logging. '
1190 print ('Activating auto-logging. '
1191 'Current session state plus future input saved.')
1191 'Current session state plus future input saved.')
1192 logger.logstate()
1192 logger.logstate()
1193
1193
1194 def magic_logstop(self,parameter_s=''):
1194 def magic_logstop(self,parameter_s=''):
1195 """Fully stop logging and close log file.
1195 """Fully stop logging and close log file.
1196
1196
1197 In order to start logging again, a new %logstart call needs to be made,
1197 In order to start logging again, a new %logstart call needs to be made,
1198 possibly (though not necessarily) with a new filename, mode and other
1198 possibly (though not necessarily) with a new filename, mode and other
1199 options."""
1199 options."""
1200 self.logger.logstop()
1200 self.logger.logstop()
1201
1201
1202 def magic_logoff(self,parameter_s=''):
1202 def magic_logoff(self,parameter_s=''):
1203 """Temporarily stop logging.
1203 """Temporarily stop logging.
1204
1204
1205 You must have previously started logging."""
1205 You must have previously started logging."""
1206 self.shell.logger.switch_log(0)
1206 self.shell.logger.switch_log(0)
1207
1207
1208 def magic_logon(self,parameter_s=''):
1208 def magic_logon(self,parameter_s=''):
1209 """Restart logging.
1209 """Restart logging.
1210
1210
1211 This function is for restarting logging which you've temporarily
1211 This function is for restarting logging which you've temporarily
1212 stopped with %logoff. For starting logging for the first time, you
1212 stopped with %logoff. For starting logging for the first time, you
1213 must use the %logstart function, which allows you to specify an
1213 must use the %logstart function, which allows you to specify an
1214 optional log filename."""
1214 optional log filename."""
1215
1215
1216 self.shell.logger.switch_log(1)
1216 self.shell.logger.switch_log(1)
1217
1217
1218 def magic_logstate(self,parameter_s=''):
1218 def magic_logstate(self,parameter_s=''):
1219 """Print the status of the logging system."""
1219 """Print the status of the logging system."""
1220
1220
1221 self.shell.logger.logstate()
1221 self.shell.logger.logstate()
1222
1222
1223 def magic_pdb(self, parameter_s=''):
1223 def magic_pdb(self, parameter_s=''):
1224 """Control the automatic calling of the pdb interactive debugger.
1224 """Control the automatic calling of the pdb interactive debugger.
1225
1225
1226 Call as '%pdb on', '%pdb 1', '%pdb off' or '%pdb 0'. If called without
1226 Call as '%pdb on', '%pdb 1', '%pdb off' or '%pdb 0'. If called without
1227 argument it works as a toggle.
1227 argument it works as a toggle.
1228
1228
1229 When an exception is triggered, IPython can optionally call the
1229 When an exception is triggered, IPython can optionally call the
1230 interactive pdb debugger after the traceback printout. %pdb toggles
1230 interactive pdb debugger after the traceback printout. %pdb toggles
1231 this feature on and off.
1231 this feature on and off.
1232
1232
1233 The initial state of this feature is set in your ipythonrc
1233 The initial state of this feature is set in your ipythonrc
1234 configuration file (the variable is called 'pdb').
1234 configuration file (the variable is called 'pdb').
1235
1235
1236 If you want to just activate the debugger AFTER an exception has fired,
1236 If you want to just activate the debugger AFTER an exception has fired,
1237 without having to type '%pdb on' and rerunning your code, you can use
1237 without having to type '%pdb on' and rerunning your code, you can use
1238 the %debug magic."""
1238 the %debug magic."""
1239
1239
1240 par = parameter_s.strip().lower()
1240 par = parameter_s.strip().lower()
1241
1241
1242 if par:
1242 if par:
1243 try:
1243 try:
1244 new_pdb = {'off':0,'0':0,'on':1,'1':1}[par]
1244 new_pdb = {'off':0,'0':0,'on':1,'1':1}[par]
1245 except KeyError:
1245 except KeyError:
1246 print ('Incorrect argument. Use on/1, off/0, '
1246 print ('Incorrect argument. Use on/1, off/0, '
1247 'or nothing for a toggle.')
1247 'or nothing for a toggle.')
1248 return
1248 return
1249 else:
1249 else:
1250 # toggle
1250 # toggle
1251 new_pdb = not self.shell.call_pdb
1251 new_pdb = not self.shell.call_pdb
1252
1252
1253 # set on the shell
1253 # set on the shell
1254 self.shell.call_pdb = new_pdb
1254 self.shell.call_pdb = new_pdb
1255 print 'Automatic pdb calling has been turned',on_off(new_pdb)
1255 print 'Automatic pdb calling has been turned',on_off(new_pdb)
1256
1256
1257 def magic_debug(self, parameter_s=''):
1257 def magic_debug(self, parameter_s=''):
1258 """Activate the interactive debugger in post-mortem mode.
1258 """Activate the interactive debugger in post-mortem mode.
1259
1259
1260 If an exception has just occurred, this lets you inspect its stack
1260 If an exception has just occurred, this lets you inspect its stack
1261 frames interactively. Note that this will always work only on the last
1261 frames interactively. Note that this will always work only on the last
1262 traceback that occurred, so you must call this quickly after an
1262 traceback that occurred, so you must call this quickly after an
1263 exception that you wish to inspect has fired, because if another one
1263 exception that you wish to inspect has fired, because if another one
1264 occurs, it clobbers the previous one.
1264 occurs, it clobbers the previous one.
1265
1265
1266 If you want IPython to automatically do this on every exception, see
1266 If you want IPython to automatically do this on every exception, see
1267 the %pdb magic for more details.
1267 the %pdb magic for more details.
1268 """
1268 """
1269
1269
1270 self.shell.debugger(force=True)
1270 self.shell.debugger(force=True)
1271
1271
1272 @testdec.skip_doctest
1272 @testdec.skip_doctest
1273 def magic_prun(self, parameter_s ='',user_mode=1,
1273 def magic_prun(self, parameter_s ='',user_mode=1,
1274 opts=None,arg_lst=None,prog_ns=None):
1274 opts=None,arg_lst=None,prog_ns=None):
1275
1275
1276 """Run a statement through the python code profiler.
1276 """Run a statement through the python code profiler.
1277
1277
1278 Usage:
1278 Usage:
1279 %prun [options] statement
1279 %prun [options] statement
1280
1280
1281 The given statement (which doesn't require quote marks) is run via the
1281 The given statement (which doesn't require quote marks) is run via the
1282 python profiler in a manner similar to the profile.run() function.
1282 python profiler in a manner similar to the profile.run() function.
1283 Namespaces are internally managed to work correctly; profile.run
1283 Namespaces are internally managed to work correctly; profile.run
1284 cannot be used in IPython because it makes certain assumptions about
1284 cannot be used in IPython because it makes certain assumptions about
1285 namespaces which do not hold under IPython.
1285 namespaces which do not hold under IPython.
1286
1286
1287 Options:
1287 Options:
1288
1288
1289 -l <limit>: you can place restrictions on what or how much of the
1289 -l <limit>: you can place restrictions on what or how much of the
1290 profile gets printed. The limit value can be:
1290 profile gets printed. The limit value can be:
1291
1291
1292 * A string: only information for function names containing this string
1292 * A string: only information for function names containing this string
1293 is printed.
1293 is printed.
1294
1294
1295 * An integer: only these many lines are printed.
1295 * An integer: only these many lines are printed.
1296
1296
1297 * A float (between 0 and 1): this fraction of the report is printed
1297 * A float (between 0 and 1): this fraction of the report is printed
1298 (for example, use a limit of 0.4 to see the topmost 40% only).
1298 (for example, use a limit of 0.4 to see the topmost 40% only).
1299
1299
1300 You can combine several limits with repeated use of the option. For
1300 You can combine several limits with repeated use of the option. For
1301 example, '-l __init__ -l 5' will print only the topmost 5 lines of
1301 example, '-l __init__ -l 5' will print only the topmost 5 lines of
1302 information about class constructors.
1302 information about class constructors.
1303
1303
1304 -r: return the pstats.Stats object generated by the profiling. This
1304 -r: return the pstats.Stats object generated by the profiling. This
1305 object has all the information about the profile in it, and you can
1305 object has all the information about the profile in it, and you can
1306 later use it for further analysis or in other functions.
1306 later use it for further analysis or in other functions.
1307
1307
1308 -s <key>: sort profile by given key. You can provide more than one key
1308 -s <key>: sort profile by given key. You can provide more than one key
1309 by using the option several times: '-s key1 -s key2 -s key3...'. The
1309 by using the option several times: '-s key1 -s key2 -s key3...'. The
1310 default sorting key is 'time'.
1310 default sorting key is 'time'.
1311
1311
1312 The following is copied verbatim from the profile documentation
1312 The following is copied verbatim from the profile documentation
1313 referenced below:
1313 referenced below:
1314
1314
1315 When more than one key is provided, additional keys are used as
1315 When more than one key is provided, additional keys are used as
1316 secondary criteria when the there is equality in all keys selected
1316 secondary criteria when the there is equality in all keys selected
1317 before them.
1317 before them.
1318
1318
1319 Abbreviations can be used for any key names, as long as the
1319 Abbreviations can be used for any key names, as long as the
1320 abbreviation is unambiguous. The following are the keys currently
1320 abbreviation is unambiguous. The following are the keys currently
1321 defined:
1321 defined:
1322
1322
1323 Valid Arg Meaning
1323 Valid Arg Meaning
1324 "calls" call count
1324 "calls" call count
1325 "cumulative" cumulative time
1325 "cumulative" cumulative time
1326 "file" file name
1326 "file" file name
1327 "module" file name
1327 "module" file name
1328 "pcalls" primitive call count
1328 "pcalls" primitive call count
1329 "line" line number
1329 "line" line number
1330 "name" function name
1330 "name" function name
1331 "nfl" name/file/line
1331 "nfl" name/file/line
1332 "stdname" standard name
1332 "stdname" standard name
1333 "time" internal time
1333 "time" internal time
1334
1334
1335 Note that all sorts on statistics are in descending order (placing
1335 Note that all sorts on statistics are in descending order (placing
1336 most time consuming items first), where as name, file, and line number
1336 most time consuming items first), where as name, file, and line number
1337 searches are in ascending order (i.e., alphabetical). The subtle
1337 searches are in ascending order (i.e., alphabetical). The subtle
1338 distinction between "nfl" and "stdname" is that the standard name is a
1338 distinction between "nfl" and "stdname" is that the standard name is a
1339 sort of the name as printed, which means that the embedded line
1339 sort of the name as printed, which means that the embedded line
1340 numbers get compared in an odd way. For example, lines 3, 20, and 40
1340 numbers get compared in an odd way. For example, lines 3, 20, and 40
1341 would (if the file names were the same) appear in the string order
1341 would (if the file names were the same) appear in the string order
1342 "20" "3" and "40". In contrast, "nfl" does a numeric compare of the
1342 "20" "3" and "40". In contrast, "nfl" does a numeric compare of the
1343 line numbers. In fact, sort_stats("nfl") is the same as
1343 line numbers. In fact, sort_stats("nfl") is the same as
1344 sort_stats("name", "file", "line").
1344 sort_stats("name", "file", "line").
1345
1345
1346 -T <filename>: save profile results as shown on screen to a text
1346 -T <filename>: save profile results as shown on screen to a text
1347 file. The profile is still shown on screen.
1347 file. The profile is still shown on screen.
1348
1348
1349 -D <filename>: save (via dump_stats) profile statistics to given
1349 -D <filename>: save (via dump_stats) profile statistics to given
1350 filename. This data is in a format understod by the pstats module, and
1350 filename. This data is in a format understod by the pstats module, and
1351 is generated by a call to the dump_stats() method of profile
1351 is generated by a call to the dump_stats() method of profile
1352 objects. The profile is still shown on screen.
1352 objects. The profile is still shown on screen.
1353
1353
1354 If you want to run complete programs under the profiler's control, use
1354 If you want to run complete programs under the profiler's control, use
1355 '%run -p [prof_opts] filename.py [args to program]' where prof_opts
1355 '%run -p [prof_opts] filename.py [args to program]' where prof_opts
1356 contains profiler specific options as described here.
1356 contains profiler specific options as described here.
1357
1357
1358 You can read the complete documentation for the profile module with::
1358 You can read the complete documentation for the profile module with::
1359
1359
1360 In [1]: import profile; profile.help()
1360 In [1]: import profile; profile.help()
1361 """
1361 """
1362
1362
1363 opts_def = Struct(D=[''],l=[],s=['time'],T=[''])
1363 opts_def = Struct(D=[''],l=[],s=['time'],T=[''])
1364 # protect user quote marks
1364 # protect user quote marks
1365 parameter_s = parameter_s.replace('"',r'\"').replace("'",r"\'")
1365 parameter_s = parameter_s.replace('"',r'\"').replace("'",r"\'")
1366
1366
1367 if user_mode: # regular user call
1367 if user_mode: # regular user call
1368 opts,arg_str = self.parse_options(parameter_s,'D:l:rs:T:',
1368 opts,arg_str = self.parse_options(parameter_s,'D:l:rs:T:',
1369 list_all=1)
1369 list_all=1)
1370 namespace = self.shell.user_ns
1370 namespace = self.shell.user_ns
1371 else: # called to run a program by %run -p
1371 else: # called to run a program by %run -p
1372 try:
1372 try:
1373 filename = get_py_filename(arg_lst[0])
1373 filename = get_py_filename(arg_lst[0])
1374 except IOError,msg:
1374 except IOError,msg:
1375 error(msg)
1375 error(msg)
1376 return
1376 return
1377
1377
1378 arg_str = 'execfile(filename,prog_ns)'
1378 arg_str = 'execfile(filename,prog_ns)'
1379 namespace = locals()
1379 namespace = locals()
1380
1380
1381 opts.merge(opts_def)
1381 opts.merge(opts_def)
1382
1382
1383 prof = profile.Profile()
1383 prof = profile.Profile()
1384 try:
1384 try:
1385 prof = prof.runctx(arg_str,namespace,namespace)
1385 prof = prof.runctx(arg_str,namespace,namespace)
1386 sys_exit = ''
1386 sys_exit = ''
1387 except SystemExit:
1387 except SystemExit:
1388 sys_exit = """*** SystemExit exception caught in code being profiled."""
1388 sys_exit = """*** SystemExit exception caught in code being profiled."""
1389
1389
1390 stats = pstats.Stats(prof).strip_dirs().sort_stats(*opts.s)
1390 stats = pstats.Stats(prof).strip_dirs().sort_stats(*opts.s)
1391
1391
1392 lims = opts.l
1392 lims = opts.l
1393 if lims:
1393 if lims:
1394 lims = [] # rebuild lims with ints/floats/strings
1394 lims = [] # rebuild lims with ints/floats/strings
1395 for lim in opts.l:
1395 for lim in opts.l:
1396 try:
1396 try:
1397 lims.append(int(lim))
1397 lims.append(int(lim))
1398 except ValueError:
1398 except ValueError:
1399 try:
1399 try:
1400 lims.append(float(lim))
1400 lims.append(float(lim))
1401 except ValueError:
1401 except ValueError:
1402 lims.append(lim)
1402 lims.append(lim)
1403
1403
1404 # Trap output.
1404 # Trap output.
1405 stdout_trap = StringIO()
1405 stdout_trap = StringIO()
1406
1406
1407 if hasattr(stats,'stream'):
1407 if hasattr(stats,'stream'):
1408 # In newer versions of python, the stats object has a 'stream'
1408 # In newer versions of python, the stats object has a 'stream'
1409 # attribute to write into.
1409 # attribute to write into.
1410 stats.stream = stdout_trap
1410 stats.stream = stdout_trap
1411 stats.print_stats(*lims)
1411 stats.print_stats(*lims)
1412 else:
1412 else:
1413 # For older versions, we manually redirect stdout during printing
1413 # For older versions, we manually redirect stdout during printing
1414 sys_stdout = sys.stdout
1414 sys_stdout = sys.stdout
1415 try:
1415 try:
1416 sys.stdout = stdout_trap
1416 sys.stdout = stdout_trap
1417 stats.print_stats(*lims)
1417 stats.print_stats(*lims)
1418 finally:
1418 finally:
1419 sys.stdout = sys_stdout
1419 sys.stdout = sys_stdout
1420
1420
1421 output = stdout_trap.getvalue()
1421 output = stdout_trap.getvalue()
1422 output = output.rstrip()
1422 output = output.rstrip()
1423
1423
1424 page(output,screen_lines=self.shell.rc.screen_length)
1424 page(output,screen_lines=self.shell.rc.screen_length)
1425 print sys_exit,
1425 print sys_exit,
1426
1426
1427 dump_file = opts.D[0]
1427 dump_file = opts.D[0]
1428 text_file = opts.T[0]
1428 text_file = opts.T[0]
1429 if dump_file:
1429 if dump_file:
1430 prof.dump_stats(dump_file)
1430 prof.dump_stats(dump_file)
1431 print '\n*** Profile stats marshalled to file',\
1431 print '\n*** Profile stats marshalled to file',\
1432 `dump_file`+'.',sys_exit
1432 `dump_file`+'.',sys_exit
1433 if text_file:
1433 if text_file:
1434 pfile = file(text_file,'w')
1434 pfile = file(text_file,'w')
1435 pfile.write(output)
1435 pfile.write(output)
1436 pfile.close()
1436 pfile.close()
1437 print '\n*** Profile printout saved to text file',\
1437 print '\n*** Profile printout saved to text file',\
1438 `text_file`+'.',sys_exit
1438 `text_file`+'.',sys_exit
1439
1439
1440 if opts.has_key('r'):
1440 if opts.has_key('r'):
1441 return stats
1441 return stats
1442 else:
1442 else:
1443 return None
1443 return None
1444
1444
1445 @testdec.skip_doctest
1445 @testdec.skip_doctest
1446 def magic_run(self, parameter_s ='',runner=None,
1446 def magic_run(self, parameter_s ='',runner=None,
1447 file_finder=get_py_filename):
1447 file_finder=get_py_filename):
1448 """Run the named file inside IPython as a program.
1448 """Run the named file inside IPython as a program.
1449
1449
1450 Usage:\\
1450 Usage:\\
1451 %run [-n -i -t [-N<N>] -d [-b<N>] -p [profile options]] file [args]
1451 %run [-n -i -t [-N<N>] -d [-b<N>] -p [profile options]] file [args]
1452
1452
1453 Parameters after the filename are passed as command-line arguments to
1453 Parameters after the filename are passed as command-line arguments to
1454 the program (put in sys.argv). Then, control returns to IPython's
1454 the program (put in sys.argv). Then, control returns to IPython's
1455 prompt.
1455 prompt.
1456
1456
1457 This is similar to running at a system prompt:\\
1457 This is similar to running at a system prompt:\\
1458 $ python file args\\
1458 $ python file args\\
1459 but with the advantage of giving you IPython's tracebacks, and of
1459 but with the advantage of giving you IPython's tracebacks, and of
1460 loading all variables into your interactive namespace for further use
1460 loading all variables into your interactive namespace for further use
1461 (unless -p is used, see below).
1461 (unless -p is used, see below).
1462
1462
1463 The file is executed in a namespace initially consisting only of
1463 The file is executed in a namespace initially consisting only of
1464 __name__=='__main__' and sys.argv constructed as indicated. It thus
1464 __name__=='__main__' and sys.argv constructed as indicated. It thus
1465 sees its environment as if it were being run as a stand-alone program
1465 sees its environment as if it were being run as a stand-alone program
1466 (except for sharing global objects such as previously imported
1466 (except for sharing global objects such as previously imported
1467 modules). But after execution, the IPython interactive namespace gets
1467 modules). But after execution, the IPython interactive namespace gets
1468 updated with all variables defined in the program (except for __name__
1468 updated with all variables defined in the program (except for __name__
1469 and sys.argv). This allows for very convenient loading of code for
1469 and sys.argv). This allows for very convenient loading of code for
1470 interactive work, while giving each program a 'clean sheet' to run in.
1470 interactive work, while giving each program a 'clean sheet' to run in.
1471
1471
1472 Options:
1472 Options:
1473
1473
1474 -n: __name__ is NOT set to '__main__', but to the running file's name
1474 -n: __name__ is NOT set to '__main__', but to the running file's name
1475 without extension (as python does under import). This allows running
1475 without extension (as python does under import). This allows running
1476 scripts and reloading the definitions in them without calling code
1476 scripts and reloading the definitions in them without calling code
1477 protected by an ' if __name__ == "__main__" ' clause.
1477 protected by an ' if __name__ == "__main__" ' clause.
1478
1478
1479 -i: run the file in IPython's namespace instead of an empty one. This
1479 -i: run the file in IPython's namespace instead of an empty one. This
1480 is useful if you are experimenting with code written in a text editor
1480 is useful if you are experimenting with code written in a text editor
1481 which depends on variables defined interactively.
1481 which depends on variables defined interactively.
1482
1482
1483 -e: ignore sys.exit() calls or SystemExit exceptions in the script
1483 -e: ignore sys.exit() calls or SystemExit exceptions in the script
1484 being run. This is particularly useful if IPython is being used to
1484 being run. This is particularly useful if IPython is being used to
1485 run unittests, which always exit with a sys.exit() call. In such
1485 run unittests, which always exit with a sys.exit() call. In such
1486 cases you are interested in the output of the test results, not in
1486 cases you are interested in the output of the test results, not in
1487 seeing a traceback of the unittest module.
1487 seeing a traceback of the unittest module.
1488
1488
1489 -t: print timing information at the end of the run. IPython will give
1489 -t: print timing information at the end of the run. IPython will give
1490 you an estimated CPU time consumption for your script, which under
1490 you an estimated CPU time consumption for your script, which under
1491 Unix uses the resource module to avoid the wraparound problems of
1491 Unix uses the resource module to avoid the wraparound problems of
1492 time.clock(). Under Unix, an estimate of time spent on system tasks
1492 time.clock(). Under Unix, an estimate of time spent on system tasks
1493 is also given (for Windows platforms this is reported as 0.0).
1493 is also given (for Windows platforms this is reported as 0.0).
1494
1494
1495 If -t is given, an additional -N<N> option can be given, where <N>
1495 If -t is given, an additional -N<N> option can be given, where <N>
1496 must be an integer indicating how many times you want the script to
1496 must be an integer indicating how many times you want the script to
1497 run. The final timing report will include total and per run results.
1497 run. The final timing report will include total and per run results.
1498
1498
1499 For example (testing the script uniq_stable.py):
1499 For example (testing the script uniq_stable.py):
1500
1500
1501 In [1]: run -t uniq_stable
1501 In [1]: run -t uniq_stable
1502
1502
1503 IPython CPU timings (estimated):\\
1503 IPython CPU timings (estimated):\\
1504 User : 0.19597 s.\\
1504 User : 0.19597 s.\\
1505 System: 0.0 s.\\
1505 System: 0.0 s.\\
1506
1506
1507 In [2]: run -t -N5 uniq_stable
1507 In [2]: run -t -N5 uniq_stable
1508
1508
1509 IPython CPU timings (estimated):\\
1509 IPython CPU timings (estimated):\\
1510 Total runs performed: 5\\
1510 Total runs performed: 5\\
1511 Times : Total Per run\\
1511 Times : Total Per run\\
1512 User : 0.910862 s, 0.1821724 s.\\
1512 User : 0.910862 s, 0.1821724 s.\\
1513 System: 0.0 s, 0.0 s.
1513 System: 0.0 s, 0.0 s.
1514
1514
1515 -d: run your program under the control of pdb, the Python debugger.
1515 -d: run your program under the control of pdb, the Python debugger.
1516 This allows you to execute your program step by step, watch variables,
1516 This allows you to execute your program step by step, watch variables,
1517 etc. Internally, what IPython does is similar to calling:
1517 etc. Internally, what IPython does is similar to calling:
1518
1518
1519 pdb.run('execfile("YOURFILENAME")')
1519 pdb.run('execfile("YOURFILENAME")')
1520
1520
1521 with a breakpoint set on line 1 of your file. You can change the line
1521 with a breakpoint set on line 1 of your file. You can change the line
1522 number for this automatic breakpoint to be <N> by using the -bN option
1522 number for this automatic breakpoint to be <N> by using the -bN option
1523 (where N must be an integer). For example:
1523 (where N must be an integer). For example:
1524
1524
1525 %run -d -b40 myscript
1525 %run -d -b40 myscript
1526
1526
1527 will set the first breakpoint at line 40 in myscript.py. Note that
1527 will set the first breakpoint at line 40 in myscript.py. Note that
1528 the first breakpoint must be set on a line which actually does
1528 the first breakpoint must be set on a line which actually does
1529 something (not a comment or docstring) for it to stop execution.
1529 something (not a comment or docstring) for it to stop execution.
1530
1530
1531 When the pdb debugger starts, you will see a (Pdb) prompt. You must
1531 When the pdb debugger starts, you will see a (Pdb) prompt. You must
1532 first enter 'c' (without qoutes) to start execution up to the first
1532 first enter 'c' (without qoutes) to start execution up to the first
1533 breakpoint.
1533 breakpoint.
1534
1534
1535 Entering 'help' gives information about the use of the debugger. You
1535 Entering 'help' gives information about the use of the debugger. You
1536 can easily see pdb's full documentation with "import pdb;pdb.help()"
1536 can easily see pdb's full documentation with "import pdb;pdb.help()"
1537 at a prompt.
1537 at a prompt.
1538
1538
1539 -p: run program under the control of the Python profiler module (which
1539 -p: run program under the control of the Python profiler module (which
1540 prints a detailed report of execution times, function calls, etc).
1540 prints a detailed report of execution times, function calls, etc).
1541
1541
1542 You can pass other options after -p which affect the behavior of the
1542 You can pass other options after -p which affect the behavior of the
1543 profiler itself. See the docs for %prun for details.
1543 profiler itself. See the docs for %prun for details.
1544
1544
1545 In this mode, the program's variables do NOT propagate back to the
1545 In this mode, the program's variables do NOT propagate back to the
1546 IPython interactive namespace (because they remain in the namespace
1546 IPython interactive namespace (because they remain in the namespace
1547 where the profiler executes them).
1547 where the profiler executes them).
1548
1548
1549 Internally this triggers a call to %prun, see its documentation for
1549 Internally this triggers a call to %prun, see its documentation for
1550 details on the options available specifically for profiling.
1550 details on the options available specifically for profiling.
1551
1551
1552 There is one special usage for which the text above doesn't apply:
1552 There is one special usage for which the text above doesn't apply:
1553 if the filename ends with .ipy, the file is run as ipython script,
1553 if the filename ends with .ipy, the file is run as ipython script,
1554 just as if the commands were written on IPython prompt.
1554 just as if the commands were written on IPython prompt.
1555 """
1555 """
1556
1556
1557 # get arguments and set sys.argv for program to be run.
1557 # get arguments and set sys.argv for program to be run.
1558 opts,arg_lst = self.parse_options(parameter_s,'nidtN:b:pD:l:rs:T:e',
1558 opts,arg_lst = self.parse_options(parameter_s,'nidtN:b:pD:l:rs:T:e',
1559 mode='list',list_all=1)
1559 mode='list',list_all=1)
1560
1560
1561 try:
1561 try:
1562 filename = file_finder(arg_lst[0])
1562 filename = file_finder(arg_lst[0])
1563 except IndexError:
1563 except IndexError:
1564 warn('you must provide at least a filename.')
1564 warn('you must provide at least a filename.')
1565 print '\n%run:\n',OInspect.getdoc(self.magic_run)
1565 print '\n%run:\n',OInspect.getdoc(self.magic_run)
1566 return
1566 return
1567 except IOError,msg:
1567 except IOError,msg:
1568 error(msg)
1568 error(msg)
1569 return
1569 return
1570
1570
1571 if filename.lower().endswith('.ipy'):
1571 if filename.lower().endswith('.ipy'):
1572 self.api.runlines(open(filename).read())
1572 self.api.runlines(open(filename).read())
1573 return
1573 return
1574
1574
1575 # Control the response to exit() calls made by the script being run
1575 # Control the response to exit() calls made by the script being run
1576 exit_ignore = opts.has_key('e')
1576 exit_ignore = opts.has_key('e')
1577
1577
1578 # Make sure that the running script gets a proper sys.argv as if it
1578 # Make sure that the running script gets a proper sys.argv as if it
1579 # were run from a system shell.
1579 # were run from a system shell.
1580 save_argv = sys.argv # save it for later restoring
1580 save_argv = sys.argv # save it for later restoring
1581 sys.argv = [filename]+ arg_lst[1:] # put in the proper filename
1581 sys.argv = [filename]+ arg_lst[1:] # put in the proper filename
1582
1582
1583 if opts.has_key('i'):
1583 if opts.has_key('i'):
1584 # Run in user's interactive namespace
1584 # Run in user's interactive namespace
1585 prog_ns = self.shell.user_ns
1585 prog_ns = self.shell.user_ns
1586 __name__save = self.shell.user_ns['__name__']
1586 __name__save = self.shell.user_ns['__name__']
1587 prog_ns['__name__'] = '__main__'
1587 prog_ns['__name__'] = '__main__'
1588 main_mod = self.shell.new_main_mod(prog_ns)
1588 main_mod = self.shell.new_main_mod(prog_ns)
1589 else:
1589 else:
1590 # Run in a fresh, empty namespace
1590 # Run in a fresh, empty namespace
1591 if opts.has_key('n'):
1591 if opts.has_key('n'):
1592 name = os.path.splitext(os.path.basename(filename))[0]
1592 name = os.path.splitext(os.path.basename(filename))[0]
1593 else:
1593 else:
1594 name = '__main__'
1594 name = '__main__'
1595
1595
1596 main_mod = self.shell.new_main_mod()
1596 main_mod = self.shell.new_main_mod()
1597 prog_ns = main_mod.__dict__
1597 prog_ns = main_mod.__dict__
1598 prog_ns['__name__'] = name
1598 prog_ns['__name__'] = name
1599
1599
1600 # Since '%run foo' emulates 'python foo.py' at the cmd line, we must
1600 # Since '%run foo' emulates 'python foo.py' at the cmd line, we must
1601 # set the __file__ global in the script's namespace
1601 # set the __file__ global in the script's namespace
1602 prog_ns['__file__'] = filename
1602 prog_ns['__file__'] = filename
1603
1603
1604 # pickle fix. See iplib for an explanation. But we need to make sure
1604 # pickle fix. See iplib for an explanation. But we need to make sure
1605 # that, if we overwrite __main__, we replace it at the end
1605 # that, if we overwrite __main__, we replace it at the end
1606 main_mod_name = prog_ns['__name__']
1606 main_mod_name = prog_ns['__name__']
1607
1607
1608 if main_mod_name == '__main__':
1608 if main_mod_name == '__main__':
1609 restore_main = sys.modules['__main__']
1609 restore_main = sys.modules['__main__']
1610 else:
1610 else:
1611 restore_main = False
1611 restore_main = False
1612
1612
1613 # This needs to be undone at the end to prevent holding references to
1613 # This needs to be undone at the end to prevent holding references to
1614 # every single object ever created.
1614 # every single object ever created.
1615 sys.modules[main_mod_name] = main_mod
1615 sys.modules[main_mod_name] = main_mod
1616
1616
1617 stats = None
1617 stats = None
1618 try:
1618 try:
1619 self.shell.savehist()
1619 self.shell.savehist()
1620
1620
1621 if opts.has_key('p'):
1621 if opts.has_key('p'):
1622 stats = self.magic_prun('',0,opts,arg_lst,prog_ns)
1622 stats = self.magic_prun('',0,opts,arg_lst,prog_ns)
1623 else:
1623 else:
1624 if opts.has_key('d'):
1624 if opts.has_key('d'):
1625 deb = debugger.Pdb(self.shell.rc.colors)
1625 deb = debugger.Pdb(self.shell.rc.colors)
1626 # reset Breakpoint state, which is moronically kept
1626 # reset Breakpoint state, which is moronically kept
1627 # in a class
1627 # in a class
1628 bdb.Breakpoint.next = 1
1628 bdb.Breakpoint.next = 1
1629 bdb.Breakpoint.bplist = {}
1629 bdb.Breakpoint.bplist = {}
1630 bdb.Breakpoint.bpbynumber = [None]
1630 bdb.Breakpoint.bpbynumber = [None]
1631 # Set an initial breakpoint to stop execution
1631 # Set an initial breakpoint to stop execution
1632 maxtries = 10
1632 maxtries = 10
1633 bp = int(opts.get('b',[1])[0])
1633 bp = int(opts.get('b',[1])[0])
1634 checkline = deb.checkline(filename,bp)
1634 checkline = deb.checkline(filename,bp)
1635 if not checkline:
1635 if not checkline:
1636 for bp in range(bp+1,bp+maxtries+1):
1636 for bp in range(bp+1,bp+maxtries+1):
1637 if deb.checkline(filename,bp):
1637 if deb.checkline(filename,bp):
1638 break
1638 break
1639 else:
1639 else:
1640 msg = ("\nI failed to find a valid line to set "
1640 msg = ("\nI failed to find a valid line to set "
1641 "a breakpoint\n"
1641 "a breakpoint\n"
1642 "after trying up to line: %s.\n"
1642 "after trying up to line: %s.\n"
1643 "Please set a valid breakpoint manually "
1643 "Please set a valid breakpoint manually "
1644 "with the -b option." % bp)
1644 "with the -b option." % bp)
1645 error(msg)
1645 error(msg)
1646 return
1646 return
1647 # if we find a good linenumber, set the breakpoint
1647 # if we find a good linenumber, set the breakpoint
1648 deb.do_break('%s:%s' % (filename,bp))
1648 deb.do_break('%s:%s' % (filename,bp))
1649 # Start file run
1649 # Start file run
1650 print "NOTE: Enter 'c' at the",
1650 print "NOTE: Enter 'c' at the",
1651 print "%s prompt to start your script." % deb.prompt
1651 print "%s prompt to start your script." % deb.prompt
1652 try:
1652 try:
1653 deb.run('execfile("%s")' % filename,prog_ns)
1653 deb.run('execfile("%s")' % filename,prog_ns)
1654
1654
1655 except:
1655 except:
1656 etype, value, tb = sys.exc_info()
1656 etype, value, tb = sys.exc_info()
1657 # Skip three frames in the traceback: the %run one,
1657 # Skip three frames in the traceback: the %run one,
1658 # one inside bdb.py, and the command-line typed by the
1658 # one inside bdb.py, and the command-line typed by the
1659 # user (run by exec in pdb itself).
1659 # user (run by exec in pdb itself).
1660 self.shell.InteractiveTB(etype,value,tb,tb_offset=3)
1660 self.shell.InteractiveTB(etype,value,tb,tb_offset=3)
1661 else:
1661 else:
1662 if runner is None:
1662 if runner is None:
1663 runner = self.shell.safe_execfile
1663 runner = self.shell.safe_execfile
1664 if opts.has_key('t'):
1664 if opts.has_key('t'):
1665 # timed execution
1665 # timed execution
1666 try:
1666 try:
1667 nruns = int(opts['N'][0])
1667 nruns = int(opts['N'][0])
1668 if nruns < 1:
1668 if nruns < 1:
1669 error('Number of runs must be >=1')
1669 error('Number of runs must be >=1')
1670 return
1670 return
1671 except (KeyError):
1671 except (KeyError):
1672 nruns = 1
1672 nruns = 1
1673 if nruns == 1:
1673 if nruns == 1:
1674 t0 = clock2()
1674 t0 = clock2()
1675 runner(filename,prog_ns,prog_ns,
1675 runner(filename,prog_ns,prog_ns,
1676 exit_ignore=exit_ignore)
1676 exit_ignore=exit_ignore)
1677 t1 = clock2()
1677 t1 = clock2()
1678 t_usr = t1[0]-t0[0]
1678 t_usr = t1[0]-t0[0]
1679 t_sys = t1[1]-t0[1]
1679 t_sys = t1[1]-t0[1]
1680 print "\nIPython CPU timings (estimated):"
1680 print "\nIPython CPU timings (estimated):"
1681 print " User : %10s s." % t_usr
1681 print " User : %10s s." % t_usr
1682 print " System: %10s s." % t_sys
1682 print " System: %10s s." % t_sys
1683 else:
1683 else:
1684 runs = range(nruns)
1684 runs = range(nruns)
1685 t0 = clock2()
1685 t0 = clock2()
1686 for nr in runs:
1686 for nr in runs:
1687 runner(filename,prog_ns,prog_ns,
1687 runner(filename,prog_ns,prog_ns,
1688 exit_ignore=exit_ignore)
1688 exit_ignore=exit_ignore)
1689 t1 = clock2()
1689 t1 = clock2()
1690 t_usr = t1[0]-t0[0]
1690 t_usr = t1[0]-t0[0]
1691 t_sys = t1[1]-t0[1]
1691 t_sys = t1[1]-t0[1]
1692 print "\nIPython CPU timings (estimated):"
1692 print "\nIPython CPU timings (estimated):"
1693 print "Total runs performed:",nruns
1693 print "Total runs performed:",nruns
1694 print " Times : %10s %10s" % ('Total','Per run')
1694 print " Times : %10s %10s" % ('Total','Per run')
1695 print " User : %10s s, %10s s." % (t_usr,t_usr/nruns)
1695 print " User : %10s s, %10s s." % (t_usr,t_usr/nruns)
1696 print " System: %10s s, %10s s." % (t_sys,t_sys/nruns)
1696 print " System: %10s s, %10s s." % (t_sys,t_sys/nruns)
1697
1697
1698 else:
1698 else:
1699 # regular execution
1699 # regular execution
1700 runner(filename,prog_ns,prog_ns,exit_ignore=exit_ignore)
1700 runner(filename,prog_ns,prog_ns,exit_ignore=exit_ignore)
1701
1701
1702 if opts.has_key('i'):
1702 if opts.has_key('i'):
1703 self.shell.user_ns['__name__'] = __name__save
1703 self.shell.user_ns['__name__'] = __name__save
1704 else:
1704 else:
1705 # The shell MUST hold a reference to prog_ns so after %run
1705 # The shell MUST hold a reference to prog_ns so after %run
1706 # exits, the python deletion mechanism doesn't zero it out
1706 # exits, the python deletion mechanism doesn't zero it out
1707 # (leaving dangling references).
1707 # (leaving dangling references).
1708 self.shell.cache_main_mod(prog_ns,filename)
1708 self.shell.cache_main_mod(prog_ns,filename)
1709 # update IPython interactive namespace
1709 # update IPython interactive namespace
1710 del prog_ns['__name__']
1710 del prog_ns['__name__']
1711 self.shell.user_ns.update(prog_ns)
1711 self.shell.user_ns.update(prog_ns)
1712 finally:
1712 finally:
1713 # It's a bit of a mystery why, but __builtins__ can change from
1713 # It's a bit of a mystery why, but __builtins__ can change from
1714 # being a module to becoming a dict missing some key data after
1714 # being a module to becoming a dict missing some key data after
1715 # %run. As best I can see, this is NOT something IPython is doing
1715 # %run. As best I can see, this is NOT something IPython is doing
1716 # at all, and similar problems have been reported before:
1716 # at all, and similar problems have been reported before:
1717 # http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-10/0188.html
1717 # http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-10/0188.html
1718 # Since this seems to be done by the interpreter itself, the best
1718 # Since this seems to be done by the interpreter itself, the best
1719 # we can do is to at least restore __builtins__ for the user on
1719 # we can do is to at least restore __builtins__ for the user on
1720 # exit.
1720 # exit.
1721 self.shell.user_ns['__builtins__'] = __builtin__
1721 self.shell.user_ns['__builtins__'] = __builtin__
1722
1722
1723 # Ensure key global structures are restored
1723 # Ensure key global structures are restored
1724 sys.argv = save_argv
1724 sys.argv = save_argv
1725 if restore_main:
1725 if restore_main:
1726 sys.modules['__main__'] = restore_main
1726 sys.modules['__main__'] = restore_main
1727 else:
1727 else:
1728 # Remove from sys.modules the reference to main_mod we'd
1728 # Remove from sys.modules the reference to main_mod we'd
1729 # added. Otherwise it will trap references to objects
1729 # added. Otherwise it will trap references to objects
1730 # contained therein.
1730 # contained therein.
1731 del sys.modules[main_mod_name]
1731 del sys.modules[main_mod_name]
1732
1732
1733 self.shell.reloadhist()
1733 self.shell.reloadhist()
1734
1734
1735 return stats
1735 return stats
1736
1736
1737 def magic_runlog(self, parameter_s =''):
1737 def magic_runlog(self, parameter_s =''):
1738 """Run files as logs.
1738 """Run files as logs.
1739
1739
1740 Usage:\\
1740 Usage:\\
1741 %runlog file1 file2 ...
1741 %runlog file1 file2 ...
1742
1742
1743 Run the named files (treating them as log files) in sequence inside
1743 Run the named files (treating them as log files) in sequence inside
1744 the interpreter, and return to the prompt. This is much slower than
1744 the interpreter, and return to the prompt. This is much slower than
1745 %run because each line is executed in a try/except block, but it
1745 %run because each line is executed in a try/except block, but it
1746 allows running files with syntax errors in them.
1746 allows running files with syntax errors in them.
1747
1747
1748 Normally IPython will guess when a file is one of its own logfiles, so
1748 Normally IPython will guess when a file is one of its own logfiles, so
1749 you can typically use %run even for logs. This shorthand allows you to
1749 you can typically use %run even for logs. This shorthand allows you to
1750 force any file to be treated as a log file."""
1750 force any file to be treated as a log file."""
1751
1751
1752 for f in parameter_s.split():
1752 for f in parameter_s.split():
1753 self.shell.safe_execfile(f,self.shell.user_ns,
1753 self.shell.safe_execfile(f,self.shell.user_ns,
1754 self.shell.user_ns,islog=1)
1754 self.shell.user_ns,islog=1)
1755
1755
1756 @testdec.skip_doctest
1756 @testdec.skip_doctest
1757 def magic_timeit(self, parameter_s =''):
1757 def magic_timeit(self, parameter_s =''):
1758 """Time execution of a Python statement or expression
1758 """Time execution of a Python statement or expression
1759
1759
1760 Usage:\\
1760 Usage:\\
1761 %timeit [-n<N> -r<R> [-t|-c]] statement
1761 %timeit [-n<N> -r<R> [-t|-c]] statement
1762
1762
1763 Time execution of a Python statement or expression using the timeit
1763 Time execution of a Python statement or expression using the timeit
1764 module.
1764 module.
1765
1765
1766 Options:
1766 Options:
1767 -n<N>: execute the given statement <N> times in a loop. If this value
1767 -n<N>: execute the given statement <N> times in a loop. If this value
1768 is not given, a fitting value is chosen.
1768 is not given, a fitting value is chosen.
1769
1769
1770 -r<R>: repeat the loop iteration <R> times and take the best result.
1770 -r<R>: repeat the loop iteration <R> times and take the best result.
1771 Default: 3
1771 Default: 3
1772
1772
1773 -t: use time.time to measure the time, which is the default on Unix.
1773 -t: use time.time to measure the time, which is the default on Unix.
1774 This function measures wall time.
1774 This function measures wall time.
1775
1775
1776 -c: use time.clock to measure the time, which is the default on
1776 -c: use time.clock to measure the time, which is the default on
1777 Windows and measures wall time. On Unix, resource.getrusage is used
1777 Windows and measures wall time. On Unix, resource.getrusage is used
1778 instead and returns the CPU user time.
1778 instead and returns the CPU user time.
1779
1779
1780 -p<P>: use a precision of <P> digits to display the timing result.
1780 -p<P>: use a precision of <P> digits to display the timing result.
1781 Default: 3
1781 Default: 3
1782
1782
1783
1783
1784 Examples:
1784 Examples:
1785
1785
1786 In [1]: %timeit pass
1786 In [1]: %timeit pass
1787 10000000 loops, best of 3: 53.3 ns per loop
1787 10000000 loops, best of 3: 53.3 ns per loop
1788
1788
1789 In [2]: u = None
1789 In [2]: u = None
1790
1790
1791 In [3]: %timeit u is None
1791 In [3]: %timeit u is None
1792 10000000 loops, best of 3: 184 ns per loop
1792 10000000 loops, best of 3: 184 ns per loop
1793
1793
1794 In [4]: %timeit -r 4 u == None
1794 In [4]: %timeit -r 4 u == None
1795 1000000 loops, best of 4: 242 ns per loop
1795 1000000 loops, best of 4: 242 ns per loop
1796
1796
1797 In [5]: import time
1797 In [5]: import time
1798
1798
1799 In [6]: %timeit -n1 time.sleep(2)
1799 In [6]: %timeit -n1 time.sleep(2)
1800 1 loops, best of 3: 2 s per loop
1800 1 loops, best of 3: 2 s per loop
1801
1801
1802
1802
1803 The times reported by %timeit will be slightly higher than those
1803 The times reported by %timeit will be slightly higher than those
1804 reported by the timeit.py script when variables are accessed. This is
1804 reported by the timeit.py script when variables are accessed. This is
1805 due to the fact that %timeit executes the statement in the namespace
1805 due to the fact that %timeit executes the statement in the namespace
1806 of the shell, compared with timeit.py, which uses a single setup
1806 of the shell, compared with timeit.py, which uses a single setup
1807 statement to import function or create variables. Generally, the bias
1807 statement to import function or create variables. Generally, the bias
1808 does not matter as long as results from timeit.py are not mixed with
1808 does not matter as long as results from timeit.py are not mixed with
1809 those from %timeit."""
1809 those from %timeit."""
1810
1810
1811 import timeit
1811 import timeit
1812 import math
1812 import math
1813
1813
1814 # XXX: Unfortunately the unicode 'micro' symbol can cause problems in
1814 # XXX: Unfortunately the unicode 'micro' symbol can cause problems in
1815 # certain terminals. Until we figure out a robust way of
1815 # certain terminals. Until we figure out a robust way of
1816 # auto-detecting if the terminal can deal with it, use plain 'us' for
1816 # auto-detecting if the terminal can deal with it, use plain 'us' for
1817 # microseconds. I am really NOT happy about disabling the proper
1817 # microseconds. I am really NOT happy about disabling the proper
1818 # 'micro' prefix, but crashing is worse... If anyone knows what the
1818 # 'micro' prefix, but crashing is worse... If anyone knows what the
1819 # right solution for this is, I'm all ears...
1819 # right solution for this is, I'm all ears...
1820 #
1820 #
1821 # Note: using
1821 # Note: using
1822 #
1822 #
1823 # s = u'\xb5'
1823 # s = u'\xb5'
1824 # s.encode(sys.getdefaultencoding())
1824 # s.encode(sys.getdefaultencoding())
1825 #
1825 #
1826 # is not sufficient, as I've seen terminals where that fails but
1826 # is not sufficient, as I've seen terminals where that fails but
1827 # print s
1827 # print s
1828 #
1828 #
1829 # succeeds
1829 # succeeds
1830 #
1830 #
1831 # See bug: https://bugs.launchpad.net/ipython/+bug/348466
1831 # See bug: https://bugs.launchpad.net/ipython/+bug/348466
1832
1832
1833 #units = [u"s", u"ms",u'\xb5',"ns"]
1833 #units = [u"s", u"ms",u'\xb5',"ns"]
1834 units = [u"s", u"ms",u'us',"ns"]
1834 units = [u"s", u"ms",u'us',"ns"]
1835
1835
1836 scaling = [1, 1e3, 1e6, 1e9]
1836 scaling = [1, 1e3, 1e6, 1e9]
1837
1837
1838 opts, stmt = self.parse_options(parameter_s,'n:r:tcp:',
1838 opts, stmt = self.parse_options(parameter_s,'n:r:tcp:',
1839 posix=False)
1839 posix=False)
1840 if stmt == "":
1840 if stmt == "":
1841 return
1841 return
1842 timefunc = timeit.default_timer
1842 timefunc = timeit.default_timer
1843 number = int(getattr(opts, "n", 0))
1843 number = int(getattr(opts, "n", 0))
1844 repeat = int(getattr(opts, "r", timeit.default_repeat))
1844 repeat = int(getattr(opts, "r", timeit.default_repeat))
1845 precision = int(getattr(opts, "p", 3))
1845 precision = int(getattr(opts, "p", 3))
1846 if hasattr(opts, "t"):
1846 if hasattr(opts, "t"):
1847 timefunc = time.time
1847 timefunc = time.time
1848 if hasattr(opts, "c"):
1848 if hasattr(opts, "c"):
1849 timefunc = clock
1849 timefunc = clock
1850
1850
1851 timer = timeit.Timer(timer=timefunc)
1851 timer = timeit.Timer(timer=timefunc)
1852 # this code has tight coupling to the inner workings of timeit.Timer,
1852 # this code has tight coupling to the inner workings of timeit.Timer,
1853 # but is there a better way to achieve that the code stmt has access
1853 # but is there a better way to achieve that the code stmt has access
1854 # to the shell namespace?
1854 # to the shell namespace?
1855
1855
1856 src = timeit.template % {'stmt': timeit.reindent(stmt, 8),
1856 src = timeit.template % {'stmt': timeit.reindent(stmt, 8),
1857 'setup': "pass"}
1857 'setup': "pass"}
1858 # Track compilation time so it can be reported if too long
1858 # Track compilation time so it can be reported if too long
1859 # Minimum time above which compilation time will be reported
1859 # Minimum time above which compilation time will be reported
1860 tc_min = 0.1
1860 tc_min = 0.1
1861
1861
1862 t0 = clock()
1862 t0 = clock()
1863 code = compile(src, "<magic-timeit>", "exec")
1863 code = compile(src, "<magic-timeit>", "exec")
1864 tc = clock()-t0
1864 tc = clock()-t0
1865
1865
1866 ns = {}
1866 ns = {}
1867 exec code in self.shell.user_ns, ns
1867 exec code in self.shell.user_ns, ns
1868 timer.inner = ns["inner"]
1868 timer.inner = ns["inner"]
1869
1869
1870 if number == 0:
1870 if number == 0:
1871 # determine number so that 0.2 <= total time < 2.0
1871 # determine number so that 0.2 <= total time < 2.0
1872 number = 1
1872 number = 1
1873 for i in range(1, 10):
1873 for i in range(1, 10):
1874 if timer.timeit(number) >= 0.2:
1874 if timer.timeit(number) >= 0.2:
1875 break
1875 break
1876 number *= 10
1876 number *= 10
1877
1877
1878 best = min(timer.repeat(repeat, number)) / number
1878 best = min(timer.repeat(repeat, number)) / number
1879
1879
1880 if best > 0.0:
1880 if best > 0.0:
1881 order = min(-int(math.floor(math.log10(best)) // 3), 3)
1881 order = min(-int(math.floor(math.log10(best)) // 3), 3)
1882 else:
1882 else:
1883 order = 3
1883 order = 3
1884 print u"%d loops, best of %d: %.*g %s per loop" % (number, repeat,
1884 print u"%d loops, best of %d: %.*g %s per loop" % (number, repeat,
1885 precision,
1885 precision,
1886 best * scaling[order],
1886 best * scaling[order],
1887 units[order])
1887 units[order])
1888 if tc > tc_min:
1888 if tc > tc_min:
1889 print "Compiler time: %.2f s" % tc
1889 print "Compiler time: %.2f s" % tc
1890
1890
1891 @testdec.skip_doctest
1891 @testdec.skip_doctest
1892 def magic_time(self,parameter_s = ''):
1892 def magic_time(self,parameter_s = ''):
1893 """Time execution of a Python statement or expression.
1893 """Time execution of a Python statement or expression.
1894
1894
1895 The CPU and wall clock times are printed, and the value of the
1895 The CPU and wall clock times are printed, and the value of the
1896 expression (if any) is returned. Note that under Win32, system time
1896 expression (if any) is returned. Note that under Win32, system time
1897 is always reported as 0, since it can not be measured.
1897 is always reported as 0, since it can not be measured.
1898
1898
1899 This function provides very basic timing functionality. In Python
1899 This function provides very basic timing functionality. In Python
1900 2.3, the timeit module offers more control and sophistication, so this
1900 2.3, the timeit module offers more control and sophistication, so this
1901 could be rewritten to use it (patches welcome).
1901 could be rewritten to use it (patches welcome).
1902
1902
1903 Some examples:
1903 Some examples:
1904
1904
1905 In [1]: time 2**128
1905 In [1]: time 2**128
1906 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1906 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1907 Wall time: 0.00
1907 Wall time: 0.00
1908 Out[1]: 340282366920938463463374607431768211456L
1908 Out[1]: 340282366920938463463374607431768211456L
1909
1909
1910 In [2]: n = 1000000
1910 In [2]: n = 1000000
1911
1911
1912 In [3]: time sum(range(n))
1912 In [3]: time sum(range(n))
1913 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
1913 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
1914 Wall time: 1.37
1914 Wall time: 1.37
1915 Out[3]: 499999500000L
1915 Out[3]: 499999500000L
1916
1916
1917 In [4]: time print 'hello world'
1917 In [4]: time print 'hello world'
1918 hello world
1918 hello world
1919 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1919 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1920 Wall time: 0.00
1920 Wall time: 0.00
1921
1921
1922 Note that the time needed by Python to compile the given expression
1922 Note that the time needed by Python to compile the given expression
1923 will be reported if it is more than 0.1s. In this example, the
1923 will be reported if it is more than 0.1s. In this example, the
1924 actual exponentiation is done by Python at compilation time, so while
1924 actual exponentiation is done by Python at compilation time, so while
1925 the expression can take a noticeable amount of time to compute, that
1925 the expression can take a noticeable amount of time to compute, that
1926 time is purely due to the compilation:
1926 time is purely due to the compilation:
1927
1927
1928 In [5]: time 3**9999;
1928 In [5]: time 3**9999;
1929 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1929 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1930 Wall time: 0.00 s
1930 Wall time: 0.00 s
1931
1931
1932 In [6]: time 3**999999;
1932 In [6]: time 3**999999;
1933 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1933 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1934 Wall time: 0.00 s
1934 Wall time: 0.00 s
1935 Compiler : 0.78 s
1935 Compiler : 0.78 s
1936 """
1936 """
1937
1937
1938 # fail immediately if the given expression can't be compiled
1938 # fail immediately if the given expression can't be compiled
1939
1939
1940 expr = self.shell.prefilter(parameter_s,False)
1940 expr = self.shell.prefilter(parameter_s,False)
1941
1941
1942 # Minimum time above which compilation time will be reported
1942 # Minimum time above which compilation time will be reported
1943 tc_min = 0.1
1943 tc_min = 0.1
1944
1944
1945 try:
1945 try:
1946 mode = 'eval'
1946 mode = 'eval'
1947 t0 = clock()
1947 t0 = clock()
1948 code = compile(expr,'<timed eval>',mode)
1948 code = compile(expr,'<timed eval>',mode)
1949 tc = clock()-t0
1949 tc = clock()-t0
1950 except SyntaxError:
1950 except SyntaxError:
1951 mode = 'exec'
1951 mode = 'exec'
1952 t0 = clock()
1952 t0 = clock()
1953 code = compile(expr,'<timed exec>',mode)
1953 code = compile(expr,'<timed exec>',mode)
1954 tc = clock()-t0
1954 tc = clock()-t0
1955 # skew measurement as little as possible
1955 # skew measurement as little as possible
1956 glob = self.shell.user_ns
1956 glob = self.shell.user_ns
1957 clk = clock2
1957 clk = clock2
1958 wtime = time.time
1958 wtime = time.time
1959 # time execution
1959 # time execution
1960 wall_st = wtime()
1960 wall_st = wtime()
1961 if mode=='eval':
1961 if mode=='eval':
1962 st = clk()
1962 st = clk()
1963 out = eval(code,glob)
1963 out = eval(code,glob)
1964 end = clk()
1964 end = clk()
1965 else:
1965 else:
1966 st = clk()
1966 st = clk()
1967 exec code in glob
1967 exec code in glob
1968 end = clk()
1968 end = clk()
1969 out = None
1969 out = None
1970 wall_end = wtime()
1970 wall_end = wtime()
1971 # Compute actual times and report
1971 # Compute actual times and report
1972 wall_time = wall_end-wall_st
1972 wall_time = wall_end-wall_st
1973 cpu_user = end[0]-st[0]
1973 cpu_user = end[0]-st[0]
1974 cpu_sys = end[1]-st[1]
1974 cpu_sys = end[1]-st[1]
1975 cpu_tot = cpu_user+cpu_sys
1975 cpu_tot = cpu_user+cpu_sys
1976 print "CPU times: user %.2f s, sys: %.2f s, total: %.2f s" % \
1976 print "CPU times: user %.2f s, sys: %.2f s, total: %.2f s" % \
1977 (cpu_user,cpu_sys,cpu_tot)
1977 (cpu_user,cpu_sys,cpu_tot)
1978 print "Wall time: %.2f s" % wall_time
1978 print "Wall time: %.2f s" % wall_time
1979 if tc > tc_min:
1979 if tc > tc_min:
1980 print "Compiler : %.2f s" % tc
1980 print "Compiler : %.2f s" % tc
1981 return out
1981 return out
1982
1982
1983 @testdec.skip_doctest
1983 @testdec.skip_doctest
1984 def magic_macro(self,parameter_s = ''):
1984 def magic_macro(self,parameter_s = ''):
1985 """Define a set of input lines as a macro for future re-execution.
1985 """Define a set of input lines as a macro for future re-execution.
1986
1986
1987 Usage:\\
1987 Usage:\\
1988 %macro [options] name n1-n2 n3-n4 ... n5 .. n6 ...
1988 %macro [options] name n1-n2 n3-n4 ... n5 .. n6 ...
1989
1989
1990 Options:
1990 Options:
1991
1991
1992 -r: use 'raw' input. By default, the 'processed' history is used,
1992 -r: use 'raw' input. By default, the 'processed' history is used,
1993 so that magics are loaded in their transformed version to valid
1993 so that magics are loaded in their transformed version to valid
1994 Python. If this option is given, the raw input as typed as the
1994 Python. If this option is given, the raw input as typed as the
1995 command line is used instead.
1995 command line is used instead.
1996
1996
1997 This will define a global variable called `name` which is a string
1997 This will define a global variable called `name` which is a string
1998 made of joining the slices and lines you specify (n1,n2,... numbers
1998 made of joining the slices and lines you specify (n1,n2,... numbers
1999 above) from your input history into a single string. This variable
1999 above) from your input history into a single string. This variable
2000 acts like an automatic function which re-executes those lines as if
2000 acts like an automatic function which re-executes those lines as if
2001 you had typed them. You just type 'name' at the prompt and the code
2001 you had typed them. You just type 'name' at the prompt and the code
2002 executes.
2002 executes.
2003
2003
2004 The notation for indicating number ranges is: n1-n2 means 'use line
2004 The notation for indicating number ranges is: n1-n2 means 'use line
2005 numbers n1,...n2' (the endpoint is included). That is, '5-7' means
2005 numbers n1,...n2' (the endpoint is included). That is, '5-7' means
2006 using the lines numbered 5,6 and 7.
2006 using the lines numbered 5,6 and 7.
2007
2007
2008 Note: as a 'hidden' feature, you can also use traditional python slice
2008 Note: as a 'hidden' feature, you can also use traditional python slice
2009 notation, where N:M means numbers N through M-1.
2009 notation, where N:M means numbers N through M-1.
2010
2010
2011 For example, if your history contains (%hist prints it):
2011 For example, if your history contains (%hist prints it):
2012
2012
2013 44: x=1
2013 44: x=1
2014 45: y=3
2014 45: y=3
2015 46: z=x+y
2015 46: z=x+y
2016 47: print x
2016 47: print x
2017 48: a=5
2017 48: a=5
2018 49: print 'x',x,'y',y
2018 49: print 'x',x,'y',y
2019
2019
2020 you can create a macro with lines 44 through 47 (included) and line 49
2020 you can create a macro with lines 44 through 47 (included) and line 49
2021 called my_macro with:
2021 called my_macro with:
2022
2022
2023 In [55]: %macro my_macro 44-47 49
2023 In [55]: %macro my_macro 44-47 49
2024
2024
2025 Now, typing `my_macro` (without quotes) will re-execute all this code
2025 Now, typing `my_macro` (without quotes) will re-execute all this code
2026 in one pass.
2026 in one pass.
2027
2027
2028 You don't need to give the line-numbers in order, and any given line
2028 You don't need to give the line-numbers in order, and any given line
2029 number can appear multiple times. You can assemble macros with any
2029 number can appear multiple times. You can assemble macros with any
2030 lines from your input history in any order.
2030 lines from your input history in any order.
2031
2031
2032 The macro is a simple object which holds its value in an attribute,
2032 The macro is a simple object which holds its value in an attribute,
2033 but IPython's display system checks for macros and executes them as
2033 but IPython's display system checks for macros and executes them as
2034 code instead of printing them when you type their name.
2034 code instead of printing them when you type their name.
2035
2035
2036 You can view a macro's contents by explicitly printing it with:
2036 You can view a macro's contents by explicitly printing it with:
2037
2037
2038 'print macro_name'.
2038 'print macro_name'.
2039
2039
2040 For one-off cases which DON'T contain magic function calls in them you
2040 For one-off cases which DON'T contain magic function calls in them you
2041 can obtain similar results by explicitly executing slices from your
2041 can obtain similar results by explicitly executing slices from your
2042 input history with:
2042 input history with:
2043
2043
2044 In [60]: exec In[44:48]+In[49]"""
2044 In [60]: exec In[44:48]+In[49]"""
2045
2045
2046 opts,args = self.parse_options(parameter_s,'r',mode='list')
2046 opts,args = self.parse_options(parameter_s,'r',mode='list')
2047 if not args:
2047 if not args:
2048 macs = [k for k,v in self.shell.user_ns.items() if isinstance(v, Macro)]
2048 macs = [k for k,v in self.shell.user_ns.items() if isinstance(v, Macro)]
2049 macs.sort()
2049 macs.sort()
2050 return macs
2050 return macs
2051 if len(args) == 1:
2051 if len(args) == 1:
2052 raise UsageError(
2052 raise UsageError(
2053 "%macro insufficient args; usage '%macro name n1-n2 n3-4...")
2053 "%macro insufficient args; usage '%macro name n1-n2 n3-4...")
2054 name,ranges = args[0], args[1:]
2054 name,ranges = args[0], args[1:]
2055
2055
2056 #print 'rng',ranges # dbg
2056 #print 'rng',ranges # dbg
2057 lines = self.extract_input_slices(ranges,opts.has_key('r'))
2057 lines = self.extract_input_slices(ranges,opts.has_key('r'))
2058 macro = Macro(lines)
2058 macro = Macro(lines)
2059 self.shell.user_ns.update({name:macro})
2059 self.shell.user_ns.update({name:macro})
2060 print 'Macro `%s` created. To execute, type its name (without quotes).' % name
2060 print 'Macro `%s` created. To execute, type its name (without quotes).' % name
2061 print 'Macro contents:'
2061 print 'Macro contents:'
2062 print macro,
2062 print macro,
2063
2063
2064 def magic_save(self,parameter_s = ''):
2064 def magic_save(self,parameter_s = ''):
2065 """Save a set of lines to a given filename.
2065 """Save a set of lines to a given filename.
2066
2066
2067 Usage:\\
2067 Usage:\\
2068 %save [options] filename n1-n2 n3-n4 ... n5 .. n6 ...
2068 %save [options] filename n1-n2 n3-n4 ... n5 .. n6 ...
2069
2069
2070 Options:
2070 Options:
2071
2071
2072 -r: use 'raw' input. By default, the 'processed' history is used,
2072 -r: use 'raw' input. By default, the 'processed' history is used,
2073 so that magics are loaded in their transformed version to valid
2073 so that magics are loaded in their transformed version to valid
2074 Python. If this option is given, the raw input as typed as the
2074 Python. If this option is given, the raw input as typed as the
2075 command line is used instead.
2075 command line is used instead.
2076
2076
2077 This function uses the same syntax as %macro for line extraction, but
2077 This function uses the same syntax as %macro for line extraction, but
2078 instead of creating a macro it saves the resulting string to the
2078 instead of creating a macro it saves the resulting string to the
2079 filename you specify.
2079 filename you specify.
2080
2080
2081 It adds a '.py' extension to the file if you don't do so yourself, and
2081 It adds a '.py' extension to the file if you don't do so yourself, and
2082 it asks for confirmation before overwriting existing files."""
2082 it asks for confirmation before overwriting existing files."""
2083
2083
2084 opts,args = self.parse_options(parameter_s,'r',mode='list')
2084 opts,args = self.parse_options(parameter_s,'r',mode='list')
2085 fname,ranges = args[0], args[1:]
2085 fname,ranges = args[0], args[1:]
2086 if not fname.endswith('.py'):
2086 if not fname.endswith('.py'):
2087 fname += '.py'
2087 fname += '.py'
2088 if os.path.isfile(fname):
2088 if os.path.isfile(fname):
2089 ans = raw_input('File `%s` exists. Overwrite (y/[N])? ' % fname)
2089 ans = raw_input('File `%s` exists. Overwrite (y/[N])? ' % fname)
2090 if ans.lower() not in ['y','yes']:
2090 if ans.lower() not in ['y','yes']:
2091 print 'Operation cancelled.'
2091 print 'Operation cancelled.'
2092 return
2092 return
2093 cmds = ''.join(self.extract_input_slices(ranges,opts.has_key('r')))
2093 cmds = ''.join(self.extract_input_slices(ranges,opts.has_key('r')))
2094 f = file(fname,'w')
2094 f = file(fname,'w')
2095 f.write(cmds)
2095 f.write(cmds)
2096 f.close()
2096 f.close()
2097 print 'The following commands were written to file `%s`:' % fname
2097 print 'The following commands were written to file `%s`:' % fname
2098 print cmds
2098 print cmds
2099
2099
2100 def _edit_macro(self,mname,macro):
2100 def _edit_macro(self,mname,macro):
2101 """open an editor with the macro data in a file"""
2101 """open an editor with the macro data in a file"""
2102 filename = self.shell.mktempfile(macro.value)
2102 filename = self.shell.mktempfile(macro.value)
2103 self.shell.hooks.editor(filename)
2103 self.shell.hooks.editor(filename)
2104
2104
2105 # and make a new macro object, to replace the old one
2105 # and make a new macro object, to replace the old one
2106 mfile = open(filename)
2106 mfile = open(filename)
2107 mvalue = mfile.read()
2107 mvalue = mfile.read()
2108 mfile.close()
2108 mfile.close()
2109 self.shell.user_ns[mname] = Macro(mvalue)
2109 self.shell.user_ns[mname] = Macro(mvalue)
2110
2110
2111 def magic_ed(self,parameter_s=''):
2111 def magic_ed(self,parameter_s=''):
2112 """Alias to %edit."""
2112 """Alias to %edit."""
2113 return self.magic_edit(parameter_s)
2113 return self.magic_edit(parameter_s)
2114
2114
2115 @testdec.skip_doctest
2115 @testdec.skip_doctest
2116 def magic_edit(self,parameter_s='',last_call=['','']):
2116 def magic_edit(self,parameter_s='',last_call=['','']):
2117 """Bring up an editor and execute the resulting code.
2117 """Bring up an editor and execute the resulting code.
2118
2118
2119 Usage:
2119 Usage:
2120 %edit [options] [args]
2120 %edit [options] [args]
2121
2121
2122 %edit runs IPython's editor hook. The default version of this hook is
2122 %edit runs IPython's editor hook. The default version of this hook is
2123 set to call the __IPYTHON__.rc.editor command. This is read from your
2123 set to call the __IPYTHON__.rc.editor command. This is read from your
2124 environment variable $EDITOR. If this isn't found, it will default to
2124 environment variable $EDITOR. If this isn't found, it will default to
2125 vi under Linux/Unix and to notepad under Windows. See the end of this
2125 vi under Linux/Unix and to notepad under Windows. See the end of this
2126 docstring for how to change the editor hook.
2126 docstring for how to change the editor hook.
2127
2127
2128 You can also set the value of this editor via the command line option
2128 You can also set the value of this editor via the command line option
2129 '-editor' or in your ipythonrc file. This is useful if you wish to use
2129 '-editor' or in your ipythonrc file. This is useful if you wish to use
2130 specifically for IPython an editor different from your typical default
2130 specifically for IPython an editor different from your typical default
2131 (and for Windows users who typically don't set environment variables).
2131 (and for Windows users who typically don't set environment variables).
2132
2132
2133 This command allows you to conveniently edit multi-line code right in
2133 This command allows you to conveniently edit multi-line code right in
2134 your IPython session.
2134 your IPython session.
2135
2135
2136 If called without arguments, %edit opens up an empty editor with a
2136 If called without arguments, %edit opens up an empty editor with a
2137 temporary file and will execute the contents of this file when you
2137 temporary file and will execute the contents of this file when you
2138 close it (don't forget to save it!).
2138 close it (don't forget to save it!).
2139
2139
2140
2140
2141 Options:
2141 Options:
2142
2142
2143 -n <number>: open the editor at a specified line number. By default,
2143 -n <number>: open the editor at a specified line number. By default,
2144 the IPython editor hook uses the unix syntax 'editor +N filename', but
2144 the IPython editor hook uses the unix syntax 'editor +N filename', but
2145 you can configure this by providing your own modified hook if your
2145 you can configure this by providing your own modified hook if your
2146 favorite editor supports line-number specifications with a different
2146 favorite editor supports line-number specifications with a different
2147 syntax.
2147 syntax.
2148
2148
2149 -p: this will call the editor with the same data as the previous time
2149 -p: this will call the editor with the same data as the previous time
2150 it was used, regardless of how long ago (in your current session) it
2150 it was used, regardless of how long ago (in your current session) it
2151 was.
2151 was.
2152
2152
2153 -r: use 'raw' input. This option only applies to input taken from the
2153 -r: use 'raw' input. This option only applies to input taken from the
2154 user's history. By default, the 'processed' history is used, so that
2154 user's history. By default, the 'processed' history is used, so that
2155 magics are loaded in their transformed version to valid Python. If
2155 magics are loaded in their transformed version to valid Python. If
2156 this option is given, the raw input as typed as the command line is
2156 this option is given, the raw input as typed as the command line is
2157 used instead. When you exit the editor, it will be executed by
2157 used instead. When you exit the editor, it will be executed by
2158 IPython's own processor.
2158 IPython's own processor.
2159
2159
2160 -x: do not execute the edited code immediately upon exit. This is
2160 -x: do not execute the edited code immediately upon exit. This is
2161 mainly useful if you are editing programs which need to be called with
2161 mainly useful if you are editing programs which need to be called with
2162 command line arguments, which you can then do using %run.
2162 command line arguments, which you can then do using %run.
2163
2163
2164
2164
2165 Arguments:
2165 Arguments:
2166
2166
2167 If arguments are given, the following possibilites exist:
2167 If arguments are given, the following possibilites exist:
2168
2168
2169 - The arguments are numbers or pairs of colon-separated numbers (like
2169 - The arguments are numbers or pairs of colon-separated numbers (like
2170 1 4:8 9). These are interpreted as lines of previous input to be
2170 1 4:8 9). These are interpreted as lines of previous input to be
2171 loaded into the editor. The syntax is the same of the %macro command.
2171 loaded into the editor. The syntax is the same of the %macro command.
2172
2172
2173 - If the argument doesn't start with a number, it is evaluated as a
2173 - If the argument doesn't start with a number, it is evaluated as a
2174 variable and its contents loaded into the editor. You can thus edit
2174 variable and its contents loaded into the editor. You can thus edit
2175 any string which contains python code (including the result of
2175 any string which contains python code (including the result of
2176 previous edits).
2176 previous edits).
2177
2177
2178 - If the argument is the name of an object (other than a string),
2178 - If the argument is the name of an object (other than a string),
2179 IPython will try to locate the file where it was defined and open the
2179 IPython will try to locate the file where it was defined and open the
2180 editor at the point where it is defined. You can use `%edit function`
2180 editor at the point where it is defined. You can use `%edit function`
2181 to load an editor exactly at the point where 'function' is defined,
2181 to load an editor exactly at the point where 'function' is defined,
2182 edit it and have the file be executed automatically.
2182 edit it and have the file be executed automatically.
2183
2183
2184 If the object is a macro (see %macro for details), this opens up your
2184 If the object is a macro (see %macro for details), this opens up your
2185 specified editor with a temporary file containing the macro's data.
2185 specified editor with a temporary file containing the macro's data.
2186 Upon exit, the macro is reloaded with the contents of the file.
2186 Upon exit, the macro is reloaded with the contents of the file.
2187
2187
2188 Note: opening at an exact line is only supported under Unix, and some
2188 Note: opening at an exact line is only supported under Unix, and some
2189 editors (like kedit and gedit up to Gnome 2.8) do not understand the
2189 editors (like kedit and gedit up to Gnome 2.8) do not understand the
2190 '+NUMBER' parameter necessary for this feature. Good editors like
2190 '+NUMBER' parameter necessary for this feature. Good editors like
2191 (X)Emacs, vi, jed, pico and joe all do.
2191 (X)Emacs, vi, jed, pico and joe all do.
2192
2192
2193 - If the argument is not found as a variable, IPython will look for a
2193 - If the argument is not found as a variable, IPython will look for a
2194 file with that name (adding .py if necessary) and load it into the
2194 file with that name (adding .py if necessary) and load it into the
2195 editor. It will execute its contents with execfile() when you exit,
2195 editor. It will execute its contents with execfile() when you exit,
2196 loading any code in the file into your interactive namespace.
2196 loading any code in the file into your interactive namespace.
2197
2197
2198 After executing your code, %edit will return as output the code you
2198 After executing your code, %edit will return as output the code you
2199 typed in the editor (except when it was an existing file). This way
2199 typed in the editor (except when it was an existing file). This way
2200 you can reload the code in further invocations of %edit as a variable,
2200 you can reload the code in further invocations of %edit as a variable,
2201 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
2201 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
2202 the output.
2202 the output.
2203
2203
2204 Note that %edit is also available through the alias %ed.
2204 Note that %edit is also available through the alias %ed.
2205
2205
2206 This is an example of creating a simple function inside the editor and
2206 This is an example of creating a simple function inside the editor and
2207 then modifying it. First, start up the editor:
2207 then modifying it. First, start up the editor:
2208
2208
2209 In [1]: ed
2209 In [1]: ed
2210 Editing... done. Executing edited code...
2210 Editing... done. Executing edited code...
2211 Out[1]: 'def foo():n print "foo() was defined in an editing session"n'
2211 Out[1]: 'def foo():n print "foo() was defined in an editing session"n'
2212
2212
2213 We can then call the function foo():
2213 We can then call the function foo():
2214
2214
2215 In [2]: foo()
2215 In [2]: foo()
2216 foo() was defined in an editing session
2216 foo() was defined in an editing session
2217
2217
2218 Now we edit foo. IPython automatically loads the editor with the
2218 Now we edit foo. IPython automatically loads the editor with the
2219 (temporary) file where foo() was previously defined:
2219 (temporary) file where foo() was previously defined:
2220
2220
2221 In [3]: ed foo
2221 In [3]: ed foo
2222 Editing... done. Executing edited code...
2222 Editing... done. Executing edited code...
2223
2223
2224 And if we call foo() again we get the modified version:
2224 And if we call foo() again we get the modified version:
2225
2225
2226 In [4]: foo()
2226 In [4]: foo()
2227 foo() has now been changed!
2227 foo() has now been changed!
2228
2228
2229 Here is an example of how to edit a code snippet successive
2229 Here is an example of how to edit a code snippet successive
2230 times. First we call the editor:
2230 times. First we call the editor:
2231
2231
2232 In [5]: ed
2232 In [5]: ed
2233 Editing... done. Executing edited code...
2233 Editing... done. Executing edited code...
2234 hello
2234 hello
2235 Out[5]: "print 'hello'n"
2235 Out[5]: "print 'hello'n"
2236
2236
2237 Now we call it again with the previous output (stored in _):
2237 Now we call it again with the previous output (stored in _):
2238
2238
2239 In [6]: ed _
2239 In [6]: ed _
2240 Editing... done. Executing edited code...
2240 Editing... done. Executing edited code...
2241 hello world
2241 hello world
2242 Out[6]: "print 'hello world'n"
2242 Out[6]: "print 'hello world'n"
2243
2243
2244 Now we call it with the output #8 (stored in _8, also as Out[8]):
2244 Now we call it with the output #8 (stored in _8, also as Out[8]):
2245
2245
2246 In [7]: ed _8
2246 In [7]: ed _8
2247 Editing... done. Executing edited code...
2247 Editing... done. Executing edited code...
2248 hello again
2248 hello again
2249 Out[7]: "print 'hello again'n"
2249 Out[7]: "print 'hello again'n"
2250
2250
2251
2251
2252 Changing the default editor hook:
2252 Changing the default editor hook:
2253
2253
2254 If you wish to write your own editor hook, you can put it in a
2254 If you wish to write your own editor hook, you can put it in a
2255 configuration file which you load at startup time. The default hook
2255 configuration file which you load at startup time. The default hook
2256 is defined in the IPython.core.hooks module, and you can use that as a
2256 is defined in the IPython.core.hooks module, and you can use that as a
2257 starting example for further modifications. That file also has
2257 starting example for further modifications. That file also has
2258 general instructions on how to set a new hook for use once you've
2258 general instructions on how to set a new hook for use once you've
2259 defined it."""
2259 defined it."""
2260
2260
2261 # FIXME: This function has become a convoluted mess. It needs a
2261 # FIXME: This function has become a convoluted mess. It needs a
2262 # ground-up rewrite with clean, simple logic.
2262 # ground-up rewrite with clean, simple logic.
2263
2263
2264 def make_filename(arg):
2264 def make_filename(arg):
2265 "Make a filename from the given args"
2265 "Make a filename from the given args"
2266 try:
2266 try:
2267 filename = get_py_filename(arg)
2267 filename = get_py_filename(arg)
2268 except IOError:
2268 except IOError:
2269 if args.endswith('.py'):
2269 if args.endswith('.py'):
2270 filename = arg
2270 filename = arg
2271 else:
2271 else:
2272 filename = None
2272 filename = None
2273 return filename
2273 return filename
2274
2274
2275 # custom exceptions
2275 # custom exceptions
2276 class DataIsObject(Exception): pass
2276 class DataIsObject(Exception): pass
2277
2277
2278 opts,args = self.parse_options(parameter_s,'prxn:')
2278 opts,args = self.parse_options(parameter_s,'prxn:')
2279 # Set a few locals from the options for convenience:
2279 # Set a few locals from the options for convenience:
2280 opts_p = opts.has_key('p')
2280 opts_p = opts.has_key('p')
2281 opts_r = opts.has_key('r')
2281 opts_r = opts.has_key('r')
2282
2282
2283 # Default line number value
2283 # Default line number value
2284 lineno = opts.get('n',None)
2284 lineno = opts.get('n',None)
2285
2285
2286 if opts_p:
2286 if opts_p:
2287 args = '_%s' % last_call[0]
2287 args = '_%s' % last_call[0]
2288 if not self.shell.user_ns.has_key(args):
2288 if not self.shell.user_ns.has_key(args):
2289 args = last_call[1]
2289 args = last_call[1]
2290
2290
2291 # use last_call to remember the state of the previous call, but don't
2291 # use last_call to remember the state of the previous call, but don't
2292 # let it be clobbered by successive '-p' calls.
2292 # let it be clobbered by successive '-p' calls.
2293 try:
2293 try:
2294 last_call[0] = self.shell.outputcache.prompt_count
2294 last_call[0] = self.shell.outputcache.prompt_count
2295 if not opts_p:
2295 if not opts_p:
2296 last_call[1] = parameter_s
2296 last_call[1] = parameter_s
2297 except:
2297 except:
2298 pass
2298 pass
2299
2299
2300 # by default this is done with temp files, except when the given
2300 # by default this is done with temp files, except when the given
2301 # arg is a filename
2301 # arg is a filename
2302 use_temp = 1
2302 use_temp = 1
2303
2303
2304 if re.match(r'\d',args):
2304 if re.match(r'\d',args):
2305 # Mode where user specifies ranges of lines, like in %macro.
2305 # Mode where user specifies ranges of lines, like in %macro.
2306 # This means that you can't edit files whose names begin with
2306 # This means that you can't edit files whose names begin with
2307 # numbers this way. Tough.
2307 # numbers this way. Tough.
2308 ranges = args.split()
2308 ranges = args.split()
2309 data = ''.join(self.extract_input_slices(ranges,opts_r))
2309 data = ''.join(self.extract_input_slices(ranges,opts_r))
2310 elif args.endswith('.py'):
2310 elif args.endswith('.py'):
2311 filename = make_filename(args)
2311 filename = make_filename(args)
2312 data = ''
2312 data = ''
2313 use_temp = 0
2313 use_temp = 0
2314 elif args:
2314 elif args:
2315 try:
2315 try:
2316 # Load the parameter given as a variable. If not a string,
2316 # Load the parameter given as a variable. If not a string,
2317 # process it as an object instead (below)
2317 # process it as an object instead (below)
2318
2318
2319 #print '*** args',args,'type',type(args) # dbg
2319 #print '*** args',args,'type',type(args) # dbg
2320 data = eval(args,self.shell.user_ns)
2320 data = eval(args,self.shell.user_ns)
2321 if not type(data) in StringTypes:
2321 if not type(data) in StringTypes:
2322 raise DataIsObject
2322 raise DataIsObject
2323
2323
2324 except (NameError,SyntaxError):
2324 except (NameError,SyntaxError):
2325 # given argument is not a variable, try as a filename
2325 # given argument is not a variable, try as a filename
2326 filename = make_filename(args)
2326 filename = make_filename(args)
2327 if filename is None:
2327 if filename is None:
2328 warn("Argument given (%s) can't be found as a variable "
2328 warn("Argument given (%s) can't be found as a variable "
2329 "or as a filename." % args)
2329 "or as a filename." % args)
2330 return
2330 return
2331
2331
2332 data = ''
2332 data = ''
2333 use_temp = 0
2333 use_temp = 0
2334 except DataIsObject:
2334 except DataIsObject:
2335
2335
2336 # macros have a special edit function
2336 # macros have a special edit function
2337 if isinstance(data,Macro):
2337 if isinstance(data,Macro):
2338 self._edit_macro(args,data)
2338 self._edit_macro(args,data)
2339 return
2339 return
2340
2340
2341 # For objects, try to edit the file where they are defined
2341 # For objects, try to edit the file where they are defined
2342 try:
2342 try:
2343 filename = inspect.getabsfile(data)
2343 filename = inspect.getabsfile(data)
2344 if 'fakemodule' in filename.lower() and inspect.isclass(data):
2344 if 'fakemodule' in filename.lower() and inspect.isclass(data):
2345 # class created by %edit? Try to find source
2345 # class created by %edit? Try to find source
2346 # by looking for method definitions instead, the
2346 # by looking for method definitions instead, the
2347 # __module__ in those classes is FakeModule.
2347 # __module__ in those classes is FakeModule.
2348 attrs = [getattr(data, aname) for aname in dir(data)]
2348 attrs = [getattr(data, aname) for aname in dir(data)]
2349 for attr in attrs:
2349 for attr in attrs:
2350 if not inspect.ismethod(attr):
2350 if not inspect.ismethod(attr):
2351 continue
2351 continue
2352 filename = inspect.getabsfile(attr)
2352 filename = inspect.getabsfile(attr)
2353 if filename and 'fakemodule' not in filename.lower():
2353 if filename and 'fakemodule' not in filename.lower():
2354 # change the attribute to be the edit target instead
2354 # change the attribute to be the edit target instead
2355 data = attr
2355 data = attr
2356 break
2356 break
2357
2357
2358 datafile = 1
2358 datafile = 1
2359 except TypeError:
2359 except TypeError:
2360 filename = make_filename(args)
2360 filename = make_filename(args)
2361 datafile = 1
2361 datafile = 1
2362 warn('Could not find file where `%s` is defined.\n'
2362 warn('Could not find file where `%s` is defined.\n'
2363 'Opening a file named `%s`' % (args,filename))
2363 'Opening a file named `%s`' % (args,filename))
2364 # Now, make sure we can actually read the source (if it was in
2364 # Now, make sure we can actually read the source (if it was in
2365 # a temp file it's gone by now).
2365 # a temp file it's gone by now).
2366 if datafile:
2366 if datafile:
2367 try:
2367 try:
2368 if lineno is None:
2368 if lineno is None:
2369 lineno = inspect.getsourcelines(data)[1]
2369 lineno = inspect.getsourcelines(data)[1]
2370 except IOError:
2370 except IOError:
2371 filename = make_filename(args)
2371 filename = make_filename(args)
2372 if filename is None:
2372 if filename is None:
2373 warn('The file `%s` where `%s` was defined cannot '
2373 warn('The file `%s` where `%s` was defined cannot '
2374 'be read.' % (filename,data))
2374 'be read.' % (filename,data))
2375 return
2375 return
2376 use_temp = 0
2376 use_temp = 0
2377 else:
2377 else:
2378 data = ''
2378 data = ''
2379
2379
2380 if use_temp:
2380 if use_temp:
2381 filename = self.shell.mktempfile(data)
2381 filename = self.shell.mktempfile(data)
2382 print 'IPython will make a temporary file named:',filename
2382 print 'IPython will make a temporary file named:',filename
2383
2383
2384 # do actual editing here
2384 # do actual editing here
2385 print 'Editing...',
2385 print 'Editing...',
2386 sys.stdout.flush()
2386 sys.stdout.flush()
2387 try:
2387 try:
2388 self.shell.hooks.editor(filename,lineno)
2388 self.shell.hooks.editor(filename,lineno)
2389 except ipapi.TryNext:
2389 except ipapi.TryNext:
2390 warn('Could not open editor')
2390 warn('Could not open editor')
2391 return
2391 return
2392
2392
2393 # XXX TODO: should this be generalized for all string vars?
2393 # XXX TODO: should this be generalized for all string vars?
2394 # For now, this is special-cased to blocks created by cpaste
2394 # For now, this is special-cased to blocks created by cpaste
2395 if args.strip() == 'pasted_block':
2395 if args.strip() == 'pasted_block':
2396 self.shell.user_ns['pasted_block'] = file_read(filename)
2396 self.shell.user_ns['pasted_block'] = file_read(filename)
2397
2397
2398 if opts.has_key('x'): # -x prevents actual execution
2398 if opts.has_key('x'): # -x prevents actual execution
2399 print
2399 print
2400 else:
2400 else:
2401 print 'done. Executing edited code...'
2401 print 'done. Executing edited code...'
2402 if opts_r:
2402 if opts_r:
2403 self.shell.runlines(file_read(filename))
2403 self.shell.runlines(file_read(filename))
2404 else:
2404 else:
2405 self.shell.safe_execfile(filename,self.shell.user_ns,
2405 self.shell.safe_execfile(filename,self.shell.user_ns,
2406 self.shell.user_ns)
2406 self.shell.user_ns)
2407
2407
2408
2408
2409 if use_temp:
2409 if use_temp:
2410 try:
2410 try:
2411 return open(filename).read()
2411 return open(filename).read()
2412 except IOError,msg:
2412 except IOError,msg:
2413 if msg.filename == filename:
2413 if msg.filename == filename:
2414 warn('File not found. Did you forget to save?')
2414 warn('File not found. Did you forget to save?')
2415 return
2415 return
2416 else:
2416 else:
2417 self.shell.showtraceback()
2417 self.shell.showtraceback()
2418
2418
2419 def magic_xmode(self,parameter_s = ''):
2419 def magic_xmode(self,parameter_s = ''):
2420 """Switch modes for the exception handlers.
2420 """Switch modes for the exception handlers.
2421
2421
2422 Valid modes: Plain, Context and Verbose.
2422 Valid modes: Plain, Context and Verbose.
2423
2423
2424 If called without arguments, acts as a toggle."""
2424 If called without arguments, acts as a toggle."""
2425
2425
2426 def xmode_switch_err(name):
2426 def xmode_switch_err(name):
2427 warn('Error changing %s exception modes.\n%s' %
2427 warn('Error changing %s exception modes.\n%s' %
2428 (name,sys.exc_info()[1]))
2428 (name,sys.exc_info()[1]))
2429
2429
2430 shell = self.shell
2430 shell = self.shell
2431 new_mode = parameter_s.strip().capitalize()
2431 new_mode = parameter_s.strip().capitalize()
2432 try:
2432 try:
2433 shell.InteractiveTB.set_mode(mode=new_mode)
2433 shell.InteractiveTB.set_mode(mode=new_mode)
2434 print 'Exception reporting mode:',shell.InteractiveTB.mode
2434 print 'Exception reporting mode:',shell.InteractiveTB.mode
2435 except:
2435 except:
2436 xmode_switch_err('user')
2436 xmode_switch_err('user')
2437
2437
2438 # threaded shells use a special handler in sys.excepthook
2438 # threaded shells use a special handler in sys.excepthook
2439 if shell.isthreaded:
2439 if shell.isthreaded:
2440 try:
2440 try:
2441 shell.sys_excepthook.set_mode(mode=new_mode)
2441 shell.sys_excepthook.set_mode(mode=new_mode)
2442 except:
2442 except:
2443 xmode_switch_err('threaded')
2443 xmode_switch_err('threaded')
2444
2444
2445 def magic_colors(self,parameter_s = ''):
2445 def magic_colors(self,parameter_s = ''):
2446 """Switch color scheme for prompts, info system and exception handlers.
2446 """Switch color scheme for prompts, info system and exception handlers.
2447
2447
2448 Currently implemented schemes: NoColor, Linux, LightBG.
2448 Currently implemented schemes: NoColor, Linux, LightBG.
2449
2449
2450 Color scheme names are not case-sensitive."""
2450 Color scheme names are not case-sensitive."""
2451
2451
2452 def color_switch_err(name):
2452 def color_switch_err(name):
2453 warn('Error changing %s color schemes.\n%s' %
2453 warn('Error changing %s color schemes.\n%s' %
2454 (name,sys.exc_info()[1]))
2454 (name,sys.exc_info()[1]))
2455
2455
2456
2456
2457 new_scheme = parameter_s.strip()
2457 new_scheme = parameter_s.strip()
2458 if not new_scheme:
2458 if not new_scheme:
2459 raise UsageError(
2459 raise UsageError(
2460 "%colors: you must specify a color scheme. See '%colors?'")
2460 "%colors: you must specify a color scheme. See '%colors?'")
2461 return
2461 return
2462 # local shortcut
2462 # local shortcut
2463 shell = self.shell
2463 shell = self.shell
2464
2464
2465 import IPython.rlineimpl as readline
2465 import IPython.rlineimpl as readline
2466
2466
2467 if not readline.have_readline and sys.platform == "win32":
2467 if not readline.have_readline and sys.platform == "win32":
2468 msg = """\
2468 msg = """\
2469 Proper color support under MS Windows requires the pyreadline library.
2469 Proper color support under MS Windows requires the pyreadline library.
2470 You can find it at:
2470 You can find it at:
2471 http://ipython.scipy.org/moin/PyReadline/Intro
2471 http://ipython.scipy.org/moin/PyReadline/Intro
2472 Gary's readline needs the ctypes module, from:
2472 Gary's readline needs the ctypes module, from:
2473 http://starship.python.net/crew/theller/ctypes
2473 http://starship.python.net/crew/theller/ctypes
2474 (Note that ctypes is already part of Python versions 2.5 and newer).
2474 (Note that ctypes is already part of Python versions 2.5 and newer).
2475
2475
2476 Defaulting color scheme to 'NoColor'"""
2476 Defaulting color scheme to 'NoColor'"""
2477 new_scheme = 'NoColor'
2477 new_scheme = 'NoColor'
2478 warn(msg)
2478 warn(msg)
2479
2479
2480 # readline option is 0
2480 # readline option is 0
2481 if not shell.has_readline:
2481 if not shell.has_readline:
2482 new_scheme = 'NoColor'
2482 new_scheme = 'NoColor'
2483
2483
2484 # Set prompt colors
2484 # Set prompt colors
2485 try:
2485 try:
2486 shell.outputcache.set_colors(new_scheme)
2486 shell.outputcache.set_colors(new_scheme)
2487 except:
2487 except:
2488 color_switch_err('prompt')
2488 color_switch_err('prompt')
2489 else:
2489 else:
2490 shell.rc.colors = \
2490 shell.rc.colors = \
2491 shell.outputcache.color_table.active_scheme_name
2491 shell.outputcache.color_table.active_scheme_name
2492 # Set exception colors
2492 # Set exception colors
2493 try:
2493 try:
2494 shell.InteractiveTB.set_colors(scheme = new_scheme)
2494 shell.InteractiveTB.set_colors(scheme = new_scheme)
2495 shell.SyntaxTB.set_colors(scheme = new_scheme)
2495 shell.SyntaxTB.set_colors(scheme = new_scheme)
2496 except:
2496 except:
2497 color_switch_err('exception')
2497 color_switch_err('exception')
2498
2498
2499 # threaded shells use a verbose traceback in sys.excepthook
2499 # threaded shells use a verbose traceback in sys.excepthook
2500 if shell.isthreaded:
2500 if shell.isthreaded:
2501 try:
2501 try:
2502 shell.sys_excepthook.set_colors(scheme=new_scheme)
2502 shell.sys_excepthook.set_colors(scheme=new_scheme)
2503 except:
2503 except:
2504 color_switch_err('system exception handler')
2504 color_switch_err('system exception handler')
2505
2505
2506 # Set info (for 'object?') colors
2506 # Set info (for 'object?') colors
2507 if shell.rc.color_info:
2507 if shell.rc.color_info:
2508 try:
2508 try:
2509 shell.inspector.set_active_scheme(new_scheme)
2509 shell.inspector.set_active_scheme(new_scheme)
2510 except:
2510 except:
2511 color_switch_err('object inspector')
2511 color_switch_err('object inspector')
2512 else:
2512 else:
2513 shell.inspector.set_active_scheme('NoColor')
2513 shell.inspector.set_active_scheme('NoColor')
2514
2514
2515 def magic_color_info(self,parameter_s = ''):
2515 def magic_color_info(self,parameter_s = ''):
2516 """Toggle color_info.
2516 """Toggle color_info.
2517
2517
2518 The color_info configuration parameter controls whether colors are
2518 The color_info configuration parameter controls whether colors are
2519 used for displaying object details (by things like %psource, %pfile or
2519 used for displaying object details (by things like %psource, %pfile or
2520 the '?' system). This function toggles this value with each call.
2520 the '?' system). This function toggles this value with each call.
2521
2521
2522 Note that unless you have a fairly recent pager (less works better
2522 Note that unless you have a fairly recent pager (less works better
2523 than more) in your system, using colored object information displays
2523 than more) in your system, using colored object information displays
2524 will not work properly. Test it and see."""
2524 will not work properly. Test it and see."""
2525
2525
2526 self.shell.rc.color_info = 1 - self.shell.rc.color_info
2526 self.shell.rc.color_info = 1 - self.shell.rc.color_info
2527 self.magic_colors(self.shell.rc.colors)
2527 self.magic_colors(self.shell.rc.colors)
2528 print 'Object introspection functions have now coloring:',
2528 print 'Object introspection functions have now coloring:',
2529 print ['OFF','ON'][self.shell.rc.color_info]
2529 print ['OFF','ON'][self.shell.rc.color_info]
2530
2530
2531 def magic_Pprint(self, parameter_s=''):
2531 def magic_Pprint(self, parameter_s=''):
2532 """Toggle pretty printing on/off."""
2532 """Toggle pretty printing on/off."""
2533
2533
2534 self.shell.rc.pprint = 1 - self.shell.rc.pprint
2534 self.shell.rc.pprint = 1 - self.shell.rc.pprint
2535 print 'Pretty printing has been turned', \
2535 print 'Pretty printing has been turned', \
2536 ['OFF','ON'][self.shell.rc.pprint]
2536 ['OFF','ON'][self.shell.rc.pprint]
2537
2537
2538 def magic_exit(self, parameter_s=''):
2538 def magic_exit(self, parameter_s=''):
2539 """Exit IPython, confirming if configured to do so.
2539 """Exit IPython, confirming if configured to do so.
2540
2540
2541 You can configure whether IPython asks for confirmation upon exit by
2541 You can configure whether IPython asks for confirmation upon exit by
2542 setting the confirm_exit flag in the ipythonrc file."""
2542 setting the confirm_exit flag in the ipythonrc file."""
2543
2543
2544 self.shell.exit()
2544 self.shell.exit()
2545
2545
2546 def magic_quit(self, parameter_s=''):
2546 def magic_quit(self, parameter_s=''):
2547 """Exit IPython, confirming if configured to do so (like %exit)"""
2547 """Exit IPython, confirming if configured to do so (like %exit)"""
2548
2548
2549 self.shell.exit()
2549 self.shell.exit()
2550
2550
2551 def magic_Exit(self, parameter_s=''):
2551 def magic_Exit(self, parameter_s=''):
2552 """Exit IPython without confirmation."""
2552 """Exit IPython without confirmation."""
2553
2553
2554 self.shell.ask_exit()
2554 self.shell.ask_exit()
2555
2555
2556 #......................................................................
2556 #......................................................................
2557 # Functions to implement unix shell-type things
2557 # Functions to implement unix shell-type things
2558
2558
2559 @testdec.skip_doctest
2559 @testdec.skip_doctest
2560 def magic_alias(self, parameter_s = ''):
2560 def magic_alias(self, parameter_s = ''):
2561 """Define an alias for a system command.
2561 """Define an alias for a system command.
2562
2562
2563 '%alias alias_name cmd' defines 'alias_name' as an alias for 'cmd'
2563 '%alias alias_name cmd' defines 'alias_name' as an alias for 'cmd'
2564
2564
2565 Then, typing 'alias_name params' will execute the system command 'cmd
2565 Then, typing 'alias_name params' will execute the system command 'cmd
2566 params' (from your underlying operating system).
2566 params' (from your underlying operating system).
2567
2567
2568 Aliases have lower precedence than magic functions and Python normal
2568 Aliases have lower precedence than magic functions and Python normal
2569 variables, so if 'foo' is both a Python variable and an alias, the
2569 variables, so if 'foo' is both a Python variable and an alias, the
2570 alias can not be executed until 'del foo' removes the Python variable.
2570 alias can not be executed until 'del foo' removes the Python variable.
2571
2571
2572 You can use the %l specifier in an alias definition to represent the
2572 You can use the %l specifier in an alias definition to represent the
2573 whole line when the alias is called. For example:
2573 whole line when the alias is called. For example:
2574
2574
2575 In [2]: alias all echo "Input in brackets: <%l>"
2575 In [2]: alias all echo "Input in brackets: <%l>"
2576 In [3]: all hello world
2576 In [3]: all hello world
2577 Input in brackets: <hello world>
2577 Input in brackets: <hello world>
2578
2578
2579 You can also define aliases with parameters using %s specifiers (one
2579 You can also define aliases with parameters using %s specifiers (one
2580 per parameter):
2580 per parameter):
2581
2581
2582 In [1]: alias parts echo first %s second %s
2582 In [1]: alias parts echo first %s second %s
2583 In [2]: %parts A B
2583 In [2]: %parts A B
2584 first A second B
2584 first A second B
2585 In [3]: %parts A
2585 In [3]: %parts A
2586 Incorrect number of arguments: 2 expected.
2586 Incorrect number of arguments: 2 expected.
2587 parts is an alias to: 'echo first %s second %s'
2587 parts is an alias to: 'echo first %s second %s'
2588
2588
2589 Note that %l and %s are mutually exclusive. You can only use one or
2589 Note that %l and %s are mutually exclusive. You can only use one or
2590 the other in your aliases.
2590 the other in your aliases.
2591
2591
2592 Aliases expand Python variables just like system calls using ! or !!
2592 Aliases expand Python variables just like system calls using ! or !!
2593 do: all expressions prefixed with '$' get expanded. For details of
2593 do: all expressions prefixed with '$' get expanded. For details of
2594 the semantic rules, see PEP-215:
2594 the semantic rules, see PEP-215:
2595 http://www.python.org/peps/pep-0215.html. This is the library used by
2595 http://www.python.org/peps/pep-0215.html. This is the library used by
2596 IPython for variable expansion. If you want to access a true shell
2596 IPython for variable expansion. If you want to access a true shell
2597 variable, an extra $ is necessary to prevent its expansion by IPython:
2597 variable, an extra $ is necessary to prevent its expansion by IPython:
2598
2598
2599 In [6]: alias show echo
2599 In [6]: alias show echo
2600 In [7]: PATH='A Python string'
2600 In [7]: PATH='A Python string'
2601 In [8]: show $PATH
2601 In [8]: show $PATH
2602 A Python string
2602 A Python string
2603 In [9]: show $$PATH
2603 In [9]: show $$PATH
2604 /usr/local/lf9560/bin:/usr/local/intel/compiler70/ia32/bin:...
2604 /usr/local/lf9560/bin:/usr/local/intel/compiler70/ia32/bin:...
2605
2605
2606 You can use the alias facility to acess all of $PATH. See the %rehash
2606 You can use the alias facility to acess all of $PATH. See the %rehash
2607 and %rehashx functions, which automatically create aliases for the
2607 and %rehashx functions, which automatically create aliases for the
2608 contents of your $PATH.
2608 contents of your $PATH.
2609
2609
2610 If called with no parameters, %alias prints the current alias table."""
2610 If called with no parameters, %alias prints the current alias table."""
2611
2611
2612 par = parameter_s.strip()
2612 par = parameter_s.strip()
2613 if not par:
2613 if not par:
2614 stored = self.db.get('stored_aliases', {} )
2614 stored = self.db.get('stored_aliases', {} )
2615 atab = self.shell.alias_table
2615 atab = self.shell.alias_table
2616 aliases = atab.keys()
2616 aliases = atab.keys()
2617 aliases.sort()
2617 aliases.sort()
2618 res = []
2618 res = []
2619 showlast = []
2619 showlast = []
2620 for alias in aliases:
2620 for alias in aliases:
2621 special = False
2621 special = False
2622 try:
2622 try:
2623 tgt = atab[alias][1]
2623 tgt = atab[alias][1]
2624 except (TypeError, AttributeError):
2624 except (TypeError, AttributeError):
2625 # unsubscriptable? probably a callable
2625 # unsubscriptable? probably a callable
2626 tgt = atab[alias]
2626 tgt = atab[alias]
2627 special = True
2627 special = True
2628 # 'interesting' aliases
2628 # 'interesting' aliases
2629 if (alias in stored or
2629 if (alias in stored or
2630 special or
2630 special or
2631 alias.lower() != os.path.splitext(tgt)[0].lower() or
2631 alias.lower() != os.path.splitext(tgt)[0].lower() or
2632 ' ' in tgt):
2632 ' ' in tgt):
2633 showlast.append((alias, tgt))
2633 showlast.append((alias, tgt))
2634 else:
2634 else:
2635 res.append((alias, tgt ))
2635 res.append((alias, tgt ))
2636
2636
2637 # show most interesting aliases last
2637 # show most interesting aliases last
2638 res.extend(showlast)
2638 res.extend(showlast)
2639 print "Total number of aliases:",len(aliases)
2639 print "Total number of aliases:",len(aliases)
2640 return res
2640 return res
2641 try:
2641 try:
2642 alias,cmd = par.split(None,1)
2642 alias,cmd = par.split(None,1)
2643 except:
2643 except:
2644 print OInspect.getdoc(self.magic_alias)
2644 print OInspect.getdoc(self.magic_alias)
2645 else:
2645 else:
2646 nargs = cmd.count('%s')
2646 nargs = cmd.count('%s')
2647 if nargs>0 and cmd.find('%l')>=0:
2647 if nargs>0 and cmd.find('%l')>=0:
2648 error('The %s and %l specifiers are mutually exclusive '
2648 error('The %s and %l specifiers are mutually exclusive '
2649 'in alias definitions.')
2649 'in alias definitions.')
2650 else: # all looks OK
2650 else: # all looks OK
2651 self.shell.alias_table[alias] = (nargs,cmd)
2651 self.shell.alias_table[alias] = (nargs,cmd)
2652 self.shell.alias_table_validate(verbose=0)
2652 self.shell.alias_table_validate(verbose=0)
2653 # end magic_alias
2653 # end magic_alias
2654
2654
2655 def magic_unalias(self, parameter_s = ''):
2655 def magic_unalias(self, parameter_s = ''):
2656 """Remove an alias"""
2656 """Remove an alias"""
2657
2657
2658 aname = parameter_s.strip()
2658 aname = parameter_s.strip()
2659 if aname in self.shell.alias_table:
2659 if aname in self.shell.alias_table:
2660 del self.shell.alias_table[aname]
2660 del self.shell.alias_table[aname]
2661 stored = self.db.get('stored_aliases', {} )
2661 stored = self.db.get('stored_aliases', {} )
2662 if aname in stored:
2662 if aname in stored:
2663 print "Removing %stored alias",aname
2663 print "Removing %stored alias",aname
2664 del stored[aname]
2664 del stored[aname]
2665 self.db['stored_aliases'] = stored
2665 self.db['stored_aliases'] = stored
2666
2666
2667
2667
2668 def magic_rehashx(self, parameter_s = ''):
2668 def magic_rehashx(self, parameter_s = ''):
2669 """Update the alias table with all executable files in $PATH.
2669 """Update the alias table with all executable files in $PATH.
2670
2670
2671 This version explicitly checks that every entry in $PATH is a file
2671 This version explicitly checks that every entry in $PATH is a file
2672 with execute access (os.X_OK), so it is much slower than %rehash.
2672 with execute access (os.X_OK), so it is much slower than %rehash.
2673
2673
2674 Under Windows, it checks executability as a match agains a
2674 Under Windows, it checks executability as a match agains a
2675 '|'-separated string of extensions, stored in the IPython config
2675 '|'-separated string of extensions, stored in the IPython config
2676 variable win_exec_ext. This defaults to 'exe|com|bat'.
2676 variable win_exec_ext. This defaults to 'exe|com|bat'.
2677
2677
2678 This function also resets the root module cache of module completer,
2678 This function also resets the root module cache of module completer,
2679 used on slow filesystems.
2679 used on slow filesystems.
2680 """
2680 """
2681
2681
2682
2682
2683 ip = self.api
2683 ip = self.api
2684
2684
2685 # for the benefit of module completer in ipy_completers.py
2685 # for the benefit of module completer in ipy_completers.py
2686 del ip.db['rootmodules']
2686 del ip.db['rootmodules']
2687
2687
2688 path = [os.path.abspath(os.path.expanduser(p)) for p in
2688 path = [os.path.abspath(os.path.expanduser(p)) for p in
2689 os.environ.get('PATH','').split(os.pathsep)]
2689 os.environ.get('PATH','').split(os.pathsep)]
2690 path = filter(os.path.isdir,path)
2690 path = filter(os.path.isdir,path)
2691
2691
2692 alias_table = self.shell.alias_table
2692 alias_table = self.shell.alias_table
2693 syscmdlist = []
2693 syscmdlist = []
2694 if os.name == 'posix':
2694 if os.name == 'posix':
2695 isexec = lambda fname:os.path.isfile(fname) and \
2695 isexec = lambda fname:os.path.isfile(fname) and \
2696 os.access(fname,os.X_OK)
2696 os.access(fname,os.X_OK)
2697 else:
2697 else:
2698
2698
2699 try:
2699 try:
2700 winext = os.environ['pathext'].replace(';','|').replace('.','')
2700 winext = os.environ['pathext'].replace(';','|').replace('.','')
2701 except KeyError:
2701 except KeyError:
2702 winext = 'exe|com|bat|py'
2702 winext = 'exe|com|bat|py'
2703 if 'py' not in winext:
2703 if 'py' not in winext:
2704 winext += '|py'
2704 winext += '|py'
2705 execre = re.compile(r'(.*)\.(%s)$' % winext,re.IGNORECASE)
2705 execre = re.compile(r'(.*)\.(%s)$' % winext,re.IGNORECASE)
2706 isexec = lambda fname:os.path.isfile(fname) and execre.match(fname)
2706 isexec = lambda fname:os.path.isfile(fname) and execre.match(fname)
2707 savedir = os.getcwd()
2707 savedir = os.getcwd()
2708 try:
2708 try:
2709 # write the whole loop for posix/Windows so we don't have an if in
2709 # write the whole loop for posix/Windows so we don't have an if in
2710 # the innermost part
2710 # the innermost part
2711 if os.name == 'posix':
2711 if os.name == 'posix':
2712 for pdir in path:
2712 for pdir in path:
2713 os.chdir(pdir)
2713 os.chdir(pdir)
2714 for ff in os.listdir(pdir):
2714 for ff in os.listdir(pdir):
2715 if isexec(ff) and ff not in self.shell.no_alias:
2715 if isexec(ff) and ff not in self.shell.no_alias:
2716 # each entry in the alias table must be (N,name),
2716 # each entry in the alias table must be (N,name),
2717 # where N is the number of positional arguments of the
2717 # where N is the number of positional arguments of the
2718 # alias.
2718 # alias.
2719 # Dots will be removed from alias names, since ipython
2719 # Dots will be removed from alias names, since ipython
2720 # assumes names with dots to be python code
2720 # assumes names with dots to be python code
2721 alias_table[ff.replace('.','')] = (0,ff)
2721 alias_table[ff.replace('.','')] = (0,ff)
2722 syscmdlist.append(ff)
2722 syscmdlist.append(ff)
2723 else:
2723 else:
2724 for pdir in path:
2724 for pdir in path:
2725 os.chdir(pdir)
2725 os.chdir(pdir)
2726 for ff in os.listdir(pdir):
2726 for ff in os.listdir(pdir):
2727 base, ext = os.path.splitext(ff)
2727 base, ext = os.path.splitext(ff)
2728 if isexec(ff) and base.lower() not in self.shell.no_alias:
2728 if isexec(ff) and base.lower() not in self.shell.no_alias:
2729 if ext.lower() == '.exe':
2729 if ext.lower() == '.exe':
2730 ff = base
2730 ff = base
2731 alias_table[base.lower().replace('.','')] = (0,ff)
2731 alias_table[base.lower().replace('.','')] = (0,ff)
2732 syscmdlist.append(ff)
2732 syscmdlist.append(ff)
2733 # Make sure the alias table doesn't contain keywords or builtins
2733 # Make sure the alias table doesn't contain keywords or builtins
2734 self.shell.alias_table_validate()
2734 self.shell.alias_table_validate()
2735 # Call again init_auto_alias() so we get 'rm -i' and other
2735 # Call again init_auto_alias() so we get 'rm -i' and other
2736 # modified aliases since %rehashx will probably clobber them
2736 # modified aliases since %rehashx will probably clobber them
2737
2737
2738 # no, we don't want them. if %rehashx clobbers them, good,
2738 # no, we don't want them. if %rehashx clobbers them, good,
2739 # we'll probably get better versions
2739 # we'll probably get better versions
2740 # self.shell.init_auto_alias()
2740 # self.shell.init_auto_alias()
2741 db = ip.db
2741 db = ip.db
2742 db['syscmdlist'] = syscmdlist
2742 db['syscmdlist'] = syscmdlist
2743 finally:
2743 finally:
2744 os.chdir(savedir)
2744 os.chdir(savedir)
2745
2745
2746 def magic_pwd(self, parameter_s = ''):
2746 def magic_pwd(self, parameter_s = ''):
2747 """Return the current working directory path."""
2747 """Return the current working directory path."""
2748 return os.getcwd()
2748 return os.getcwd()
2749
2749
2750 def magic_cd(self, parameter_s=''):
2750 def magic_cd(self, parameter_s=''):
2751 """Change the current working directory.
2751 """Change the current working directory.
2752
2752
2753 This command automatically maintains an internal list of directories
2753 This command automatically maintains an internal list of directories
2754 you visit during your IPython session, in the variable _dh. The
2754 you visit during your IPython session, in the variable _dh. The
2755 command %dhist shows this history nicely formatted. You can also
2755 command %dhist shows this history nicely formatted. You can also
2756 do 'cd -<tab>' to see directory history conveniently.
2756 do 'cd -<tab>' to see directory history conveniently.
2757
2757
2758 Usage:
2758 Usage:
2759
2759
2760 cd 'dir': changes to directory 'dir'.
2760 cd 'dir': changes to directory 'dir'.
2761
2761
2762 cd -: changes to the last visited directory.
2762 cd -: changes to the last visited directory.
2763
2763
2764 cd -<n>: changes to the n-th directory in the directory history.
2764 cd -<n>: changes to the n-th directory in the directory history.
2765
2765
2766 cd --foo: change to directory that matches 'foo' in history
2766 cd --foo: change to directory that matches 'foo' in history
2767
2767
2768 cd -b <bookmark_name>: jump to a bookmark set by %bookmark
2768 cd -b <bookmark_name>: jump to a bookmark set by %bookmark
2769 (note: cd <bookmark_name> is enough if there is no
2769 (note: cd <bookmark_name> is enough if there is no
2770 directory <bookmark_name>, but a bookmark with the name exists.)
2770 directory <bookmark_name>, but a bookmark with the name exists.)
2771 'cd -b <tab>' allows you to tab-complete bookmark names.
2771 'cd -b <tab>' allows you to tab-complete bookmark names.
2772
2772
2773 Options:
2773 Options:
2774
2774
2775 -q: quiet. Do not print the working directory after the cd command is
2775 -q: quiet. Do not print the working directory after the cd command is
2776 executed. By default IPython's cd command does print this directory,
2776 executed. By default IPython's cd command does print this directory,
2777 since the default prompts do not display path information.
2777 since the default prompts do not display path information.
2778
2778
2779 Note that !cd doesn't work for this purpose because the shell where
2779 Note that !cd doesn't work for this purpose because the shell where
2780 !command runs is immediately discarded after executing 'command'."""
2780 !command runs is immediately discarded after executing 'command'."""
2781
2781
2782 parameter_s = parameter_s.strip()
2782 parameter_s = parameter_s.strip()
2783 #bkms = self.shell.persist.get("bookmarks",{})
2783 #bkms = self.shell.persist.get("bookmarks",{})
2784
2784
2785 oldcwd = os.getcwd()
2785 oldcwd = os.getcwd()
2786 numcd = re.match(r'(-)(\d+)$',parameter_s)
2786 numcd = re.match(r'(-)(\d+)$',parameter_s)
2787 # jump in directory history by number
2787 # jump in directory history by number
2788 if numcd:
2788 if numcd:
2789 nn = int(numcd.group(2))
2789 nn = int(numcd.group(2))
2790 try:
2790 try:
2791 ps = self.shell.user_ns['_dh'][nn]
2791 ps = self.shell.user_ns['_dh'][nn]
2792 except IndexError:
2792 except IndexError:
2793 print 'The requested directory does not exist in history.'
2793 print 'The requested directory does not exist in history.'
2794 return
2794 return
2795 else:
2795 else:
2796 opts = {}
2796 opts = {}
2797 elif parameter_s.startswith('--'):
2797 elif parameter_s.startswith('--'):
2798 ps = None
2798 ps = None
2799 fallback = None
2799 fallback = None
2800 pat = parameter_s[2:]
2800 pat = parameter_s[2:]
2801 dh = self.shell.user_ns['_dh']
2801 dh = self.shell.user_ns['_dh']
2802 # first search only by basename (last component)
2802 # first search only by basename (last component)
2803 for ent in reversed(dh):
2803 for ent in reversed(dh):
2804 if pat in os.path.basename(ent) and os.path.isdir(ent):
2804 if pat in os.path.basename(ent) and os.path.isdir(ent):
2805 ps = ent
2805 ps = ent
2806 break
2806 break
2807
2807
2808 if fallback is None and pat in ent and os.path.isdir(ent):
2808 if fallback is None and pat in ent and os.path.isdir(ent):
2809 fallback = ent
2809 fallback = ent
2810
2810
2811 # if we have no last part match, pick the first full path match
2811 # if we have no last part match, pick the first full path match
2812 if ps is None:
2812 if ps is None:
2813 ps = fallback
2813 ps = fallback
2814
2814
2815 if ps is None:
2815 if ps is None:
2816 print "No matching entry in directory history"
2816 print "No matching entry in directory history"
2817 return
2817 return
2818 else:
2818 else:
2819 opts = {}
2819 opts = {}
2820
2820
2821
2821
2822 else:
2822 else:
2823 #turn all non-space-escaping backslashes to slashes,
2823 #turn all non-space-escaping backslashes to slashes,
2824 # for c:\windows\directory\names\
2824 # for c:\windows\directory\names\
2825 parameter_s = re.sub(r'\\(?! )','/', parameter_s)
2825 parameter_s = re.sub(r'\\(?! )','/', parameter_s)
2826 opts,ps = self.parse_options(parameter_s,'qb',mode='string')
2826 opts,ps = self.parse_options(parameter_s,'qb',mode='string')
2827 # jump to previous
2827 # jump to previous
2828 if ps == '-':
2828 if ps == '-':
2829 try:
2829 try:
2830 ps = self.shell.user_ns['_dh'][-2]
2830 ps = self.shell.user_ns['_dh'][-2]
2831 except IndexError:
2831 except IndexError:
2832 raise UsageError('%cd -: No previous directory to change to.')
2832 raise UsageError('%cd -: No previous directory to change to.')
2833 # jump to bookmark if needed
2833 # jump to bookmark if needed
2834 else:
2834 else:
2835 if not os.path.isdir(ps) or opts.has_key('b'):
2835 if not os.path.isdir(ps) or opts.has_key('b'):
2836 bkms = self.db.get('bookmarks', {})
2836 bkms = self.db.get('bookmarks', {})
2837
2837
2838 if bkms.has_key(ps):
2838 if bkms.has_key(ps):
2839 target = bkms[ps]
2839 target = bkms[ps]
2840 print '(bookmark:%s) -> %s' % (ps,target)
2840 print '(bookmark:%s) -> %s' % (ps,target)
2841 ps = target
2841 ps = target
2842 else:
2842 else:
2843 if opts.has_key('b'):
2843 if opts.has_key('b'):
2844 raise UsageError("Bookmark '%s' not found. "
2844 raise UsageError("Bookmark '%s' not found. "
2845 "Use '%%bookmark -l' to see your bookmarks." % ps)
2845 "Use '%%bookmark -l' to see your bookmarks." % ps)
2846
2846
2847 # at this point ps should point to the target dir
2847 # at this point ps should point to the target dir
2848 if ps:
2848 if ps:
2849 try:
2849 try:
2850 os.chdir(os.path.expanduser(ps))
2850 os.chdir(os.path.expanduser(ps))
2851 if self.shell.rc.term_title:
2851 if self.shell.rc.term_title:
2852 #print 'set term title:',self.shell.rc.term_title # dbg
2852 #print 'set term title:',self.shell.rc.term_title # dbg
2853 platutils.set_term_title('IPy ' + abbrev_cwd())
2853 platutils.set_term_title('IPy ' + abbrev_cwd())
2854 except OSError:
2854 except OSError:
2855 print sys.exc_info()[1]
2855 print sys.exc_info()[1]
2856 else:
2856 else:
2857 cwd = os.getcwd()
2857 cwd = os.getcwd()
2858 dhist = self.shell.user_ns['_dh']
2858 dhist = self.shell.user_ns['_dh']
2859 if oldcwd != cwd:
2859 if oldcwd != cwd:
2860 dhist.append(cwd)
2860 dhist.append(cwd)
2861 self.db['dhist'] = compress_dhist(dhist)[-100:]
2861 self.db['dhist'] = compress_dhist(dhist)[-100:]
2862
2862
2863 else:
2863 else:
2864 os.chdir(self.shell.home_dir)
2864 os.chdir(self.shell.home_dir)
2865 if self.shell.rc.term_title:
2865 if self.shell.rc.term_title:
2866 platutils.set_term_title("IPy ~")
2866 platutils.set_term_title("IPy ~")
2867 cwd = os.getcwd()
2867 cwd = os.getcwd()
2868 dhist = self.shell.user_ns['_dh']
2868 dhist = self.shell.user_ns['_dh']
2869
2869
2870 if oldcwd != cwd:
2870 if oldcwd != cwd:
2871 dhist.append(cwd)
2871 dhist.append(cwd)
2872 self.db['dhist'] = compress_dhist(dhist)[-100:]
2872 self.db['dhist'] = compress_dhist(dhist)[-100:]
2873 if not 'q' in opts and self.shell.user_ns['_dh']:
2873 if not 'q' in opts and self.shell.user_ns['_dh']:
2874 print self.shell.user_ns['_dh'][-1]
2874 print self.shell.user_ns['_dh'][-1]
2875
2875
2876
2876
2877 def magic_env(self, parameter_s=''):
2877 def magic_env(self, parameter_s=''):
2878 """List environment variables."""
2878 """List environment variables."""
2879
2879
2880 return os.environ.data
2880 return os.environ.data
2881
2881
2882 def magic_pushd(self, parameter_s=''):
2882 def magic_pushd(self, parameter_s=''):
2883 """Place the current dir on stack and change directory.
2883 """Place the current dir on stack and change directory.
2884
2884
2885 Usage:\\
2885 Usage:\\
2886 %pushd ['dirname']
2886 %pushd ['dirname']
2887 """
2887 """
2888
2888
2889 dir_s = self.shell.dir_stack
2889 dir_s = self.shell.dir_stack
2890 tgt = os.path.expanduser(parameter_s)
2890 tgt = os.path.expanduser(parameter_s)
2891 cwd = os.getcwd().replace(self.home_dir,'~')
2891 cwd = os.getcwd().replace(self.home_dir,'~')
2892 if tgt:
2892 if tgt:
2893 self.magic_cd(parameter_s)
2893 self.magic_cd(parameter_s)
2894 dir_s.insert(0,cwd)
2894 dir_s.insert(0,cwd)
2895 return self.magic_dirs()
2895 return self.magic_dirs()
2896
2896
2897 def magic_popd(self, parameter_s=''):
2897 def magic_popd(self, parameter_s=''):
2898 """Change to directory popped off the top of the stack.
2898 """Change to directory popped off the top of the stack.
2899 """
2899 """
2900 if not self.shell.dir_stack:
2900 if not self.shell.dir_stack:
2901 raise UsageError("%popd on empty stack")
2901 raise UsageError("%popd on empty stack")
2902 top = self.shell.dir_stack.pop(0)
2902 top = self.shell.dir_stack.pop(0)
2903 self.magic_cd(top)
2903 self.magic_cd(top)
2904 print "popd ->",top
2904 print "popd ->",top
2905
2905
2906 def magic_dirs(self, parameter_s=''):
2906 def magic_dirs(self, parameter_s=''):
2907 """Return the current directory stack."""
2907 """Return the current directory stack."""
2908
2908
2909 return self.shell.dir_stack
2909 return self.shell.dir_stack
2910
2910
2911 def magic_dhist(self, parameter_s=''):
2911 def magic_dhist(self, parameter_s=''):
2912 """Print your history of visited directories.
2912 """Print your history of visited directories.
2913
2913
2914 %dhist -> print full history\\
2914 %dhist -> print full history\\
2915 %dhist n -> print last n entries only\\
2915 %dhist n -> print last n entries only\\
2916 %dhist n1 n2 -> print entries between n1 and n2 (n1 not included)\\
2916 %dhist n1 n2 -> print entries between n1 and n2 (n1 not included)\\
2917
2917
2918 This history is automatically maintained by the %cd command, and
2918 This history is automatically maintained by the %cd command, and
2919 always available as the global list variable _dh. You can use %cd -<n>
2919 always available as the global list variable _dh. You can use %cd -<n>
2920 to go to directory number <n>.
2920 to go to directory number <n>.
2921
2921
2922 Note that most of time, you should view directory history by entering
2922 Note that most of time, you should view directory history by entering
2923 cd -<TAB>.
2923 cd -<TAB>.
2924
2924
2925 """
2925 """
2926
2926
2927 dh = self.shell.user_ns['_dh']
2927 dh = self.shell.user_ns['_dh']
2928 if parameter_s:
2928 if parameter_s:
2929 try:
2929 try:
2930 args = map(int,parameter_s.split())
2930 args = map(int,parameter_s.split())
2931 except:
2931 except:
2932 self.arg_err(Magic.magic_dhist)
2932 self.arg_err(Magic.magic_dhist)
2933 return
2933 return
2934 if len(args) == 1:
2934 if len(args) == 1:
2935 ini,fin = max(len(dh)-(args[0]),0),len(dh)
2935 ini,fin = max(len(dh)-(args[0]),0),len(dh)
2936 elif len(args) == 2:
2936 elif len(args) == 2:
2937 ini,fin = args
2937 ini,fin = args
2938 else:
2938 else:
2939 self.arg_err(Magic.magic_dhist)
2939 self.arg_err(Magic.magic_dhist)
2940 return
2940 return
2941 else:
2941 else:
2942 ini,fin = 0,len(dh)
2942 ini,fin = 0,len(dh)
2943 nlprint(dh,
2943 nlprint(dh,
2944 header = 'Directory history (kept in _dh)',
2944 header = 'Directory history (kept in _dh)',
2945 start=ini,stop=fin)
2945 start=ini,stop=fin)
2946
2946
2947 @testdec.skip_doctest
2947 @testdec.skip_doctest
2948 def magic_sc(self, parameter_s=''):
2948 def magic_sc(self, parameter_s=''):
2949 """Shell capture - execute a shell command and capture its output.
2949 """Shell capture - execute a shell command and capture its output.
2950
2950
2951 DEPRECATED. Suboptimal, retained for backwards compatibility.
2951 DEPRECATED. Suboptimal, retained for backwards compatibility.
2952
2952
2953 You should use the form 'var = !command' instead. Example:
2953 You should use the form 'var = !command' instead. Example:
2954
2954
2955 "%sc -l myfiles = ls ~" should now be written as
2955 "%sc -l myfiles = ls ~" should now be written as
2956
2956
2957 "myfiles = !ls ~"
2957 "myfiles = !ls ~"
2958
2958
2959 myfiles.s, myfiles.l and myfiles.n still apply as documented
2959 myfiles.s, myfiles.l and myfiles.n still apply as documented
2960 below.
2960 below.
2961
2961
2962 --
2962 --
2963 %sc [options] varname=command
2963 %sc [options] varname=command
2964
2964
2965 IPython will run the given command using commands.getoutput(), and
2965 IPython will run the given command using commands.getoutput(), and
2966 will then update the user's interactive namespace with a variable
2966 will then update the user's interactive namespace with a variable
2967 called varname, containing the value of the call. Your command can
2967 called varname, containing the value of the call. Your command can
2968 contain shell wildcards, pipes, etc.
2968 contain shell wildcards, pipes, etc.
2969
2969
2970 The '=' sign in the syntax is mandatory, and the variable name you
2970 The '=' sign in the syntax is mandatory, and the variable name you
2971 supply must follow Python's standard conventions for valid names.
2971 supply must follow Python's standard conventions for valid names.
2972
2972
2973 (A special format without variable name exists for internal use)
2973 (A special format without variable name exists for internal use)
2974
2974
2975 Options:
2975 Options:
2976
2976
2977 -l: list output. Split the output on newlines into a list before
2977 -l: list output. Split the output on newlines into a list before
2978 assigning it to the given variable. By default the output is stored
2978 assigning it to the given variable. By default the output is stored
2979 as a single string.
2979 as a single string.
2980
2980
2981 -v: verbose. Print the contents of the variable.
2981 -v: verbose. Print the contents of the variable.
2982
2982
2983 In most cases you should not need to split as a list, because the
2983 In most cases you should not need to split as a list, because the
2984 returned value is a special type of string which can automatically
2984 returned value is a special type of string which can automatically
2985 provide its contents either as a list (split on newlines) or as a
2985 provide its contents either as a list (split on newlines) or as a
2986 space-separated string. These are convenient, respectively, either
2986 space-separated string. These are convenient, respectively, either
2987 for sequential processing or to be passed to a shell command.
2987 for sequential processing or to be passed to a shell command.
2988
2988
2989 For example:
2989 For example:
2990
2990
2991 # all-random
2991 # all-random
2992
2992
2993 # Capture into variable a
2993 # Capture into variable a
2994 In [1]: sc a=ls *py
2994 In [1]: sc a=ls *py
2995
2995
2996 # a is a string with embedded newlines
2996 # a is a string with embedded newlines
2997 In [2]: a
2997 In [2]: a
2998 Out[2]: 'setup.py\\nwin32_manual_post_install.py'
2998 Out[2]: 'setup.py\\nwin32_manual_post_install.py'
2999
2999
3000 # which can be seen as a list:
3000 # which can be seen as a list:
3001 In [3]: a.l
3001 In [3]: a.l
3002 Out[3]: ['setup.py', 'win32_manual_post_install.py']
3002 Out[3]: ['setup.py', 'win32_manual_post_install.py']
3003
3003
3004 # or as a whitespace-separated string:
3004 # or as a whitespace-separated string:
3005 In [4]: a.s
3005 In [4]: a.s
3006 Out[4]: 'setup.py win32_manual_post_install.py'
3006 Out[4]: 'setup.py win32_manual_post_install.py'
3007
3007
3008 # a.s is useful to pass as a single command line:
3008 # a.s is useful to pass as a single command line:
3009 In [5]: !wc -l $a.s
3009 In [5]: !wc -l $a.s
3010 146 setup.py
3010 146 setup.py
3011 130 win32_manual_post_install.py
3011 130 win32_manual_post_install.py
3012 276 total
3012 276 total
3013
3013
3014 # while the list form is useful to loop over:
3014 # while the list form is useful to loop over:
3015 In [6]: for f in a.l:
3015 In [6]: for f in a.l:
3016 ...: !wc -l $f
3016 ...: !wc -l $f
3017 ...:
3017 ...:
3018 146 setup.py
3018 146 setup.py
3019 130 win32_manual_post_install.py
3019 130 win32_manual_post_install.py
3020
3020
3021 Similiarly, the lists returned by the -l option are also special, in
3021 Similiarly, the lists returned by the -l option are also special, in
3022 the sense that you can equally invoke the .s attribute on them to
3022 the sense that you can equally invoke the .s attribute on them to
3023 automatically get a whitespace-separated string from their contents:
3023 automatically get a whitespace-separated string from their contents:
3024
3024
3025 In [7]: sc -l b=ls *py
3025 In [7]: sc -l b=ls *py
3026
3026
3027 In [8]: b
3027 In [8]: b
3028 Out[8]: ['setup.py', 'win32_manual_post_install.py']
3028 Out[8]: ['setup.py', 'win32_manual_post_install.py']
3029
3029
3030 In [9]: b.s
3030 In [9]: b.s
3031 Out[9]: 'setup.py win32_manual_post_install.py'
3031 Out[9]: 'setup.py win32_manual_post_install.py'
3032
3032
3033 In summary, both the lists and strings used for ouptut capture have
3033 In summary, both the lists and strings used for ouptut capture have
3034 the following special attributes:
3034 the following special attributes:
3035
3035
3036 .l (or .list) : value as list.
3036 .l (or .list) : value as list.
3037 .n (or .nlstr): value as newline-separated string.
3037 .n (or .nlstr): value as newline-separated string.
3038 .s (or .spstr): value as space-separated string.
3038 .s (or .spstr): value as space-separated string.
3039 """
3039 """
3040
3040
3041 opts,args = self.parse_options(parameter_s,'lv')
3041 opts,args = self.parse_options(parameter_s,'lv')
3042 # Try to get a variable name and command to run
3042 # Try to get a variable name and command to run
3043 try:
3043 try:
3044 # the variable name must be obtained from the parse_options
3044 # the variable name must be obtained from the parse_options
3045 # output, which uses shlex.split to strip options out.
3045 # output, which uses shlex.split to strip options out.
3046 var,_ = args.split('=',1)
3046 var,_ = args.split('=',1)
3047 var = var.strip()
3047 var = var.strip()
3048 # But the the command has to be extracted from the original input
3048 # But the the command has to be extracted from the original input
3049 # parameter_s, not on what parse_options returns, to avoid the
3049 # parameter_s, not on what parse_options returns, to avoid the
3050 # quote stripping which shlex.split performs on it.
3050 # quote stripping which shlex.split performs on it.
3051 _,cmd = parameter_s.split('=',1)
3051 _,cmd = parameter_s.split('=',1)
3052 except ValueError:
3052 except ValueError:
3053 var,cmd = '',''
3053 var,cmd = '',''
3054 # If all looks ok, proceed
3054 # If all looks ok, proceed
3055 out,err = self.shell.getoutputerror(cmd)
3055 out,err = self.shell.getoutputerror(cmd)
3056 if err:
3056 if err:
3057 print >> Term.cerr,err
3057 print >> Term.cerr,err
3058 if opts.has_key('l'):
3058 if opts.has_key('l'):
3059 out = SList(out.split('\n'))
3059 out = SList(out.split('\n'))
3060 else:
3060 else:
3061 out = LSString(out)
3061 out = LSString(out)
3062 if opts.has_key('v'):
3062 if opts.has_key('v'):
3063 print '%s ==\n%s' % (var,pformat(out))
3063 print '%s ==\n%s' % (var,pformat(out))
3064 if var:
3064 if var:
3065 self.shell.user_ns.update({var:out})
3065 self.shell.user_ns.update({var:out})
3066 else:
3066 else:
3067 return out
3067 return out
3068
3068
3069 def magic_sx(self, parameter_s=''):
3069 def magic_sx(self, parameter_s=''):
3070 """Shell execute - run a shell command and capture its output.
3070 """Shell execute - run a shell command and capture its output.
3071
3071
3072 %sx command
3072 %sx command
3073
3073
3074 IPython will run the given command using commands.getoutput(), and
3074 IPython will run the given command using commands.getoutput(), and
3075 return the result formatted as a list (split on '\\n'). Since the
3075 return the result formatted as a list (split on '\\n'). Since the
3076 output is _returned_, it will be stored in ipython's regular output
3076 output is _returned_, it will be stored in ipython's regular output
3077 cache Out[N] and in the '_N' automatic variables.
3077 cache Out[N] and in the '_N' automatic variables.
3078
3078
3079 Notes:
3079 Notes:
3080
3080
3081 1) If an input line begins with '!!', then %sx is automatically
3081 1) If an input line begins with '!!', then %sx is automatically
3082 invoked. That is, while:
3082 invoked. That is, while:
3083 !ls
3083 !ls
3084 causes ipython to simply issue system('ls'), typing
3084 causes ipython to simply issue system('ls'), typing
3085 !!ls
3085 !!ls
3086 is a shorthand equivalent to:
3086 is a shorthand equivalent to:
3087 %sx ls
3087 %sx ls
3088
3088
3089 2) %sx differs from %sc in that %sx automatically splits into a list,
3089 2) %sx differs from %sc in that %sx automatically splits into a list,
3090 like '%sc -l'. The reason for this is to make it as easy as possible
3090 like '%sc -l'. The reason for this is to make it as easy as possible
3091 to process line-oriented shell output via further python commands.
3091 to process line-oriented shell output via further python commands.
3092 %sc is meant to provide much finer control, but requires more
3092 %sc is meant to provide much finer control, but requires more
3093 typing.
3093 typing.
3094
3094
3095 3) Just like %sc -l, this is a list with special attributes:
3095 3) Just like %sc -l, this is a list with special attributes:
3096
3096
3097 .l (or .list) : value as list.
3097 .l (or .list) : value as list.
3098 .n (or .nlstr): value as newline-separated string.
3098 .n (or .nlstr): value as newline-separated string.
3099 .s (or .spstr): value as whitespace-separated string.
3099 .s (or .spstr): value as whitespace-separated string.
3100
3100
3101 This is very useful when trying to use such lists as arguments to
3101 This is very useful when trying to use such lists as arguments to
3102 system commands."""
3102 system commands."""
3103
3103
3104 if parameter_s:
3104 if parameter_s:
3105 out,err = self.shell.getoutputerror(parameter_s)
3105 out,err = self.shell.getoutputerror(parameter_s)
3106 if err:
3106 if err:
3107 print >> Term.cerr,err
3107 print >> Term.cerr,err
3108 return SList(out.split('\n'))
3108 return SList(out.split('\n'))
3109
3109
3110 def magic_bg(self, parameter_s=''):
3110 def magic_bg(self, parameter_s=''):
3111 """Run a job in the background, in a separate thread.
3111 """Run a job in the background, in a separate thread.
3112
3112
3113 For example,
3113 For example,
3114
3114
3115 %bg myfunc(x,y,z=1)
3115 %bg myfunc(x,y,z=1)
3116
3116
3117 will execute 'myfunc(x,y,z=1)' in a background thread. As soon as the
3117 will execute 'myfunc(x,y,z=1)' in a background thread. As soon as the
3118 execution starts, a message will be printed indicating the job
3118 execution starts, a message will be printed indicating the job
3119 number. If your job number is 5, you can use
3119 number. If your job number is 5, you can use
3120
3120
3121 myvar = jobs.result(5) or myvar = jobs[5].result
3121 myvar = jobs.result(5) or myvar = jobs[5].result
3122
3122
3123 to assign this result to variable 'myvar'.
3123 to assign this result to variable 'myvar'.
3124
3124
3125 IPython has a job manager, accessible via the 'jobs' object. You can
3125 IPython has a job manager, accessible via the 'jobs' object. You can
3126 type jobs? to get more information about it, and use jobs.<TAB> to see
3126 type jobs? to get more information about it, and use jobs.<TAB> to see
3127 its attributes. All attributes not starting with an underscore are
3127 its attributes. All attributes not starting with an underscore are
3128 meant for public use.
3128 meant for public use.
3129
3129
3130 In particular, look at the jobs.new() method, which is used to create
3130 In particular, look at the jobs.new() method, which is used to create
3131 new jobs. This magic %bg function is just a convenience wrapper
3131 new jobs. This magic %bg function is just a convenience wrapper
3132 around jobs.new(), for expression-based jobs. If you want to create a
3132 around jobs.new(), for expression-based jobs. If you want to create a
3133 new job with an explicit function object and arguments, you must call
3133 new job with an explicit function object and arguments, you must call
3134 jobs.new() directly.
3134 jobs.new() directly.
3135
3135
3136 The jobs.new docstring also describes in detail several important
3136 The jobs.new docstring also describes in detail several important
3137 caveats associated with a thread-based model for background job
3137 caveats associated with a thread-based model for background job
3138 execution. Type jobs.new? for details.
3138 execution. Type jobs.new? for details.
3139
3139
3140 You can check the status of all jobs with jobs.status().
3140 You can check the status of all jobs with jobs.status().
3141
3141
3142 The jobs variable is set by IPython into the Python builtin namespace.
3142 The jobs variable is set by IPython into the Python builtin namespace.
3143 If you ever declare a variable named 'jobs', you will shadow this
3143 If you ever declare a variable named 'jobs', you will shadow this
3144 name. You can either delete your global jobs variable to regain
3144 name. You can either delete your global jobs variable to regain
3145 access to the job manager, or make a new name and assign it manually
3145 access to the job manager, or make a new name and assign it manually
3146 to the manager (stored in IPython's namespace). For example, to
3146 to the manager (stored in IPython's namespace). For example, to
3147 assign the job manager to the Jobs name, use:
3147 assign the job manager to the Jobs name, use:
3148
3148
3149 Jobs = __builtins__.jobs"""
3149 Jobs = __builtins__.jobs"""
3150
3150
3151 self.shell.jobs.new(parameter_s,self.shell.user_ns)
3151 self.shell.jobs.new(parameter_s,self.shell.user_ns)
3152
3152
3153 def magic_r(self, parameter_s=''):
3153 def magic_r(self, parameter_s=''):
3154 """Repeat previous input.
3154 """Repeat previous input.
3155
3155
3156 Note: Consider using the more powerfull %rep instead!
3156 Note: Consider using the more powerfull %rep instead!
3157
3157
3158 If given an argument, repeats the previous command which starts with
3158 If given an argument, repeats the previous command which starts with
3159 the same string, otherwise it just repeats the previous input.
3159 the same string, otherwise it just repeats the previous input.
3160
3160
3161 Shell escaped commands (with ! as first character) are not recognized
3161 Shell escaped commands (with ! as first character) are not recognized
3162 by this system, only pure python code and magic commands.
3162 by this system, only pure python code and magic commands.
3163 """
3163 """
3164
3164
3165 start = parameter_s.strip()
3165 start = parameter_s.strip()
3166 esc_magic = self.shell.ESC_MAGIC
3166 esc_magic = self.shell.ESC_MAGIC
3167 # Identify magic commands even if automagic is on (which means
3167 # Identify magic commands even if automagic is on (which means
3168 # the in-memory version is different from that typed by the user).
3168 # the in-memory version is different from that typed by the user).
3169 if self.shell.rc.automagic:
3169 if self.shell.rc.automagic:
3170 start_magic = esc_magic+start
3170 start_magic = esc_magic+start
3171 else:
3171 else:
3172 start_magic = start
3172 start_magic = start
3173 # Look through the input history in reverse
3173 # Look through the input history in reverse
3174 for n in range(len(self.shell.input_hist)-2,0,-1):
3174 for n in range(len(self.shell.input_hist)-2,0,-1):
3175 input = self.shell.input_hist[n]
3175 input = self.shell.input_hist[n]
3176 # skip plain 'r' lines so we don't recurse to infinity
3176 # skip plain 'r' lines so we don't recurse to infinity
3177 if input != '_ip.magic("r")\n' and \
3177 if input != '_ip.magic("r")\n' and \
3178 (input.startswith(start) or input.startswith(start_magic)):
3178 (input.startswith(start) or input.startswith(start_magic)):
3179 #print 'match',`input` # dbg
3179 #print 'match',`input` # dbg
3180 print 'Executing:',input,
3180 print 'Executing:',input,
3181 self.shell.runlines(input)
3181 self.shell.runlines(input)
3182 return
3182 return
3183 print 'No previous input matching `%s` found.' % start
3183 print 'No previous input matching `%s` found.' % start
3184
3184
3185
3185
3186 def magic_bookmark(self, parameter_s=''):
3186 def magic_bookmark(self, parameter_s=''):
3187 """Manage IPython's bookmark system.
3187 """Manage IPython's bookmark system.
3188
3188
3189 %bookmark <name> - set bookmark to current dir
3189 %bookmark <name> - set bookmark to current dir
3190 %bookmark <name> <dir> - set bookmark to <dir>
3190 %bookmark <name> <dir> - set bookmark to <dir>
3191 %bookmark -l - list all bookmarks
3191 %bookmark -l - list all bookmarks
3192 %bookmark -d <name> - remove bookmark
3192 %bookmark -d <name> - remove bookmark
3193 %bookmark -r - remove all bookmarks
3193 %bookmark -r - remove all bookmarks
3194
3194
3195 You can later on access a bookmarked folder with:
3195 You can later on access a bookmarked folder with:
3196 %cd -b <name>
3196 %cd -b <name>
3197 or simply '%cd <name>' if there is no directory called <name> AND
3197 or simply '%cd <name>' if there is no directory called <name> AND
3198 there is such a bookmark defined.
3198 there is such a bookmark defined.
3199
3199
3200 Your bookmarks persist through IPython sessions, but they are
3200 Your bookmarks persist through IPython sessions, but they are
3201 associated with each profile."""
3201 associated with each profile."""
3202
3202
3203 opts,args = self.parse_options(parameter_s,'drl',mode='list')
3203 opts,args = self.parse_options(parameter_s,'drl',mode='list')
3204 if len(args) > 2:
3204 if len(args) > 2:
3205 raise UsageError("%bookmark: too many arguments")
3205 raise UsageError("%bookmark: too many arguments")
3206
3206
3207 bkms = self.db.get('bookmarks',{})
3207 bkms = self.db.get('bookmarks',{})
3208
3208
3209 if opts.has_key('d'):
3209 if opts.has_key('d'):
3210 try:
3210 try:
3211 todel = args[0]
3211 todel = args[0]
3212 except IndexError:
3212 except IndexError:
3213 raise UsageError(
3213 raise UsageError(
3214 "%bookmark -d: must provide a bookmark to delete")
3214 "%bookmark -d: must provide a bookmark to delete")
3215 else:
3215 else:
3216 try:
3216 try:
3217 del bkms[todel]
3217 del bkms[todel]
3218 except KeyError:
3218 except KeyError:
3219 raise UsageError(
3219 raise UsageError(
3220 "%%bookmark -d: Can't delete bookmark '%s'" % todel)
3220 "%%bookmark -d: Can't delete bookmark '%s'" % todel)
3221
3221
3222 elif opts.has_key('r'):
3222 elif opts.has_key('r'):
3223 bkms = {}
3223 bkms = {}
3224 elif opts.has_key('l'):
3224 elif opts.has_key('l'):
3225 bks = bkms.keys()
3225 bks = bkms.keys()
3226 bks.sort()
3226 bks.sort()
3227 if bks:
3227 if bks:
3228 size = max(map(len,bks))
3228 size = max(map(len,bks))
3229 else:
3229 else:
3230 size = 0
3230 size = 0
3231 fmt = '%-'+str(size)+'s -> %s'
3231 fmt = '%-'+str(size)+'s -> %s'
3232 print 'Current bookmarks:'
3232 print 'Current bookmarks:'
3233 for bk in bks:
3233 for bk in bks:
3234 print fmt % (bk,bkms[bk])
3234 print fmt % (bk,bkms[bk])
3235 else:
3235 else:
3236 if not args:
3236 if not args:
3237 raise UsageError("%bookmark: You must specify the bookmark name")
3237 raise UsageError("%bookmark: You must specify the bookmark name")
3238 elif len(args)==1:
3238 elif len(args)==1:
3239 bkms[args[0]] = os.getcwd()
3239 bkms[args[0]] = os.getcwd()
3240 elif len(args)==2:
3240 elif len(args)==2:
3241 bkms[args[0]] = args[1]
3241 bkms[args[0]] = args[1]
3242 self.db['bookmarks'] = bkms
3242 self.db['bookmarks'] = bkms
3243
3243
3244 def magic_pycat(self, parameter_s=''):
3244 def magic_pycat(self, parameter_s=''):
3245 """Show a syntax-highlighted file through a pager.
3245 """Show a syntax-highlighted file through a pager.
3246
3246
3247 This magic is similar to the cat utility, but it will assume the file
3247 This magic is similar to the cat utility, but it will assume the file
3248 to be Python source and will show it with syntax highlighting. """
3248 to be Python source and will show it with syntax highlighting. """
3249
3249
3250 try:
3250 try:
3251 filename = get_py_filename(parameter_s)
3251 filename = get_py_filename(parameter_s)
3252 cont = file_read(filename)
3252 cont = file_read(filename)
3253 except IOError:
3253 except IOError:
3254 try:
3254 try:
3255 cont = eval(parameter_s,self.user_ns)
3255 cont = eval(parameter_s,self.user_ns)
3256 except NameError:
3256 except NameError:
3257 cont = None
3257 cont = None
3258 if cont is None:
3258 if cont is None:
3259 print "Error: no such file or variable"
3259 print "Error: no such file or variable"
3260 return
3260 return
3261
3261
3262 page(self.shell.pycolorize(cont),
3262 page(self.shell.pycolorize(cont),
3263 screen_lines=self.shell.rc.screen_length)
3263 screen_lines=self.shell.rc.screen_length)
3264
3264
3265 def magic_cpaste(self, parameter_s=''):
3265 def magic_cpaste(self, parameter_s=''):
3266 """Allows you to paste & execute a pre-formatted code block from clipboard.
3266 """Allows you to paste & execute a pre-formatted code block from clipboard.
3267
3267
3268 You must terminate the block with '--' (two minus-signs) alone on the
3268 You must terminate the block with '--' (two minus-signs) alone on the
3269 line. You can also provide your own sentinel with '%paste -s %%' ('%%'
3269 line. You can also provide your own sentinel with '%paste -s %%' ('%%'
3270 is the new sentinel for this operation)
3270 is the new sentinel for this operation)
3271
3271
3272 The block is dedented prior to execution to enable execution of method
3272 The block is dedented prior to execution to enable execution of method
3273 definitions. '>' and '+' characters at the beginning of a line are
3273 definitions. '>' and '+' characters at the beginning of a line are
3274 ignored, to allow pasting directly from e-mails, diff files and
3274 ignored, to allow pasting directly from e-mails, diff files and
3275 doctests (the '...' continuation prompt is also stripped). The
3275 doctests (the '...' continuation prompt is also stripped). The
3276 executed block is also assigned to variable named 'pasted_block' for
3276 executed block is also assigned to variable named 'pasted_block' for
3277 later editing with '%edit pasted_block'.
3277 later editing with '%edit pasted_block'.
3278
3278
3279 You can also pass a variable name as an argument, e.g. '%cpaste foo'.
3279 You can also pass a variable name as an argument, e.g. '%cpaste foo'.
3280 This assigns the pasted block to variable 'foo' as string, without
3280 This assigns the pasted block to variable 'foo' as string, without
3281 dedenting or executing it (preceding >>> and + is still stripped)
3281 dedenting or executing it (preceding >>> and + is still stripped)
3282
3282
3283 '%cpaste -r' re-executes the block previously entered by cpaste.
3283 '%cpaste -r' re-executes the block previously entered by cpaste.
3284
3284
3285 Do not be alarmed by garbled output on Windows (it's a readline bug).
3285 Do not be alarmed by garbled output on Windows (it's a readline bug).
3286 Just press enter and type -- (and press enter again) and the block
3286 Just press enter and type -- (and press enter again) and the block
3287 will be what was just pasted.
3287 will be what was just pasted.
3288
3288
3289 IPython statements (magics, shell escapes) are not supported (yet).
3289 IPython statements (magics, shell escapes) are not supported (yet).
3290 """
3290 """
3291 opts,args = self.parse_options(parameter_s,'rs:',mode='string')
3291 opts,args = self.parse_options(parameter_s,'rs:',mode='string')
3292 par = args.strip()
3292 par = args.strip()
3293 if opts.has_key('r'):
3293 if opts.has_key('r'):
3294 b = self.user_ns.get('pasted_block', None)
3294 b = self.user_ns.get('pasted_block', None)
3295 if b is None:
3295 if b is None:
3296 raise UsageError('No previous pasted block available')
3296 raise UsageError('No previous pasted block available')
3297 print "Re-executing '%s...' (%d chars)"% (b.split('\n',1)[0], len(b))
3297 print "Re-executing '%s...' (%d chars)"% (b.split('\n',1)[0], len(b))
3298 exec b in self.user_ns
3298 exec b in self.user_ns
3299 return
3299 return
3300
3300
3301 sentinel = opts.get('s','--')
3301 sentinel = opts.get('s','--')
3302
3302
3303 # Regular expressions that declare text we strip from the input:
3303 # Regular expressions that declare text we strip from the input:
3304 strip_re = [r'^\s*In \[\d+\]:', # IPython input prompt
3304 strip_re = [r'^\s*In \[\d+\]:', # IPython input prompt
3305 r'^\s*(\s?>)+', # Python input prompt
3305 r'^\s*(\s?>)+', # Python input prompt
3306 r'^\s*\.{3,}', # Continuation prompts
3306 r'^\s*\.{3,}', # Continuation prompts
3307 r'^\++',
3307 r'^\++',
3308 ]
3308 ]
3309
3309
3310 strip_from_start = map(re.compile,strip_re)
3310 strip_from_start = map(re.compile,strip_re)
3311
3311
3312 from IPython import iplib
3312 from IPython.core import iplib
3313 lines = []
3313 lines = []
3314 print "Pasting code; enter '%s' alone on the line to stop." % sentinel
3314 print "Pasting code; enter '%s' alone on the line to stop." % sentinel
3315 while 1:
3315 while 1:
3316 l = iplib.raw_input_original(':')
3316 l = iplib.raw_input_original(':')
3317 if l ==sentinel:
3317 if l ==sentinel:
3318 break
3318 break
3319
3319
3320 for pat in strip_from_start:
3320 for pat in strip_from_start:
3321 l = pat.sub('',l)
3321 l = pat.sub('',l)
3322 lines.append(l)
3322 lines.append(l)
3323
3323
3324 block = "\n".join(lines) + '\n'
3324 block = "\n".join(lines) + '\n'
3325 #print "block:\n",block
3325 #print "block:\n",block
3326 if not par:
3326 if not par:
3327 b = textwrap.dedent(block)
3327 b = textwrap.dedent(block)
3328 self.user_ns['pasted_block'] = b
3328 self.user_ns['pasted_block'] = b
3329 exec b in self.user_ns
3329 exec b in self.user_ns
3330 else:
3330 else:
3331 self.user_ns[par] = SList(block.splitlines())
3331 self.user_ns[par] = SList(block.splitlines())
3332 print "Block assigned to '%s'" % par
3332 print "Block assigned to '%s'" % par
3333
3333
3334 def magic_quickref(self,arg):
3334 def magic_quickref(self,arg):
3335 """ Show a quick reference sheet """
3335 """ Show a quick reference sheet """
3336 import IPython.usage
3336 import IPython.usage
3337 qr = IPython.usage.quick_reference + self.magic_magic('-brief')
3337 qr = IPython.usage.quick_reference + self.magic_magic('-brief')
3338
3338
3339 page(qr)
3339 page(qr)
3340
3340
3341 def magic_upgrade(self,arg):
3341 def magic_upgrade(self,arg):
3342 """ Upgrade your IPython installation
3342 """ Upgrade your IPython installation
3343
3343
3344 This will copy the config files that don't yet exist in your
3344 This will copy the config files that don't yet exist in your
3345 ipython dir from the system config dir. Use this after upgrading
3345 ipython dir from the system config dir. Use this after upgrading
3346 IPython if you don't wish to delete your .ipython dir.
3346 IPython if you don't wish to delete your .ipython dir.
3347
3347
3348 Call with -nolegacy to get rid of ipythonrc* files (recommended for
3348 Call with -nolegacy to get rid of ipythonrc* files (recommended for
3349 new users)
3349 new users)
3350
3350
3351 """
3351 """
3352 ip = self.getapi()
3352 ip = self.getapi()
3353 ipinstallation = path(IPython.__file__).dirname()
3353 ipinstallation = path(IPython.__file__).dirname()
3354 upgrade_script = '%s "%s"' % (sys.executable,ipinstallation / 'upgrade_dir.py')
3354 upgrade_script = '%s "%s"' % (sys.executable,ipinstallation / 'upgrade_dir.py')
3355 src_config = ipinstallation / 'UserConfig'
3355 src_config = ipinstallation / 'UserConfig'
3356 userdir = path(ip.options.ipythondir)
3356 userdir = path(ip.options.ipythondir)
3357 cmd = '%s "%s" "%s"' % (upgrade_script, src_config, userdir)
3357 cmd = '%s "%s" "%s"' % (upgrade_script, src_config, userdir)
3358 print ">",cmd
3358 print ">",cmd
3359 shell(cmd)
3359 shell(cmd)
3360 if arg == '-nolegacy':
3360 if arg == '-nolegacy':
3361 legacy = userdir.files('ipythonrc*')
3361 legacy = userdir.files('ipythonrc*')
3362 print "Nuking legacy files:",legacy
3362 print "Nuking legacy files:",legacy
3363
3363
3364 [p.remove() for p in legacy]
3364 [p.remove() for p in legacy]
3365 suffix = (sys.platform == 'win32' and '.ini' or '')
3365 suffix = (sys.platform == 'win32' and '.ini' or '')
3366 (userdir / ('ipythonrc' + suffix)).write_text('# Empty, see ipy_user_conf.py\n')
3366 (userdir / ('ipythonrc' + suffix)).write_text('# Empty, see ipy_user_conf.py\n')
3367
3367
3368
3368
3369 def magic_doctest_mode(self,parameter_s=''):
3369 def magic_doctest_mode(self,parameter_s=''):
3370 """Toggle doctest mode on and off.
3370 """Toggle doctest mode on and off.
3371
3371
3372 This mode allows you to toggle the prompt behavior between normal
3372 This mode allows you to toggle the prompt behavior between normal
3373 IPython prompts and ones that are as similar to the default IPython
3373 IPython prompts and ones that are as similar to the default IPython
3374 interpreter as possible.
3374 interpreter as possible.
3375
3375
3376 It also supports the pasting of code snippets that have leading '>>>'
3376 It also supports the pasting of code snippets that have leading '>>>'
3377 and '...' prompts in them. This means that you can paste doctests from
3377 and '...' prompts in them. This means that you can paste doctests from
3378 files or docstrings (even if they have leading whitespace), and the
3378 files or docstrings (even if they have leading whitespace), and the
3379 code will execute correctly. You can then use '%history -tn' to see
3379 code will execute correctly. You can then use '%history -tn' to see
3380 the translated history without line numbers; this will give you the
3380 the translated history without line numbers; this will give you the
3381 input after removal of all the leading prompts and whitespace, which
3381 input after removal of all the leading prompts and whitespace, which
3382 can be pasted back into an editor.
3382 can be pasted back into an editor.
3383
3383
3384 With these features, you can switch into this mode easily whenever you
3384 With these features, you can switch into this mode easily whenever you
3385 need to do testing and changes to doctests, without having to leave
3385 need to do testing and changes to doctests, without having to leave
3386 your existing IPython session.
3386 your existing IPython session.
3387 """
3387 """
3388
3388
3389 # XXX - Fix this to have cleaner activate/deactivate calls.
3389 # XXX - Fix this to have cleaner activate/deactivate calls.
3390 from IPython.Extensions import InterpreterPasteInput as ipaste
3390 from IPython.Extensions import InterpreterPasteInput as ipaste
3391 from IPython.ipstruct import Struct
3391 from IPython.ipstruct import Struct
3392
3392
3393 # Shorthands
3393 # Shorthands
3394 shell = self.shell
3394 shell = self.shell
3395 oc = shell.outputcache
3395 oc = shell.outputcache
3396 rc = shell.rc
3396 rc = shell.rc
3397 meta = shell.meta
3397 meta = shell.meta
3398 # dstore is a data store kept in the instance metadata bag to track any
3398 # dstore is a data store kept in the instance metadata bag to track any
3399 # changes we make, so we can undo them later.
3399 # changes we make, so we can undo them later.
3400 dstore = meta.setdefault('doctest_mode',Struct())
3400 dstore = meta.setdefault('doctest_mode',Struct())
3401 save_dstore = dstore.setdefault
3401 save_dstore = dstore.setdefault
3402
3402
3403 # save a few values we'll need to recover later
3403 # save a few values we'll need to recover later
3404 mode = save_dstore('mode',False)
3404 mode = save_dstore('mode',False)
3405 save_dstore('rc_pprint',rc.pprint)
3405 save_dstore('rc_pprint',rc.pprint)
3406 save_dstore('xmode',shell.InteractiveTB.mode)
3406 save_dstore('xmode',shell.InteractiveTB.mode)
3407 save_dstore('rc_separate_out',rc.separate_out)
3407 save_dstore('rc_separate_out',rc.separate_out)
3408 save_dstore('rc_separate_out2',rc.separate_out2)
3408 save_dstore('rc_separate_out2',rc.separate_out2)
3409 save_dstore('rc_prompts_pad_left',rc.prompts_pad_left)
3409 save_dstore('rc_prompts_pad_left',rc.prompts_pad_left)
3410 save_dstore('rc_separate_in',rc.separate_in)
3410 save_dstore('rc_separate_in',rc.separate_in)
3411
3411
3412 if mode == False:
3412 if mode == False:
3413 # turn on
3413 # turn on
3414 ipaste.activate_prefilter()
3414 ipaste.activate_prefilter()
3415
3415
3416 oc.prompt1.p_template = '>>> '
3416 oc.prompt1.p_template = '>>> '
3417 oc.prompt2.p_template = '... '
3417 oc.prompt2.p_template = '... '
3418 oc.prompt_out.p_template = ''
3418 oc.prompt_out.p_template = ''
3419
3419
3420 # Prompt separators like plain python
3420 # Prompt separators like plain python
3421 oc.input_sep = oc.prompt1.sep = ''
3421 oc.input_sep = oc.prompt1.sep = ''
3422 oc.output_sep = ''
3422 oc.output_sep = ''
3423 oc.output_sep2 = ''
3423 oc.output_sep2 = ''
3424
3424
3425 oc.prompt1.pad_left = oc.prompt2.pad_left = \
3425 oc.prompt1.pad_left = oc.prompt2.pad_left = \
3426 oc.prompt_out.pad_left = False
3426 oc.prompt_out.pad_left = False
3427
3427
3428 rc.pprint = False
3428 rc.pprint = False
3429
3429
3430 shell.magic_xmode('Plain')
3430 shell.magic_xmode('Plain')
3431
3431
3432 else:
3432 else:
3433 # turn off
3433 # turn off
3434 ipaste.deactivate_prefilter()
3434 ipaste.deactivate_prefilter()
3435
3435
3436 oc.prompt1.p_template = rc.prompt_in1
3436 oc.prompt1.p_template = rc.prompt_in1
3437 oc.prompt2.p_template = rc.prompt_in2
3437 oc.prompt2.p_template = rc.prompt_in2
3438 oc.prompt_out.p_template = rc.prompt_out
3438 oc.prompt_out.p_template = rc.prompt_out
3439
3439
3440 oc.input_sep = oc.prompt1.sep = dstore.rc_separate_in
3440 oc.input_sep = oc.prompt1.sep = dstore.rc_separate_in
3441
3441
3442 oc.output_sep = dstore.rc_separate_out
3442 oc.output_sep = dstore.rc_separate_out
3443 oc.output_sep2 = dstore.rc_separate_out2
3443 oc.output_sep2 = dstore.rc_separate_out2
3444
3444
3445 oc.prompt1.pad_left = oc.prompt2.pad_left = \
3445 oc.prompt1.pad_left = oc.prompt2.pad_left = \
3446 oc.prompt_out.pad_left = dstore.rc_prompts_pad_left
3446 oc.prompt_out.pad_left = dstore.rc_prompts_pad_left
3447
3447
3448 rc.pprint = dstore.rc_pprint
3448 rc.pprint = dstore.rc_pprint
3449
3449
3450 shell.magic_xmode(dstore.xmode)
3450 shell.magic_xmode(dstore.xmode)
3451
3451
3452 # Store new mode and inform
3452 # Store new mode and inform
3453 dstore.mode = bool(1-int(mode))
3453 dstore.mode = bool(1-int(mode))
3454 print 'Doctest mode is:',
3454 print 'Doctest mode is:',
3455 print ['OFF','ON'][dstore.mode]
3455 print ['OFF','ON'][dstore.mode]
3456
3456
3457 # end Magic
3457 # end Magic
@@ -1,1247 +1,1247 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """IPython Shell classes.
2 """IPython Shell classes.
3
3
4 All the matplotlib support code was co-developed with John Hunter,
4 All the matplotlib support code was co-developed with John Hunter,
5 matplotlib's author.
5 matplotlib's author.
6 """
6 """
7
7
8 #*****************************************************************************
8 #*****************************************************************************
9 # Copyright (C) 2001-2006 Fernando Perez <fperez@colorado.edu>
9 # Copyright (C) 2001-2006 Fernando Perez <fperez@colorado.edu>
10 #
10 #
11 # Distributed under the terms of the BSD License. The full license is in
11 # Distributed under the terms of the BSD License. The full license is in
12 # the file COPYING, distributed as part of this software.
12 # the file COPYING, distributed as part of this software.
13 #*****************************************************************************
13 #*****************************************************************************
14
14
15 # Code begins
15 # Code begins
16 # Stdlib imports
16 # Stdlib imports
17 import __builtin__
17 import __builtin__
18 import __main__
18 import __main__
19 import Queue
19 import Queue
20 import inspect
20 import inspect
21 import os
21 import os
22 import sys
22 import sys
23 import thread
23 import thread
24 import threading
24 import threading
25 import time
25 import time
26
26
27 from signal import signal, SIGINT
27 from signal import signal, SIGINT
28
28
29 try:
29 try:
30 import ctypes
30 import ctypes
31 HAS_CTYPES = True
31 HAS_CTYPES = True
32 except ImportError:
32 except ImportError:
33 HAS_CTYPES = False
33 HAS_CTYPES = False
34
34
35 # IPython imports
35 # IPython imports
36 import IPython
36 import IPython
37 from IPython import ultraTB
37 from IPython import ultraTB
38 from IPython.core import ipapi
38 from IPython.core import ipapi
39 from IPython.Magic import Magic
39 from IPython.Magic import Magic
40 from IPython.utils.genutils import Term,warn,error,flag_calls, ask_yes_no
40 from IPython.utils.genutils import Term,warn,error,flag_calls, ask_yes_no
41 from IPython.iplib import InteractiveShell
41 from IPython.core.iplib import InteractiveShell
42 from IPython.ipmaker import make_IPython
42 from IPython.ipmaker import make_IPython
43 from IPython.ipstruct import Struct
43 from IPython.ipstruct import Struct
44 from IPython.testing import decorators as testdec
44 from IPython.testing import decorators as testdec
45
45
46 # Globals
46 # Globals
47 # global flag to pass around information about Ctrl-C without exceptions
47 # global flag to pass around information about Ctrl-C without exceptions
48 KBINT = False
48 KBINT = False
49
49
50 # global flag to turn on/off Tk support.
50 # global flag to turn on/off Tk support.
51 USE_TK = False
51 USE_TK = False
52
52
53 # ID for the main thread, used for cross-thread exceptions
53 # ID for the main thread, used for cross-thread exceptions
54 MAIN_THREAD_ID = thread.get_ident()
54 MAIN_THREAD_ID = thread.get_ident()
55
55
56 # Tag when runcode() is active, for exception handling
56 # Tag when runcode() is active, for exception handling
57 CODE_RUN = None
57 CODE_RUN = None
58
58
59 # Default timeout for waiting for multithreaded shells (in seconds)
59 # Default timeout for waiting for multithreaded shells (in seconds)
60 GUI_TIMEOUT = 10
60 GUI_TIMEOUT = 10
61
61
62 #-----------------------------------------------------------------------------
62 #-----------------------------------------------------------------------------
63 # This class is trivial now, but I want to have it in to publish a clean
63 # This class is trivial now, but I want to have it in to publish a clean
64 # interface. Later when the internals are reorganized, code that uses this
64 # interface. Later when the internals are reorganized, code that uses this
65 # shouldn't have to change.
65 # shouldn't have to change.
66
66
67 class IPShell:
67 class IPShell:
68 """Create an IPython instance."""
68 """Create an IPython instance."""
69
69
70 def __init__(self,argv=None,user_ns=None,user_global_ns=None,
70 def __init__(self,argv=None,user_ns=None,user_global_ns=None,
71 debug=1,shell_class=InteractiveShell):
71 debug=1,shell_class=InteractiveShell):
72 self.IP = make_IPython(argv,user_ns=user_ns,
72 self.IP = make_IPython(argv,user_ns=user_ns,
73 user_global_ns=user_global_ns,
73 user_global_ns=user_global_ns,
74 debug=debug,shell_class=shell_class)
74 debug=debug,shell_class=shell_class)
75
75
76 def mainloop(self,sys_exit=0,banner=None):
76 def mainloop(self,sys_exit=0,banner=None):
77 self.IP.mainloop(banner)
77 self.IP.mainloop(banner)
78 if sys_exit:
78 if sys_exit:
79 sys.exit()
79 sys.exit()
80
80
81 #-----------------------------------------------------------------------------
81 #-----------------------------------------------------------------------------
82 def kill_embedded(self,parameter_s=''):
82 def kill_embedded(self,parameter_s=''):
83 """%kill_embedded : deactivate for good the current embedded IPython.
83 """%kill_embedded : deactivate for good the current embedded IPython.
84
84
85 This function (after asking for confirmation) sets an internal flag so that
85 This function (after asking for confirmation) sets an internal flag so that
86 an embedded IPython will never activate again. This is useful to
86 an embedded IPython will never activate again. This is useful to
87 permanently disable a shell that is being called inside a loop: once you've
87 permanently disable a shell that is being called inside a loop: once you've
88 figured out what you needed from it, you may then kill it and the program
88 figured out what you needed from it, you may then kill it and the program
89 will then continue to run without the interactive shell interfering again.
89 will then continue to run without the interactive shell interfering again.
90 """
90 """
91
91
92 kill = ask_yes_no("Are you sure you want to kill this embedded instance "
92 kill = ask_yes_no("Are you sure you want to kill this embedded instance "
93 "(y/n)? [y/N] ",'n')
93 "(y/n)? [y/N] ",'n')
94 if kill:
94 if kill:
95 self.shell.embedded_active = False
95 self.shell.embedded_active = False
96 print "This embedded IPython will not reactivate anymore once you exit."
96 print "This embedded IPython will not reactivate anymore once you exit."
97
97
98 class IPShellEmbed:
98 class IPShellEmbed:
99 """Allow embedding an IPython shell into a running program.
99 """Allow embedding an IPython shell into a running program.
100
100
101 Instances of this class are callable, with the __call__ method being an
101 Instances of this class are callable, with the __call__ method being an
102 alias to the embed() method of an InteractiveShell instance.
102 alias to the embed() method of an InteractiveShell instance.
103
103
104 Usage (see also the example-embed.py file for a running example):
104 Usage (see also the example-embed.py file for a running example):
105
105
106 ipshell = IPShellEmbed([argv,banner,exit_msg,rc_override])
106 ipshell = IPShellEmbed([argv,banner,exit_msg,rc_override])
107
107
108 - argv: list containing valid command-line options for IPython, as they
108 - argv: list containing valid command-line options for IPython, as they
109 would appear in sys.argv[1:].
109 would appear in sys.argv[1:].
110
110
111 For example, the following command-line options:
111 For example, the following command-line options:
112
112
113 $ ipython -prompt_in1 'Input <\\#>' -colors LightBG
113 $ ipython -prompt_in1 'Input <\\#>' -colors LightBG
114
114
115 would be passed in the argv list as:
115 would be passed in the argv list as:
116
116
117 ['-prompt_in1','Input <\\#>','-colors','LightBG']
117 ['-prompt_in1','Input <\\#>','-colors','LightBG']
118
118
119 - banner: string which gets printed every time the interpreter starts.
119 - banner: string which gets printed every time the interpreter starts.
120
120
121 - exit_msg: string which gets printed every time the interpreter exits.
121 - exit_msg: string which gets printed every time the interpreter exits.
122
122
123 - rc_override: a dict or Struct of configuration options such as those
123 - rc_override: a dict or Struct of configuration options such as those
124 used by IPython. These options are read from your ~/.ipython/ipythonrc
124 used by IPython. These options are read from your ~/.ipython/ipythonrc
125 file when the Shell object is created. Passing an explicit rc_override
125 file when the Shell object is created. Passing an explicit rc_override
126 dict with any options you want allows you to override those values at
126 dict with any options you want allows you to override those values at
127 creation time without having to modify the file. This way you can create
127 creation time without having to modify the file. This way you can create
128 embeddable instances configured in any way you want without editing any
128 embeddable instances configured in any way you want without editing any
129 global files (thus keeping your interactive IPython configuration
129 global files (thus keeping your interactive IPython configuration
130 unchanged).
130 unchanged).
131
131
132 Then the ipshell instance can be called anywhere inside your code:
132 Then the ipshell instance can be called anywhere inside your code:
133
133
134 ipshell(header='') -> Opens up an IPython shell.
134 ipshell(header='') -> Opens up an IPython shell.
135
135
136 - header: string printed by the IPython shell upon startup. This can let
136 - header: string printed by the IPython shell upon startup. This can let
137 you know where in your code you are when dropping into the shell. Note
137 you know where in your code you are when dropping into the shell. Note
138 that 'banner' gets prepended to all calls, so header is used for
138 that 'banner' gets prepended to all calls, so header is used for
139 location-specific information.
139 location-specific information.
140
140
141 For more details, see the __call__ method below.
141 For more details, see the __call__ method below.
142
142
143 When the IPython shell is exited with Ctrl-D, normal program execution
143 When the IPython shell is exited with Ctrl-D, normal program execution
144 resumes.
144 resumes.
145
145
146 This functionality was inspired by a posting on comp.lang.python by cmkl
146 This functionality was inspired by a posting on comp.lang.python by cmkl
147 <cmkleffner@gmx.de> on Dec. 06/01 concerning similar uses of pyrepl, and
147 <cmkleffner@gmx.de> on Dec. 06/01 concerning similar uses of pyrepl, and
148 by the IDL stop/continue commands."""
148 by the IDL stop/continue commands."""
149
149
150 def __init__(self,argv=None,banner='',exit_msg=None,rc_override=None,
150 def __init__(self,argv=None,banner='',exit_msg=None,rc_override=None,
151 user_ns=None):
151 user_ns=None):
152 """Note that argv here is a string, NOT a list."""
152 """Note that argv here is a string, NOT a list."""
153 self.set_banner(banner)
153 self.set_banner(banner)
154 self.set_exit_msg(exit_msg)
154 self.set_exit_msg(exit_msg)
155 self.set_dummy_mode(0)
155 self.set_dummy_mode(0)
156
156
157 # sys.displayhook is a global, we need to save the user's original
157 # sys.displayhook is a global, we need to save the user's original
158 # Don't rely on __displayhook__, as the user may have changed that.
158 # Don't rely on __displayhook__, as the user may have changed that.
159 self.sys_displayhook_ori = sys.displayhook
159 self.sys_displayhook_ori = sys.displayhook
160
160
161 # save readline completer status
161 # save readline completer status
162 try:
162 try:
163 #print 'Save completer',sys.ipcompleter # dbg
163 #print 'Save completer',sys.ipcompleter # dbg
164 self.sys_ipcompleter_ori = sys.ipcompleter
164 self.sys_ipcompleter_ori = sys.ipcompleter
165 except:
165 except:
166 pass # not nested with IPython
166 pass # not nested with IPython
167
167
168 self.IP = make_IPython(argv,rc_override=rc_override,
168 self.IP = make_IPython(argv,rc_override=rc_override,
169 embedded=True,
169 embedded=True,
170 user_ns=user_ns)
170 user_ns=user_ns)
171
171
172 ip = ipapi.IPApi(self.IP)
172 ip = ipapi.IPApi(self.IP)
173 ip.expose_magic("kill_embedded",kill_embedded)
173 ip.expose_magic("kill_embedded",kill_embedded)
174
174
175 # copy our own displayhook also
175 # copy our own displayhook also
176 self.sys_displayhook_embed = sys.displayhook
176 self.sys_displayhook_embed = sys.displayhook
177 # and leave the system's display hook clean
177 # and leave the system's display hook clean
178 sys.displayhook = self.sys_displayhook_ori
178 sys.displayhook = self.sys_displayhook_ori
179 # don't use the ipython crash handler so that user exceptions aren't
179 # don't use the ipython crash handler so that user exceptions aren't
180 # trapped
180 # trapped
181 sys.excepthook = ultraTB.FormattedTB(color_scheme = self.IP.rc.colors,
181 sys.excepthook = ultraTB.FormattedTB(color_scheme = self.IP.rc.colors,
182 mode = self.IP.rc.xmode,
182 mode = self.IP.rc.xmode,
183 call_pdb = self.IP.rc.pdb)
183 call_pdb = self.IP.rc.pdb)
184 self.restore_system_completer()
184 self.restore_system_completer()
185
185
186 def restore_system_completer(self):
186 def restore_system_completer(self):
187 """Restores the readline completer which was in place.
187 """Restores the readline completer which was in place.
188
188
189 This allows embedded IPython within IPython not to disrupt the
189 This allows embedded IPython within IPython not to disrupt the
190 parent's completion.
190 parent's completion.
191 """
191 """
192
192
193 try:
193 try:
194 self.IP.readline.set_completer(self.sys_ipcompleter_ori)
194 self.IP.readline.set_completer(self.sys_ipcompleter_ori)
195 sys.ipcompleter = self.sys_ipcompleter_ori
195 sys.ipcompleter = self.sys_ipcompleter_ori
196 except:
196 except:
197 pass
197 pass
198
198
199 def __call__(self,header='',local_ns=None,global_ns=None,dummy=None):
199 def __call__(self,header='',local_ns=None,global_ns=None,dummy=None):
200 """Activate the interactive interpreter.
200 """Activate the interactive interpreter.
201
201
202 __call__(self,header='',local_ns=None,global_ns,dummy=None) -> Start
202 __call__(self,header='',local_ns=None,global_ns,dummy=None) -> Start
203 the interpreter shell with the given local and global namespaces, and
203 the interpreter shell with the given local and global namespaces, and
204 optionally print a header string at startup.
204 optionally print a header string at startup.
205
205
206 The shell can be globally activated/deactivated using the
206 The shell can be globally activated/deactivated using the
207 set/get_dummy_mode methods. This allows you to turn off a shell used
207 set/get_dummy_mode methods. This allows you to turn off a shell used
208 for debugging globally.
208 for debugging globally.
209
209
210 However, *each* time you call the shell you can override the current
210 However, *each* time you call the shell you can override the current
211 state of dummy_mode with the optional keyword parameter 'dummy'. For
211 state of dummy_mode with the optional keyword parameter 'dummy'. For
212 example, if you set dummy mode on with IPShell.set_dummy_mode(1), you
212 example, if you set dummy mode on with IPShell.set_dummy_mode(1), you
213 can still have a specific call work by making it as IPShell(dummy=0).
213 can still have a specific call work by making it as IPShell(dummy=0).
214
214
215 The optional keyword parameter dummy controls whether the call
215 The optional keyword parameter dummy controls whether the call
216 actually does anything. """
216 actually does anything. """
217
217
218 # If the user has turned it off, go away
218 # If the user has turned it off, go away
219 if not self.IP.embedded_active:
219 if not self.IP.embedded_active:
220 return
220 return
221
221
222 # Normal exits from interactive mode set this flag, so the shell can't
222 # Normal exits from interactive mode set this flag, so the shell can't
223 # re-enter (it checks this variable at the start of interactive mode).
223 # re-enter (it checks this variable at the start of interactive mode).
224 self.IP.exit_now = False
224 self.IP.exit_now = False
225
225
226 # Allow the dummy parameter to override the global __dummy_mode
226 # Allow the dummy parameter to override the global __dummy_mode
227 if dummy or (dummy != 0 and self.__dummy_mode):
227 if dummy or (dummy != 0 and self.__dummy_mode):
228 return
228 return
229
229
230 # Set global subsystems (display,completions) to our values
230 # Set global subsystems (display,completions) to our values
231 sys.displayhook = self.sys_displayhook_embed
231 sys.displayhook = self.sys_displayhook_embed
232 if self.IP.has_readline:
232 if self.IP.has_readline:
233 self.IP.set_completer()
233 self.IP.set_completer()
234
234
235 if self.banner and header:
235 if self.banner and header:
236 format = '%s\n%s\n'
236 format = '%s\n%s\n'
237 else:
237 else:
238 format = '%s%s\n'
238 format = '%s%s\n'
239 banner = format % (self.banner,header)
239 banner = format % (self.banner,header)
240
240
241 # Call the embedding code with a stack depth of 1 so it can skip over
241 # Call the embedding code with a stack depth of 1 so it can skip over
242 # our call and get the original caller's namespaces.
242 # our call and get the original caller's namespaces.
243 self.IP.embed_mainloop(banner,local_ns,global_ns,stack_depth=1)
243 self.IP.embed_mainloop(banner,local_ns,global_ns,stack_depth=1)
244
244
245 if self.exit_msg:
245 if self.exit_msg:
246 print self.exit_msg
246 print self.exit_msg
247
247
248 # Restore global systems (display, completion)
248 # Restore global systems (display, completion)
249 sys.displayhook = self.sys_displayhook_ori
249 sys.displayhook = self.sys_displayhook_ori
250 self.restore_system_completer()
250 self.restore_system_completer()
251
251
252 def set_dummy_mode(self,dummy):
252 def set_dummy_mode(self,dummy):
253 """Sets the embeddable shell's dummy mode parameter.
253 """Sets the embeddable shell's dummy mode parameter.
254
254
255 set_dummy_mode(dummy): dummy = 0 or 1.
255 set_dummy_mode(dummy): dummy = 0 or 1.
256
256
257 This parameter is persistent and makes calls to the embeddable shell
257 This parameter is persistent and makes calls to the embeddable shell
258 silently return without performing any action. This allows you to
258 silently return without performing any action. This allows you to
259 globally activate or deactivate a shell you're using with a single call.
259 globally activate or deactivate a shell you're using with a single call.
260
260
261 If you need to manually"""
261 If you need to manually"""
262
262
263 if dummy not in [0,1,False,True]:
263 if dummy not in [0,1,False,True]:
264 raise ValueError,'dummy parameter must be boolean'
264 raise ValueError,'dummy parameter must be boolean'
265 self.__dummy_mode = dummy
265 self.__dummy_mode = dummy
266
266
267 def get_dummy_mode(self):
267 def get_dummy_mode(self):
268 """Return the current value of the dummy mode parameter.
268 """Return the current value of the dummy mode parameter.
269 """
269 """
270 return self.__dummy_mode
270 return self.__dummy_mode
271
271
272 def set_banner(self,banner):
272 def set_banner(self,banner):
273 """Sets the global banner.
273 """Sets the global banner.
274
274
275 This banner gets prepended to every header printed when the shell
275 This banner gets prepended to every header printed when the shell
276 instance is called."""
276 instance is called."""
277
277
278 self.banner = banner
278 self.banner = banner
279
279
280 def set_exit_msg(self,exit_msg):
280 def set_exit_msg(self,exit_msg):
281 """Sets the global exit_msg.
281 """Sets the global exit_msg.
282
282
283 This exit message gets printed upon exiting every time the embedded
283 This exit message gets printed upon exiting every time the embedded
284 shell is called. It is None by default. """
284 shell is called. It is None by default. """
285
285
286 self.exit_msg = exit_msg
286 self.exit_msg = exit_msg
287
287
288 #-----------------------------------------------------------------------------
288 #-----------------------------------------------------------------------------
289 if HAS_CTYPES:
289 if HAS_CTYPES:
290 # Add async exception support. Trick taken from:
290 # Add async exception support. Trick taken from:
291 # http://sebulba.wikispaces.com/recipe+thread2
291 # http://sebulba.wikispaces.com/recipe+thread2
292 def _async_raise(tid, exctype):
292 def _async_raise(tid, exctype):
293 """raises the exception, performs cleanup if needed"""
293 """raises the exception, performs cleanup if needed"""
294 if not inspect.isclass(exctype):
294 if not inspect.isclass(exctype):
295 raise TypeError("Only types can be raised (not instances)")
295 raise TypeError("Only types can be raised (not instances)")
296 # Explicit cast to c_long is necessary for 64-bit support:
296 # Explicit cast to c_long is necessary for 64-bit support:
297 # See https://bugs.launchpad.net/ipython/+bug/237073
297 # See https://bugs.launchpad.net/ipython/+bug/237073
298 res = ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(tid),
298 res = ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(tid),
299 ctypes.py_object(exctype))
299 ctypes.py_object(exctype))
300 if res == 0:
300 if res == 0:
301 raise ValueError("invalid thread id")
301 raise ValueError("invalid thread id")
302 elif res != 1:
302 elif res != 1:
303 # If it returns a number greater than one, you're in trouble,
303 # If it returns a number greater than one, you're in trouble,
304 # and you should call it again with exc=NULL to revert the effect
304 # and you should call it again with exc=NULL to revert the effect
305 ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, 0)
305 ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, 0)
306 raise SystemError("PyThreadState_SetAsyncExc failed")
306 raise SystemError("PyThreadState_SetAsyncExc failed")
307
307
308 def sigint_handler(signum,stack_frame):
308 def sigint_handler(signum,stack_frame):
309 """Sigint handler for threaded apps.
309 """Sigint handler for threaded apps.
310
310
311 This is a horrible hack to pass information about SIGINT _without_
311 This is a horrible hack to pass information about SIGINT _without_
312 using exceptions, since I haven't been able to properly manage
312 using exceptions, since I haven't been able to properly manage
313 cross-thread exceptions in GTK/WX. In fact, I don't think it can be
313 cross-thread exceptions in GTK/WX. In fact, I don't think it can be
314 done (or at least that's my understanding from a c.l.py thread where
314 done (or at least that's my understanding from a c.l.py thread where
315 this was discussed)."""
315 this was discussed)."""
316
316
317 global KBINT
317 global KBINT
318
318
319 if CODE_RUN:
319 if CODE_RUN:
320 _async_raise(MAIN_THREAD_ID,KeyboardInterrupt)
320 _async_raise(MAIN_THREAD_ID,KeyboardInterrupt)
321 else:
321 else:
322 KBINT = True
322 KBINT = True
323 print '\nKeyboardInterrupt - Press <Enter> to continue.',
323 print '\nKeyboardInterrupt - Press <Enter> to continue.',
324 Term.cout.flush()
324 Term.cout.flush()
325
325
326 else:
326 else:
327 def sigint_handler(signum,stack_frame):
327 def sigint_handler(signum,stack_frame):
328 """Sigint handler for threaded apps.
328 """Sigint handler for threaded apps.
329
329
330 This is a horrible hack to pass information about SIGINT _without_
330 This is a horrible hack to pass information about SIGINT _without_
331 using exceptions, since I haven't been able to properly manage
331 using exceptions, since I haven't been able to properly manage
332 cross-thread exceptions in GTK/WX. In fact, I don't think it can be
332 cross-thread exceptions in GTK/WX. In fact, I don't think it can be
333 done (or at least that's my understanding from a c.l.py thread where
333 done (or at least that's my understanding from a c.l.py thread where
334 this was discussed)."""
334 this was discussed)."""
335
335
336 global KBINT
336 global KBINT
337
337
338 print '\nKeyboardInterrupt - Press <Enter> to continue.',
338 print '\nKeyboardInterrupt - Press <Enter> to continue.',
339 Term.cout.flush()
339 Term.cout.flush()
340 # Set global flag so that runsource can know that Ctrl-C was hit
340 # Set global flag so that runsource can know that Ctrl-C was hit
341 KBINT = True
341 KBINT = True
342
342
343
343
344 class MTInteractiveShell(InteractiveShell):
344 class MTInteractiveShell(InteractiveShell):
345 """Simple multi-threaded shell."""
345 """Simple multi-threaded shell."""
346
346
347 # Threading strategy taken from:
347 # Threading strategy taken from:
348 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65109, by Brian
348 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65109, by Brian
349 # McErlean and John Finlay. Modified with corrections by Antoon Pardon,
349 # McErlean and John Finlay. Modified with corrections by Antoon Pardon,
350 # from the pygtk mailing list, to avoid lockups with system calls.
350 # from the pygtk mailing list, to avoid lockups with system calls.
351
351
352 # class attribute to indicate whether the class supports threads or not.
352 # class attribute to indicate whether the class supports threads or not.
353 # Subclasses with thread support should override this as needed.
353 # Subclasses with thread support should override this as needed.
354 isthreaded = True
354 isthreaded = True
355
355
356 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
356 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
357 user_ns=None,user_global_ns=None,banner2='',
357 user_ns=None,user_global_ns=None,banner2='',
358 gui_timeout=GUI_TIMEOUT,**kw):
358 gui_timeout=GUI_TIMEOUT,**kw):
359 """Similar to the normal InteractiveShell, but with threading control"""
359 """Similar to the normal InteractiveShell, but with threading control"""
360
360
361 InteractiveShell.__init__(self,name,usage,rc,user_ns,
361 InteractiveShell.__init__(self,name,usage,rc,user_ns,
362 user_global_ns,banner2)
362 user_global_ns,banner2)
363
363
364 # Timeout we wait for GUI thread
364 # Timeout we wait for GUI thread
365 self.gui_timeout = gui_timeout
365 self.gui_timeout = gui_timeout
366
366
367 # A queue to hold the code to be executed.
367 # A queue to hold the code to be executed.
368 self.code_queue = Queue.Queue()
368 self.code_queue = Queue.Queue()
369
369
370 # Stuff to do at closing time
370 # Stuff to do at closing time
371 self._kill = None
371 self._kill = None
372 on_kill = kw.get('on_kill', [])
372 on_kill = kw.get('on_kill', [])
373 # Check that all things to kill are callable:
373 # Check that all things to kill are callable:
374 for t in on_kill:
374 for t in on_kill:
375 if not callable(t):
375 if not callable(t):
376 raise TypeError,'on_kill must be a list of callables'
376 raise TypeError,'on_kill must be a list of callables'
377 self.on_kill = on_kill
377 self.on_kill = on_kill
378 # thread identity of the "worker thread" (that may execute code directly)
378 # thread identity of the "worker thread" (that may execute code directly)
379 self.worker_ident = None
379 self.worker_ident = None
380
380
381 def runsource(self, source, filename="<input>", symbol="single"):
381 def runsource(self, source, filename="<input>", symbol="single"):
382 """Compile and run some source in the interpreter.
382 """Compile and run some source in the interpreter.
383
383
384 Modified version of code.py's runsource(), to handle threading issues.
384 Modified version of code.py's runsource(), to handle threading issues.
385 See the original for full docstring details."""
385 See the original for full docstring details."""
386
386
387 global KBINT
387 global KBINT
388
388
389 # If Ctrl-C was typed, we reset the flag and return right away
389 # If Ctrl-C was typed, we reset the flag and return right away
390 if KBINT:
390 if KBINT:
391 KBINT = False
391 KBINT = False
392 return False
392 return False
393
393
394 if self._kill:
394 if self._kill:
395 # can't queue new code if we are being killed
395 # can't queue new code if we are being killed
396 return True
396 return True
397
397
398 try:
398 try:
399 code = self.compile(source, filename, symbol)
399 code = self.compile(source, filename, symbol)
400 except (OverflowError, SyntaxError, ValueError):
400 except (OverflowError, SyntaxError, ValueError):
401 # Case 1
401 # Case 1
402 self.showsyntaxerror(filename)
402 self.showsyntaxerror(filename)
403 return False
403 return False
404
404
405 if code is None:
405 if code is None:
406 # Case 2
406 # Case 2
407 return True
407 return True
408
408
409 # shortcut - if we are in worker thread, or the worker thread is not
409 # shortcut - if we are in worker thread, or the worker thread is not
410 # running, execute directly (to allow recursion and prevent deadlock if
410 # running, execute directly (to allow recursion and prevent deadlock if
411 # code is run early in IPython construction)
411 # code is run early in IPython construction)
412
412
413 if (self.worker_ident is None
413 if (self.worker_ident is None
414 or self.worker_ident == thread.get_ident() ):
414 or self.worker_ident == thread.get_ident() ):
415 InteractiveShell.runcode(self,code)
415 InteractiveShell.runcode(self,code)
416 return False
416 return False
417
417
418 # Case 3
418 # Case 3
419 # Store code in queue, so the execution thread can handle it.
419 # Store code in queue, so the execution thread can handle it.
420
420
421 completed_ev, received_ev = threading.Event(), threading.Event()
421 completed_ev, received_ev = threading.Event(), threading.Event()
422
422
423 self.code_queue.put((code,completed_ev, received_ev))
423 self.code_queue.put((code,completed_ev, received_ev))
424 # first make sure the message was received, with timeout
424 # first make sure the message was received, with timeout
425 received_ev.wait(self.gui_timeout)
425 received_ev.wait(self.gui_timeout)
426 if not received_ev.isSet():
426 if not received_ev.isSet():
427 # the mainloop is dead, start executing code directly
427 # the mainloop is dead, start executing code directly
428 print "Warning: Timeout for mainloop thread exceeded"
428 print "Warning: Timeout for mainloop thread exceeded"
429 print "switching to nonthreaded mode (until mainloop wakes up again)"
429 print "switching to nonthreaded mode (until mainloop wakes up again)"
430 self.worker_ident = None
430 self.worker_ident = None
431 else:
431 else:
432 completed_ev.wait()
432 completed_ev.wait()
433 return False
433 return False
434
434
435 def runcode(self):
435 def runcode(self):
436 """Execute a code object.
436 """Execute a code object.
437
437
438 Multithreaded wrapper around IPython's runcode()."""
438 Multithreaded wrapper around IPython's runcode()."""
439
439
440 global CODE_RUN
440 global CODE_RUN
441
441
442 # we are in worker thread, stash out the id for runsource()
442 # we are in worker thread, stash out the id for runsource()
443 self.worker_ident = thread.get_ident()
443 self.worker_ident = thread.get_ident()
444
444
445 if self._kill:
445 if self._kill:
446 print >>Term.cout, 'Closing threads...',
446 print >>Term.cout, 'Closing threads...',
447 Term.cout.flush()
447 Term.cout.flush()
448 for tokill in self.on_kill:
448 for tokill in self.on_kill:
449 tokill()
449 tokill()
450 print >>Term.cout, 'Done.'
450 print >>Term.cout, 'Done.'
451 # allow kill() to return
451 # allow kill() to return
452 self._kill.set()
452 self._kill.set()
453 return True
453 return True
454
454
455 # Install sigint handler. We do it every time to ensure that if user
455 # Install sigint handler. We do it every time to ensure that if user
456 # code modifies it, we restore our own handling.
456 # code modifies it, we restore our own handling.
457 try:
457 try:
458 signal(SIGINT,sigint_handler)
458 signal(SIGINT,sigint_handler)
459 except SystemError:
459 except SystemError:
460 # This happens under Windows, which seems to have all sorts
460 # This happens under Windows, which seems to have all sorts
461 # of problems with signal handling. Oh well...
461 # of problems with signal handling. Oh well...
462 pass
462 pass
463
463
464 # Flush queue of pending code by calling the run methood of the parent
464 # Flush queue of pending code by calling the run methood of the parent
465 # class with all items which may be in the queue.
465 # class with all items which may be in the queue.
466 code_to_run = None
466 code_to_run = None
467 while 1:
467 while 1:
468 try:
468 try:
469 code_to_run, completed_ev, received_ev = self.code_queue.get_nowait()
469 code_to_run, completed_ev, received_ev = self.code_queue.get_nowait()
470 except Queue.Empty:
470 except Queue.Empty:
471 break
471 break
472 received_ev.set()
472 received_ev.set()
473
473
474 # Exceptions need to be raised differently depending on which
474 # Exceptions need to be raised differently depending on which
475 # thread is active. This convoluted try/except is only there to
475 # thread is active. This convoluted try/except is only there to
476 # protect against asynchronous exceptions, to ensure that a KBINT
476 # protect against asynchronous exceptions, to ensure that a KBINT
477 # at the wrong time doesn't deadlock everything. The global
477 # at the wrong time doesn't deadlock everything. The global
478 # CODE_TO_RUN is set to true/false as close as possible to the
478 # CODE_TO_RUN is set to true/false as close as possible to the
479 # runcode() call, so that the KBINT handler is correctly informed.
479 # runcode() call, so that the KBINT handler is correctly informed.
480 try:
480 try:
481 try:
481 try:
482 CODE_RUN = True
482 CODE_RUN = True
483 InteractiveShell.runcode(self,code_to_run)
483 InteractiveShell.runcode(self,code_to_run)
484 except KeyboardInterrupt:
484 except KeyboardInterrupt:
485 print "Keyboard interrupted in mainloop"
485 print "Keyboard interrupted in mainloop"
486 while not self.code_queue.empty():
486 while not self.code_queue.empty():
487 code, ev1,ev2 = self.code_queue.get_nowait()
487 code, ev1,ev2 = self.code_queue.get_nowait()
488 ev1.set()
488 ev1.set()
489 ev2.set()
489 ev2.set()
490 break
490 break
491 finally:
491 finally:
492 CODE_RUN = False
492 CODE_RUN = False
493 # allow runsource() return from wait
493 # allow runsource() return from wait
494 completed_ev.set()
494 completed_ev.set()
495
495
496
496
497 # This MUST return true for gtk threading to work
497 # This MUST return true for gtk threading to work
498 return True
498 return True
499
499
500 def kill(self):
500 def kill(self):
501 """Kill the thread, returning when it has been shut down."""
501 """Kill the thread, returning when it has been shut down."""
502 self._kill = threading.Event()
502 self._kill = threading.Event()
503 self._kill.wait()
503 self._kill.wait()
504
504
505 class MatplotlibShellBase:
505 class MatplotlibShellBase:
506 """Mixin class to provide the necessary modifications to regular IPython
506 """Mixin class to provide the necessary modifications to regular IPython
507 shell classes for matplotlib support.
507 shell classes for matplotlib support.
508
508
509 Given Python's MRO, this should be used as the FIRST class in the
509 Given Python's MRO, this should be used as the FIRST class in the
510 inheritance hierarchy, so that it overrides the relevant methods."""
510 inheritance hierarchy, so that it overrides the relevant methods."""
511
511
512 def _matplotlib_config(self,name,user_ns,user_global_ns=None):
512 def _matplotlib_config(self,name,user_ns,user_global_ns=None):
513 """Return items needed to setup the user's shell with matplotlib"""
513 """Return items needed to setup the user's shell with matplotlib"""
514
514
515 # Initialize matplotlib to interactive mode always
515 # Initialize matplotlib to interactive mode always
516 import matplotlib
516 import matplotlib
517 from matplotlib import backends
517 from matplotlib import backends
518 matplotlib.interactive(True)
518 matplotlib.interactive(True)
519
519
520 def use(arg):
520 def use(arg):
521 """IPython wrapper for matplotlib's backend switcher.
521 """IPython wrapper for matplotlib's backend switcher.
522
522
523 In interactive use, we can not allow switching to a different
523 In interactive use, we can not allow switching to a different
524 interactive backend, since thread conflicts will most likely crash
524 interactive backend, since thread conflicts will most likely crash
525 the python interpreter. This routine does a safety check first,
525 the python interpreter. This routine does a safety check first,
526 and refuses to perform a dangerous switch. It still allows
526 and refuses to perform a dangerous switch. It still allows
527 switching to non-interactive backends."""
527 switching to non-interactive backends."""
528
528
529 if arg in backends.interactive_bk and arg != self.mpl_backend:
529 if arg in backends.interactive_bk and arg != self.mpl_backend:
530 m=('invalid matplotlib backend switch.\n'
530 m=('invalid matplotlib backend switch.\n'
531 'This script attempted to switch to the interactive '
531 'This script attempted to switch to the interactive '
532 'backend: `%s`\n'
532 'backend: `%s`\n'
533 'Your current choice of interactive backend is: `%s`\n\n'
533 'Your current choice of interactive backend is: `%s`\n\n'
534 'Switching interactive matplotlib backends at runtime\n'
534 'Switching interactive matplotlib backends at runtime\n'
535 'would crash the python interpreter, '
535 'would crash the python interpreter, '
536 'and IPython has blocked it.\n\n'
536 'and IPython has blocked it.\n\n'
537 'You need to either change your choice of matplotlib backend\n'
537 'You need to either change your choice of matplotlib backend\n'
538 'by editing your .matplotlibrc file, or run this script as a \n'
538 'by editing your .matplotlibrc file, or run this script as a \n'
539 'standalone file from the command line, not using IPython.\n' %
539 'standalone file from the command line, not using IPython.\n' %
540 (arg,self.mpl_backend) )
540 (arg,self.mpl_backend) )
541 raise RuntimeError, m
541 raise RuntimeError, m
542 else:
542 else:
543 self.mpl_use(arg)
543 self.mpl_use(arg)
544 self.mpl_use._called = True
544 self.mpl_use._called = True
545
545
546 self.matplotlib = matplotlib
546 self.matplotlib = matplotlib
547 self.mpl_backend = matplotlib.rcParams['backend']
547 self.mpl_backend = matplotlib.rcParams['backend']
548
548
549 # we also need to block switching of interactive backends by use()
549 # we also need to block switching of interactive backends by use()
550 self.mpl_use = matplotlib.use
550 self.mpl_use = matplotlib.use
551 self.mpl_use._called = False
551 self.mpl_use._called = False
552 # overwrite the original matplotlib.use with our wrapper
552 # overwrite the original matplotlib.use with our wrapper
553 matplotlib.use = use
553 matplotlib.use = use
554
554
555 # This must be imported last in the matplotlib series, after
555 # This must be imported last in the matplotlib series, after
556 # backend/interactivity choices have been made
556 # backend/interactivity choices have been made
557 import matplotlib.pylab as pylab
557 import matplotlib.pylab as pylab
558 self.pylab = pylab
558 self.pylab = pylab
559
559
560 self.pylab.show._needmain = False
560 self.pylab.show._needmain = False
561 # We need to detect at runtime whether show() is called by the user.
561 # We need to detect at runtime whether show() is called by the user.
562 # For this, we wrap it into a decorator which adds a 'called' flag.
562 # For this, we wrap it into a decorator which adds a 'called' flag.
563 self.pylab.draw_if_interactive = flag_calls(self.pylab.draw_if_interactive)
563 self.pylab.draw_if_interactive = flag_calls(self.pylab.draw_if_interactive)
564
564
565 # Build a user namespace initialized with matplotlib/matlab features.
565 # Build a user namespace initialized with matplotlib/matlab features.
566 user_ns, user_global_ns = ipapi.make_user_namespaces(user_ns,
566 user_ns, user_global_ns = ipapi.make_user_namespaces(user_ns,
567 user_global_ns)
567 user_global_ns)
568
568
569 # Import numpy as np/pyplot as plt are conventions we're trying to
569 # Import numpy as np/pyplot as plt are conventions we're trying to
570 # somewhat standardize on. Making them available to users by default
570 # somewhat standardize on. Making them available to users by default
571 # will greatly help this.
571 # will greatly help this.
572 exec ("import numpy\n"
572 exec ("import numpy\n"
573 "import numpy as np\n"
573 "import numpy as np\n"
574 "import matplotlib\n"
574 "import matplotlib\n"
575 "import matplotlib.pylab as pylab\n"
575 "import matplotlib.pylab as pylab\n"
576 "try:\n"
576 "try:\n"
577 " import matplotlib.pyplot as plt\n"
577 " import matplotlib.pyplot as plt\n"
578 "except ImportError:\n"
578 "except ImportError:\n"
579 " pass\n"
579 " pass\n"
580 ) in user_ns
580 ) in user_ns
581
581
582 # Build matplotlib info banner
582 # Build matplotlib info banner
583 b="""
583 b="""
584 Welcome to pylab, a matplotlib-based Python environment.
584 Welcome to pylab, a matplotlib-based Python environment.
585 For more information, type 'help(pylab)'.
585 For more information, type 'help(pylab)'.
586 """
586 """
587 return user_ns,user_global_ns,b
587 return user_ns,user_global_ns,b
588
588
589 def mplot_exec(self,fname,*where,**kw):
589 def mplot_exec(self,fname,*where,**kw):
590 """Execute a matplotlib script.
590 """Execute a matplotlib script.
591
591
592 This is a call to execfile(), but wrapped in safeties to properly
592 This is a call to execfile(), but wrapped in safeties to properly
593 handle interactive rendering and backend switching."""
593 handle interactive rendering and backend switching."""
594
594
595 #print '*** Matplotlib runner ***' # dbg
595 #print '*** Matplotlib runner ***' # dbg
596 # turn off rendering until end of script
596 # turn off rendering until end of script
597 isInteractive = self.matplotlib.rcParams['interactive']
597 isInteractive = self.matplotlib.rcParams['interactive']
598 self.matplotlib.interactive(False)
598 self.matplotlib.interactive(False)
599 self.safe_execfile(fname,*where,**kw)
599 self.safe_execfile(fname,*where,**kw)
600 self.matplotlib.interactive(isInteractive)
600 self.matplotlib.interactive(isInteractive)
601 # make rendering call now, if the user tried to do it
601 # make rendering call now, if the user tried to do it
602 if self.pylab.draw_if_interactive.called:
602 if self.pylab.draw_if_interactive.called:
603 self.pylab.draw()
603 self.pylab.draw()
604 self.pylab.draw_if_interactive.called = False
604 self.pylab.draw_if_interactive.called = False
605
605
606 # if a backend switch was performed, reverse it now
606 # if a backend switch was performed, reverse it now
607 if self.mpl_use._called:
607 if self.mpl_use._called:
608 self.matplotlib.rcParams['backend'] = self.mpl_backend
608 self.matplotlib.rcParams['backend'] = self.mpl_backend
609
609
610 @testdec.skip_doctest
610 @testdec.skip_doctest
611 def magic_run(self,parameter_s=''):
611 def magic_run(self,parameter_s=''):
612 Magic.magic_run(self,parameter_s,runner=self.mplot_exec)
612 Magic.magic_run(self,parameter_s,runner=self.mplot_exec)
613
613
614 # Fix the docstring so users see the original as well
614 # Fix the docstring so users see the original as well
615 magic_run.__doc__ = "%s\n%s" % (Magic.magic_run.__doc__,
615 magic_run.__doc__ = "%s\n%s" % (Magic.magic_run.__doc__,
616 "\n *** Modified %run for Matplotlib,"
616 "\n *** Modified %run for Matplotlib,"
617 " with proper interactive handling ***")
617 " with proper interactive handling ***")
618
618
619 # Now we provide 2 versions of a matplotlib-aware IPython base shells, single
619 # Now we provide 2 versions of a matplotlib-aware IPython base shells, single
620 # and multithreaded. Note that these are meant for internal use, the IPShell*
620 # and multithreaded. Note that these are meant for internal use, the IPShell*
621 # classes below are the ones meant for public consumption.
621 # classes below are the ones meant for public consumption.
622
622
623 class MatplotlibShell(MatplotlibShellBase,InteractiveShell):
623 class MatplotlibShell(MatplotlibShellBase,InteractiveShell):
624 """Single-threaded shell with matplotlib support."""
624 """Single-threaded shell with matplotlib support."""
625
625
626 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
626 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
627 user_ns=None,user_global_ns=None,**kw):
627 user_ns=None,user_global_ns=None,**kw):
628 user_ns,user_global_ns,b2 = self._matplotlib_config(name,user_ns,user_global_ns)
628 user_ns,user_global_ns,b2 = self._matplotlib_config(name,user_ns,user_global_ns)
629 InteractiveShell.__init__(self,name,usage,rc,user_ns,user_global_ns,
629 InteractiveShell.__init__(self,name,usage,rc,user_ns,user_global_ns,
630 banner2=b2,**kw)
630 banner2=b2,**kw)
631
631
632 class MatplotlibMTShell(MatplotlibShellBase,MTInteractiveShell):
632 class MatplotlibMTShell(MatplotlibShellBase,MTInteractiveShell):
633 """Multi-threaded shell with matplotlib support."""
633 """Multi-threaded shell with matplotlib support."""
634
634
635 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
635 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
636 user_ns=None,user_global_ns=None, **kw):
636 user_ns=None,user_global_ns=None, **kw):
637 user_ns,user_global_ns,b2 = self._matplotlib_config(name,user_ns,user_global_ns)
637 user_ns,user_global_ns,b2 = self._matplotlib_config(name,user_ns,user_global_ns)
638 MTInteractiveShell.__init__(self,name,usage,rc,user_ns,user_global_ns,
638 MTInteractiveShell.__init__(self,name,usage,rc,user_ns,user_global_ns,
639 banner2=b2,**kw)
639 banner2=b2,**kw)
640
640
641 #-----------------------------------------------------------------------------
641 #-----------------------------------------------------------------------------
642 # Utility functions for the different GUI enabled IPShell* classes.
642 # Utility functions for the different GUI enabled IPShell* classes.
643
643
644 def get_tk():
644 def get_tk():
645 """Tries to import Tkinter and returns a withdrawn Tkinter root
645 """Tries to import Tkinter and returns a withdrawn Tkinter root
646 window. If Tkinter is already imported or not available, this
646 window. If Tkinter is already imported or not available, this
647 returns None. This function calls `hijack_tk` underneath.
647 returns None. This function calls `hijack_tk` underneath.
648 """
648 """
649 if not USE_TK or sys.modules.has_key('Tkinter'):
649 if not USE_TK or sys.modules.has_key('Tkinter'):
650 return None
650 return None
651 else:
651 else:
652 try:
652 try:
653 import Tkinter
653 import Tkinter
654 except ImportError:
654 except ImportError:
655 return None
655 return None
656 else:
656 else:
657 hijack_tk()
657 hijack_tk()
658 r = Tkinter.Tk()
658 r = Tkinter.Tk()
659 r.withdraw()
659 r.withdraw()
660 return r
660 return r
661
661
662 def hijack_tk():
662 def hijack_tk():
663 """Modifies Tkinter's mainloop with a dummy so when a module calls
663 """Modifies Tkinter's mainloop with a dummy so when a module calls
664 mainloop, it does not block.
664 mainloop, it does not block.
665
665
666 """
666 """
667 def misc_mainloop(self, n=0):
667 def misc_mainloop(self, n=0):
668 pass
668 pass
669 def tkinter_mainloop(n=0):
669 def tkinter_mainloop(n=0):
670 pass
670 pass
671
671
672 import Tkinter
672 import Tkinter
673 Tkinter.Misc.mainloop = misc_mainloop
673 Tkinter.Misc.mainloop = misc_mainloop
674 Tkinter.mainloop = tkinter_mainloop
674 Tkinter.mainloop = tkinter_mainloop
675
675
676 def update_tk(tk):
676 def update_tk(tk):
677 """Updates the Tkinter event loop. This is typically called from
677 """Updates the Tkinter event loop. This is typically called from
678 the respective WX or GTK mainloops.
678 the respective WX or GTK mainloops.
679 """
679 """
680 if tk:
680 if tk:
681 tk.update()
681 tk.update()
682
682
683 def hijack_wx():
683 def hijack_wx():
684 """Modifies wxPython's MainLoop with a dummy so user code does not
684 """Modifies wxPython's MainLoop with a dummy so user code does not
685 block IPython. The hijacked mainloop function is returned.
685 block IPython. The hijacked mainloop function is returned.
686 """
686 """
687 def dummy_mainloop(*args, **kw):
687 def dummy_mainloop(*args, **kw):
688 pass
688 pass
689
689
690 try:
690 try:
691 import wx
691 import wx
692 except ImportError:
692 except ImportError:
693 # For very old versions of WX
693 # For very old versions of WX
694 import wxPython as wx
694 import wxPython as wx
695
695
696 ver = wx.__version__
696 ver = wx.__version__
697 orig_mainloop = None
697 orig_mainloop = None
698 if ver[:3] >= '2.5':
698 if ver[:3] >= '2.5':
699 import wx
699 import wx
700 if hasattr(wx, '_core_'): core = getattr(wx, '_core_')
700 if hasattr(wx, '_core_'): core = getattr(wx, '_core_')
701 elif hasattr(wx, '_core'): core = getattr(wx, '_core')
701 elif hasattr(wx, '_core'): core = getattr(wx, '_core')
702 else: raise AttributeError('Could not find wx core module')
702 else: raise AttributeError('Could not find wx core module')
703 orig_mainloop = core.PyApp_MainLoop
703 orig_mainloop = core.PyApp_MainLoop
704 core.PyApp_MainLoop = dummy_mainloop
704 core.PyApp_MainLoop = dummy_mainloop
705 elif ver[:3] == '2.4':
705 elif ver[:3] == '2.4':
706 orig_mainloop = wx.wxc.wxPyApp_MainLoop
706 orig_mainloop = wx.wxc.wxPyApp_MainLoop
707 wx.wxc.wxPyApp_MainLoop = dummy_mainloop
707 wx.wxc.wxPyApp_MainLoop = dummy_mainloop
708 else:
708 else:
709 warn("Unable to find either wxPython version 2.4 or >= 2.5.")
709 warn("Unable to find either wxPython version 2.4 or >= 2.5.")
710 return orig_mainloop
710 return orig_mainloop
711
711
712 def hijack_gtk():
712 def hijack_gtk():
713 """Modifies pyGTK's mainloop with a dummy so user code does not
713 """Modifies pyGTK's mainloop with a dummy so user code does not
714 block IPython. This function returns the original `gtk.mainloop`
714 block IPython. This function returns the original `gtk.mainloop`
715 function that has been hijacked.
715 function that has been hijacked.
716 """
716 """
717 def dummy_mainloop(*args, **kw):
717 def dummy_mainloop(*args, **kw):
718 pass
718 pass
719 import gtk
719 import gtk
720 if gtk.pygtk_version >= (2,4,0): orig_mainloop = gtk.main
720 if gtk.pygtk_version >= (2,4,0): orig_mainloop = gtk.main
721 else: orig_mainloop = gtk.mainloop
721 else: orig_mainloop = gtk.mainloop
722 gtk.mainloop = dummy_mainloop
722 gtk.mainloop = dummy_mainloop
723 gtk.main = dummy_mainloop
723 gtk.main = dummy_mainloop
724 return orig_mainloop
724 return orig_mainloop
725
725
726 def hijack_qt():
726 def hijack_qt():
727 """Modifies PyQt's mainloop with a dummy so user code does not
727 """Modifies PyQt's mainloop with a dummy so user code does not
728 block IPython. This function returns the original
728 block IPython. This function returns the original
729 `qt.qApp.exec_loop` function that has been hijacked.
729 `qt.qApp.exec_loop` function that has been hijacked.
730 """
730 """
731 def dummy_mainloop(*args, **kw):
731 def dummy_mainloop(*args, **kw):
732 pass
732 pass
733 import qt
733 import qt
734 orig_mainloop = qt.qApp.exec_loop
734 orig_mainloop = qt.qApp.exec_loop
735 qt.qApp.exec_loop = dummy_mainloop
735 qt.qApp.exec_loop = dummy_mainloop
736 qt.QApplication.exec_loop = dummy_mainloop
736 qt.QApplication.exec_loop = dummy_mainloop
737 return orig_mainloop
737 return orig_mainloop
738
738
739 def hijack_qt4():
739 def hijack_qt4():
740 """Modifies PyQt4's mainloop with a dummy so user code does not
740 """Modifies PyQt4's mainloop with a dummy so user code does not
741 block IPython. This function returns the original
741 block IPython. This function returns the original
742 `QtGui.qApp.exec_` function that has been hijacked.
742 `QtGui.qApp.exec_` function that has been hijacked.
743 """
743 """
744 def dummy_mainloop(*args, **kw):
744 def dummy_mainloop(*args, **kw):
745 pass
745 pass
746 from PyQt4 import QtGui, QtCore
746 from PyQt4 import QtGui, QtCore
747 orig_mainloop = QtGui.qApp.exec_
747 orig_mainloop = QtGui.qApp.exec_
748 QtGui.qApp.exec_ = dummy_mainloop
748 QtGui.qApp.exec_ = dummy_mainloop
749 QtGui.QApplication.exec_ = dummy_mainloop
749 QtGui.QApplication.exec_ = dummy_mainloop
750 QtCore.QCoreApplication.exec_ = dummy_mainloop
750 QtCore.QCoreApplication.exec_ = dummy_mainloop
751 return orig_mainloop
751 return orig_mainloop
752
752
753 #-----------------------------------------------------------------------------
753 #-----------------------------------------------------------------------------
754 # The IPShell* classes below are the ones meant to be run by external code as
754 # The IPShell* classes below are the ones meant to be run by external code as
755 # IPython instances. Note that unless a specific threading strategy is
755 # IPython instances. Note that unless a specific threading strategy is
756 # desired, the factory function start() below should be used instead (it
756 # desired, the factory function start() below should be used instead (it
757 # selects the proper threaded class).
757 # selects the proper threaded class).
758
758
759 class IPThread(threading.Thread):
759 class IPThread(threading.Thread):
760 def run(self):
760 def run(self):
761 self.IP.mainloop(self._banner)
761 self.IP.mainloop(self._banner)
762 self.IP.kill()
762 self.IP.kill()
763
763
764 class IPShellGTK(IPThread):
764 class IPShellGTK(IPThread):
765 """Run a gtk mainloop() in a separate thread.
765 """Run a gtk mainloop() in a separate thread.
766
766
767 Python commands can be passed to the thread where they will be executed.
767 Python commands can be passed to the thread where they will be executed.
768 This is implemented by periodically checking for passed code using a
768 This is implemented by periodically checking for passed code using a
769 GTK timeout callback."""
769 GTK timeout callback."""
770
770
771 TIMEOUT = 100 # Millisecond interval between timeouts.
771 TIMEOUT = 100 # Millisecond interval between timeouts.
772
772
773 def __init__(self,argv=None,user_ns=None,user_global_ns=None,
773 def __init__(self,argv=None,user_ns=None,user_global_ns=None,
774 debug=1,shell_class=MTInteractiveShell):
774 debug=1,shell_class=MTInteractiveShell):
775
775
776 import gtk
776 import gtk
777 # Check for set_interactive, coming up in new pygtk.
777 # Check for set_interactive, coming up in new pygtk.
778 # Disable it so that this code works, but notify
778 # Disable it so that this code works, but notify
779 # the user that he has a better option as well.
779 # the user that he has a better option as well.
780 # XXX TODO better support when set_interactive is released
780 # XXX TODO better support when set_interactive is released
781 try:
781 try:
782 gtk.set_interactive(False)
782 gtk.set_interactive(False)
783 print "Your PyGtk has set_interactive(), so you can use the"
783 print "Your PyGtk has set_interactive(), so you can use the"
784 print "more stable single-threaded Gtk mode."
784 print "more stable single-threaded Gtk mode."
785 print "See https://bugs.launchpad.net/ipython/+bug/270856"
785 print "See https://bugs.launchpad.net/ipython/+bug/270856"
786 except AttributeError:
786 except AttributeError:
787 pass
787 pass
788
788
789 self.gtk = gtk
789 self.gtk = gtk
790 self.gtk_mainloop = hijack_gtk()
790 self.gtk_mainloop = hijack_gtk()
791
791
792 # Allows us to use both Tk and GTK.
792 # Allows us to use both Tk and GTK.
793 self.tk = get_tk()
793 self.tk = get_tk()
794
794
795 if gtk.pygtk_version >= (2,4,0): mainquit = self.gtk.main_quit
795 if gtk.pygtk_version >= (2,4,0): mainquit = self.gtk.main_quit
796 else: mainquit = self.gtk.mainquit
796 else: mainquit = self.gtk.mainquit
797
797
798 self.IP = make_IPython(argv,user_ns=user_ns,
798 self.IP = make_IPython(argv,user_ns=user_ns,
799 user_global_ns=user_global_ns,
799 user_global_ns=user_global_ns,
800 debug=debug,
800 debug=debug,
801 shell_class=shell_class,
801 shell_class=shell_class,
802 on_kill=[mainquit])
802 on_kill=[mainquit])
803
803
804 # HACK: slot for banner in self; it will be passed to the mainloop
804 # HACK: slot for banner in self; it will be passed to the mainloop
805 # method only and .run() needs it. The actual value will be set by
805 # method only and .run() needs it. The actual value will be set by
806 # .mainloop().
806 # .mainloop().
807 self._banner = None
807 self._banner = None
808
808
809 threading.Thread.__init__(self)
809 threading.Thread.__init__(self)
810
810
811 def mainloop(self,sys_exit=0,banner=None):
811 def mainloop(self,sys_exit=0,banner=None):
812
812
813 self._banner = banner
813 self._banner = banner
814
814
815 if self.gtk.pygtk_version >= (2,4,0):
815 if self.gtk.pygtk_version >= (2,4,0):
816 import gobject
816 import gobject
817 gobject.idle_add(self.on_timer)
817 gobject.idle_add(self.on_timer)
818 else:
818 else:
819 self.gtk.idle_add(self.on_timer)
819 self.gtk.idle_add(self.on_timer)
820
820
821 if sys.platform != 'win32':
821 if sys.platform != 'win32':
822 try:
822 try:
823 if self.gtk.gtk_version[0] >= 2:
823 if self.gtk.gtk_version[0] >= 2:
824 self.gtk.gdk.threads_init()
824 self.gtk.gdk.threads_init()
825 except AttributeError:
825 except AttributeError:
826 pass
826 pass
827 except RuntimeError:
827 except RuntimeError:
828 error('Your pyGTK likely has not been compiled with '
828 error('Your pyGTK likely has not been compiled with '
829 'threading support.\n'
829 'threading support.\n'
830 'The exception printout is below.\n'
830 'The exception printout is below.\n'
831 'You can either rebuild pyGTK with threads, or '
831 'You can either rebuild pyGTK with threads, or '
832 'try using \n'
832 'try using \n'
833 'matplotlib with a different backend (like Tk or WX).\n'
833 'matplotlib with a different backend (like Tk or WX).\n'
834 'Note that matplotlib will most likely not work in its '
834 'Note that matplotlib will most likely not work in its '
835 'current state!')
835 'current state!')
836 self.IP.InteractiveTB()
836 self.IP.InteractiveTB()
837
837
838 self.start()
838 self.start()
839 self.gtk.gdk.threads_enter()
839 self.gtk.gdk.threads_enter()
840 self.gtk_mainloop()
840 self.gtk_mainloop()
841 self.gtk.gdk.threads_leave()
841 self.gtk.gdk.threads_leave()
842 self.join()
842 self.join()
843
843
844 def on_timer(self):
844 def on_timer(self):
845 """Called when GTK is idle.
845 """Called when GTK is idle.
846
846
847 Must return True always, otherwise GTK stops calling it"""
847 Must return True always, otherwise GTK stops calling it"""
848
848
849 update_tk(self.tk)
849 update_tk(self.tk)
850 self.IP.runcode()
850 self.IP.runcode()
851 time.sleep(0.01)
851 time.sleep(0.01)
852 return True
852 return True
853
853
854
854
855 class IPShellWX(IPThread):
855 class IPShellWX(IPThread):
856 """Run a wx mainloop() in a separate thread.
856 """Run a wx mainloop() in a separate thread.
857
857
858 Python commands can be passed to the thread where they will be executed.
858 Python commands can be passed to the thread where they will be executed.
859 This is implemented by periodically checking for passed code using a
859 This is implemented by periodically checking for passed code using a
860 GTK timeout callback."""
860 GTK timeout callback."""
861
861
862 TIMEOUT = 100 # Millisecond interval between timeouts.
862 TIMEOUT = 100 # Millisecond interval between timeouts.
863
863
864 def __init__(self,argv=None,user_ns=None,user_global_ns=None,
864 def __init__(self,argv=None,user_ns=None,user_global_ns=None,
865 debug=1,shell_class=MTInteractiveShell):
865 debug=1,shell_class=MTInteractiveShell):
866
866
867 self.IP = make_IPython(argv,user_ns=user_ns,
867 self.IP = make_IPython(argv,user_ns=user_ns,
868 user_global_ns=user_global_ns,
868 user_global_ns=user_global_ns,
869 debug=debug,
869 debug=debug,
870 shell_class=shell_class,
870 shell_class=shell_class,
871 on_kill=[self.wxexit])
871 on_kill=[self.wxexit])
872
872
873 wantedwxversion=self.IP.rc.wxversion
873 wantedwxversion=self.IP.rc.wxversion
874 if wantedwxversion!="0":
874 if wantedwxversion!="0":
875 try:
875 try:
876 import wxversion
876 import wxversion
877 except ImportError:
877 except ImportError:
878 error('The wxversion module is needed for WX version selection')
878 error('The wxversion module is needed for WX version selection')
879 else:
879 else:
880 try:
880 try:
881 wxversion.select(wantedwxversion)
881 wxversion.select(wantedwxversion)
882 except:
882 except:
883 self.IP.InteractiveTB()
883 self.IP.InteractiveTB()
884 error('Requested wxPython version %s could not be loaded' %
884 error('Requested wxPython version %s could not be loaded' %
885 wantedwxversion)
885 wantedwxversion)
886
886
887 import wx
887 import wx
888
888
889 threading.Thread.__init__(self)
889 threading.Thread.__init__(self)
890 self.wx = wx
890 self.wx = wx
891 self.wx_mainloop = hijack_wx()
891 self.wx_mainloop = hijack_wx()
892
892
893 # Allows us to use both Tk and GTK.
893 # Allows us to use both Tk and GTK.
894 self.tk = get_tk()
894 self.tk = get_tk()
895
895
896 # HACK: slot for banner in self; it will be passed to the mainloop
896 # HACK: slot for banner in self; it will be passed to the mainloop
897 # method only and .run() needs it. The actual value will be set by
897 # method only and .run() needs it. The actual value will be set by
898 # .mainloop().
898 # .mainloop().
899 self._banner = None
899 self._banner = None
900
900
901 self.app = None
901 self.app = None
902
902
903 def wxexit(self, *args):
903 def wxexit(self, *args):
904 if self.app is not None:
904 if self.app is not None:
905 self.app.agent.timer.Stop()
905 self.app.agent.timer.Stop()
906 self.app.ExitMainLoop()
906 self.app.ExitMainLoop()
907
907
908 def mainloop(self,sys_exit=0,banner=None):
908 def mainloop(self,sys_exit=0,banner=None):
909
909
910 self._banner = banner
910 self._banner = banner
911
911
912 self.start()
912 self.start()
913
913
914 class TimerAgent(self.wx.MiniFrame):
914 class TimerAgent(self.wx.MiniFrame):
915 wx = self.wx
915 wx = self.wx
916 IP = self.IP
916 IP = self.IP
917 tk = self.tk
917 tk = self.tk
918 def __init__(self, parent, interval):
918 def __init__(self, parent, interval):
919 style = self.wx.DEFAULT_FRAME_STYLE | self.wx.TINY_CAPTION_HORIZ
919 style = self.wx.DEFAULT_FRAME_STYLE | self.wx.TINY_CAPTION_HORIZ
920 self.wx.MiniFrame.__init__(self, parent, -1, ' ', pos=(200, 200),
920 self.wx.MiniFrame.__init__(self, parent, -1, ' ', pos=(200, 200),
921 size=(100, 100),style=style)
921 size=(100, 100),style=style)
922 self.Show(False)
922 self.Show(False)
923 self.interval = interval
923 self.interval = interval
924 self.timerId = self.wx.NewId()
924 self.timerId = self.wx.NewId()
925
925
926 def StartWork(self):
926 def StartWork(self):
927 self.timer = self.wx.Timer(self, self.timerId)
927 self.timer = self.wx.Timer(self, self.timerId)
928 self.wx.EVT_TIMER(self, self.timerId, self.OnTimer)
928 self.wx.EVT_TIMER(self, self.timerId, self.OnTimer)
929 self.timer.Start(self.interval)
929 self.timer.Start(self.interval)
930
930
931 def OnTimer(self, event):
931 def OnTimer(self, event):
932 update_tk(self.tk)
932 update_tk(self.tk)
933 self.IP.runcode()
933 self.IP.runcode()
934
934
935 class App(self.wx.App):
935 class App(self.wx.App):
936 wx = self.wx
936 wx = self.wx
937 TIMEOUT = self.TIMEOUT
937 TIMEOUT = self.TIMEOUT
938 def OnInit(self):
938 def OnInit(self):
939 'Create the main window and insert the custom frame'
939 'Create the main window and insert the custom frame'
940 self.agent = TimerAgent(None, self.TIMEOUT)
940 self.agent = TimerAgent(None, self.TIMEOUT)
941 self.agent.Show(False)
941 self.agent.Show(False)
942 self.agent.StartWork()
942 self.agent.StartWork()
943 return True
943 return True
944
944
945 self.app = App(redirect=False)
945 self.app = App(redirect=False)
946 self.wx_mainloop(self.app)
946 self.wx_mainloop(self.app)
947 self.join()
947 self.join()
948
948
949
949
950 class IPShellQt(IPThread):
950 class IPShellQt(IPThread):
951 """Run a Qt event loop in a separate thread.
951 """Run a Qt event loop in a separate thread.
952
952
953 Python commands can be passed to the thread where they will be executed.
953 Python commands can be passed to the thread where they will be executed.
954 This is implemented by periodically checking for passed code using a
954 This is implemented by periodically checking for passed code using a
955 Qt timer / slot."""
955 Qt timer / slot."""
956
956
957 TIMEOUT = 100 # Millisecond interval between timeouts.
957 TIMEOUT = 100 # Millisecond interval between timeouts.
958
958
959 def __init__(self, argv=None, user_ns=None, user_global_ns=None,
959 def __init__(self, argv=None, user_ns=None, user_global_ns=None,
960 debug=0, shell_class=MTInteractiveShell):
960 debug=0, shell_class=MTInteractiveShell):
961
961
962 import qt
962 import qt
963
963
964 self.exec_loop = hijack_qt()
964 self.exec_loop = hijack_qt()
965
965
966 # Allows us to use both Tk and QT.
966 # Allows us to use both Tk and QT.
967 self.tk = get_tk()
967 self.tk = get_tk()
968
968
969 self.IP = make_IPython(argv,
969 self.IP = make_IPython(argv,
970 user_ns=user_ns,
970 user_ns=user_ns,
971 user_global_ns=user_global_ns,
971 user_global_ns=user_global_ns,
972 debug=debug,
972 debug=debug,
973 shell_class=shell_class,
973 shell_class=shell_class,
974 on_kill=[qt.qApp.exit])
974 on_kill=[qt.qApp.exit])
975
975
976 # HACK: slot for banner in self; it will be passed to the mainloop
976 # HACK: slot for banner in self; it will be passed to the mainloop
977 # method only and .run() needs it. The actual value will be set by
977 # method only and .run() needs it. The actual value will be set by
978 # .mainloop().
978 # .mainloop().
979 self._banner = None
979 self._banner = None
980
980
981 threading.Thread.__init__(self)
981 threading.Thread.__init__(self)
982
982
983 def mainloop(self, sys_exit=0, banner=None):
983 def mainloop(self, sys_exit=0, banner=None):
984
984
985 import qt
985 import qt
986
986
987 self._banner = banner
987 self._banner = banner
988
988
989 if qt.QApplication.startingUp():
989 if qt.QApplication.startingUp():
990 a = qt.QApplication(sys.argv)
990 a = qt.QApplication(sys.argv)
991
991
992 self.timer = qt.QTimer()
992 self.timer = qt.QTimer()
993 qt.QObject.connect(self.timer,
993 qt.QObject.connect(self.timer,
994 qt.SIGNAL('timeout()'),
994 qt.SIGNAL('timeout()'),
995 self.on_timer)
995 self.on_timer)
996
996
997 self.start()
997 self.start()
998 self.timer.start(self.TIMEOUT, True)
998 self.timer.start(self.TIMEOUT, True)
999 while True:
999 while True:
1000 if self.IP._kill: break
1000 if self.IP._kill: break
1001 self.exec_loop()
1001 self.exec_loop()
1002 self.join()
1002 self.join()
1003
1003
1004 def on_timer(self):
1004 def on_timer(self):
1005 update_tk(self.tk)
1005 update_tk(self.tk)
1006 result = self.IP.runcode()
1006 result = self.IP.runcode()
1007 self.timer.start(self.TIMEOUT, True)
1007 self.timer.start(self.TIMEOUT, True)
1008 return result
1008 return result
1009
1009
1010
1010
1011 class IPShellQt4(IPThread):
1011 class IPShellQt4(IPThread):
1012 """Run a Qt event loop in a separate thread.
1012 """Run a Qt event loop in a separate thread.
1013
1013
1014 Python commands can be passed to the thread where they will be executed.
1014 Python commands can be passed to the thread where they will be executed.
1015 This is implemented by periodically checking for passed code using a
1015 This is implemented by periodically checking for passed code using a
1016 Qt timer / slot."""
1016 Qt timer / slot."""
1017
1017
1018 TIMEOUT = 100 # Millisecond interval between timeouts.
1018 TIMEOUT = 100 # Millisecond interval between timeouts.
1019
1019
1020 def __init__(self, argv=None, user_ns=None, user_global_ns=None,
1020 def __init__(self, argv=None, user_ns=None, user_global_ns=None,
1021 debug=0, shell_class=MTInteractiveShell):
1021 debug=0, shell_class=MTInteractiveShell):
1022
1022
1023 from PyQt4 import QtCore, QtGui
1023 from PyQt4 import QtCore, QtGui
1024
1024
1025 try:
1025 try:
1026 # present in PyQt4-4.2.1 or later
1026 # present in PyQt4-4.2.1 or later
1027 QtCore.pyqtRemoveInputHook()
1027 QtCore.pyqtRemoveInputHook()
1028 except AttributeError:
1028 except AttributeError:
1029 pass
1029 pass
1030
1030
1031 if QtCore.PYQT_VERSION_STR == '4.3':
1031 if QtCore.PYQT_VERSION_STR == '4.3':
1032 warn('''PyQt4 version 4.3 detected.
1032 warn('''PyQt4 version 4.3 detected.
1033 If you experience repeated threading warnings, please update PyQt4.
1033 If you experience repeated threading warnings, please update PyQt4.
1034 ''')
1034 ''')
1035
1035
1036 self.exec_ = hijack_qt4()
1036 self.exec_ = hijack_qt4()
1037
1037
1038 # Allows us to use both Tk and QT.
1038 # Allows us to use both Tk and QT.
1039 self.tk = get_tk()
1039 self.tk = get_tk()
1040
1040
1041 self.IP = make_IPython(argv,
1041 self.IP = make_IPython(argv,
1042 user_ns=user_ns,
1042 user_ns=user_ns,
1043 user_global_ns=user_global_ns,
1043 user_global_ns=user_global_ns,
1044 debug=debug,
1044 debug=debug,
1045 shell_class=shell_class,
1045 shell_class=shell_class,
1046 on_kill=[QtGui.qApp.exit])
1046 on_kill=[QtGui.qApp.exit])
1047
1047
1048 # HACK: slot for banner in self; it will be passed to the mainloop
1048 # HACK: slot for banner in self; it will be passed to the mainloop
1049 # method only and .run() needs it. The actual value will be set by
1049 # method only and .run() needs it. The actual value will be set by
1050 # .mainloop().
1050 # .mainloop().
1051 self._banner = None
1051 self._banner = None
1052
1052
1053 threading.Thread.__init__(self)
1053 threading.Thread.__init__(self)
1054
1054
1055 def mainloop(self, sys_exit=0, banner=None):
1055 def mainloop(self, sys_exit=0, banner=None):
1056
1056
1057 from PyQt4 import QtCore, QtGui
1057 from PyQt4 import QtCore, QtGui
1058
1058
1059 self._banner = banner
1059 self._banner = banner
1060
1060
1061 if QtGui.QApplication.startingUp():
1061 if QtGui.QApplication.startingUp():
1062 a = QtGui.QApplication(sys.argv)
1062 a = QtGui.QApplication(sys.argv)
1063
1063
1064 self.timer = QtCore.QTimer()
1064 self.timer = QtCore.QTimer()
1065 QtCore.QObject.connect(self.timer,
1065 QtCore.QObject.connect(self.timer,
1066 QtCore.SIGNAL('timeout()'),
1066 QtCore.SIGNAL('timeout()'),
1067 self.on_timer)
1067 self.on_timer)
1068
1068
1069 self.start()
1069 self.start()
1070 self.timer.start(self.TIMEOUT)
1070 self.timer.start(self.TIMEOUT)
1071 while True:
1071 while True:
1072 if self.IP._kill: break
1072 if self.IP._kill: break
1073 self.exec_()
1073 self.exec_()
1074 self.join()
1074 self.join()
1075
1075
1076 def on_timer(self):
1076 def on_timer(self):
1077 update_tk(self.tk)
1077 update_tk(self.tk)
1078 result = self.IP.runcode()
1078 result = self.IP.runcode()
1079 self.timer.start(self.TIMEOUT)
1079 self.timer.start(self.TIMEOUT)
1080 return result
1080 return result
1081
1081
1082
1082
1083 # A set of matplotlib public IPython shell classes, for single-threaded (Tk*
1083 # A set of matplotlib public IPython shell classes, for single-threaded (Tk*
1084 # and FLTK*) and multithreaded (GTK*, WX* and Qt*) backends to use.
1084 # and FLTK*) and multithreaded (GTK*, WX* and Qt*) backends to use.
1085 def _load_pylab(user_ns):
1085 def _load_pylab(user_ns):
1086 """Allow users to disable pulling all of pylab into the top-level
1086 """Allow users to disable pulling all of pylab into the top-level
1087 namespace.
1087 namespace.
1088
1088
1089 This little utility must be called AFTER the actual ipython instance is
1089 This little utility must be called AFTER the actual ipython instance is
1090 running, since only then will the options file have been fully parsed."""
1090 running, since only then will the options file have been fully parsed."""
1091
1091
1092 ip = ipapi.get()
1092 ip = ipapi.get()
1093 if ip.options.pylab_import_all:
1093 if ip.options.pylab_import_all:
1094 ip.ex("from matplotlib.pylab import *")
1094 ip.ex("from matplotlib.pylab import *")
1095 ip.IP.user_config_ns.update(ip.user_ns)
1095 ip.IP.user_config_ns.update(ip.user_ns)
1096
1096
1097
1097
1098 class IPShellMatplotlib(IPShell):
1098 class IPShellMatplotlib(IPShell):
1099 """Subclass IPShell with MatplotlibShell as the internal shell.
1099 """Subclass IPShell with MatplotlibShell as the internal shell.
1100
1100
1101 Single-threaded class, meant for the Tk* and FLTK* backends.
1101 Single-threaded class, meant for the Tk* and FLTK* backends.
1102
1102
1103 Having this on a separate class simplifies the external driver code."""
1103 Having this on a separate class simplifies the external driver code."""
1104
1104
1105 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1105 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1106 IPShell.__init__(self,argv,user_ns,user_global_ns,debug,
1106 IPShell.__init__(self,argv,user_ns,user_global_ns,debug,
1107 shell_class=MatplotlibShell)
1107 shell_class=MatplotlibShell)
1108 _load_pylab(self.IP.user_ns)
1108 _load_pylab(self.IP.user_ns)
1109
1109
1110 class IPShellMatplotlibGTK(IPShellGTK):
1110 class IPShellMatplotlibGTK(IPShellGTK):
1111 """Subclass IPShellGTK with MatplotlibMTShell as the internal shell.
1111 """Subclass IPShellGTK with MatplotlibMTShell as the internal shell.
1112
1112
1113 Multi-threaded class, meant for the GTK* backends."""
1113 Multi-threaded class, meant for the GTK* backends."""
1114
1114
1115 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1115 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1116 IPShellGTK.__init__(self,argv,user_ns,user_global_ns,debug,
1116 IPShellGTK.__init__(self,argv,user_ns,user_global_ns,debug,
1117 shell_class=MatplotlibMTShell)
1117 shell_class=MatplotlibMTShell)
1118 _load_pylab(self.IP.user_ns)
1118 _load_pylab(self.IP.user_ns)
1119
1119
1120 class IPShellMatplotlibWX(IPShellWX):
1120 class IPShellMatplotlibWX(IPShellWX):
1121 """Subclass IPShellWX with MatplotlibMTShell as the internal shell.
1121 """Subclass IPShellWX with MatplotlibMTShell as the internal shell.
1122
1122
1123 Multi-threaded class, meant for the WX* backends."""
1123 Multi-threaded class, meant for the WX* backends."""
1124
1124
1125 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1125 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1126 IPShellWX.__init__(self,argv,user_ns,user_global_ns,debug,
1126 IPShellWX.__init__(self,argv,user_ns,user_global_ns,debug,
1127 shell_class=MatplotlibMTShell)
1127 shell_class=MatplotlibMTShell)
1128 _load_pylab(self.IP.user_ns)
1128 _load_pylab(self.IP.user_ns)
1129
1129
1130 class IPShellMatplotlibQt(IPShellQt):
1130 class IPShellMatplotlibQt(IPShellQt):
1131 """Subclass IPShellQt with MatplotlibMTShell as the internal shell.
1131 """Subclass IPShellQt with MatplotlibMTShell as the internal shell.
1132
1132
1133 Multi-threaded class, meant for the Qt* backends."""
1133 Multi-threaded class, meant for the Qt* backends."""
1134
1134
1135 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1135 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1136 IPShellQt.__init__(self,argv,user_ns,user_global_ns,debug,
1136 IPShellQt.__init__(self,argv,user_ns,user_global_ns,debug,
1137 shell_class=MatplotlibMTShell)
1137 shell_class=MatplotlibMTShell)
1138 _load_pylab(self.IP.user_ns)
1138 _load_pylab(self.IP.user_ns)
1139
1139
1140 class IPShellMatplotlibQt4(IPShellQt4):
1140 class IPShellMatplotlibQt4(IPShellQt4):
1141 """Subclass IPShellQt4 with MatplotlibMTShell as the internal shell.
1141 """Subclass IPShellQt4 with MatplotlibMTShell as the internal shell.
1142
1142
1143 Multi-threaded class, meant for the Qt4* backends."""
1143 Multi-threaded class, meant for the Qt4* backends."""
1144
1144
1145 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1145 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1146 IPShellQt4.__init__(self,argv,user_ns,user_global_ns,debug,
1146 IPShellQt4.__init__(self,argv,user_ns,user_global_ns,debug,
1147 shell_class=MatplotlibMTShell)
1147 shell_class=MatplotlibMTShell)
1148 _load_pylab(self.IP.user_ns)
1148 _load_pylab(self.IP.user_ns)
1149
1149
1150 #-----------------------------------------------------------------------------
1150 #-----------------------------------------------------------------------------
1151 # Factory functions to actually start the proper thread-aware shell
1151 # Factory functions to actually start the proper thread-aware shell
1152
1152
1153 def _select_shell(argv):
1153 def _select_shell(argv):
1154 """Select a shell from the given argv vector.
1154 """Select a shell from the given argv vector.
1155
1155
1156 This function implements the threading selection policy, allowing runtime
1156 This function implements the threading selection policy, allowing runtime
1157 control of the threading mode, both for general users and for matplotlib.
1157 control of the threading mode, both for general users and for matplotlib.
1158
1158
1159 Return:
1159 Return:
1160 Shell class to be instantiated for runtime operation.
1160 Shell class to be instantiated for runtime operation.
1161 """
1161 """
1162
1162
1163 global USE_TK
1163 global USE_TK
1164
1164
1165 mpl_shell = {'gthread' : IPShellMatplotlibGTK,
1165 mpl_shell = {'gthread' : IPShellMatplotlibGTK,
1166 'wthread' : IPShellMatplotlibWX,
1166 'wthread' : IPShellMatplotlibWX,
1167 'qthread' : IPShellMatplotlibQt,
1167 'qthread' : IPShellMatplotlibQt,
1168 'q4thread' : IPShellMatplotlibQt4,
1168 'q4thread' : IPShellMatplotlibQt4,
1169 'tkthread' : IPShellMatplotlib, # Tk is built-in
1169 'tkthread' : IPShellMatplotlib, # Tk is built-in
1170 }
1170 }
1171
1171
1172 th_shell = {'gthread' : IPShellGTK,
1172 th_shell = {'gthread' : IPShellGTK,
1173 'wthread' : IPShellWX,
1173 'wthread' : IPShellWX,
1174 'qthread' : IPShellQt,
1174 'qthread' : IPShellQt,
1175 'q4thread' : IPShellQt4,
1175 'q4thread' : IPShellQt4,
1176 'tkthread' : IPShell, # Tk is built-in
1176 'tkthread' : IPShell, # Tk is built-in
1177 }
1177 }
1178
1178
1179 backends = {'gthread' : 'GTKAgg',
1179 backends = {'gthread' : 'GTKAgg',
1180 'wthread' : 'WXAgg',
1180 'wthread' : 'WXAgg',
1181 'qthread' : 'QtAgg',
1181 'qthread' : 'QtAgg',
1182 'q4thread' :'Qt4Agg',
1182 'q4thread' :'Qt4Agg',
1183 'tkthread' :'TkAgg',
1183 'tkthread' :'TkAgg',
1184 }
1184 }
1185
1185
1186 all_opts = set(['tk','pylab','gthread','qthread','q4thread','wthread',
1186 all_opts = set(['tk','pylab','gthread','qthread','q4thread','wthread',
1187 'tkthread'])
1187 'tkthread'])
1188 user_opts = set([s.replace('-','') for s in argv[:3]])
1188 user_opts = set([s.replace('-','') for s in argv[:3]])
1189 special_opts = user_opts & all_opts
1189 special_opts = user_opts & all_opts
1190
1190
1191 if 'tk' in special_opts:
1191 if 'tk' in special_opts:
1192 USE_TK = True
1192 USE_TK = True
1193 special_opts.remove('tk')
1193 special_opts.remove('tk')
1194
1194
1195 if 'pylab' in special_opts:
1195 if 'pylab' in special_opts:
1196
1196
1197 try:
1197 try:
1198 import matplotlib
1198 import matplotlib
1199 except ImportError:
1199 except ImportError:
1200 error('matplotlib could NOT be imported! Starting normal IPython.')
1200 error('matplotlib could NOT be imported! Starting normal IPython.')
1201 return IPShell
1201 return IPShell
1202
1202
1203 special_opts.remove('pylab')
1203 special_opts.remove('pylab')
1204 # If there's any option left, it means the user wants to force the
1204 # If there's any option left, it means the user wants to force the
1205 # threading backend, else it's auto-selected from the rc file
1205 # threading backend, else it's auto-selected from the rc file
1206 if special_opts:
1206 if special_opts:
1207 th_mode = special_opts.pop()
1207 th_mode = special_opts.pop()
1208 matplotlib.rcParams['backend'] = backends[th_mode]
1208 matplotlib.rcParams['backend'] = backends[th_mode]
1209 else:
1209 else:
1210 backend = matplotlib.rcParams['backend']
1210 backend = matplotlib.rcParams['backend']
1211 if backend.startswith('GTK'):
1211 if backend.startswith('GTK'):
1212 th_mode = 'gthread'
1212 th_mode = 'gthread'
1213 elif backend.startswith('WX'):
1213 elif backend.startswith('WX'):
1214 th_mode = 'wthread'
1214 th_mode = 'wthread'
1215 elif backend.startswith('Qt4'):
1215 elif backend.startswith('Qt4'):
1216 th_mode = 'q4thread'
1216 th_mode = 'q4thread'
1217 elif backend.startswith('Qt'):
1217 elif backend.startswith('Qt'):
1218 th_mode = 'qthread'
1218 th_mode = 'qthread'
1219 else:
1219 else:
1220 # Any other backend, use plain Tk
1220 # Any other backend, use plain Tk
1221 th_mode = 'tkthread'
1221 th_mode = 'tkthread'
1222
1222
1223 return mpl_shell[th_mode]
1223 return mpl_shell[th_mode]
1224 else:
1224 else:
1225 # No pylab requested, just plain threads
1225 # No pylab requested, just plain threads
1226 try:
1226 try:
1227 th_mode = special_opts.pop()
1227 th_mode = special_opts.pop()
1228 except KeyError:
1228 except KeyError:
1229 th_mode = 'tkthread'
1229 th_mode = 'tkthread'
1230 return th_shell[th_mode]
1230 return th_shell[th_mode]
1231
1231
1232
1232
1233 # This is the one which should be called by external code.
1233 # This is the one which should be called by external code.
1234 def start(user_ns = None):
1234 def start(user_ns = None):
1235 """Return a running shell instance, dealing with threading options.
1235 """Return a running shell instance, dealing with threading options.
1236
1236
1237 This is a factory function which will instantiate the proper IPython shell
1237 This is a factory function which will instantiate the proper IPython shell
1238 based on the user's threading choice. Such a selector is needed because
1238 based on the user's threading choice. Such a selector is needed because
1239 different GUI toolkits require different thread handling details."""
1239 different GUI toolkits require different thread handling details."""
1240
1240
1241 shell = _select_shell(sys.argv)
1241 shell = _select_shell(sys.argv)
1242 return shell(user_ns = user_ns)
1242 return shell(user_ns = user_ns)
1243
1243
1244 # Some aliases for backwards compatibility
1244 # Some aliases for backwards compatibility
1245 IPythonShell = IPShell
1245 IPythonShell = IPShell
1246 IPythonShellEmbed = IPShellEmbed
1246 IPythonShellEmbed = IPShellEmbed
1247 #************************ End of file <Shell.py> ***************************
1247 #************************ End of file <Shell.py> ***************************
@@ -1,631 +1,631 b''
1 # -*- Mode: Shell-Script -*- Not really, but shows comments correctly
1 # -*- Mode: Shell-Script -*- Not really, but shows comments correctly
2
2
3 #***************************************************************************
3 #***************************************************************************
4 #
4 #
5 # Configuration file for IPython -- ipythonrc format
5 # Configuration file for IPython -- ipythonrc format
6 #
6 #
7 # ===========================================================
7 # ===========================================================
8 # Deprecation note: you should look into modifying ipy_user_conf.py (located
8 # Deprecation note: you should look into modifying ipy_user_conf.py (located
9 # in ~/.ipython or ~/_ipython, depending on your platform) instead, it's a
9 # in ~/.ipython or ~/_ipython, depending on your platform) instead, it's a
10 # more flexible and robust (and better supported!) configuration
10 # more flexible and robust (and better supported!) configuration
11 # method.
11 # method.
12 # ===========================================================
12 # ===========================================================
13 #
13 #
14 # The format of this file is simply one of 'key value' lines.
14 # The format of this file is simply one of 'key value' lines.
15 # Lines containing only whitespace at the beginning and then a # are ignored
15 # Lines containing only whitespace at the beginning and then a # are ignored
16 # as comments. But comments can NOT be put on lines with data.
16 # as comments. But comments can NOT be put on lines with data.
17
17
18 # The meaning and use of each key are explained below.
18 # The meaning and use of each key are explained below.
19
19
20 #---------------------------------------------------------------------------
20 #---------------------------------------------------------------------------
21 # Section: included files
21 # Section: included files
22
22
23 # Put one or more *config* files (with the syntax of this file) you want to
23 # Put one or more *config* files (with the syntax of this file) you want to
24 # include. For keys with a unique value the outermost file has precedence. For
24 # include. For keys with a unique value the outermost file has precedence. For
25 # keys with multiple values, they all get assembled into a list which then
25 # keys with multiple values, they all get assembled into a list which then
26 # gets loaded by IPython.
26 # gets loaded by IPython.
27
27
28 # In this file, all lists of things should simply be space-separated.
28 # In this file, all lists of things should simply be space-separated.
29
29
30 # This allows you to build hierarchies of files which recursively load
30 # This allows you to build hierarchies of files which recursively load
31 # lower-level services. If this is your main ~/.ipython/ipythonrc file, you
31 # lower-level services. If this is your main ~/.ipython/ipythonrc file, you
32 # should only keep here basic things you always want available. Then you can
32 # should only keep here basic things you always want available. Then you can
33 # include it in every other special-purpose config file you create.
33 # include it in every other special-purpose config file you create.
34 include
34 include
35
35
36 #---------------------------------------------------------------------------
36 #---------------------------------------------------------------------------
37 # Section: startup setup
37 # Section: startup setup
38
38
39 # These are mostly things which parallel a command line option of the same
39 # These are mostly things which parallel a command line option of the same
40 # name.
40 # name.
41
41
42 # Keys in this section should only appear once. If any key from this section
42 # Keys in this section should only appear once. If any key from this section
43 # is encountered more than once, the last value remains, all earlier ones get
43 # is encountered more than once, the last value remains, all earlier ones get
44 # discarded.
44 # discarded.
45
45
46
46
47 # Automatic calling of callable objects. If set to 1 or 2, callable objects
47 # Automatic calling of callable objects. If set to 1 or 2, callable objects
48 # are automatically called when invoked at the command line, even if you don't
48 # are automatically called when invoked at the command line, even if you don't
49 # type parentheses. IPython adds the parentheses for you. For example:
49 # type parentheses. IPython adds the parentheses for you. For example:
50
50
51 #In [1]: str 45
51 #In [1]: str 45
52 #------> str(45)
52 #------> str(45)
53 #Out[1]: '45'
53 #Out[1]: '45'
54
54
55 # IPython reprints your line with '---->' indicating that it added
55 # IPython reprints your line with '---->' indicating that it added
56 # parentheses. While this option is very convenient for interactive use, it
56 # parentheses. While this option is very convenient for interactive use, it
57 # may occasionally cause problems with objects which have side-effects if
57 # may occasionally cause problems with objects which have side-effects if
58 # called unexpectedly.
58 # called unexpectedly.
59
59
60 # The valid values for autocall are:
60 # The valid values for autocall are:
61
61
62 # autocall 0 -> disabled (you can toggle it at runtime with the %autocall magic)
62 # autocall 0 -> disabled (you can toggle it at runtime with the %autocall magic)
63
63
64 # autocall 1 -> active, but do not apply if there are no arguments on the line.
64 # autocall 1 -> active, but do not apply if there are no arguments on the line.
65
65
66 # In this mode, you get:
66 # In this mode, you get:
67
67
68 #In [1]: callable
68 #In [1]: callable
69 #Out[1]: <built-in function callable>
69 #Out[1]: <built-in function callable>
70
70
71 #In [2]: callable 'hello'
71 #In [2]: callable 'hello'
72 #------> callable('hello')
72 #------> callable('hello')
73 #Out[2]: False
73 #Out[2]: False
74
74
75 # 2 -> Active always. Even if no arguments are present, the callable object
75 # 2 -> Active always. Even if no arguments are present, the callable object
76 # is called:
76 # is called:
77
77
78 #In [4]: callable
78 #In [4]: callable
79 #------> callable()
79 #------> callable()
80
80
81 # Note that even with autocall off, you can still use '/' at the start of a
81 # Note that even with autocall off, you can still use '/' at the start of a
82 # line to treat the first argument on the command line as a function and add
82 # line to treat the first argument on the command line as a function and add
83 # parentheses to it:
83 # parentheses to it:
84
84
85 #In [8]: /str 43
85 #In [8]: /str 43
86 #------> str(43)
86 #------> str(43)
87 #Out[8]: '43'
87 #Out[8]: '43'
88
88
89 autocall 1
89 autocall 1
90
90
91 # Auto-edit syntax errors. When you use the %edit magic in ipython to edit
91 # Auto-edit syntax errors. When you use the %edit magic in ipython to edit
92 # source code (see the 'editor' variable below), it is possible that you save
92 # source code (see the 'editor' variable below), it is possible that you save
93 # a file with syntax errors in it. If this variable is true, IPython will ask
93 # a file with syntax errors in it. If this variable is true, IPython will ask
94 # you whether to re-open the editor immediately to correct such an error.
94 # you whether to re-open the editor immediately to correct such an error.
95
95
96 autoedit_syntax 0
96 autoedit_syntax 0
97
97
98 # Auto-indent. IPython can recognize lines ending in ':' and indent the next
98 # Auto-indent. IPython can recognize lines ending in ':' and indent the next
99 # line, while also un-indenting automatically after 'raise' or 'return'.
99 # line, while also un-indenting automatically after 'raise' or 'return'.
100
100
101 # This feature uses the readline library, so it will honor your ~/.inputrc
101 # This feature uses the readline library, so it will honor your ~/.inputrc
102 # configuration (or whatever file your INPUTRC variable points to). Adding
102 # configuration (or whatever file your INPUTRC variable points to). Adding
103 # the following lines to your .inputrc file can make indent/unindenting more
103 # the following lines to your .inputrc file can make indent/unindenting more
104 # convenient (M-i indents, M-u unindents):
104 # convenient (M-i indents, M-u unindents):
105
105
106 # $if Python
106 # $if Python
107 # "\M-i": " "
107 # "\M-i": " "
108 # "\M-u": "\d\d\d\d"
108 # "\M-u": "\d\d\d\d"
109 # $endif
109 # $endif
110
110
111 # The feature is potentially a bit dangerous, because it can cause problems
111 # The feature is potentially a bit dangerous, because it can cause problems
112 # with pasting of indented code (the pasted code gets re-indented on each
112 # with pasting of indented code (the pasted code gets re-indented on each
113 # line). But it's a huge time-saver when working interactively. The magic
113 # line). But it's a huge time-saver when working interactively. The magic
114 # function %autoindent allows you to toggle it on/off at runtime.
114 # function %autoindent allows you to toggle it on/off at runtime.
115
115
116 autoindent 1
116 autoindent 1
117
117
118 # Auto-magic. This gives you access to all the magic functions without having
118 # Auto-magic. This gives you access to all the magic functions without having
119 # to prepend them with an % sign. If you define a variable with the same name
119 # to prepend them with an % sign. If you define a variable with the same name
120 # as a magic function (say who=1), you will need to access the magic function
120 # as a magic function (say who=1), you will need to access the magic function
121 # with % (%who in this example). However, if later you delete your variable
121 # with % (%who in this example). However, if later you delete your variable
122 # (del who), you'll recover the automagic calling form.
122 # (del who), you'll recover the automagic calling form.
123
123
124 # Considering that many magic functions provide a lot of shell-like
124 # Considering that many magic functions provide a lot of shell-like
125 # functionality, automagic gives you something close to a full Python+system
125 # functionality, automagic gives you something close to a full Python+system
126 # shell environment (and you can extend it further if you want).
126 # shell environment (and you can extend it further if you want).
127
127
128 automagic 1
128 automagic 1
129
129
130 # Size of the output cache. After this many entries are stored, the cache will
130 # Size of the output cache. After this many entries are stored, the cache will
131 # get flushed. Depending on the size of your intermediate calculations, you
131 # get flushed. Depending on the size of your intermediate calculations, you
132 # may have memory problems if you make it too big, since keeping things in the
132 # may have memory problems if you make it too big, since keeping things in the
133 # cache prevents Python from reclaiming the memory for old results. Experiment
133 # cache prevents Python from reclaiming the memory for old results. Experiment
134 # with a value that works well for you.
134 # with a value that works well for you.
135
135
136 # If you choose cache_size 0 IPython will revert to python's regular >>>
136 # If you choose cache_size 0 IPython will revert to python's regular >>>
137 # unnumbered prompt. You will still have _, __ and ___ for your last three
137 # unnumbered prompt. You will still have _, __ and ___ for your last three
138 # results, but that will be it. No dynamic _1, _2, etc. will be created. If
138 # results, but that will be it. No dynamic _1, _2, etc. will be created. If
139 # you are running on a slow machine or with very limited memory, this may
139 # you are running on a slow machine or with very limited memory, this may
140 # help.
140 # help.
141
141
142 cache_size 1000
142 cache_size 1000
143
143
144 # Classic mode: Setting 'classic 1' you lose many of IPython niceties,
144 # Classic mode: Setting 'classic 1' you lose many of IPython niceties,
145 # but that's your choice! Classic 1 -> same as IPython -classic.
145 # but that's your choice! Classic 1 -> same as IPython -classic.
146 # Note that this is _not_ the normal python interpreter, it's simply
146 # Note that this is _not_ the normal python interpreter, it's simply
147 # IPython emulating most of the classic interpreter's behavior.
147 # IPython emulating most of the classic interpreter's behavior.
148 classic 0
148 classic 0
149
149
150 # colors - Coloring option for prompts and traceback printouts.
150 # colors - Coloring option for prompts and traceback printouts.
151
151
152 # Currently available schemes: NoColor, Linux, LightBG.
152 # Currently available schemes: NoColor, Linux, LightBG.
153
153
154 # This option allows coloring the prompts and traceback printouts. This
154 # This option allows coloring the prompts and traceback printouts. This
155 # requires a terminal which can properly handle color escape sequences. If you
155 # requires a terminal which can properly handle color escape sequences. If you
156 # are having problems with this, use the NoColor scheme (uses no color escapes
156 # are having problems with this, use the NoColor scheme (uses no color escapes
157 # at all).
157 # at all).
158
158
159 # The Linux option works well in linux console type environments: dark
159 # The Linux option works well in linux console type environments: dark
160 # background with light fonts.
160 # background with light fonts.
161
161
162 # LightBG is similar to Linux but swaps dark/light colors to be more readable
162 # LightBG is similar to Linux but swaps dark/light colors to be more readable
163 # in light background terminals.
163 # in light background terminals.
164
164
165 # keep uncommented only the one you want:
165 # keep uncommented only the one you want:
166 colors Linux
166 colors Linux
167 #colors LightBG
167 #colors LightBG
168 #colors NoColor
168 #colors NoColor
169
169
170 ########################
170 ########################
171 # Note to Windows users
171 # Note to Windows users
172 #
172 #
173 # Color and readline support is avaialble to Windows users via Gary Bishop's
173 # Color and readline support is avaialble to Windows users via Gary Bishop's
174 # readline library. You can find Gary's tools at
174 # readline library. You can find Gary's tools at
175 # http://sourceforge.net/projects/uncpythontools.
175 # http://sourceforge.net/projects/uncpythontools.
176 # Note that his readline module requires in turn the ctypes library, available
176 # Note that his readline module requires in turn the ctypes library, available
177 # at http://starship.python.net/crew/theller/ctypes.
177 # at http://starship.python.net/crew/theller/ctypes.
178 ########################
178 ########################
179
179
180 # color_info: IPython can display information about objects via a set of
180 # color_info: IPython can display information about objects via a set of
181 # functions, and optionally can use colors for this, syntax highlighting
181 # functions, and optionally can use colors for this, syntax highlighting
182 # source code and various other elements. This information is passed through a
182 # source code and various other elements. This information is passed through a
183 # pager (it defaults to 'less' if $PAGER is not set).
183 # pager (it defaults to 'less' if $PAGER is not set).
184
184
185 # If your pager has problems, try to setting it to properly handle escapes
185 # If your pager has problems, try to setting it to properly handle escapes
186 # (see the less manpage for detail), or disable this option. The magic
186 # (see the less manpage for detail), or disable this option. The magic
187 # function %color_info allows you to toggle this interactively for testing.
187 # function %color_info allows you to toggle this interactively for testing.
188
188
189 color_info 1
189 color_info 1
190
190
191 # confirm_exit: set to 1 if you want IPython to confirm when you try to exit
191 # confirm_exit: set to 1 if you want IPython to confirm when you try to exit
192 # with an EOF (Control-d in Unix, Control-Z/Enter in Windows). Note that using
192 # with an EOF (Control-d in Unix, Control-Z/Enter in Windows). Note that using
193 # the magic functions %Exit or %Quit you can force a direct exit, bypassing
193 # the magic functions %Exit or %Quit you can force a direct exit, bypassing
194 # any confirmation.
194 # any confirmation.
195
195
196 confirm_exit 1
196 confirm_exit 1
197
197
198 # Use deep_reload() as a substitute for reload() by default. deep_reload() is
198 # Use deep_reload() as a substitute for reload() by default. deep_reload() is
199 # still available as dreload() and appears as a builtin.
199 # still available as dreload() and appears as a builtin.
200
200
201 deep_reload 0
201 deep_reload 0
202
202
203 # Which editor to use with the %edit command. If you leave this at 0, IPython
203 # Which editor to use with the %edit command. If you leave this at 0, IPython
204 # will honor your EDITOR environment variable. Since this editor is invoked on
204 # will honor your EDITOR environment variable. Since this editor is invoked on
205 # the fly by ipython and is meant for editing small code snippets, you may
205 # the fly by ipython and is meant for editing small code snippets, you may
206 # want to use a small, lightweight editor here.
206 # want to use a small, lightweight editor here.
207
207
208 # For Emacs users, setting up your Emacs server properly as described in the
208 # For Emacs users, setting up your Emacs server properly as described in the
209 # manual is a good idea. An alternative is to use jed, a very light editor
209 # manual is a good idea. An alternative is to use jed, a very light editor
210 # with much of the feel of Emacs (though not as powerful for heavy-duty work).
210 # with much of the feel of Emacs (though not as powerful for heavy-duty work).
211
211
212 editor 0
212 editor 0
213
213
214 # log 1 -> same as ipython -log. This automatically logs to ./ipython.log
214 # log 1 -> same as ipython -log. This automatically logs to ./ipython.log
215 log 0
215 log 0
216
216
217 # Same as ipython -Logfile YourLogfileName.
217 # Same as ipython -Logfile YourLogfileName.
218 # Don't use with log 1 (use one or the other)
218 # Don't use with log 1 (use one or the other)
219 logfile ''
219 logfile ''
220
220
221 # banner 0 -> same as ipython -nobanner
221 # banner 0 -> same as ipython -nobanner
222 banner 1
222 banner 1
223
223
224 # messages 0 -> same as ipython -nomessages
224 # messages 0 -> same as ipython -nomessages
225 messages 1
225 messages 1
226
226
227 # Automatically call the pdb debugger after every uncaught exception. If you
227 # Automatically call the pdb debugger after every uncaught exception. If you
228 # are used to debugging using pdb, this puts you automatically inside of it
228 # are used to debugging using pdb, this puts you automatically inside of it
229 # after any call (either in IPython or in code called by it) which triggers an
229 # after any call (either in IPython or in code called by it) which triggers an
230 # exception which goes uncaught.
230 # exception which goes uncaught.
231 pdb 0
231 pdb 0
232
232
233 # Enable the pprint module for printing. pprint tends to give a more readable
233 # Enable the pprint module for printing. pprint tends to give a more readable
234 # display (than print) for complex nested data structures.
234 # display (than print) for complex nested data structures.
235 pprint 1
235 pprint 1
236
236
237 # Prompt strings
237 # Prompt strings
238
238
239 # Most bash-like escapes can be used to customize IPython's prompts, as well as
239 # Most bash-like escapes can be used to customize IPython's prompts, as well as
240 # a few additional ones which are IPython-specific. All valid prompt escapes
240 # a few additional ones which are IPython-specific. All valid prompt escapes
241 # are described in detail in the Customization section of the IPython HTML/PDF
241 # are described in detail in the Customization section of the IPython HTML/PDF
242 # manual.
242 # manual.
243
243
244 # Use \# to represent the current prompt number, and quote them to protect
244 # Use \# to represent the current prompt number, and quote them to protect
245 # spaces.
245 # spaces.
246 prompt_in1 'In [\#]: '
246 prompt_in1 'In [\#]: '
247
247
248 # \D is replaced by as many dots as there are digits in the
248 # \D is replaced by as many dots as there are digits in the
249 # current value of \#.
249 # current value of \#.
250 prompt_in2 ' .\D.: '
250 prompt_in2 ' .\D.: '
251
251
252 prompt_out 'Out[\#]: '
252 prompt_out 'Out[\#]: '
253
253
254 # Select whether to left-pad the output prompts to match the length of the
254 # Select whether to left-pad the output prompts to match the length of the
255 # input ones. This allows you for example to use a simple '>' as an output
255 # input ones. This allows you for example to use a simple '>' as an output
256 # prompt, and yet have the output line up with the input. If set to false,
256 # prompt, and yet have the output line up with the input. If set to false,
257 # the output prompts will be unpadded (flush left).
257 # the output prompts will be unpadded (flush left).
258 prompts_pad_left 1
258 prompts_pad_left 1
259
259
260 # Pylab support: when ipython is started with the -pylab switch, by default it
260 # Pylab support: when ipython is started with the -pylab switch, by default it
261 # executes 'from matplotlib.pylab import *'. Set this variable to false if you
261 # executes 'from matplotlib.pylab import *'. Set this variable to false if you
262 # want to disable this behavior.
262 # want to disable this behavior.
263
263
264 # For details on pylab, see the matplotlib website:
264 # For details on pylab, see the matplotlib website:
265 # http://matplotlib.sf.net
265 # http://matplotlib.sf.net
266 pylab_import_all 1
266 pylab_import_all 1
267
267
268
268
269 # quick 1 -> same as ipython -quick
269 # quick 1 -> same as ipython -quick
270 quick 0
270 quick 0
271
271
272 # Use the readline library (1) or not (0). Most users will want this on, but
272 # Use the readline library (1) or not (0). Most users will want this on, but
273 # if you experience strange problems with line management (mainly when using
273 # if you experience strange problems with line management (mainly when using
274 # IPython inside Emacs buffers) you may try disabling it. Not having it on
274 # IPython inside Emacs buffers) you may try disabling it. Not having it on
275 # prevents you from getting command history with the arrow keys, searching and
275 # prevents you from getting command history with the arrow keys, searching and
276 # name completion using TAB.
276 # name completion using TAB.
277
277
278 readline 1
278 readline 1
279
279
280 # Screen Length: number of lines of your screen. This is used to control
280 # Screen Length: number of lines of your screen. This is used to control
281 # printing of very long strings. Strings longer than this number of lines will
281 # printing of very long strings. Strings longer than this number of lines will
282 # be paged with the less command instead of directly printed.
282 # be paged with the less command instead of directly printed.
283
283
284 # The default value for this is 0, which means IPython will auto-detect your
284 # The default value for this is 0, which means IPython will auto-detect your
285 # screen size every time it needs to print. If for some reason this isn't
285 # screen size every time it needs to print. If for some reason this isn't
286 # working well (it needs curses support), specify it yourself. Otherwise don't
286 # working well (it needs curses support), specify it yourself. Otherwise don't
287 # change the default.
287 # change the default.
288
288
289 screen_length 0
289 screen_length 0
290
290
291 # Prompt separators for input and output.
291 # Prompt separators for input and output.
292 # Use \n for newline explicitly, without quotes.
292 # Use \n for newline explicitly, without quotes.
293 # Use 0 (like at the cmd line) to turn off a given separator.
293 # Use 0 (like at the cmd line) to turn off a given separator.
294
294
295 # The structure of prompt printing is:
295 # The structure of prompt printing is:
296 # (SeparateIn)Input....
296 # (SeparateIn)Input....
297 # (SeparateOut)Output...
297 # (SeparateOut)Output...
298 # (SeparateOut2), # that is, no newline is printed after Out2
298 # (SeparateOut2), # that is, no newline is printed after Out2
299 # By choosing these you can organize your output any way you want.
299 # By choosing these you can organize your output any way you want.
300
300
301 separate_in \n
301 separate_in \n
302 separate_out 0
302 separate_out 0
303 separate_out2 0
303 separate_out2 0
304
304
305 # 'nosep 1' is a shorthand for '-SeparateIn 0 -SeparateOut 0 -SeparateOut2 0'.
305 # 'nosep 1' is a shorthand for '-SeparateIn 0 -SeparateOut 0 -SeparateOut2 0'.
306 # Simply removes all input/output separators, overriding the choices above.
306 # Simply removes all input/output separators, overriding the choices above.
307 nosep 0
307 nosep 0
308
308
309 # Wildcard searches - IPython has a system for searching names using
309 # Wildcard searches - IPython has a system for searching names using
310 # shell-like wildcards; type %psearch? for details. This variables sets
310 # shell-like wildcards; type %psearch? for details. This variables sets
311 # whether by default such searches should be case sensitive or not. You can
311 # whether by default such searches should be case sensitive or not. You can
312 # always override the default at the system command line or the IPython
312 # always override the default at the system command line or the IPython
313 # prompt.
313 # prompt.
314
314
315 wildcards_case_sensitive 1
315 wildcards_case_sensitive 1
316
316
317 # Object information: at what level of detail to display the string form of an
317 # Object information: at what level of detail to display the string form of an
318 # object. If set to 0, ipython will compute the string form of any object X,
318 # object. If set to 0, ipython will compute the string form of any object X,
319 # by calling str(X), when X? is typed. If set to 1, str(X) will only be
319 # by calling str(X), when X? is typed. If set to 1, str(X) will only be
320 # computed when X?? is given, and if set to 2 or higher, it will never be
320 # computed when X?? is given, and if set to 2 or higher, it will never be
321 # computed (there is no X??? level of detail). This is mostly of use to
321 # computed (there is no X??? level of detail). This is mostly of use to
322 # people who frequently manipulate objects whose string representation is
322 # people who frequently manipulate objects whose string representation is
323 # extremely expensive to compute.
323 # extremely expensive to compute.
324
324
325 object_info_string_level 0
325 object_info_string_level 0
326
326
327 # xmode - Exception reporting mode.
327 # xmode - Exception reporting mode.
328
328
329 # Valid modes: Plain, Context and Verbose.
329 # Valid modes: Plain, Context and Verbose.
330
330
331 # Plain: similar to python's normal traceback printing.
331 # Plain: similar to python's normal traceback printing.
332
332
333 # Context: prints 5 lines of context source code around each line in the
333 # Context: prints 5 lines of context source code around each line in the
334 # traceback.
334 # traceback.
335
335
336 # Verbose: similar to Context, but additionally prints the variables currently
336 # Verbose: similar to Context, but additionally prints the variables currently
337 # visible where the exception happened (shortening their strings if too
337 # visible where the exception happened (shortening their strings if too
338 # long). This can potentially be very slow, if you happen to have a huge data
338 # long). This can potentially be very slow, if you happen to have a huge data
339 # structure whose string representation is complex to compute. Your computer
339 # structure whose string representation is complex to compute. Your computer
340 # may appear to freeze for a while with cpu usage at 100%. If this occurs, you
340 # may appear to freeze for a while with cpu usage at 100%. If this occurs, you
341 # can cancel the traceback with Ctrl-C (maybe hitting it more than once).
341 # can cancel the traceback with Ctrl-C (maybe hitting it more than once).
342
342
343 #xmode Plain
343 #xmode Plain
344 xmode Context
344 xmode Context
345 #xmode Verbose
345 #xmode Verbose
346
346
347 # multi_line_specials: if true, allow magics, aliases and shell escapes (via
347 # multi_line_specials: if true, allow magics, aliases and shell escapes (via
348 # !cmd) to be used in multi-line input (like for loops). For example, if you
348 # !cmd) to be used in multi-line input (like for loops). For example, if you
349 # have this active, the following is valid in IPython:
349 # have this active, the following is valid in IPython:
350 #
350 #
351 #In [17]: for i in range(3):
351 #In [17]: for i in range(3):
352 # ....: mkdir $i
352 # ....: mkdir $i
353 # ....: !touch $i/hello
353 # ....: !touch $i/hello
354 # ....: ls -l $i
354 # ....: ls -l $i
355
355
356 multi_line_specials 1
356 multi_line_specials 1
357
357
358
358
359 # System calls: When IPython makes system calls (e.g. via special syntax like
359 # System calls: When IPython makes system calls (e.g. via special syntax like
360 # !cmd or !!cmd, or magics like %sc or %sx), it can print the command it is
360 # !cmd or !!cmd, or magics like %sc or %sx), it can print the command it is
361 # executing to standard output, prefixed by a header string.
361 # executing to standard output, prefixed by a header string.
362
362
363 system_header "IPython system call: "
363 system_header "IPython system call: "
364
364
365 system_verbose 1
365 system_verbose 1
366
366
367 # wxversion: request a specific wxPython version (used for -wthread)
367 # wxversion: request a specific wxPython version (used for -wthread)
368
368
369 # Set this to the value of wxPython you want to use, but note that this
369 # Set this to the value of wxPython you want to use, but note that this
370 # feature requires you to have the wxversion Python module to work. If you
370 # feature requires you to have the wxversion Python module to work. If you
371 # don't have the wxversion module (try 'import wxversion' at the prompt to
371 # don't have the wxversion module (try 'import wxversion' at the prompt to
372 # check) or simply want to leave the system to pick up the default, leave this
372 # check) or simply want to leave the system to pick up the default, leave this
373 # variable at 0.
373 # variable at 0.
374
374
375 wxversion 0
375 wxversion 0
376
376
377 #---------------------------------------------------------------------------
377 #---------------------------------------------------------------------------
378 # Section: Readline configuration (readline is not available for MS-Windows)
378 # Section: Readline configuration (readline is not available for MS-Windows)
379
379
380 # This is done via the following options:
380 # This is done via the following options:
381
381
382 # (i) readline_parse_and_bind: this option can appear as many times as you
382 # (i) readline_parse_and_bind: this option can appear as many times as you
383 # want, each time defining a string to be executed via a
383 # want, each time defining a string to be executed via a
384 # readline.parse_and_bind() command. The syntax for valid commands of this
384 # readline.parse_and_bind() command. The syntax for valid commands of this
385 # kind can be found by reading the documentation for the GNU readline library,
385 # kind can be found by reading the documentation for the GNU readline library,
386 # as these commands are of the kind which readline accepts in its
386 # as these commands are of the kind which readline accepts in its
387 # configuration file.
387 # configuration file.
388
388
389 # The TAB key can be used to complete names at the command line in one of two
389 # The TAB key can be used to complete names at the command line in one of two
390 # ways: 'complete' and 'menu-complete'. The difference is that 'complete' only
390 # ways: 'complete' and 'menu-complete'. The difference is that 'complete' only
391 # completes as much as possible while 'menu-complete' cycles through all
391 # completes as much as possible while 'menu-complete' cycles through all
392 # possible completions. Leave the one you prefer uncommented.
392 # possible completions. Leave the one you prefer uncommented.
393
393
394 readline_parse_and_bind tab: complete
394 readline_parse_and_bind tab: complete
395 #readline_parse_and_bind tab: menu-complete
395 #readline_parse_and_bind tab: menu-complete
396
396
397 # This binds Control-l to printing the list of all possible completions when
397 # This binds Control-l to printing the list of all possible completions when
398 # there is more than one (what 'complete' does when hitting TAB twice, or at
398 # there is more than one (what 'complete' does when hitting TAB twice, or at
399 # the first TAB if show-all-if-ambiguous is on)
399 # the first TAB if show-all-if-ambiguous is on)
400 readline_parse_and_bind "\C-l": possible-completions
400 readline_parse_and_bind "\C-l": possible-completions
401
401
402 # This forces readline to automatically print the above list when tab
402 # This forces readline to automatically print the above list when tab
403 # completion is set to 'complete'. You can still get this list manually by
403 # completion is set to 'complete'. You can still get this list manually by
404 # using the key bound to 'possible-completions' (Control-l by default) or by
404 # using the key bound to 'possible-completions' (Control-l by default) or by
405 # hitting TAB twice. Turning this on makes the printing happen at the first
405 # hitting TAB twice. Turning this on makes the printing happen at the first
406 # TAB.
406 # TAB.
407 readline_parse_and_bind set show-all-if-ambiguous on
407 readline_parse_and_bind set show-all-if-ambiguous on
408
408
409 # If you have TAB set to complete names, you can rebind any key (Control-o by
409 # If you have TAB set to complete names, you can rebind any key (Control-o by
410 # default) to insert a true TAB character.
410 # default) to insert a true TAB character.
411 readline_parse_and_bind "\C-o": tab-insert
411 readline_parse_and_bind "\C-o": tab-insert
412
412
413 # These commands allow you to indent/unindent easily, with the 4-space
413 # These commands allow you to indent/unindent easily, with the 4-space
414 # convention of the Python coding standards. Since IPython's internal
414 # convention of the Python coding standards. Since IPython's internal
415 # auto-indent system also uses 4 spaces, you should not change the number of
415 # auto-indent system also uses 4 spaces, you should not change the number of
416 # spaces in the code below.
416 # spaces in the code below.
417 readline_parse_and_bind "\M-i": " "
417 readline_parse_and_bind "\M-i": " "
418 readline_parse_and_bind "\M-o": "\d\d\d\d"
418 readline_parse_and_bind "\M-o": "\d\d\d\d"
419 readline_parse_and_bind "\M-I": "\d\d\d\d"
419 readline_parse_and_bind "\M-I": "\d\d\d\d"
420
420
421 # Bindings for incremental searches in the history. These searches use the
421 # Bindings for incremental searches in the history. These searches use the
422 # string typed so far on the command line and search anything in the previous
422 # string typed so far on the command line and search anything in the previous
423 # input history containing them.
423 # input history containing them.
424 readline_parse_and_bind "\C-r": reverse-search-history
424 readline_parse_and_bind "\C-r": reverse-search-history
425 readline_parse_and_bind "\C-s": forward-search-history
425 readline_parse_and_bind "\C-s": forward-search-history
426
426
427 # Bindings for completing the current line in the history of previous
427 # Bindings for completing the current line in the history of previous
428 # commands. This allows you to recall any previous command by typing its first
428 # commands. This allows you to recall any previous command by typing its first
429 # few letters and hitting Control-p, bypassing all intermediate commands which
429 # few letters and hitting Control-p, bypassing all intermediate commands which
430 # may be in the history (much faster than hitting up-arrow 50 times!)
430 # may be in the history (much faster than hitting up-arrow 50 times!)
431 readline_parse_and_bind "\C-p": history-search-backward
431 readline_parse_and_bind "\C-p": history-search-backward
432 readline_parse_and_bind "\C-n": history-search-forward
432 readline_parse_and_bind "\C-n": history-search-forward
433
433
434 # I also like to have the same functionality on the plain arrow keys. If you'd
434 # I also like to have the same functionality on the plain arrow keys. If you'd
435 # rather have the arrows use all the history (and not just match what you've
435 # rather have the arrows use all the history (and not just match what you've
436 # typed so far), comment out or delete the next two lines.
436 # typed so far), comment out or delete the next two lines.
437 readline_parse_and_bind "\e[A": history-search-backward
437 readline_parse_and_bind "\e[A": history-search-backward
438 readline_parse_and_bind "\e[B": history-search-forward
438 readline_parse_and_bind "\e[B": history-search-forward
439
439
440 # These are typically on by default under *nix, but not win32.
440 # These are typically on by default under *nix, but not win32.
441 readline_parse_and_bind "\C-k": kill-line
441 readline_parse_and_bind "\C-k": kill-line
442 readline_parse_and_bind "\C-u": unix-line-discard
442 readline_parse_and_bind "\C-u": unix-line-discard
443
443
444 # (ii) readline_remove_delims: a string of characters to be removed from the
444 # (ii) readline_remove_delims: a string of characters to be removed from the
445 # default word-delimiters list used by readline, so that completions may be
445 # default word-delimiters list used by readline, so that completions may be
446 # performed on strings which contain them.
446 # performed on strings which contain them.
447
447
448 readline_remove_delims -/~
448 readline_remove_delims -/~
449
449
450 # (iii) readline_merge_completions: whether to merge the result of all
450 # (iii) readline_merge_completions: whether to merge the result of all
451 # possible completions or not. If true, IPython will complete filenames,
451 # possible completions or not. If true, IPython will complete filenames,
452 # python names and aliases and return all possible completions. If you set it
452 # python names and aliases and return all possible completions. If you set it
453 # to false, each completer is used at a time, and only if it doesn't return
453 # to false, each completer is used at a time, and only if it doesn't return
454 # any completions is the next one used.
454 # any completions is the next one used.
455
455
456 # The default order is: [python_matches, file_matches, alias_matches]
456 # The default order is: [python_matches, file_matches, alias_matches]
457
457
458 readline_merge_completions 1
458 readline_merge_completions 1
459
459
460 # (iv) readline_omit__names: normally hitting <tab> after a '.' in a name
460 # (iv) readline_omit__names: normally hitting <tab> after a '.' in a name
461 # will complete all attributes of an object, including all the special methods
461 # will complete all attributes of an object, including all the special methods
462 # whose names start with single or double underscores (like __getitem__ or
462 # whose names start with single or double underscores (like __getitem__ or
463 # __class__).
463 # __class__).
464
464
465 # This variable allows you to control this completion behavior:
465 # This variable allows you to control this completion behavior:
466
466
467 # readline_omit__names 1 -> completion will omit showing any names starting
467 # readline_omit__names 1 -> completion will omit showing any names starting
468 # with two __, but it will still show names starting with one _.
468 # with two __, but it will still show names starting with one _.
469
469
470 # readline_omit__names 2 -> completion will omit all names beginning with one
470 # readline_omit__names 2 -> completion will omit all names beginning with one
471 # _ (which obviously means filtering out the double __ ones).
471 # _ (which obviously means filtering out the double __ ones).
472
472
473 # Even when this option is set, you can still see those names by explicitly
473 # Even when this option is set, you can still see those names by explicitly
474 # typing a _ after the period and hitting <tab>: 'name._<tab>' will always
474 # typing a _ after the period and hitting <tab>: 'name._<tab>' will always
475 # complete attribute names starting with '_'.
475 # complete attribute names starting with '_'.
476
476
477 # This option is off by default so that new users see all attributes of any
477 # This option is off by default so that new users see all attributes of any
478 # objects they are dealing with.
478 # objects they are dealing with.
479
479
480 readline_omit__names 0
480 readline_omit__names 0
481
481
482 #---------------------------------------------------------------------------
482 #---------------------------------------------------------------------------
483 # Section: modules to be loaded with 'import ...'
483 # Section: modules to be loaded with 'import ...'
484
484
485 # List, separated by spaces, the names of the modules you want to import
485 # List, separated by spaces, the names of the modules you want to import
486
486
487 # Example:
487 # Example:
488 # import_mod sys os
488 # import_mod sys os
489 # will produce internally the statements
489 # will produce internally the statements
490 # import sys
490 # import sys
491 # import os
491 # import os
492
492
493 # Each import is executed in its own try/except block, so if one module
493 # Each import is executed in its own try/except block, so if one module
494 # fails to load the others will still be ok.
494 # fails to load the others will still be ok.
495
495
496 import_mod
496 import_mod
497
497
498 #---------------------------------------------------------------------------
498 #---------------------------------------------------------------------------
499 # Section: modules to import some functions from: 'from ... import ...'
499 # Section: modules to import some functions from: 'from ... import ...'
500
500
501 # List, one per line, the modules for which you want only to import some
501 # List, one per line, the modules for which you want only to import some
502 # functions. Give the module name first and then the name of functions to be
502 # functions. Give the module name first and then the name of functions to be
503 # imported from that module.
503 # imported from that module.
504
504
505 # Example:
505 # Example:
506
506
507 # import_some IPython.utils.genutils timing timings
507 # import_some IPython.utils.genutils timing timings
508 # will produce internally the statement
508 # will produce internally the statement
509 # from IPython.utils.genutils import timing, timings
509 # from IPython.utils.genutils import timing, timings
510
510
511 # timing() and timings() are two IPython utilities for timing the execution of
511 # timing() and timings() are two IPython utilities for timing the execution of
512 # your own functions, which you may find useful. Just commment out the above
512 # your own functions, which you may find useful. Just commment out the above
513 # line if you want to test them.
513 # line if you want to test them.
514
514
515 # If you have more than one modules_some line, each gets its own try/except
515 # If you have more than one modules_some line, each gets its own try/except
516 # block (like modules, see above).
516 # block (like modules, see above).
517
517
518 import_some
518 import_some
519
519
520 #---------------------------------------------------------------------------
520 #---------------------------------------------------------------------------
521 # Section: modules to import all from : 'from ... import *'
521 # Section: modules to import all from : 'from ... import *'
522
522
523 # List (same syntax as import_mod above) those modules for which you want to
523 # List (same syntax as import_mod above) those modules for which you want to
524 # import all functions. Remember, this is a potentially dangerous thing to do,
524 # import all functions. Remember, this is a potentially dangerous thing to do,
525 # since it is very easy to overwrite names of things you need. Use with
525 # since it is very easy to overwrite names of things you need. Use with
526 # caution.
526 # caution.
527
527
528 # Example:
528 # Example:
529 # import_all sys os
529 # import_all sys os
530 # will produce internally the statements
530 # will produce internally the statements
531 # from sys import *
531 # from sys import *
532 # from os import *
532 # from os import *
533
533
534 # As before, each will be called in a separate try/except block.
534 # As before, each will be called in a separate try/except block.
535
535
536 import_all
536 import_all
537
537
538 #---------------------------------------------------------------------------
538 #---------------------------------------------------------------------------
539 # Section: Python code to execute.
539 # Section: Python code to execute.
540
540
541 # Put here code to be explicitly executed (keep it simple!)
541 # Put here code to be explicitly executed (keep it simple!)
542 # Put one line of python code per line. All whitespace is removed (this is a
542 # Put one line of python code per line. All whitespace is removed (this is a
543 # feature, not a bug), so don't get fancy building loops here.
543 # feature, not a bug), so don't get fancy building loops here.
544 # This is just for quick convenient creation of things you want available.
544 # This is just for quick convenient creation of things you want available.
545
545
546 # Example:
546 # Example:
547 # execute x = 1
547 # execute x = 1
548 # execute print 'hello world'; y = z = 'a'
548 # execute print 'hello world'; y = z = 'a'
549 # will produce internally
549 # will produce internally
550 # x = 1
550 # x = 1
551 # print 'hello world'; y = z = 'a'
551 # print 'hello world'; y = z = 'a'
552 # and each *line* (not each statement, we don't do python syntax parsing) is
552 # and each *line* (not each statement, we don't do python syntax parsing) is
553 # executed in its own try/except block.
553 # executed in its own try/except block.
554
554
555 execute
555 execute
556
556
557 # Note for the adventurous: you can use this to define your own names for the
557 # Note for the adventurous: you can use this to define your own names for the
558 # magic functions, by playing some namespace tricks:
558 # magic functions, by playing some namespace tricks:
559
559
560 # execute __IPYTHON__.magic_pf = __IPYTHON__.magic_profile
560 # execute __IPYTHON__.magic_pf = __IPYTHON__.magic_profile
561
561
562 # defines %pf as a new name for %profile.
562 # defines %pf as a new name for %profile.
563
563
564 #---------------------------------------------------------------------------
564 #---------------------------------------------------------------------------
565 # Section: Pyhton files to load and execute.
565 # Section: Pyhton files to load and execute.
566
566
567 # Put here the full names of files you want executed with execfile(file). If
567 # Put here the full names of files you want executed with execfile(file). If
568 # you want complicated initialization, just write whatever you want in a
568 # you want complicated initialization, just write whatever you want in a
569 # regular python file and load it from here.
569 # regular python file and load it from here.
570
570
571 # Filenames defined here (which *must* include the extension) are searched for
571 # Filenames defined here (which *must* include the extension) are searched for
572 # through all of sys.path. Since IPython adds your .ipython directory to
572 # through all of sys.path. Since IPython adds your .ipython directory to
573 # sys.path, they can also be placed in your .ipython dir and will be
573 # sys.path, they can also be placed in your .ipython dir and will be
574 # found. Otherwise (if you want to execute things not in .ipyton nor in
574 # found. Otherwise (if you want to execute things not in .ipyton nor in
575 # sys.path) give a full path (you can use ~, it gets expanded)
575 # sys.path) give a full path (you can use ~, it gets expanded)
576
576
577 # Example:
577 # Example:
578 # execfile file1.py ~/file2.py
578 # execfile file1.py ~/file2.py
579 # will generate
579 # will generate
580 # execfile('file1.py')
580 # execfile('file1.py')
581 # execfile('_path_to_your_home/file2.py')
581 # execfile('_path_to_your_home/file2.py')
582
582
583 # As before, each file gets its own try/except block.
583 # As before, each file gets its own try/except block.
584
584
585 execfile
585 execfile
586
586
587 # If you are feeling adventurous, you can even add functionality to IPython
587 # If you are feeling adventurous, you can even add functionality to IPython
588 # through here. IPython works through a global variable called __ip which
588 # through here. IPython works through a global variable called __ip which
589 # exists at the time when these files are read. If you know what you are doing
589 # exists at the time when these files are read. If you know what you are doing
590 # (read the source) you can add functions to __ip in files loaded here.
590 # (read the source) you can add functions to __ip in files loaded here.
591
591
592 # The file example-magic.py contains a simple but correct example. Try it:
592 # The file example-magic.py contains a simple but correct example. Try it:
593
593
594 # execfile example-magic.py
594 # execfile example-magic.py
595
595
596 # Look at the examples in IPython/iplib.py for more details on how these magic
596 # Look at the examples in IPython/core/iplib.py for more details on how
597 # functions need to process their arguments.
597 # these magic functions need to process their arguments.
598
598
599 #---------------------------------------------------------------------------
599 #---------------------------------------------------------------------------
600 # Section: aliases for system shell commands
600 # Section: aliases for system shell commands
601
601
602 # Here you can define your own names for system commands. The syntax is
602 # Here you can define your own names for system commands. The syntax is
603 # similar to that of the builtin %alias function:
603 # similar to that of the builtin %alias function:
604
604
605 # alias alias_name command_string
605 # alias alias_name command_string
606
606
607 # The resulting aliases are auto-generated magic functions (hence usable as
607 # The resulting aliases are auto-generated magic functions (hence usable as
608 # %alias_name)
608 # %alias_name)
609
609
610 # For example:
610 # For example:
611
611
612 # alias myls ls -la
612 # alias myls ls -la
613
613
614 # will define 'myls' as an alias for executing the system command 'ls -la'.
614 # will define 'myls' as an alias for executing the system command 'ls -la'.
615 # This allows you to customize IPython's environment to have the same aliases
615 # This allows you to customize IPython's environment to have the same aliases
616 # you are accustomed to from your own shell.
616 # you are accustomed to from your own shell.
617
617
618 # You can also define aliases with parameters using %s specifiers (one per
618 # You can also define aliases with parameters using %s specifiers (one per
619 # parameter):
619 # parameter):
620
620
621 # alias parts echo first %s second %s
621 # alias parts echo first %s second %s
622
622
623 # will give you in IPython:
623 # will give you in IPython:
624 # >>> %parts A B
624 # >>> %parts A B
625 # first A second B
625 # first A second B
626
626
627 # Use one 'alias' statement per alias you wish to define.
627 # Use one 'alias' statement per alias you wish to define.
628
628
629 # alias
629 # alias
630
630
631 #************************* end of file <ipythonrc> ************************
631 #************************* end of file <ipythonrc> ************************
1 NO CONTENT: file renamed from IPython/iplib.py to IPython/core/iplib.py
NO CONTENT: file renamed from IPython/iplib.py to IPython/core/iplib.py
@@ -1,29 +1,33 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3
3
4 def test_import_completer():
4 def test_import_completer():
5 from IPython.core import completer
5 from IPython.core import completer
6
6
7 def test_import_crashhandler():
7 def test_import_crashhandler():
8 from IPython.core import crashhandler
8 from IPython.core import crashhandler
9
9
10 def test_import_debugger():
10 def test_import_debugger():
11 from IPython.core import debugger
11 from IPython.core import debugger
12
12
13 def test_import_fakemodule():
13 def test_import_fakemodule():
14 from IPython.core import fakemodule
14 from IPython.core import fakemodule
15
15
16 def test_import_excolors():
16 def test_import_excolors():
17 from IPython.core import excolors
17 from IPython.core import excolors
18
18
19 def test_import_history():
19 def test_import_history():
20 from IPython.core import history
20 from IPython.core import history
21
21
22 def test_import_hooks():
22 def test_import_hooks():
23 from IPython.core import hooks
23 from IPython.core import hooks
24
24
25 def test_import_ipapi():
25 def test_import_ipapi():
26 from IPython.core import ipapi
26 from IPython.core import ipapi
27
27
28 def test_imort_iplib():
29 from IPython.core import iplib
30
31
28
32
29
33
@@ -1,81 +1,81 b''
1 """Tests for the key iplib module, where the main ipython class is defined.
1 """Tests for the key iplib module, where the main ipython class is defined.
2 """
2 """
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4 # Module imports
4 # Module imports
5 #-----------------------------------------------------------------------------
5 #-----------------------------------------------------------------------------
6
6
7 # stdlib
7 # stdlib
8 import os
8 import os
9 import shutil
9 import shutil
10 import tempfile
10 import tempfile
11
11
12 # third party
12 # third party
13 import nose.tools as nt
13 import nose.tools as nt
14
14
15 # our own packages
15 # our own packages
16 from IPython import iplib
16 from IPython.core import iplib
17 from IPython.core import ipapi
17 from IPython.core import ipapi
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Globals
20 # Globals
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22
22
23 # Useful global ipapi object and main IPython one. Unfortunately we have a
23 # Useful global ipapi object and main IPython one. Unfortunately we have a
24 # long precedent of carrying the 'ipapi' global object which is injected into
24 # long precedent of carrying the 'ipapi' global object which is injected into
25 # the system namespace as _ip, but that keeps a pointer to the actual IPython
25 # the system namespace as _ip, but that keeps a pointer to the actual IPython
26 # InteractiveShell instance, which is named IP. Since in testing we do need
26 # InteractiveShell instance, which is named IP. Since in testing we do need
27 # access to the real thing (we want to probe beyond what ipapi exposes), make
27 # access to the real thing (we want to probe beyond what ipapi exposes), make
28 # here a global reference to each. In general, things that are exposed by the
28 # here a global reference to each. In general, things that are exposed by the
29 # ipapi instance should be read from there, but we also will often need to use
29 # ipapi instance should be read from there, but we also will often need to use
30 # the actual IPython one.
30 # the actual IPython one.
31
31
32 # Get the public instance of IPython, and if it's None, make one so we can use
32 # Get the public instance of IPython, and if it's None, make one so we can use
33 # it for testing
33 # it for testing
34 ip = ipapi.get()
34 ip = ipapi.get()
35 if ip is None:
35 if ip is None:
36 # IPython not running yet, make one from the testing machinery for
36 # IPython not running yet, make one from the testing machinery for
37 # consistency when the test suite is being run via iptest
37 # consistency when the test suite is being run via iptest
38 from IPython.testing.plugin import ipdoctest
38 from IPython.testing.plugin import ipdoctest
39 ip = ipapi.get()
39 ip = ipapi.get()
40
40
41 IP = ip.IP # This is the actual IPython shell 'raw' object.
41 IP = ip.IP # This is the actual IPython shell 'raw' object.
42
42
43 #-----------------------------------------------------------------------------
43 #-----------------------------------------------------------------------------
44 # Test functions
44 # Test functions
45 #-----------------------------------------------------------------------------
45 #-----------------------------------------------------------------------------
46
46
47 def test_reset():
47 def test_reset():
48 """reset must clear most namespaces."""
48 """reset must clear most namespaces."""
49 IP.reset() # first, it should run without error
49 IP.reset() # first, it should run without error
50 # Then, check that most namespaces end up empty
50 # Then, check that most namespaces end up empty
51 for ns in IP.ns_refs_table:
51 for ns in IP.ns_refs_table:
52 if ns is IP.user_ns:
52 if ns is IP.user_ns:
53 # The user namespace is reset with some data, so we can't check for
53 # The user namespace is reset with some data, so we can't check for
54 # it being empty
54 # it being empty
55 continue
55 continue
56 nt.assert_equals(len(ns),0)
56 nt.assert_equals(len(ns),0)
57
57
58
58
59 # make sure that user_setup can be run re-entrantly in 'install' mode.
59 # make sure that user_setup can be run re-entrantly in 'install' mode.
60 def test_user_setup():
60 def test_user_setup():
61 # use a lambda to pass kwargs to the generator
61 # use a lambda to pass kwargs to the generator
62 user_setup = lambda a,k: iplib.user_setup(*a,**k)
62 user_setup = lambda a,k: iplib.user_setup(*a,**k)
63 kw = dict(mode='install', interactive=False)
63 kw = dict(mode='install', interactive=False)
64
64
65 # Call the user setup and verify that the directory exists
65 # Call the user setup and verify that the directory exists
66 yield user_setup, (ip.options.ipythondir,''), kw
66 yield user_setup, (ip.options.ipythondir,''), kw
67 yield os.path.isdir, ip.options.ipythondir
67 yield os.path.isdir, ip.options.ipythondir
68
68
69 # Now repeat the operation with a non-existent directory. Check both that
69 # Now repeat the operation with a non-existent directory. Check both that
70 # the call succeeds and that the directory is created.
70 # the call succeeds and that the directory is created.
71 tmpdir = tempfile.mktemp(prefix='ipython-test-')
71 tmpdir = tempfile.mktemp(prefix='ipython-test-')
72 # Use a try with an empty except because try/finally doesn't work with a
72 # Use a try with an empty except because try/finally doesn't work with a
73 # yield in Python 2.4.
73 # yield in Python 2.4.
74 try:
74 try:
75 yield user_setup, (tmpdir,''), kw
75 yield user_setup, (tmpdir,''), kw
76 yield os.path.isdir, tmpdir
76 yield os.path.isdir, tmpdir
77 except:
77 except:
78 pass
78 pass
79 # Clean up the temp dir once done
79 # Clean up the temp dir once done
80 shutil.rmtree(tmpdir)
80 shutil.rmtree(tmpdir)
81 No newline at end of file
81
@@ -1,147 +1,147 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Interactive functions and magic functions for Gnuplot usage.
2 """Interactive functions and magic functions for Gnuplot usage.
3
3
4 This requires the Gnuplot.py module for interfacing python with Gnuplot, which
4 This requires the Gnuplot.py module for interfacing python with Gnuplot, which
5 can be downloaded from:
5 can be downloaded from:
6
6
7 http://gnuplot-py.sourceforge.net/
7 http://gnuplot-py.sourceforge.net/
8
8
9 See gphelp() below for details on the services offered by this module.
9 See gphelp() below for details on the services offered by this module.
10
10
11 Inspired by a suggestion/request from Arnd Baecker.
11 Inspired by a suggestion/request from Arnd Baecker.
12 """
12 """
13
13
14 __all__ = ['Gnuplot','gp','gp_new','plot','plot2','splot','replot',
14 __all__ = ['Gnuplot','gp','gp_new','plot','plot2','splot','replot',
15 'hardcopy','gpdata','gpfile','gpstring','gpfunc','gpgrid',
15 'hardcopy','gpdata','gpfile','gpstring','gpfunc','gpgrid',
16 'gphelp']
16 'gphelp']
17
17
18 import IPython.GnuplotRuntime as GRun
18 import IPython.GnuplotRuntime as GRun
19 from IPython.utils.genutils import page,warn
19 from IPython.utils.genutils import page,warn
20
20
21 # Set global names for interactive use
21 # Set global names for interactive use
22 Gnuplot = GRun.Gnuplot
22 Gnuplot = GRun.Gnuplot
23 gp_new = GRun.gp_new
23 gp_new = GRun.gp_new
24 gp = GRun.gp
24 gp = GRun.gp
25 plot = gp.plot
25 plot = gp.plot
26 plot2 = gp.plot2
26 plot2 = gp.plot2
27 splot = gp.splot
27 splot = gp.splot
28 replot = gp.replot
28 replot = gp.replot
29 hardcopy = gp.hardcopy
29 hardcopy = gp.hardcopy
30
30
31 # Accessors for the main plot object constructors:
31 # Accessors for the main plot object constructors:
32 gpdata = Gnuplot.Data
32 gpdata = Gnuplot.Data
33 gpfile = Gnuplot.File
33 gpfile = Gnuplot.File
34 gpstring = Gnuplot.String
34 gpstring = Gnuplot.String
35 gpfunc = Gnuplot.Func
35 gpfunc = Gnuplot.Func
36 gpgrid = Gnuplot.GridData
36 gpgrid = Gnuplot.GridData
37
37
38 def gphelp():
38 def gphelp():
39 """Print information about the Gnuplot facilities in IPython."""
39 """Print information about the Gnuplot facilities in IPython."""
40
40
41 page("""
41 page("""
42 IPython provides an interface to access the Gnuplot scientific plotting
42 IPython provides an interface to access the Gnuplot scientific plotting
43 system, in an environment similar to that of Mathematica or Matlab.
43 system, in an environment similar to that of Mathematica or Matlab.
44
44
45 New top-level global objects
45 New top-level global objects
46 ----------------------------
46 ----------------------------
47
47
48 Please see their respective docstrings for further details.
48 Please see their respective docstrings for further details.
49
49
50 - gp: a running Gnuplot instance. You can access its methods as
50 - gp: a running Gnuplot instance. You can access its methods as
51 gp.<method>. gp(`a string`) will execute the given string as if it had been
51 gp.<method>. gp(`a string`) will execute the given string as if it had been
52 typed in an interactive gnuplot window.
52 typed in an interactive gnuplot window.
53
53
54 - plot, splot, replot and hardcopy: aliases to the methods of the same name in
54 - plot, splot, replot and hardcopy: aliases to the methods of the same name in
55 the global running Gnuplot instance gp. These allow you to simply type:
55 the global running Gnuplot instance gp. These allow you to simply type:
56
56
57 In [1]: plot(x,sin(x),title='Sin(x)') # assuming x is a Numeric array
57 In [1]: plot(x,sin(x),title='Sin(x)') # assuming x is a Numeric array
58
58
59 and obtain a plot of sin(x) vs x with the title 'Sin(x)'.
59 and obtain a plot of sin(x) vs x with the title 'Sin(x)'.
60
60
61 - gp_new: a function which returns a new Gnuplot instance. This can be used to
61 - gp_new: a function which returns a new Gnuplot instance. This can be used to
62 have multiple Gnuplot instances running in your session to compare different
62 have multiple Gnuplot instances running in your session to compare different
63 plots, each in a separate window.
63 plots, each in a separate window.
64
64
65 - Gnuplot: alias to the Gnuplot2 module, an improved drop-in replacement for
65 - Gnuplot: alias to the Gnuplot2 module, an improved drop-in replacement for
66 the original Gnuplot.py. Gnuplot2 needs Gnuplot but redefines several of its
66 the original Gnuplot.py. Gnuplot2 needs Gnuplot but redefines several of its
67 functions with improved versions (Gnuplot2 comes with IPython).
67 functions with improved versions (Gnuplot2 comes with IPython).
68
68
69 - gpdata, gpfile, gpstring, gpfunc, gpgrid: aliases to Gnuplot.Data,
69 - gpdata, gpfile, gpstring, gpfunc, gpgrid: aliases to Gnuplot.Data,
70 Gnuplot.File, Gnuplot.String, Gnuplot.Func and Gnuplot.GridData
70 Gnuplot.File, Gnuplot.String, Gnuplot.Func and Gnuplot.GridData
71 respectively. These functions create objects which can then be passed to the
71 respectively. These functions create objects which can then be passed to the
72 plotting commands. See the Gnuplot.py documentation for details.
72 plotting commands. See the Gnuplot.py documentation for details.
73
73
74 Keep in mind that all commands passed to a Gnuplot instance are executed in
74 Keep in mind that all commands passed to a Gnuplot instance are executed in
75 the Gnuplot namespace, where no Python variables exist. For example, for
75 the Gnuplot namespace, where no Python variables exist. For example, for
76 plotting sin(x) vs x as above, typing
76 plotting sin(x) vs x as above, typing
77
77
78 In [2]: gp('plot x,sin(x)')
78 In [2]: gp('plot x,sin(x)')
79
79
80 would not work. Instead, you would get the plot of BOTH the functions 'x' and
80 would not work. Instead, you would get the plot of BOTH the functions 'x' and
81 'sin(x)', since Gnuplot doesn't know about the 'x' Python array. The plot()
81 'sin(x)', since Gnuplot doesn't know about the 'x' Python array. The plot()
82 method lives in python and does know about these variables.
82 method lives in python and does know about these variables.
83
83
84
84
85 New magic functions
85 New magic functions
86 -------------------
86 -------------------
87
87
88 %gpc: pass one command to Gnuplot and execute it or open a Gnuplot shell where
88 %gpc: pass one command to Gnuplot and execute it or open a Gnuplot shell where
89 each line of input is executed.
89 each line of input is executed.
90
90
91 %gp_set_default: reset the value of IPython's global Gnuplot instance.""")
91 %gp_set_default: reset the value of IPython's global Gnuplot instance.""")
92
92
93 # Code below is all for IPython use
93 # Code below is all for IPython use
94 # Define the magic functions for communicating with the above gnuplot instance.
94 # Define the magic functions for communicating with the above gnuplot instance.
95 def magic_gpc(self,parameter_s=''):
95 def magic_gpc(self,parameter_s=''):
96 """Execute a gnuplot command or open a gnuplot shell.
96 """Execute a gnuplot command or open a gnuplot shell.
97
97
98 Usage (omit the % if automagic is on). There are two ways to use it:
98 Usage (omit the % if automagic is on). There are two ways to use it:
99
99
100 1) %gpc 'command' -> passes 'command' directly to the gnuplot instance.
100 1) %gpc 'command' -> passes 'command' directly to the gnuplot instance.
101
101
102 2) %gpc -> will open up a prompt (gnuplot>>>) which takes input like the
102 2) %gpc -> will open up a prompt (gnuplot>>>) which takes input like the
103 standard gnuplot interactive prompt. If you need to type a multi-line
103 standard gnuplot interactive prompt. If you need to type a multi-line
104 command, use \\ at the end of each intermediate line.
104 command, use \\ at the end of each intermediate line.
105
105
106 Upon exiting of the gnuplot sub-shell, you return to your IPython
106 Upon exiting of the gnuplot sub-shell, you return to your IPython
107 session (the gnuplot sub-shell can be invoked as many times as needed).
107 session (the gnuplot sub-shell can be invoked as many times as needed).
108 """
108 """
109
109
110 if parameter_s.strip():
110 if parameter_s.strip():
111 self.shell.gnuplot(parameter_s)
111 self.shell.gnuplot(parameter_s)
112 else:
112 else:
113 self.shell.gnuplot.interact()
113 self.shell.gnuplot.interact()
114
114
115 def magic_gp_set_default(self,parameter_s=''):
115 def magic_gp_set_default(self,parameter_s=''):
116 """Set the default gnuplot instance accessed by the %gp magic function.
116 """Set the default gnuplot instance accessed by the %gp magic function.
117
117
118 %gp_set_default name
118 %gp_set_default name
119
119
120 Call with the name of the new instance at the command line. If you want to
120 Call with the name of the new instance at the command line. If you want to
121 set this instance in your own code (using an embedded IPython, for
121 set this instance in your own code (using an embedded IPython, for
122 example), simply set the variable __IPYTHON__.gnuplot to your own gnuplot
122 example), simply set the variable __IPYTHON__.gnuplot to your own gnuplot
123 instance object."""
123 instance object."""
124
124
125 gname = parameter_s.strip()
125 gname = parameter_s.strip()
126 G = eval(gname,self.shell.user_ns)
126 G = eval(gname,self.shell.user_ns)
127 self.shell.gnuplot = G
127 self.shell.gnuplot = G
128 self.shell.user_ns.update({'plot':G.plot,'splot':G.splot,'plot2':G.plot2,
128 self.shell.user_ns.update({'plot':G.plot,'splot':G.splot,'plot2':G.plot2,
129 'replot':G.replot,'hardcopy':G.hardcopy})
129 'replot':G.replot,'hardcopy':G.hardcopy})
130
130
131 try:
131 try:
132 __IPYTHON__
132 __IPYTHON__
133 except NameError:
133 except NameError:
134 pass
134 pass
135 else:
135 else:
136 # make the global Gnuplot instance known to IPython
136 # make the global Gnuplot instance known to IPython
137 __IPYTHON__.gnuplot = GRun.gp
137 __IPYTHON__.gnuplot = GRun.gp
138 __IPYTHON__.gnuplot.shell_first_time = 1
138 __IPYTHON__.gnuplot.shell_first_time = 1
139
139
140 print """*** Type `gphelp` for help on the Gnuplot integration features."""
140 print """*** Type `gphelp` for help on the Gnuplot integration features."""
141
141
142 # Add the new magic functions to the class dict
142 # Add the new magic functions to the class dict
143 from IPython.iplib import InteractiveShell
143 from IPython.core.iplib import InteractiveShell
144 InteractiveShell.magic_gpc = magic_gpc
144 InteractiveShell.magic_gpc = magic_gpc
145 InteractiveShell.magic_gp_set_default = magic_gp_set_default
145 InteractiveShell.magic_gp_set_default = magic_gp_set_default
146
146
147 #********************** End of file <GnuplotInteractive.py> *******************
147 #********************** End of file <GnuplotInteractive.py> *******************
@@ -1,282 +1,282 b''
1 """Twisted shell support.
1 """Twisted shell support.
2
2
3 XXX - This module is missing proper docs.
3 XXX - This module is missing proper docs.
4 """
4 """
5 import sys
5 import sys
6
6
7 from twisted.internet import reactor, threads
7 from twisted.internet import reactor, threads
8
8
9 from IPython.ipmaker import make_IPython
9 from IPython.ipmaker import make_IPython
10 from IPython.iplib import InteractiveShell
10 from IPython.core.iplib import InteractiveShell
11 from IPython.ipstruct import Struct
11 from IPython.ipstruct import Struct
12 import Queue,thread,threading,signal
12 import Queue,thread,threading,signal
13 from signal import signal, SIGINT
13 from signal import signal, SIGINT
14 from IPython.utils.genutils import Term,warn,error,flag_calls, ask_yes_no
14 from IPython.utils.genutils import Term,warn,error,flag_calls, ask_yes_no
15 import shellglobals
15 import shellglobals
16
16
17 def install_gtk2():
17 def install_gtk2():
18 """ Install gtk2 reactor, needs to be called bef """
18 """ Install gtk2 reactor, needs to be called bef """
19 from twisted.internet import gtk2reactor
19 from twisted.internet import gtk2reactor
20 gtk2reactor.install()
20 gtk2reactor.install()
21
21
22
22
23 def hijack_reactor():
23 def hijack_reactor():
24 """Modifies Twisted's reactor with a dummy so user code does
24 """Modifies Twisted's reactor with a dummy so user code does
25 not block IPython. This function returns the original
25 not block IPython. This function returns the original
26 'twisted.internet.reactor' that has been hijacked.
26 'twisted.internet.reactor' that has been hijacked.
27
27
28 NOTE: Make sure you call this *AFTER* you've installed
28 NOTE: Make sure you call this *AFTER* you've installed
29 the reactor of your choice.
29 the reactor of your choice.
30 """
30 """
31 from twisted import internet
31 from twisted import internet
32 orig_reactor = internet.reactor
32 orig_reactor = internet.reactor
33
33
34 class DummyReactor(object):
34 class DummyReactor(object):
35 def run(self):
35 def run(self):
36 pass
36 pass
37 def __getattr__(self, name):
37 def __getattr__(self, name):
38 return getattr(orig_reactor, name)
38 return getattr(orig_reactor, name)
39 def __setattr__(self, name, value):
39 def __setattr__(self, name, value):
40 return setattr(orig_reactor, name, value)
40 return setattr(orig_reactor, name, value)
41
41
42 internet.reactor = DummyReactor()
42 internet.reactor = DummyReactor()
43 return orig_reactor
43 return orig_reactor
44
44
45 class TwistedInteractiveShell(InteractiveShell):
45 class TwistedInteractiveShell(InteractiveShell):
46 """Simple multi-threaded shell."""
46 """Simple multi-threaded shell."""
47
47
48 # Threading strategy taken from:
48 # Threading strategy taken from:
49 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65109, by Brian
49 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65109, by Brian
50 # McErlean and John Finlay. Modified with corrections by Antoon Pardon,
50 # McErlean and John Finlay. Modified with corrections by Antoon Pardon,
51 # from the pygtk mailing list, to avoid lockups with system calls.
51 # from the pygtk mailing list, to avoid lockups with system calls.
52
52
53 # class attribute to indicate whether the class supports threads or not.
53 # class attribute to indicate whether the class supports threads or not.
54 # Subclasses with thread support should override this as needed.
54 # Subclasses with thread support should override this as needed.
55 isthreaded = True
55 isthreaded = True
56
56
57 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
57 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
58 user_ns=None,user_global_ns=None,banner2='',**kw):
58 user_ns=None,user_global_ns=None,banner2='',**kw):
59 """Similar to the normal InteractiveShell, but with threading control"""
59 """Similar to the normal InteractiveShell, but with threading control"""
60
60
61 InteractiveShell.__init__(self,name,usage,rc,user_ns,
61 InteractiveShell.__init__(self,name,usage,rc,user_ns,
62 user_global_ns,banner2)
62 user_global_ns,banner2)
63
63
64
64
65 # A queue to hold the code to be executed.
65 # A queue to hold the code to be executed.
66 self.code_queue = Queue.Queue()
66 self.code_queue = Queue.Queue()
67
67
68 # Stuff to do at closing time
68 # Stuff to do at closing time
69 self._kill = None
69 self._kill = None
70 on_kill = kw.get('on_kill', [])
70 on_kill = kw.get('on_kill', [])
71 # Check that all things to kill are callable:
71 # Check that all things to kill are callable:
72 for t in on_kill:
72 for t in on_kill:
73 if not callable(t):
73 if not callable(t):
74 raise TypeError,'on_kill must be a list of callables'
74 raise TypeError,'on_kill must be a list of callables'
75 self.on_kill = on_kill
75 self.on_kill = on_kill
76 # thread identity of the "worker thread" (that may execute code directly)
76 # thread identity of the "worker thread" (that may execute code directly)
77 self.worker_ident = None
77 self.worker_ident = None
78 self.reactor_started = False
78 self.reactor_started = False
79 self.first_run = True
79 self.first_run = True
80
80
81 def runsource(self, source, filename="<input>", symbol="single"):
81 def runsource(self, source, filename="<input>", symbol="single"):
82 """Compile and run some source in the interpreter.
82 """Compile and run some source in the interpreter.
83
83
84 Modified version of code.py's runsource(), to handle threading issues.
84 Modified version of code.py's runsource(), to handle threading issues.
85 See the original for full docstring details."""
85 See the original for full docstring details."""
86
86
87 # If Ctrl-C was typed, we reset the flag and return right away
87 # If Ctrl-C was typed, we reset the flag and return right away
88 if shellglobals.KBINT:
88 if shellglobals.KBINT:
89 shellglobals.KBINT = False
89 shellglobals.KBINT = False
90 return False
90 return False
91
91
92 if self._kill:
92 if self._kill:
93 # can't queue new code if we are being killed
93 # can't queue new code if we are being killed
94 return True
94 return True
95
95
96 try:
96 try:
97 code = self.compile(source, filename, symbol)
97 code = self.compile(source, filename, symbol)
98 except (OverflowError, SyntaxError, ValueError):
98 except (OverflowError, SyntaxError, ValueError):
99 # Case 1
99 # Case 1
100 self.showsyntaxerror(filename)
100 self.showsyntaxerror(filename)
101 return False
101 return False
102
102
103 if code is None:
103 if code is None:
104 # Case 2
104 # Case 2
105 return True
105 return True
106
106
107 # shortcut - if we are in worker thread, or the worker thread is not running,
107 # shortcut - if we are in worker thread, or the worker thread is not running,
108 # execute directly (to allow recursion and prevent deadlock if code is run early
108 # execute directly (to allow recursion and prevent deadlock if code is run early
109 # in IPython construction)
109 # in IPython construction)
110
110
111 if (not self.reactor_started or (self.worker_ident is None and not self.first_run)
111 if (not self.reactor_started or (self.worker_ident is None and not self.first_run)
112 or self.worker_ident == thread.get_ident() or shellglobals.run_in_frontend(source)):
112 or self.worker_ident == thread.get_ident() or shellglobals.run_in_frontend(source)):
113 InteractiveShell.runcode(self,code)
113 InteractiveShell.runcode(self,code)
114 return
114 return
115
115
116 # Case 3
116 # Case 3
117 # Store code in queue, so the execution thread can handle it.
117 # Store code in queue, so the execution thread can handle it.
118
118
119 self.first_run = False
119 self.first_run = False
120 completed_ev, received_ev = threading.Event(), threading.Event()
120 completed_ev, received_ev = threading.Event(), threading.Event()
121
121
122 self.code_queue.put((code,completed_ev, received_ev))
122 self.code_queue.put((code,completed_ev, received_ev))
123
123
124 reactor.callLater(0.0,self.runcode)
124 reactor.callLater(0.0,self.runcode)
125 received_ev.wait(5)
125 received_ev.wait(5)
126 if not received_ev.isSet():
126 if not received_ev.isSet():
127 # the mainloop is dead, start executing code directly
127 # the mainloop is dead, start executing code directly
128 print "Warning: Timeout for mainloop thread exceeded"
128 print "Warning: Timeout for mainloop thread exceeded"
129 print "switching to nonthreaded mode (until mainloop wakes up again)"
129 print "switching to nonthreaded mode (until mainloop wakes up again)"
130 self.worker_ident = None
130 self.worker_ident = None
131 else:
131 else:
132 completed_ev.wait()
132 completed_ev.wait()
133
133
134 return False
134 return False
135
135
136 def runcode(self):
136 def runcode(self):
137 """Execute a code object.
137 """Execute a code object.
138
138
139 Multithreaded wrapper around IPython's runcode()."""
139 Multithreaded wrapper around IPython's runcode()."""
140
140
141
141
142 # we are in worker thread, stash out the id for runsource()
142 # we are in worker thread, stash out the id for runsource()
143 self.worker_ident = thread.get_ident()
143 self.worker_ident = thread.get_ident()
144
144
145 if self._kill:
145 if self._kill:
146 print >>Term.cout, 'Closing threads...',
146 print >>Term.cout, 'Closing threads...',
147 Term.cout.flush()
147 Term.cout.flush()
148 for tokill in self.on_kill:
148 for tokill in self.on_kill:
149 tokill()
149 tokill()
150 print >>Term.cout, 'Done.'
150 print >>Term.cout, 'Done.'
151 # allow kill() to return
151 # allow kill() to return
152 self._kill.set()
152 self._kill.set()
153 return True
153 return True
154
154
155 # Install SIGINT handler. We do it every time to ensure that if user
155 # Install SIGINT handler. We do it every time to ensure that if user
156 # code modifies it, we restore our own handling.
156 # code modifies it, we restore our own handling.
157 try:
157 try:
158 pass
158 pass
159 signal(SIGINT,shellglobals.sigint_handler)
159 signal(SIGINT,shellglobals.sigint_handler)
160 except SystemError:
160 except SystemError:
161 # This happens under Windows, which seems to have all sorts
161 # This happens under Windows, which seems to have all sorts
162 # of problems with signal handling. Oh well...
162 # of problems with signal handling. Oh well...
163 pass
163 pass
164
164
165 # Flush queue of pending code by calling the run methood of the parent
165 # Flush queue of pending code by calling the run methood of the parent
166 # class with all items which may be in the queue.
166 # class with all items which may be in the queue.
167 code_to_run = None
167 code_to_run = None
168 while 1:
168 while 1:
169 try:
169 try:
170 code_to_run, completed_ev, received_ev = self.code_queue.get_nowait()
170 code_to_run, completed_ev, received_ev = self.code_queue.get_nowait()
171 except Queue.Empty:
171 except Queue.Empty:
172 break
172 break
173 received_ev.set()
173 received_ev.set()
174
174
175
175
176 # Exceptions need to be raised differently depending on which
176 # Exceptions need to be raised differently depending on which
177 # thread is active. This convoluted try/except is only there to
177 # thread is active. This convoluted try/except is only there to
178 # protect against asynchronous exceptions, to ensure that a shellglobals.KBINT
178 # protect against asynchronous exceptions, to ensure that a shellglobals.KBINT
179 # at the wrong time doesn't deadlock everything. The global
179 # at the wrong time doesn't deadlock everything. The global
180 # CODE_TO_RUN is set to true/false as close as possible to the
180 # CODE_TO_RUN is set to true/false as close as possible to the
181 # runcode() call, so that the KBINT handler is correctly informed.
181 # runcode() call, so that the KBINT handler is correctly informed.
182 try:
182 try:
183 try:
183 try:
184 shellglobals.CODE_RUN = True
184 shellglobals.CODE_RUN = True
185 InteractiveShell.runcode(self,code_to_run)
185 InteractiveShell.runcode(self,code_to_run)
186 except KeyboardInterrupt:
186 except KeyboardInterrupt:
187 print "Keyboard interrupted in mainloop"
187 print "Keyboard interrupted in mainloop"
188 while not self.code_queue.empty():
188 while not self.code_queue.empty():
189 code = self.code_queue.get_nowait()
189 code = self.code_queue.get_nowait()
190 break
190 break
191 finally:
191 finally:
192 shellglobals.CODE_RUN = False
192 shellglobals.CODE_RUN = False
193 # allow runsource() return from wait
193 # allow runsource() return from wait
194 completed_ev.set()
194 completed_ev.set()
195
195
196 # This MUST return true for gtk threading to work
196 # This MUST return true for gtk threading to work
197 return True
197 return True
198
198
199 def kill(self):
199 def kill(self):
200 """Kill the thread, returning when it has been shut down."""
200 """Kill the thread, returning when it has been shut down."""
201 self._kill = threading.Event()
201 self._kill = threading.Event()
202 reactor.callLater(0.0,self.runcode)
202 reactor.callLater(0.0,self.runcode)
203 self._kill.wait()
203 self._kill.wait()
204
204
205
205
206
206
207 class IPShellTwisted:
207 class IPShellTwisted:
208 """Run a Twisted reactor while in an IPython session.
208 """Run a Twisted reactor while in an IPython session.
209
209
210 Python commands can be passed to the thread where they will be
210 Python commands can be passed to the thread where they will be
211 executed. This is implemented by periodically checking for
211 executed. This is implemented by periodically checking for
212 passed code using a Twisted reactor callback.
212 passed code using a Twisted reactor callback.
213 """
213 """
214
214
215 TIMEOUT = 0.01 # Millisecond interval between reactor runs.
215 TIMEOUT = 0.01 # Millisecond interval between reactor runs.
216
216
217 def __init__(self, argv=None, user_ns=None, debug=1,
217 def __init__(self, argv=None, user_ns=None, debug=1,
218 shell_class=TwistedInteractiveShell):
218 shell_class=TwistedInteractiveShell):
219
219
220 from twisted.internet import reactor
220 from twisted.internet import reactor
221 self.reactor = hijack_reactor()
221 self.reactor = hijack_reactor()
222
222
223 mainquit = self.reactor.stop
223 mainquit = self.reactor.stop
224
224
225 # Make sure IPython keeps going after reactor stop.
225 # Make sure IPython keeps going after reactor stop.
226 def reactorstop():
226 def reactorstop():
227 pass
227 pass
228 self.reactor.stop = reactorstop
228 self.reactor.stop = reactorstop
229 reactorrun_orig = self.reactor.run
229 reactorrun_orig = self.reactor.run
230 self.quitting = False
230 self.quitting = False
231 def reactorrun():
231 def reactorrun():
232 while True and not self.quitting:
232 while True and not self.quitting:
233 reactorrun_orig()
233 reactorrun_orig()
234 self.reactor.run = reactorrun
234 self.reactor.run = reactorrun
235
235
236 self.IP = make_IPython(argv, user_ns=user_ns, debug=debug,
236 self.IP = make_IPython(argv, user_ns=user_ns, debug=debug,
237 shell_class=shell_class,
237 shell_class=shell_class,
238 on_kill=[mainquit])
238 on_kill=[mainquit])
239
239
240 # threading.Thread.__init__(self)
240 # threading.Thread.__init__(self)
241
241
242 def run(self):
242 def run(self):
243 self.IP.mainloop()
243 self.IP.mainloop()
244 self.quitting = True
244 self.quitting = True
245 self.IP.kill()
245 self.IP.kill()
246
246
247 def mainloop(self):
247 def mainloop(self):
248 def mainLoopThreadDeath(r):
248 def mainLoopThreadDeath(r):
249 print "mainLoopThreadDeath: ", str(r)
249 print "mainLoopThreadDeath: ", str(r)
250 def spawnMainloopThread():
250 def spawnMainloopThread():
251 d=threads.deferToThread(self.run)
251 d=threads.deferToThread(self.run)
252 d.addBoth(mainLoopThreadDeath)
252 d.addBoth(mainLoopThreadDeath)
253 reactor.callWhenRunning(spawnMainloopThread)
253 reactor.callWhenRunning(spawnMainloopThread)
254 self.IP.reactor_started = True
254 self.IP.reactor_started = True
255 self.reactor.run()
255 self.reactor.run()
256 print "mainloop ending...."
256 print "mainloop ending...."
257
257
258 exists = True
258 exists = True
259
259
260
260
261 if __name__ == '__main__':
261 if __name__ == '__main__':
262 # Sample usage.
262 # Sample usage.
263
263
264 # Create the shell object. This steals twisted.internet.reactor
264 # Create the shell object. This steals twisted.internet.reactor
265 # for its own purposes, to make sure you've already installed a
265 # for its own purposes, to make sure you've already installed a
266 # reactor of your choice.
266 # reactor of your choice.
267 shell = IPShellTwisted(
267 shell = IPShellTwisted(
268 argv=[],
268 argv=[],
269 user_ns={'__name__': '__example__',
269 user_ns={'__name__': '__example__',
270 'hello': 'world',
270 'hello': 'world',
271 },
271 },
272 )
272 )
273
273
274 # Run the mainloop. This runs the actual reactor.run() method.
274 # Run the mainloop. This runs the actual reactor.run() method.
275 # The twisted.internet.reactor object at this point is a dummy
275 # The twisted.internet.reactor object at this point is a dummy
276 # object that passes through to the actual reactor, but prevents
276 # object that passes through to the actual reactor, but prevents
277 # run() from being called on it again.
277 # run() from being called on it again.
278 shell.mainloop()
278 shell.mainloop()
279
279
280 # You must exit IPython to terminate your program.
280 # You must exit IPython to terminate your program.
281 print 'Goodbye!'
281 print 'Goodbye!'
282
282
@@ -1,285 +1,285 b''
1 """
1 """
2 Frontend class that uses IPython0 to prefilter the inputs.
2 Frontend class that uses IPython0 to prefilter the inputs.
3
3
4 Using the IPython0 mechanism gives us access to the magics.
4 Using the IPython0 mechanism gives us access to the magics.
5
5
6 This is a transitory class, used here to do the transition between
6 This is a transitory class, used here to do the transition between
7 ipython0 and ipython1. This class is meant to be short-lived as more
7 ipython0 and ipython1. This class is meant to be short-lived as more
8 functionnality is abstracted out of ipython0 in reusable functions and
8 functionnality is abstracted out of ipython0 in reusable functions and
9 is added on the interpreter. This class can be a used to guide this
9 is added on the interpreter. This class can be a used to guide this
10 refactoring.
10 refactoring.
11 """
11 """
12 __docformat__ = "restructuredtext en"
12 __docformat__ = "restructuredtext en"
13
13
14 #-------------------------------------------------------------------------------
14 #-------------------------------------------------------------------------------
15 # Copyright (C) 2008 The IPython Development Team
15 # Copyright (C) 2008 The IPython Development Team
16 #
16 #
17 # Distributed under the terms of the BSD License. The full license is in
17 # Distributed under the terms of the BSD License. The full license is in
18 # the file COPYING, distributed as part of this software.
18 # the file COPYING, distributed as part of this software.
19 #-------------------------------------------------------------------------------
19 #-------------------------------------------------------------------------------
20
20
21 #-------------------------------------------------------------------------------
21 #-------------------------------------------------------------------------------
22 # Imports
22 # Imports
23 #-------------------------------------------------------------------------------
23 #-------------------------------------------------------------------------------
24 import sys
24 import sys
25 import pydoc
25 import pydoc
26 import os
26 import os
27 import re
27 import re
28 import __builtin__
28 import __builtin__
29
29
30 from IPython.ipmaker import make_IPython
30 from IPython.ipmaker import make_IPython
31 from IPython.core.ipapi import IPApi
31 from IPython.core.ipapi import IPApi
32 from IPython.kernel.core.redirector_output_trap import RedirectorOutputTrap
32 from IPython.kernel.core.redirector_output_trap import RedirectorOutputTrap
33
33
34 from IPython.kernel.core.sync_traceback_trap import SyncTracebackTrap
34 from IPython.kernel.core.sync_traceback_trap import SyncTracebackTrap
35
35
36 from IPython.utils.genutils import Term
36 from IPython.utils.genutils import Term
37
37
38 from linefrontendbase import LineFrontEndBase, common_prefix
38 from linefrontendbase import LineFrontEndBase, common_prefix
39
39
40
40
41 def mk_system_call(system_call_function, command):
41 def mk_system_call(system_call_function, command):
42 """ given a os.system replacement, and a leading string command,
42 """ given a os.system replacement, and a leading string command,
43 returns a function that will execute the command with the given
43 returns a function that will execute the command with the given
44 argument string.
44 argument string.
45 """
45 """
46 def my_system_call(args):
46 def my_system_call(args):
47 system_call_function("%s %s" % (command, args))
47 system_call_function("%s %s" % (command, args))
48
48
49 my_system_call.__doc__ = "Calls %s" % command
49 my_system_call.__doc__ = "Calls %s" % command
50 return my_system_call
50 return my_system_call
51
51
52 #-------------------------------------------------------------------------------
52 #-------------------------------------------------------------------------------
53 # Frontend class using ipython0 to do the prefiltering.
53 # Frontend class using ipython0 to do the prefiltering.
54 #-------------------------------------------------------------------------------
54 #-------------------------------------------------------------------------------
55 class PrefilterFrontEnd(LineFrontEndBase):
55 class PrefilterFrontEnd(LineFrontEndBase):
56 """ Class that uses ipython0 to do prefilter the input, do the
56 """ Class that uses ipython0 to do prefilter the input, do the
57 completion and the magics.
57 completion and the magics.
58
58
59 The core trick is to use an ipython0 instance to prefilter the
59 The core trick is to use an ipython0 instance to prefilter the
60 input, and share the namespace between the interpreter instance used
60 input, and share the namespace between the interpreter instance used
61 to execute the statements and the ipython0 used for code
61 to execute the statements and the ipython0 used for code
62 completion...
62 completion...
63 """
63 """
64
64
65 debug = False
65 debug = False
66
66
67 def __init__(self, ipython0=None, argv=None, *args, **kwargs):
67 def __init__(self, ipython0=None, argv=None, *args, **kwargs):
68 """ Parameters:
68 """ Parameters:
69 -----------
69 -----------
70
70
71 ipython0: an optional ipython0 instance to use for command
71 ipython0: an optional ipython0 instance to use for command
72 prefiltering and completion.
72 prefiltering and completion.
73
73
74 argv : list, optional
74 argv : list, optional
75 Used as the instance's argv value. If not given, [] is used.
75 Used as the instance's argv value. If not given, [] is used.
76 """
76 """
77 if argv is None:
77 if argv is None:
78 argv = []
78 argv = []
79 # This is a hack to avoid the IPython exception hook to trigger
79 # This is a hack to avoid the IPython exception hook to trigger
80 # on exceptions (https://bugs.launchpad.net/bugs/337105)
80 # on exceptions (https://bugs.launchpad.net/bugs/337105)
81 # XXX: This is horrible: module-leve monkey patching -> side
81 # XXX: This is horrible: module-leve monkey patching -> side
82 # effects.
82 # effects.
83 from IPython import iplib
83 from IPython.core import iplib
84 iplib.InteractiveShell.isthreaded = True
84 iplib.InteractiveShell.isthreaded = True
85
85
86 LineFrontEndBase.__init__(self, *args, **kwargs)
86 LineFrontEndBase.__init__(self, *args, **kwargs)
87 self.shell.output_trap = RedirectorOutputTrap(
87 self.shell.output_trap = RedirectorOutputTrap(
88 out_callback=self.write,
88 out_callback=self.write,
89 err_callback=self.write,
89 err_callback=self.write,
90 )
90 )
91 self.shell.traceback_trap = SyncTracebackTrap(
91 self.shell.traceback_trap = SyncTracebackTrap(
92 formatters=self.shell.traceback_trap.formatters,
92 formatters=self.shell.traceback_trap.formatters,
93 )
93 )
94
94
95 # Start the ipython0 instance:
95 # Start the ipython0 instance:
96 self.save_output_hooks()
96 self.save_output_hooks()
97 if ipython0 is None:
97 if ipython0 is None:
98 # Instanciate an IPython0 interpreter to be able to use the
98 # Instanciate an IPython0 interpreter to be able to use the
99 # prefiltering.
99 # prefiltering.
100 # Suppress all key input, to avoid waiting
100 # Suppress all key input, to avoid waiting
101 def my_rawinput(x=None):
101 def my_rawinput(x=None):
102 return '\n'
102 return '\n'
103 old_rawinput = __builtin__.raw_input
103 old_rawinput = __builtin__.raw_input
104 __builtin__.raw_input = my_rawinput
104 __builtin__.raw_input = my_rawinput
105 # XXX: argv=[] is a bit bold.
105 # XXX: argv=[] is a bit bold.
106 ipython0 = make_IPython(argv=argv,
106 ipython0 = make_IPython(argv=argv,
107 user_ns=self.shell.user_ns,
107 user_ns=self.shell.user_ns,
108 user_global_ns=self.shell.user_global_ns)
108 user_global_ns=self.shell.user_global_ns)
109 __builtin__.raw_input = old_rawinput
109 __builtin__.raw_input = old_rawinput
110 self.ipython0 = ipython0
110 self.ipython0 = ipython0
111 # Set the pager:
111 # Set the pager:
112 self.ipython0.set_hook('show_in_pager',
112 self.ipython0.set_hook('show_in_pager',
113 lambda s, string: self.write("\n" + string))
113 lambda s, string: self.write("\n" + string))
114 self.ipython0.write = self.write
114 self.ipython0.write = self.write
115 self._ip = _ip = IPApi(self.ipython0)
115 self._ip = _ip = IPApi(self.ipython0)
116 # Make sure the raw system call doesn't get called, as we don't
116 # Make sure the raw system call doesn't get called, as we don't
117 # have a stdin accessible.
117 # have a stdin accessible.
118 self._ip.system = self.system_call
118 self._ip.system = self.system_call
119 # XXX: Muck around with magics so that they work better
119 # XXX: Muck around with magics so that they work better
120 # in our environment
120 # in our environment
121 if not sys.platform.startswith('win'):
121 if not sys.platform.startswith('win'):
122 self.ipython0.magic_ls = mk_system_call(self.system_call,
122 self.ipython0.magic_ls = mk_system_call(self.system_call,
123 'ls -CF')
123 'ls -CF')
124 # And now clean up the mess created by ipython0
124 # And now clean up the mess created by ipython0
125 self.release_output()
125 self.release_output()
126
126
127
127
128 if not 'banner' in kwargs and self.banner is None:
128 if not 'banner' in kwargs and self.banner is None:
129 self.banner = self.ipython0.BANNER
129 self.banner = self.ipython0.BANNER
130
130
131 # FIXME: __init__ and start should be two different steps
131 # FIXME: __init__ and start should be two different steps
132 self.start()
132 self.start()
133
133
134 #--------------------------------------------------------------------------
134 #--------------------------------------------------------------------------
135 # FrontEndBase interface
135 # FrontEndBase interface
136 #--------------------------------------------------------------------------
136 #--------------------------------------------------------------------------
137
137
138 def show_traceback(self):
138 def show_traceback(self):
139 """ Use ipython0 to capture the last traceback and display it.
139 """ Use ipython0 to capture the last traceback and display it.
140 """
140 """
141 # Don't do the capture; the except_hook has already done some
141 # Don't do the capture; the except_hook has already done some
142 # modifications to the IO streams, if we store them, we'll be
142 # modifications to the IO streams, if we store them, we'll be
143 # storing the wrong ones.
143 # storing the wrong ones.
144 #self.capture_output()
144 #self.capture_output()
145 self.ipython0.showtraceback(tb_offset=-1)
145 self.ipython0.showtraceback(tb_offset=-1)
146 self.release_output()
146 self.release_output()
147
147
148
148
149 def execute(self, python_string, raw_string=None):
149 def execute(self, python_string, raw_string=None):
150 if self.debug:
150 if self.debug:
151 print 'Executing Python code:', repr(python_string)
151 print 'Executing Python code:', repr(python_string)
152 self.capture_output()
152 self.capture_output()
153 LineFrontEndBase.execute(self, python_string,
153 LineFrontEndBase.execute(self, python_string,
154 raw_string=raw_string)
154 raw_string=raw_string)
155 self.release_output()
155 self.release_output()
156
156
157
157
158 def save_output_hooks(self):
158 def save_output_hooks(self):
159 """ Store all the output hooks we can think of, to be able to
159 """ Store all the output hooks we can think of, to be able to
160 restore them.
160 restore them.
161
161
162 We need to do this early, as starting the ipython0 instance will
162 We need to do this early, as starting the ipython0 instance will
163 screw ouput hooks.
163 screw ouput hooks.
164 """
164 """
165 self.__old_cout_write = Term.cout.write
165 self.__old_cout_write = Term.cout.write
166 self.__old_cerr_write = Term.cerr.write
166 self.__old_cerr_write = Term.cerr.write
167 self.__old_stdout = sys.stdout
167 self.__old_stdout = sys.stdout
168 self.__old_stderr= sys.stderr
168 self.__old_stderr= sys.stderr
169 self.__old_help_output = pydoc.help.output
169 self.__old_help_output = pydoc.help.output
170 self.__old_display_hook = sys.displayhook
170 self.__old_display_hook = sys.displayhook
171
171
172
172
173 def capture_output(self):
173 def capture_output(self):
174 """ Capture all the output mechanisms we can think of.
174 """ Capture all the output mechanisms we can think of.
175 """
175 """
176 self.save_output_hooks()
176 self.save_output_hooks()
177 Term.cout.write = self.write
177 Term.cout.write = self.write
178 Term.cerr.write = self.write
178 Term.cerr.write = self.write
179 sys.stdout = Term.cout
179 sys.stdout = Term.cout
180 sys.stderr = Term.cerr
180 sys.stderr = Term.cerr
181 pydoc.help.output = self.shell.output_trap.out
181 pydoc.help.output = self.shell.output_trap.out
182
182
183
183
184 def release_output(self):
184 def release_output(self):
185 """ Release all the different captures we have made.
185 """ Release all the different captures we have made.
186 """
186 """
187 Term.cout.write = self.__old_cout_write
187 Term.cout.write = self.__old_cout_write
188 Term.cerr.write = self.__old_cerr_write
188 Term.cerr.write = self.__old_cerr_write
189 sys.stdout = self.__old_stdout
189 sys.stdout = self.__old_stdout
190 sys.stderr = self.__old_stderr
190 sys.stderr = self.__old_stderr
191 pydoc.help.output = self.__old_help_output
191 pydoc.help.output = self.__old_help_output
192 sys.displayhook = self.__old_display_hook
192 sys.displayhook = self.__old_display_hook
193
193
194
194
195 def complete(self, line):
195 def complete(self, line):
196 # FIXME: This should be factored out in the linefrontendbase
196 # FIXME: This should be factored out in the linefrontendbase
197 # method.
197 # method.
198 word = self._get_completion_text(line)
198 word = self._get_completion_text(line)
199 completions = self.ipython0.complete(word)
199 completions = self.ipython0.complete(word)
200 # FIXME: The proper sort should be done in the complete method.
200 # FIXME: The proper sort should be done in the complete method.
201 key = lambda x: x.replace('_', '')
201 key = lambda x: x.replace('_', '')
202 completions.sort(key=key)
202 completions.sort(key=key)
203 if completions:
203 if completions:
204 prefix = common_prefix(completions)
204 prefix = common_prefix(completions)
205 line = line[:-len(word)] + prefix
205 line = line[:-len(word)] + prefix
206 return line, completions
206 return line, completions
207
207
208
208
209 #--------------------------------------------------------------------------
209 #--------------------------------------------------------------------------
210 # LineFrontEndBase interface
210 # LineFrontEndBase interface
211 #--------------------------------------------------------------------------
211 #--------------------------------------------------------------------------
212
212
213 def prefilter_input(self, input_string):
213 def prefilter_input(self, input_string):
214 """ Using IPython0 to prefilter the commands to turn them
214 """ Using IPython0 to prefilter the commands to turn them
215 in executable statements that are valid Python strings.
215 in executable statements that are valid Python strings.
216 """
216 """
217 input_string = LineFrontEndBase.prefilter_input(self, input_string)
217 input_string = LineFrontEndBase.prefilter_input(self, input_string)
218 filtered_lines = []
218 filtered_lines = []
219 # The IPython0 prefilters sometime produce output. We need to
219 # The IPython0 prefilters sometime produce output. We need to
220 # capture it.
220 # capture it.
221 self.capture_output()
221 self.capture_output()
222 self.last_result = dict(number=self.prompt_number)
222 self.last_result = dict(number=self.prompt_number)
223
223
224 ## try:
224 ## try:
225 ## for line in input_string.split('\n'):
225 ## for line in input_string.split('\n'):
226 ## filtered_lines.append(
226 ## filtered_lines.append(
227 ## self.ipython0.prefilter(line, False).rstrip())
227 ## self.ipython0.prefilter(line, False).rstrip())
228 ## except:
228 ## except:
229 ## # XXX: probably not the right thing to do.
229 ## # XXX: probably not the right thing to do.
230 ## self.ipython0.showsyntaxerror()
230 ## self.ipython0.showsyntaxerror()
231 ## self.after_execute()
231 ## self.after_execute()
232 ## finally:
232 ## finally:
233 ## self.release_output()
233 ## self.release_output()
234
234
235
235
236 try:
236 try:
237 try:
237 try:
238 for line in input_string.split('\n'):
238 for line in input_string.split('\n'):
239 filtered_lines.append(
239 filtered_lines.append(
240 self.ipython0.prefilter(line, False).rstrip())
240 self.ipython0.prefilter(line, False).rstrip())
241 except:
241 except:
242 # XXX: probably not the right thing to do.
242 # XXX: probably not the right thing to do.
243 self.ipython0.showsyntaxerror()
243 self.ipython0.showsyntaxerror()
244 self.after_execute()
244 self.after_execute()
245 finally:
245 finally:
246 self.release_output()
246 self.release_output()
247
247
248
248
249
249
250 # Clean up the trailing whitespace, to avoid indentation errors
250 # Clean up the trailing whitespace, to avoid indentation errors
251 filtered_string = '\n'.join(filtered_lines)
251 filtered_string = '\n'.join(filtered_lines)
252 return filtered_string
252 return filtered_string
253
253
254
254
255 #--------------------------------------------------------------------------
255 #--------------------------------------------------------------------------
256 # PrefilterFrontEnd interface
256 # PrefilterFrontEnd interface
257 #--------------------------------------------------------------------------
257 #--------------------------------------------------------------------------
258
258
259 def system_call(self, command_string):
259 def system_call(self, command_string):
260 """ Allows for frontend to define their own system call, to be
260 """ Allows for frontend to define their own system call, to be
261 able capture output and redirect input.
261 able capture output and redirect input.
262 """
262 """
263 return os.system(command_string)
263 return os.system(command_string)
264
264
265
265
266 def do_exit(self):
266 def do_exit(self):
267 """ Exit the shell, cleanup and save the history.
267 """ Exit the shell, cleanup and save the history.
268 """
268 """
269 self.ipython0.atexit_operations()
269 self.ipython0.atexit_operations()
270
270
271
271
272 def _get_completion_text(self, line):
272 def _get_completion_text(self, line):
273 """ Returns the text to be completed by breaking the line at specified
273 """ Returns the text to be completed by breaking the line at specified
274 delimiters.
274 delimiters.
275 """
275 """
276 # Break at: spaces, '=', all parentheses (except if balanced).
276 # Break at: spaces, '=', all parentheses (except if balanced).
277 # FIXME2: In the future, we need to make the implementation similar to
277 # FIXME2: In the future, we need to make the implementation similar to
278 # that in the 'pyreadline' module (modes/basemode.py) where we break at
278 # that in the 'pyreadline' module (modes/basemode.py) where we break at
279 # each delimiter and try to complete the residual line, until we get a
279 # each delimiter and try to complete the residual line, until we get a
280 # successful list of completions.
280 # successful list of completions.
281 expression = '\s|=|,|:|\((?!.*\))|\[(?!.*\])|\{(?!.*\})'
281 expression = '\s|=|,|:|\((?!.*\))|\[(?!.*\])|\{(?!.*\})'
282 complete_sep = re.compile(expression)
282 complete_sep = re.compile(expression)
283 text = complete_sep.split(line)[-1]
283 text = complete_sep.split(line)[-1]
284 return text
284 return text
285
285
@@ -1,252 +1,252 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 Test process execution and IO redirection.
3 Test process execution and IO redirection.
4 """
4 """
5
5
6 __docformat__ = "restructuredtext en"
6 __docformat__ = "restructuredtext en"
7
7
8 #-------------------------------------------------------------------------------
8 #-------------------------------------------------------------------------------
9 # Copyright (C) 2008 The IPython Development Team
9 # Copyright (C) 2008 The IPython Development Team
10 #
10 #
11 # Distributed under the terms of the BSD License. The full license is
11 # Distributed under the terms of the BSD License. The full license is
12 # in the file COPYING, distributed as part of this software.
12 # in the file COPYING, distributed as part of this software.
13 #-------------------------------------------------------------------------------
13 #-------------------------------------------------------------------------------
14
14
15 from copy import copy, deepcopy
15 from copy import copy, deepcopy
16 from cStringIO import StringIO
16 from cStringIO import StringIO
17 import string
17 import string
18
18
19 from nose.tools import assert_equal
19 from nose.tools import assert_equal
20
20
21 from IPython.frontend.prefilterfrontend import PrefilterFrontEnd
21 from IPython.frontend.prefilterfrontend import PrefilterFrontEnd
22 from IPython.core.ipapi import get as get_ipython0
22 from IPython.core.ipapi import get as get_ipython0
23 from IPython.testing.plugin.ipdoctest import default_argv
23 from IPython.testing.plugin.ipdoctest import default_argv
24
24
25
25
26 def safe_deepcopy(d):
26 def safe_deepcopy(d):
27 """ Deep copy every key of the given dict, when possible. Elsewhere
27 """ Deep copy every key of the given dict, when possible. Elsewhere
28 do a copy.
28 do a copy.
29 """
29 """
30 copied_d = dict()
30 copied_d = dict()
31 for key, value in d.iteritems():
31 for key, value in d.iteritems():
32 try:
32 try:
33 copied_d[key] = deepcopy(value)
33 copied_d[key] = deepcopy(value)
34 except:
34 except:
35 try:
35 try:
36 copied_d[key] = copy(value)
36 copied_d[key] = copy(value)
37 except:
37 except:
38 copied_d[key] = value
38 copied_d[key] = value
39 return copied_d
39 return copied_d
40
40
41
41
42 class TestPrefilterFrontEnd(PrefilterFrontEnd):
42 class TestPrefilterFrontEnd(PrefilterFrontEnd):
43
43
44 input_prompt_template = string.Template('')
44 input_prompt_template = string.Template('')
45 output_prompt_template = string.Template('')
45 output_prompt_template = string.Template('')
46 banner = ''
46 banner = ''
47
47
48 def __init__(self):
48 def __init__(self):
49 self.out = StringIO()
49 self.out = StringIO()
50 PrefilterFrontEnd.__init__(self,argv=default_argv())
50 PrefilterFrontEnd.__init__(self,argv=default_argv())
51 # Some more code for isolation (yeah, crazy)
51 # Some more code for isolation (yeah, crazy)
52 self._on_enter()
52 self._on_enter()
53 self.out.flush()
53 self.out.flush()
54 self.out.reset()
54 self.out.reset()
55 self.out.truncate()
55 self.out.truncate()
56
56
57 def write(self, string, *args, **kwargs):
57 def write(self, string, *args, **kwargs):
58 self.out.write(string)
58 self.out.write(string)
59
59
60 def _on_enter(self):
60 def _on_enter(self):
61 self.input_buffer += '\n'
61 self.input_buffer += '\n'
62 PrefilterFrontEnd._on_enter(self)
62 PrefilterFrontEnd._on_enter(self)
63
63
64
64
65 def isolate_ipython0(func):
65 def isolate_ipython0(func):
66 """ Decorator to isolate execution that involves an iptyhon0.
66 """ Decorator to isolate execution that involves an iptyhon0.
67
67
68 Notes
68 Notes
69 -----
69 -----
70
70
71 Apply only to functions with no arguments. Nose skips functions
71 Apply only to functions with no arguments. Nose skips functions
72 with arguments.
72 with arguments.
73 """
73 """
74 def my_func():
74 def my_func():
75 iplib = get_ipython0()
75 iplib = get_ipython0()
76 if iplib is None:
76 if iplib is None:
77 return func()
77 return func()
78 ipython0 = iplib.IP
78 ipython0 = iplib.IP
79 global_ns = safe_deepcopy(ipython0.user_global_ns)
79 global_ns = safe_deepcopy(ipython0.user_global_ns)
80 user_ns = safe_deepcopy(ipython0.user_ns)
80 user_ns = safe_deepcopy(ipython0.user_ns)
81 try:
81 try:
82 out = func()
82 out = func()
83 finally:
83 finally:
84 ipython0.user_ns = user_ns
84 ipython0.user_ns = user_ns
85 ipython0.user_global_ns = global_ns
85 ipython0.user_global_ns = global_ns
86 # Undo the hack at creation of PrefilterFrontEnd
86 # Undo the hack at creation of PrefilterFrontEnd
87 from IPython import iplib
87 from IPythoncore. import iplib
88 iplib.InteractiveShell.isthreaded = False
88 iplib.InteractiveShell.isthreaded = False
89 return out
89 return out
90
90
91 my_func.__name__ = func.__name__
91 my_func.__name__ = func.__name__
92 return my_func
92 return my_func
93
93
94
94
95 @isolate_ipython0
95 @isolate_ipython0
96 def test_execution():
96 def test_execution():
97 """ Test execution of a command.
97 """ Test execution of a command.
98 """
98 """
99 f = TestPrefilterFrontEnd()
99 f = TestPrefilterFrontEnd()
100 f.input_buffer = 'print 1'
100 f.input_buffer = 'print 1'
101 f._on_enter()
101 f._on_enter()
102 out_value = f.out.getvalue()
102 out_value = f.out.getvalue()
103 assert_equal(out_value, '1\n')
103 assert_equal(out_value, '1\n')
104
104
105
105
106 @isolate_ipython0
106 @isolate_ipython0
107 def test_multiline():
107 def test_multiline():
108 """ Test execution of a multiline command.
108 """ Test execution of a multiline command.
109 """
109 """
110 f = TestPrefilterFrontEnd()
110 f = TestPrefilterFrontEnd()
111 f.input_buffer = 'if True:'
111 f.input_buffer = 'if True:'
112 f._on_enter()
112 f._on_enter()
113 f.input_buffer += 'print 1'
113 f.input_buffer += 'print 1'
114 f._on_enter()
114 f._on_enter()
115 out_value = f.out.getvalue()
115 out_value = f.out.getvalue()
116 yield assert_equal, out_value, ''
116 yield assert_equal, out_value, ''
117 f._on_enter()
117 f._on_enter()
118 out_value = f.out.getvalue()
118 out_value = f.out.getvalue()
119 yield assert_equal, out_value, '1\n'
119 yield assert_equal, out_value, '1\n'
120 f = TestPrefilterFrontEnd()
120 f = TestPrefilterFrontEnd()
121 f.input_buffer='(1 +'
121 f.input_buffer='(1 +'
122 f._on_enter()
122 f._on_enter()
123 f.input_buffer += '0)'
123 f.input_buffer += '0)'
124 f._on_enter()
124 f._on_enter()
125 out_value = f.out.getvalue()
125 out_value = f.out.getvalue()
126 yield assert_equal, out_value, ''
126 yield assert_equal, out_value, ''
127 f._on_enter()
127 f._on_enter()
128 out_value = f.out.getvalue()
128 out_value = f.out.getvalue()
129 yield assert_equal, out_value, '1\n'
129 yield assert_equal, out_value, '1\n'
130
130
131
131
132 @isolate_ipython0
132 @isolate_ipython0
133 def test_capture():
133 def test_capture():
134 """ Test the capture of output in different channels.
134 """ Test the capture of output in different channels.
135 """
135 """
136 # Test on the OS-level stdout, stderr.
136 # Test on the OS-level stdout, stderr.
137 f = TestPrefilterFrontEnd()
137 f = TestPrefilterFrontEnd()
138 f.input_buffer = \
138 f.input_buffer = \
139 'import os; out=os.fdopen(1, "w"); out.write("1") ; out.flush()'
139 'import os; out=os.fdopen(1, "w"); out.write("1") ; out.flush()'
140 f._on_enter()
140 f._on_enter()
141 out_value = f.out.getvalue()
141 out_value = f.out.getvalue()
142 yield assert_equal, out_value, '1'
142 yield assert_equal, out_value, '1'
143 f = TestPrefilterFrontEnd()
143 f = TestPrefilterFrontEnd()
144 f.input_buffer = \
144 f.input_buffer = \
145 'import os; out=os.fdopen(2, "w"); out.write("1") ; out.flush()'
145 'import os; out=os.fdopen(2, "w"); out.write("1") ; out.flush()'
146 f._on_enter()
146 f._on_enter()
147 out_value = f.out.getvalue()
147 out_value = f.out.getvalue()
148 yield assert_equal, out_value, '1'
148 yield assert_equal, out_value, '1'
149
149
150
150
151 @isolate_ipython0
151 @isolate_ipython0
152 def test_magic():
152 def test_magic():
153 """ Test the magic expansion and history.
153 """ Test the magic expansion and history.
154
154
155 This test is fairly fragile and will break when magics change.
155 This test is fairly fragile and will break when magics change.
156 """
156 """
157 f = TestPrefilterFrontEnd()
157 f = TestPrefilterFrontEnd()
158 # Before checking the interactive namespace, make sure it's clear (it can
158 # Before checking the interactive namespace, make sure it's clear (it can
159 # otherwise pick up things stored in the user's local db)
159 # otherwise pick up things stored in the user's local db)
160 f.input_buffer += '%reset -f'
160 f.input_buffer += '%reset -f'
161 f._on_enter()
161 f._on_enter()
162 f.complete_current_input()
162 f.complete_current_input()
163 # Now, run the %who magic and check output
163 # Now, run the %who magic and check output
164 f.input_buffer += '%who'
164 f.input_buffer += '%who'
165 f._on_enter()
165 f._on_enter()
166 out_value = f.out.getvalue()
166 out_value = f.out.getvalue()
167 assert_equal(out_value, 'Interactive namespace is empty.\n')
167 assert_equal(out_value, 'Interactive namespace is empty.\n')
168
168
169
169
170 @isolate_ipython0
170 @isolate_ipython0
171 def test_help():
171 def test_help():
172 """ Test object inspection.
172 """ Test object inspection.
173 """
173 """
174 f = TestPrefilterFrontEnd()
174 f = TestPrefilterFrontEnd()
175 f.input_buffer += "def f():"
175 f.input_buffer += "def f():"
176 f._on_enter()
176 f._on_enter()
177 f.input_buffer += "'foobar'"
177 f.input_buffer += "'foobar'"
178 f._on_enter()
178 f._on_enter()
179 f.input_buffer += "pass"
179 f.input_buffer += "pass"
180 f._on_enter()
180 f._on_enter()
181 f._on_enter()
181 f._on_enter()
182 f.input_buffer += "f?"
182 f.input_buffer += "f?"
183 f._on_enter()
183 f._on_enter()
184 assert 'traceback' not in f.last_result
184 assert 'traceback' not in f.last_result
185 ## XXX: ipython doctest magic breaks this. I have no clue why
185 ## XXX: ipython doctest magic breaks this. I have no clue why
186 #out_value = f.out.getvalue()
186 #out_value = f.out.getvalue()
187 #assert out_value.split()[-1] == 'foobar'
187 #assert out_value.split()[-1] == 'foobar'
188
188
189
189
190 @isolate_ipython0
190 @isolate_ipython0
191 def test_completion_simple():
191 def test_completion_simple():
192 """ Test command-line completion on trivial examples.
192 """ Test command-line completion on trivial examples.
193 """
193 """
194 f = TestPrefilterFrontEnd()
194 f = TestPrefilterFrontEnd()
195 f.input_buffer = 'zzza = 1'
195 f.input_buffer = 'zzza = 1'
196 f._on_enter()
196 f._on_enter()
197 f.input_buffer = 'zzzb = 2'
197 f.input_buffer = 'zzzb = 2'
198 f._on_enter()
198 f._on_enter()
199 f.input_buffer = 'zz'
199 f.input_buffer = 'zz'
200 f.complete_current_input()
200 f.complete_current_input()
201 out_value = f.out.getvalue()
201 out_value = f.out.getvalue()
202 yield assert_equal, out_value, '\nzzza zzzb '
202 yield assert_equal, out_value, '\nzzza zzzb '
203 yield assert_equal, f.input_buffer, 'zzz'
203 yield assert_equal, f.input_buffer, 'zzz'
204
204
205
205
206 @isolate_ipython0
206 @isolate_ipython0
207 def test_completion_parenthesis():
207 def test_completion_parenthesis():
208 """ Test command-line completion when a parenthesis is open.
208 """ Test command-line completion when a parenthesis is open.
209 """
209 """
210 f = TestPrefilterFrontEnd()
210 f = TestPrefilterFrontEnd()
211 f.input_buffer = 'zzza = 1'
211 f.input_buffer = 'zzza = 1'
212 f._on_enter()
212 f._on_enter()
213 f.input_buffer = 'zzzb = 2'
213 f.input_buffer = 'zzzb = 2'
214 f._on_enter()
214 f._on_enter()
215 f.input_buffer = 'map(zz'
215 f.input_buffer = 'map(zz'
216 f.complete_current_input()
216 f.complete_current_input()
217 out_value = f.out.getvalue()
217 out_value = f.out.getvalue()
218 yield assert_equal, out_value, '\nzzza zzzb '
218 yield assert_equal, out_value, '\nzzza zzzb '
219 yield assert_equal, f.input_buffer, 'map(zzz'
219 yield assert_equal, f.input_buffer, 'map(zzz'
220
220
221
221
222 @isolate_ipython0
222 @isolate_ipython0
223 def test_completion_indexing():
223 def test_completion_indexing():
224 """ Test command-line completion when indexing on objects.
224 """ Test command-line completion when indexing on objects.
225 """
225 """
226 f = TestPrefilterFrontEnd()
226 f = TestPrefilterFrontEnd()
227 f.input_buffer = 'a = [0]'
227 f.input_buffer = 'a = [0]'
228 f._on_enter()
228 f._on_enter()
229 f.input_buffer = 'a[0].'
229 f.input_buffer = 'a[0].'
230 f.complete_current_input()
230 f.complete_current_input()
231 assert_equal(f.input_buffer, 'a[0].__')
231 assert_equal(f.input_buffer, 'a[0].__')
232
232
233
233
234 @isolate_ipython0
234 @isolate_ipython0
235 def test_completion_equal():
235 def test_completion_equal():
236 """ Test command-line completion when the delimiter is "=", not " ".
236 """ Test command-line completion when the delimiter is "=", not " ".
237 """
237 """
238 f = TestPrefilterFrontEnd()
238 f = TestPrefilterFrontEnd()
239 f.input_buffer = 'a=1.'
239 f.input_buffer = 'a=1.'
240 f.complete_current_input()
240 f.complete_current_input()
241 assert_equal(f.input_buffer, 'a=1.__')
241 assert_equal(f.input_buffer, 'a=1.__')
242
242
243
243
244
244
245 if __name__ == '__main__':
245 if __name__ == '__main__':
246 test_magic()
246 test_magic()
247 test_help()
247 test_help()
248 test_execution()
248 test_execution()
249 test_multiline()
249 test_multiline()
250 test_capture()
250 test_capture()
251 test_completion_simple()
251 test_completion_simple()
252 test_completion_complex()
252 test_completion_complex()
@@ -1,526 +1,527 b''
1 #!/usr/bin/python
1 #!/usr/bin/python
2 # -*- coding: iso-8859-15 -*-
2 # -*- coding: iso-8859-15 -*-
3 '''
3 '''
4 Provides IPython remote instance.
4 Provides IPython remote instance.
5
5
6 @author: Laurent Dufrechou
6 @author: Laurent Dufrechou
7 laurent.dufrechou _at_ gmail.com
7 laurent.dufrechou _at_ gmail.com
8 @license: BSD
8 @license: BSD
9
9
10 All rights reserved. This program and the accompanying materials are made
10 All rights reserved. This program and the accompanying materials are made
11 available under the terms of the BSD which accompanies this distribution, and
11 available under the terms of the BSD which accompanies this distribution, and
12 is available at U{http://www.opensource.org/licenses/bsd-license.php}
12 is available at U{http://www.opensource.org/licenses/bsd-license.php}
13 '''
13 '''
14
14
15 __version__ = 0.9
15 __version__ = 0.9
16 __author__ = "Laurent Dufrechou"
16 __author__ = "Laurent Dufrechou"
17 __email__ = "laurent.dufrechou _at_ gmail.com"
17 __email__ = "laurent.dufrechou _at_ gmail.com"
18 __license__ = "BSD"
18 __license__ = "BSD"
19
19
20 import re
20 import re
21 import sys
21 import sys
22 import os
22 import os
23 import locale
23 import locale
24 from thread_ex import ThreadEx
24 from thread_ex import ThreadEx
25
25
26 try:
26 try:
27 import IPython
27 import IPython
28 from IPython.utils import genutils
28 from IPython.utils import genutils
29 from IPython.core import iplib
29 except Exception,e:
30 except Exception,e:
30 print "Error importing IPython (%s)" % str(e)
31 print "Error importing IPython (%s)" % str(e)
31 raise Exception, e
32 raise Exception, e
32
33
33 ##############################################################################
34 ##############################################################################
34 class _Helper(object):
35 class _Helper(object):
35 """Redefine the built-in 'help'.
36 """Redefine the built-in 'help'.
36 This is a wrapper around pydoc.help (with a twist).
37 This is a wrapper around pydoc.help (with a twist).
37 """
38 """
38
39
39 def __init__(self, pager):
40 def __init__(self, pager):
40 self._pager = pager
41 self._pager = pager
41
42
42 def __repr__(self):
43 def __repr__(self):
43 return "Type help() for interactive help, " \
44 return "Type help() for interactive help, " \
44 "or help(object) for help about object."
45 "or help(object) for help about object."
45
46
46 def __call__(self, *args, **kwds):
47 def __call__(self, *args, **kwds):
47 class DummyWriter(object):
48 class DummyWriter(object):
48 '''Dumy class to handle help output'''
49 '''Dumy class to handle help output'''
49 def __init__(self, pager):
50 def __init__(self, pager):
50 self._pager = pager
51 self._pager = pager
51
52
52 def write(self, data):
53 def write(self, data):
53 '''hook to fill self._pager'''
54 '''hook to fill self._pager'''
54 self._pager(data)
55 self._pager(data)
55
56
56 import pydoc
57 import pydoc
57 pydoc.help.output = DummyWriter(self._pager)
58 pydoc.help.output = DummyWriter(self._pager)
58 pydoc.help.interact = lambda :1
59 pydoc.help.interact = lambda :1
59
60
60 return pydoc.help(*args, **kwds)
61 return pydoc.help(*args, **kwds)
61
62
62
63
63 ##############################################################################
64 ##############################################################################
64 class _CodeExecutor(ThreadEx):
65 class _CodeExecutor(ThreadEx):
65 ''' Thread that execute ipython code '''
66 ''' Thread that execute ipython code '''
66 def __init__(self, instance):
67 def __init__(self, instance):
67 ThreadEx.__init__(self)
68 ThreadEx.__init__(self)
68 self.instance = instance
69 self.instance = instance
69
70
70 def run(self):
71 def run(self):
71 '''Thread main loop'''
72 '''Thread main loop'''
72 try:
73 try:
73 self.instance._doc_text = None
74 self.instance._doc_text = None
74 self.instance._help_text = None
75 self.instance._help_text = None
75 self.instance._execute()
76 self.instance._execute()
76 # used for uper class to generate event after execution
77 # used for uper class to generate event after execution
77 self.instance._after_execute()
78 self.instance._after_execute()
78
79
79 except KeyboardInterrupt:
80 except KeyboardInterrupt:
80 pass
81 pass
81
82
82
83
83 ##############################################################################
84 ##############################################################################
84 class NonBlockingIPShell(object):
85 class NonBlockingIPShell(object):
85 '''
86 '''
86 Create an IPython instance, running the commands in a separate,
87 Create an IPython instance, running the commands in a separate,
87 non-blocking thread.
88 non-blocking thread.
88 This allows embedding in any GUI without blockage.
89 This allows embedding in any GUI without blockage.
89
90
90 Note: The ThreadEx class supports asynchroneous function call
91 Note: The ThreadEx class supports asynchroneous function call
91 via raise_exc()
92 via raise_exc()
92 '''
93 '''
93
94
94 def __init__(self, argv=[], user_ns={}, user_global_ns=None,
95 def __init__(self, argv=[], user_ns={}, user_global_ns=None,
95 cin=None, cout=None, cerr=None,
96 cin=None, cout=None, cerr=None,
96 ask_exit_handler=None):
97 ask_exit_handler=None):
97 '''
98 '''
98 @param argv: Command line options for IPython
99 @param argv: Command line options for IPython
99 @type argv: list
100 @type argv: list
100 @param user_ns: User namespace.
101 @param user_ns: User namespace.
101 @type user_ns: dictionary
102 @type user_ns: dictionary
102 @param user_global_ns: User global namespace.
103 @param user_global_ns: User global namespace.
103 @type user_global_ns: dictionary.
104 @type user_global_ns: dictionary.
104 @param cin: Console standard input.
105 @param cin: Console standard input.
105 @type cin: IO stream
106 @type cin: IO stream
106 @param cout: Console standard output.
107 @param cout: Console standard output.
107 @type cout: IO stream
108 @type cout: IO stream
108 @param cerr: Console standard error.
109 @param cerr: Console standard error.
109 @type cerr: IO stream
110 @type cerr: IO stream
110 @param exit_handler: Replacement for builtin exit() function
111 @param exit_handler: Replacement for builtin exit() function
111 @type exit_handler: function
112 @type exit_handler: function
112 @param time_loop: Define the sleep time between two thread's loop
113 @param time_loop: Define the sleep time between two thread's loop
113 @type int
114 @type int
114 '''
115 '''
115 #ipython0 initialisation
116 #ipython0 initialisation
116 self._IP = None
117 self._IP = None
117 self.init_ipython0(argv, user_ns, user_global_ns,
118 self.init_ipython0(argv, user_ns, user_global_ns,
118 cin, cout, cerr,
119 cin, cout, cerr,
119 ask_exit_handler)
120 ask_exit_handler)
120
121
121 #vars used by _execute
122 #vars used by _execute
122 self._iter_more = 0
123 self._iter_more = 0
123 self._history_level = 0
124 self._history_level = 0
124 self._complete_sep = re.compile('[\s\{\}\[\]\(\)\=]')
125 self._complete_sep = re.compile('[\s\{\}\[\]\(\)\=]')
125 self._prompt = str(self._IP.outputcache.prompt1).strip()
126 self._prompt = str(self._IP.outputcache.prompt1).strip()
126
127
127 #thread working vars
128 #thread working vars
128 self._line_to_execute = ''
129 self._line_to_execute = ''
129 self._threading = True
130 self._threading = True
130
131
131 #vars that will be checked by GUI loop to handle thread states...
132 #vars that will be checked by GUI loop to handle thread states...
132 #will be replaced later by PostEvent GUI funtions...
133 #will be replaced later by PostEvent GUI funtions...
133 self._doc_text = None
134 self._doc_text = None
134 self._help_text = None
135 self._help_text = None
135 self._add_button = None
136 self._add_button = None
136
137
137 def init_ipython0(self, argv=[], user_ns={}, user_global_ns=None,
138 def init_ipython0(self, argv=[], user_ns={}, user_global_ns=None,
138 cin=None, cout=None, cerr=None,
139 cin=None, cout=None, cerr=None,
139 ask_exit_handler=None):
140 ask_exit_handler=None):
140 ''' Initialize an ipython0 instance '''
141 ''' Initialize an ipython0 instance '''
141
142
142 #first we redefine in/out/error functions of IPython
143 #first we redefine in/out/error functions of IPython
143 #BUG: we've got a limitation form ipython0 there
144 #BUG: we've got a limitation form ipython0 there
144 #only one instance can be instanciated else tehre will be
145 #only one instance can be instanciated else tehre will be
145 #cin/cout/cerr clash...
146 #cin/cout/cerr clash...
146 if cin:
147 if cin:
147 genutils.Term.cin = cin
148 genutils.Term.cin = cin
148 if cout:
149 if cout:
149 genutils.Term.cout = cout
150 genutils.Term.cout = cout
150 if cerr:
151 if cerr:
151 genutils.Term.cerr = cerr
152 genutils.Term.cerr = cerr
152
153
153 excepthook = sys.excepthook
154 excepthook = sys.excepthook
154
155
155 #Hack to save sys.displayhook, because ipython seems to overwrite it...
156 #Hack to save sys.displayhook, because ipython seems to overwrite it...
156 self.sys_displayhook_ori = sys.displayhook
157 self.sys_displayhook_ori = sys.displayhook
157
158
158 self._IP = IPython.Shell.make_IPython(
159 self._IP = IPython.Shell.make_IPython(
159 argv,user_ns=user_ns,
160 argv,user_ns=user_ns,
160 user_global_ns=user_global_ns,
161 user_global_ns=user_global_ns,
161 embedded=True,
162 embedded=True,
162 shell_class=IPython.Shell.InteractiveShell)
163 shell_class=IPython.Shell.InteractiveShell)
163
164
164 #we save ipython0 displayhook and we restore sys.displayhook
165 #we save ipython0 displayhook and we restore sys.displayhook
165 self.displayhook = sys.displayhook
166 self.displayhook = sys.displayhook
166 sys.displayhook = self.sys_displayhook_ori
167 sys.displayhook = self.sys_displayhook_ori
167
168
168 #we replace IPython default encoding by wx locale encoding
169 #we replace IPython default encoding by wx locale encoding
169 loc = locale.getpreferredencoding()
170 loc = locale.getpreferredencoding()
170 if loc:
171 if loc:
171 self._IP.stdin_encoding = loc
172 self._IP.stdin_encoding = loc
172 #we replace the ipython default pager by our pager
173 #we replace the ipython default pager by our pager
173 self._IP.set_hook('show_in_pager', self._pager)
174 self._IP.set_hook('show_in_pager', self._pager)
174
175
175 #we replace the ipython default shell command caller
176 #we replace the ipython default shell command caller
176 #by our shell handler
177 #by our shell handler
177 self._IP.set_hook('shell_hook', self._shell)
178 self._IP.set_hook('shell_hook', self._shell)
178
179
179 #we replace the ipython default input command caller by our method
180 #we replace the ipython default input command caller by our method
180 IPython.iplib.raw_input_original = self._raw_input_original
181 iplib.raw_input_original = self._raw_input_original
181 #we replace the ipython default exit command by our method
182 #we replace the ipython default exit command by our method
182 self._IP.exit = ask_exit_handler
183 self._IP.exit = ask_exit_handler
183 #we replace the help command
184 #we replace the help command
184 self._IP.user_ns['help'] = _Helper(self._pager_help)
185 self._IP.user_ns['help'] = _Helper(self._pager_help)
185
186
186 #we disable cpase magic... until we found a way to use it properly.
187 #we disable cpase magic... until we found a way to use it properly.
187 from IPython.core import ipapi
188 from IPython.core import ipapi
188 ip = ipapi.get()
189 ip = ipapi.get()
189 def bypass_magic(self, arg):
190 def bypass_magic(self, arg):
190 print '%this magic is currently disabled.'
191 print '%this magic is currently disabled.'
191 ip.expose_magic('cpaste', bypass_magic)
192 ip.expose_magic('cpaste', bypass_magic)
192
193
193 import __builtin__
194 import __builtin__
194 __builtin__.raw_input = self._raw_input
195 __builtin__.raw_input = self._raw_input
195
196
196 sys.excepthook = excepthook
197 sys.excepthook = excepthook
197
198
198 #----------------------- Thread management section ----------------------
199 #----------------------- Thread management section ----------------------
199 def do_execute(self, line):
200 def do_execute(self, line):
200 """
201 """
201 Tell the thread to process the 'line' command
202 Tell the thread to process the 'line' command
202 """
203 """
203
204
204 self._line_to_execute = line
205 self._line_to_execute = line
205
206
206 if self._threading:
207 if self._threading:
207 #we launch the ipython line execution in a thread to make it
208 #we launch the ipython line execution in a thread to make it
208 #interruptible with include it in self namespace to be able
209 #interruptible with include it in self namespace to be able
209 #to call ce.raise_exc(KeyboardInterrupt)
210 #to call ce.raise_exc(KeyboardInterrupt)
210 self.ce = _CodeExecutor(self)
211 self.ce = _CodeExecutor(self)
211 self.ce.start()
212 self.ce.start()
212 else:
213 else:
213 try:
214 try:
214 self._doc_text = None
215 self._doc_text = None
215 self._help_text = None
216 self._help_text = None
216 self._execute()
217 self._execute()
217 # used for uper class to generate event after execution
218 # used for uper class to generate event after execution
218 self._after_execute()
219 self._after_execute()
219
220
220 except KeyboardInterrupt:
221 except KeyboardInterrupt:
221 pass
222 pass
222
223
223 #----------------------- IPython management section ----------------------
224 #----------------------- IPython management section ----------------------
224 def get_threading(self):
225 def get_threading(self):
225 """
226 """
226 Returns threading status, is set to True, then each command sent to
227 Returns threading status, is set to True, then each command sent to
227 the interpreter will be executed in a separated thread allowing,
228 the interpreter will be executed in a separated thread allowing,
228 for example, breaking a long running commands.
229 for example, breaking a long running commands.
229 Disallowing it, permits better compatibilty with instance that is embedding
230 Disallowing it, permits better compatibilty with instance that is embedding
230 IPython instance.
231 IPython instance.
231
232
232 @return: Execution method
233 @return: Execution method
233 @rtype: bool
234 @rtype: bool
234 """
235 """
235 return self._threading
236 return self._threading
236
237
237 def set_threading(self, state):
238 def set_threading(self, state):
238 """
239 """
239 Sets threading state, if set to True, then each command sent to
240 Sets threading state, if set to True, then each command sent to
240 the interpreter will be executed in a separated thread allowing,
241 the interpreter will be executed in a separated thread allowing,
241 for example, breaking a long running commands.
242 for example, breaking a long running commands.
242 Disallowing it, permits better compatibilty with instance that is embedding
243 Disallowing it, permits better compatibilty with instance that is embedding
243 IPython instance.
244 IPython instance.
244
245
245 @param state: Sets threading state
246 @param state: Sets threading state
246 @type bool
247 @type bool
247 """
248 """
248 self._threading = state
249 self._threading = state
249
250
250 def get_doc_text(self):
251 def get_doc_text(self):
251 """
252 """
252 Returns the output of the processing that need to be paged (if any)
253 Returns the output of the processing that need to be paged (if any)
253
254
254 @return: The std output string.
255 @return: The std output string.
255 @rtype: string
256 @rtype: string
256 """
257 """
257 return self._doc_text
258 return self._doc_text
258
259
259 def get_help_text(self):
260 def get_help_text(self):
260 """
261 """
261 Returns the output of the processing that need to be paged via help pager(if any)
262 Returns the output of the processing that need to be paged via help pager(if any)
262
263
263 @return: The std output string.
264 @return: The std output string.
264 @rtype: string
265 @rtype: string
265 """
266 """
266 return self._help_text
267 return self._help_text
267
268
268 def get_banner(self):
269 def get_banner(self):
269 """
270 """
270 Returns the IPython banner for useful info on IPython instance
271 Returns the IPython banner for useful info on IPython instance
271
272
272 @return: The banner string.
273 @return: The banner string.
273 @rtype: string
274 @rtype: string
274 """
275 """
275 return self._IP.BANNER
276 return self._IP.BANNER
276
277
277 def get_prompt_count(self):
278 def get_prompt_count(self):
278 """
279 """
279 Returns the prompt number.
280 Returns the prompt number.
280 Each time a user execute a line in the IPython shell the prompt count is increased
281 Each time a user execute a line in the IPython shell the prompt count is increased
281
282
282 @return: The prompt number
283 @return: The prompt number
283 @rtype: int
284 @rtype: int
284 """
285 """
285 return self._IP.outputcache.prompt_count
286 return self._IP.outputcache.prompt_count
286
287
287 def get_prompt(self):
288 def get_prompt(self):
288 """
289 """
289 Returns current prompt inside IPython instance
290 Returns current prompt inside IPython instance
290 (Can be In [...]: ot ...:)
291 (Can be In [...]: ot ...:)
291
292
292 @return: The current prompt.
293 @return: The current prompt.
293 @rtype: string
294 @rtype: string
294 """
295 """
295 return self._prompt
296 return self._prompt
296
297
297 def get_indentation(self):
298 def get_indentation(self):
298 """
299 """
299 Returns the current indentation level
300 Returns the current indentation level
300 Usefull to put the caret at the good start position if we want to do autoindentation.
301 Usefull to put the caret at the good start position if we want to do autoindentation.
301
302
302 @return: The indentation level.
303 @return: The indentation level.
303 @rtype: int
304 @rtype: int
304 """
305 """
305 return self._IP.indent_current_nsp
306 return self._IP.indent_current_nsp
306
307
307 def update_namespace(self, ns_dict):
308 def update_namespace(self, ns_dict):
308 '''
309 '''
309 Add the current dictionary to the shell namespace.
310 Add the current dictionary to the shell namespace.
310
311
311 @param ns_dict: A dictionary of symbol-values.
312 @param ns_dict: A dictionary of symbol-values.
312 @type ns_dict: dictionary
313 @type ns_dict: dictionary
313 '''
314 '''
314 self._IP.user_ns.update(ns_dict)
315 self._IP.user_ns.update(ns_dict)
315
316
316 def complete(self, line):
317 def complete(self, line):
317 '''
318 '''
318 Returns an auto completed line and/or posibilities for completion.
319 Returns an auto completed line and/or posibilities for completion.
319
320
320 @param line: Given line so far.
321 @param line: Given line so far.
321 @type line: string
322 @type line: string
322
323
323 @return: Line completed as for as possible,
324 @return: Line completed as for as possible,
324 and possible further completions.
325 and possible further completions.
325 @rtype: tuple
326 @rtype: tuple
326 '''
327 '''
327 split_line = self._complete_sep.split(line)
328 split_line = self._complete_sep.split(line)
328 possibilities = self._IP.complete(split_line[-1])
329 possibilities = self._IP.complete(split_line[-1])
329 if possibilities:
330 if possibilities:
330
331
331 def _common_prefix(str1, str2):
332 def _common_prefix(str1, str2):
332 '''
333 '''
333 Reduction function. returns common prefix of two given strings.
334 Reduction function. returns common prefix of two given strings.
334
335
335 @param str1: First string.
336 @param str1: First string.
336 @type str1: string
337 @type str1: string
337 @param str2: Second string
338 @param str2: Second string
338 @type str2: string
339 @type str2: string
339
340
340 @return: Common prefix to both strings.
341 @return: Common prefix to both strings.
341 @rtype: string
342 @rtype: string
342 '''
343 '''
343 for i in range(len(str1)):
344 for i in range(len(str1)):
344 if not str2.startswith(str1[:i+1]):
345 if not str2.startswith(str1[:i+1]):
345 return str1[:i]
346 return str1[:i]
346 return str1
347 return str1
347 common_prefix = reduce(_common_prefix, possibilities)
348 common_prefix = reduce(_common_prefix, possibilities)
348 completed = line[:-len(split_line[-1])]+common_prefix
349 completed = line[:-len(split_line[-1])]+common_prefix
349 else:
350 else:
350 completed = line
351 completed = line
351 return completed, possibilities
352 return completed, possibilities
352
353
353 def history_back(self):
354 def history_back(self):
354 '''
355 '''
355 Provides one history command back.
356 Provides one history command back.
356
357
357 @return: The command string.
358 @return: The command string.
358 @rtype: string
359 @rtype: string
359 '''
360 '''
360 history = ''
361 history = ''
361 #the below while loop is used to suppress empty history lines
362 #the below while loop is used to suppress empty history lines
362 while((history == '' or history == '\n') and self._history_level >0):
363 while((history == '' or history == '\n') and self._history_level >0):
363 if self._history_level >= 1:
364 if self._history_level >= 1:
364 self._history_level -= 1
365 self._history_level -= 1
365 history = self._get_history()
366 history = self._get_history()
366 return history
367 return history
367
368
368 def history_forward(self):
369 def history_forward(self):
369 '''
370 '''
370 Provides one history command forward.
371 Provides one history command forward.
371
372
372 @return: The command string.
373 @return: The command string.
373 @rtype: string
374 @rtype: string
374 '''
375 '''
375 history = ''
376 history = ''
376 #the below while loop is used to suppress empty history lines
377 #the below while loop is used to suppress empty history lines
377 while((history == '' or history == '\n') \
378 while((history == '' or history == '\n') \
378 and self._history_level <= self._get_history_max_index()):
379 and self._history_level <= self._get_history_max_index()):
379 if self._history_level < self._get_history_max_index():
380 if self._history_level < self._get_history_max_index():
380 self._history_level += 1
381 self._history_level += 1
381 history = self._get_history()
382 history = self._get_history()
382 else:
383 else:
383 if self._history_level == self._get_history_max_index():
384 if self._history_level == self._get_history_max_index():
384 history = self._get_history()
385 history = self._get_history()
385 self._history_level += 1
386 self._history_level += 1
386 else:
387 else:
387 history = ''
388 history = ''
388 return history
389 return history
389
390
390 def init_history_index(self):
391 def init_history_index(self):
391 '''
392 '''
392 set history to last command entered
393 set history to last command entered
393 '''
394 '''
394 self._history_level = self._get_history_max_index()+1
395 self._history_level = self._get_history_max_index()+1
395
396
396 #----------------------- IPython PRIVATE management section --------------
397 #----------------------- IPython PRIVATE management section --------------
397 def _after_execute(self):
398 def _after_execute(self):
398 '''
399 '''
399 Can be redefined to generate post event after excution is done
400 Can be redefined to generate post event after excution is done
400 '''
401 '''
401 pass
402 pass
402
403
403 def _ask_exit(self):
404 def _ask_exit(self):
404 '''
405 '''
405 Can be redefined to generate post event to exit the Ipython shell
406 Can be redefined to generate post event to exit the Ipython shell
406 '''
407 '''
407 pass
408 pass
408
409
409 def _get_history_max_index(self):
410 def _get_history_max_index(self):
410 '''
411 '''
411 returns the max length of the history buffer
412 returns the max length of the history buffer
412
413
413 @return: history length
414 @return: history length
414 @rtype: int
415 @rtype: int
415 '''
416 '''
416 return len(self._IP.input_hist_raw)-1
417 return len(self._IP.input_hist_raw)-1
417
418
418 def _get_history(self):
419 def _get_history(self):
419 '''
420 '''
420 Get's the command string of the current history level.
421 Get's the command string of the current history level.
421
422
422 @return: Historic command stri
423 @return: Historic command stri
423 @rtype: string
424 @rtype: string
424 '''
425 '''
425 rv = self._IP.input_hist_raw[self._history_level].strip('\n')
426 rv = self._IP.input_hist_raw[self._history_level].strip('\n')
426 return rv
427 return rv
427
428
428 def _pager_help(self, text):
429 def _pager_help(self, text):
429 '''
430 '''
430 This function is used as a callback replacment to IPython help pager function
431 This function is used as a callback replacment to IPython help pager function
431
432
432 It puts the 'text' value inside the self._help_text string that can be retrived via
433 It puts the 'text' value inside the self._help_text string that can be retrived via
433 get_help_text function.
434 get_help_text function.
434 '''
435 '''
435 if self._help_text == None:
436 if self._help_text == None:
436 self._help_text = text
437 self._help_text = text
437 else:
438 else:
438 self._help_text += text
439 self._help_text += text
439
440
440 def _pager(self, IP, text):
441 def _pager(self, IP, text):
441 '''
442 '''
442 This function is used as a callback replacment to IPython pager function
443 This function is used as a callback replacment to IPython pager function
443
444
444 It puts the 'text' value inside the self._doc_text string that can be retrived via
445 It puts the 'text' value inside the self._doc_text string that can be retrived via
445 get_doc_text function.
446 get_doc_text function.
446 '''
447 '''
447 self._doc_text = text
448 self._doc_text = text
448
449
449 def _raw_input_original(self, prompt=''):
450 def _raw_input_original(self, prompt=''):
450 '''
451 '''
451 Custom raw_input() replacement. Get's current line from console buffer.
452 Custom raw_input() replacement. Get's current line from console buffer.
452
453
453 @param prompt: Prompt to print. Here for compatability as replacement.
454 @param prompt: Prompt to print. Here for compatability as replacement.
454 @type prompt: string
455 @type prompt: string
455
456
456 @return: The current command line text.
457 @return: The current command line text.
457 @rtype: string
458 @rtype: string
458 '''
459 '''
459 return self._line_to_execute
460 return self._line_to_execute
460
461
461 def _raw_input(self, prompt=''):
462 def _raw_input(self, prompt=''):
462 """ A replacement from python's raw_input.
463 """ A replacement from python's raw_input.
463 """
464 """
464 raise NotImplementedError
465 raise NotImplementedError
465
466
466 def _execute(self):
467 def _execute(self):
467 '''
468 '''
468 Executes the current line provided by the shell object.
469 Executes the current line provided by the shell object.
469 '''
470 '''
470
471
471 orig_stdout = sys.stdout
472 orig_stdout = sys.stdout
472 sys.stdout = IPython.Shell.Term.cout
473 sys.stdout = IPython.Shell.Term.cout
473 #self.sys_displayhook_ori = sys.displayhook
474 #self.sys_displayhook_ori = sys.displayhook
474 #sys.displayhook = self.displayhook
475 #sys.displayhook = self.displayhook
475
476
476 try:
477 try:
477 line = self._IP.raw_input(None, self._iter_more)
478 line = self._IP.raw_input(None, self._iter_more)
478 if self._IP.autoindent:
479 if self._IP.autoindent:
479 self._IP.readline_startup_hook(None)
480 self._IP.readline_startup_hook(None)
480
481
481 except KeyboardInterrupt:
482 except KeyboardInterrupt:
482 self._IP.write('\nKeyboardInterrupt\n')
483 self._IP.write('\nKeyboardInterrupt\n')
483 self._IP.resetbuffer()
484 self._IP.resetbuffer()
484 # keep cache in sync with the prompt counter:
485 # keep cache in sync with the prompt counter:
485 self._IP.outputcache.prompt_count -= 1
486 self._IP.outputcache.prompt_count -= 1
486
487
487 if self._IP.autoindent:
488 if self._IP.autoindent:
488 self._IP.indent_current_nsp = 0
489 self._IP.indent_current_nsp = 0
489 self._iter_more = 0
490 self._iter_more = 0
490 except:
491 except:
491 self._IP.showtraceback()
492 self._IP.showtraceback()
492 else:
493 else:
493 self._IP.write(str(self._IP.outputcache.prompt_out).strip())
494 self._IP.write(str(self._IP.outputcache.prompt_out).strip())
494 self._iter_more = self._IP.push(line)
495 self._iter_more = self._IP.push(line)
495 if (self._IP.SyntaxTB.last_syntax_error and \
496 if (self._IP.SyntaxTB.last_syntax_error and \
496 self._IP.rc.autoedit_syntax):
497 self._IP.rc.autoedit_syntax):
497 self._IP.edit_syntax_error()
498 self._IP.edit_syntax_error()
498 if self._iter_more:
499 if self._iter_more:
499 self._prompt = str(self._IP.outputcache.prompt2).strip()
500 self._prompt = str(self._IP.outputcache.prompt2).strip()
500 if self._IP.autoindent:
501 if self._IP.autoindent:
501 self._IP.readline_startup_hook(self._IP.pre_readline)
502 self._IP.readline_startup_hook(self._IP.pre_readline)
502 else:
503 else:
503 self._prompt = str(self._IP.outputcache.prompt1).strip()
504 self._prompt = str(self._IP.outputcache.prompt1).strip()
504 self._IP.indent_current_nsp = 0 #we set indentation to 0
505 self._IP.indent_current_nsp = 0 #we set indentation to 0
505
506
506 sys.stdout = orig_stdout
507 sys.stdout = orig_stdout
507 #sys.displayhook = self.sys_displayhook_ori
508 #sys.displayhook = self.sys_displayhook_ori
508
509
509 def _shell(self, ip, cmd):
510 def _shell(self, ip, cmd):
510 '''
511 '''
511 Replacement method to allow shell commands without them blocking.
512 Replacement method to allow shell commands without them blocking.
512
513
513 @param ip: Ipython instance, same as self._IP
514 @param ip: Ipython instance, same as self._IP
514 @type cmd: Ipython instance
515 @type cmd: Ipython instance
515 @param cmd: Shell command to execute.
516 @param cmd: Shell command to execute.
516 @type cmd: string
517 @type cmd: string
517 '''
518 '''
518 stdin, stdout = os.popen4(cmd)
519 stdin, stdout = os.popen4(cmd)
519 result = stdout.read().decode('cp437').\
520 result = stdout.read().decode('cp437').\
520 encode(locale.getpreferredencoding())
521 encode(locale.getpreferredencoding())
521 #we use print command because the shell command is called
522 #we use print command because the shell command is called
522 #inside IPython instance and thus is redirected to thread cout
523 #inside IPython instance and thus is redirected to thread cout
523 #"\x01\x1b[1;36m\x02" <-- add colour to the text...
524 #"\x01\x1b[1;36m\x02" <-- add colour to the text...
524 print "\x01\x1b[1;36m\x02"+result
525 print "\x01\x1b[1;36m\x02"+result
525 stdout.close()
526 stdout.close()
526 stdin.close()
527 stdin.close()
@@ -1,771 +1,771 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
9
10 #*****************************************************************************
10 #*****************************************************************************
11 # Copyright (C) 2008-2009 The IPython Development Team
11 # Copyright (C) 2008-2009 The IPython Development Team
12 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
12 # Copyright (C) 2001-2007 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 try:
18 try:
19 credits._Printer__data = """
19 credits._Printer__data = """
20 Python: %s
20 Python: %s
21
21
22 IPython: The IPython Development Team.
22 IPython: The IPython Development Team.
23 See http://ipython.scipy.org for more information.""" \
23 See http://ipython.scipy.org for more information.""" \
24 % credits._Printer__data
24 % credits._Printer__data
25
25
26 copyright._Printer__data += """
26 copyright._Printer__data += """
27
27
28 Copyright (c) 2008-2009 The IPython Development Team.
28 Copyright (c) 2008-2009 The IPython Development Team.
29 Copyright (c) 2001-2007 Fernando Perez, Janko Hauser, Nathan Gray.
29 Copyright (c) 2001-2007 Fernando Perez, Janko Hauser, Nathan Gray.
30 All Rights Reserved."""
30 All Rights Reserved."""
31 except NameError:
31 except NameError:
32 # Can happen if ipython was started with 'python -S', so that site.py is
32 # Can happen if ipython was started with 'python -S', so that site.py is
33 # not loaded
33 # not loaded
34 pass
34 pass
35
35
36 #****************************************************************************
36 #****************************************************************************
37 # Required modules
37 # Required modules
38
38
39 # From the standard library
39 # From the standard library
40 import __main__
40 import __main__
41 import __builtin__
41 import __builtin__
42 import os
42 import os
43 import sys
43 import sys
44 from pprint import pprint
44 from pprint import pprint
45
45
46 # Our own
46 # Our own
47 from IPython.utils import DPyGetOpt
47 from IPython.utils import DPyGetOpt
48 from IPython import Release
48 from IPython import Release
49 from IPython.ipstruct import Struct
49 from IPython.ipstruct import Struct
50 from IPython.OutputTrap import OutputTrap
50 from IPython.OutputTrap import OutputTrap
51 from IPython.config.configloader import ConfigLoader
51 from IPython.config.configloader import ConfigLoader
52 from IPython.iplib import InteractiveShell
52 from IPython.core.iplib import InteractiveShell
53 from IPython.usage import cmd_line_usage,interactive_usage
53 from IPython.usage import cmd_line_usage,interactive_usage
54 from IPython.utils.genutils import *
54 from IPython.utils.genutils import *
55
55
56 def force_import(modname,force_reload=False):
56 def force_import(modname,force_reload=False):
57 if modname in sys.modules and force_reload:
57 if modname in sys.modules and force_reload:
58 info("reloading: %s" % modname)
58 info("reloading: %s" % modname)
59 reload(sys.modules[modname])
59 reload(sys.modules[modname])
60 else:
60 else:
61 __import__(modname)
61 __import__(modname)
62
62
63
63
64 #-----------------------------------------------------------------------------
64 #-----------------------------------------------------------------------------
65 def make_IPython(argv=None,user_ns=None,user_global_ns=None,debug=1,
65 def make_IPython(argv=None,user_ns=None,user_global_ns=None,debug=1,
66 rc_override=None,shell_class=InteractiveShell,
66 rc_override=None,shell_class=InteractiveShell,
67 embedded=False,**kw):
67 embedded=False,**kw):
68 """This is a dump of IPython into a single function.
68 """This is a dump of IPython into a single function.
69
69
70 Later it will have to be broken up in a sensible manner.
70 Later it will have to be broken up in a sensible manner.
71
71
72 Arguments:
72 Arguments:
73
73
74 - argv: a list similar to sys.argv[1:]. It should NOT contain the desired
74 - argv: a list similar to sys.argv[1:]. It should NOT contain the desired
75 script name, b/c DPyGetOpt strips the first argument only for the real
75 script name, b/c DPyGetOpt strips the first argument only for the real
76 sys.argv.
76 sys.argv.
77
77
78 - user_ns: a dict to be used as the user's namespace."""
78 - user_ns: a dict to be used as the user's namespace."""
79
79
80 #----------------------------------------------------------------------
80 #----------------------------------------------------------------------
81 # Defaults and initialization
81 # Defaults and initialization
82
82
83 # For developer debugging, deactivates crash handler and uses pdb.
83 # For developer debugging, deactivates crash handler and uses pdb.
84 DEVDEBUG = False
84 DEVDEBUG = False
85
85
86 if argv is None:
86 if argv is None:
87 argv = sys.argv
87 argv = sys.argv
88
88
89 # __IP is the main global that lives throughout and represents the whole
89 # __IP is the main global that lives throughout and represents the whole
90 # application. If the user redefines it, all bets are off as to what
90 # application. If the user redefines it, all bets are off as to what
91 # happens.
91 # happens.
92
92
93 # __IP is the name of he global which the caller will have accessible as
93 # __IP is the name of he global which the caller will have accessible as
94 # __IP.name. We set its name via the first parameter passed to
94 # __IP.name. We set its name via the first parameter passed to
95 # InteractiveShell:
95 # InteractiveShell:
96
96
97 IP = shell_class('__IP',user_ns=user_ns,user_global_ns=user_global_ns,
97 IP = shell_class('__IP',user_ns=user_ns,user_global_ns=user_global_ns,
98 embedded=embedded,**kw)
98 embedded=embedded,**kw)
99
99
100 # Put 'help' in the user namespace
100 # Put 'help' in the user namespace
101 try:
101 try:
102 from site import _Helper
102 from site import _Helper
103 IP.user_ns['help'] = _Helper()
103 IP.user_ns['help'] = _Helper()
104 except ImportError:
104 except ImportError:
105 warn('help() not available - check site.py')
105 warn('help() not available - check site.py')
106
106
107 if DEVDEBUG:
107 if DEVDEBUG:
108 # For developer debugging only (global flag)
108 # For developer debugging only (global flag)
109 from IPython import ultraTB
109 from IPython import ultraTB
110 sys.excepthook = ultraTB.VerboseTB(call_pdb=1)
110 sys.excepthook = ultraTB.VerboseTB(call_pdb=1)
111
111
112 IP.BANNER_PARTS = ['Python %s\n'
112 IP.BANNER_PARTS = ['Python %s\n'
113 'Type "copyright", "credits" or "license" '
113 'Type "copyright", "credits" or "license" '
114 'for more information.\n'
114 'for more information.\n'
115 % (sys.version.split('\n')[0],),
115 % (sys.version.split('\n')[0],),
116 "IPython %s -- An enhanced Interactive Python."
116 "IPython %s -- An enhanced Interactive Python."
117 % (Release.version,),
117 % (Release.version,),
118 """\
118 """\
119 ? -> Introduction and overview of IPython's features.
119 ? -> Introduction and overview of IPython's features.
120 %quickref -> Quick reference.
120 %quickref -> Quick reference.
121 help -> Python's own help system.
121 help -> Python's own help system.
122 object? -> Details about 'object'. ?object also works, ?? prints more.
122 object? -> Details about 'object'. ?object also works, ?? prints more.
123 """ ]
123 """ ]
124
124
125 IP.usage = interactive_usage
125 IP.usage = interactive_usage
126
126
127 # Platform-dependent suffix.
127 # Platform-dependent suffix.
128 if os.name == 'posix':
128 if os.name == 'posix':
129 rc_suffix = ''
129 rc_suffix = ''
130 else:
130 else:
131 rc_suffix = '.ini'
131 rc_suffix = '.ini'
132
132
133 # default directory for configuration
133 # default directory for configuration
134 ipythondir_def = get_ipython_dir()
134 ipythondir_def = get_ipython_dir()
135
135
136 sys.path.insert(0, '') # add . to sys.path. Fix from Prabhu Ramachandran
136 sys.path.insert(0, '') # add . to sys.path. Fix from Prabhu Ramachandran
137
137
138 # we need the directory where IPython itself is installed
138 # we need the directory where IPython itself is installed
139 import IPython
139 import IPython
140 IPython_dir = os.path.dirname(IPython.__file__)
140 IPython_dir = os.path.dirname(IPython.__file__)
141 del IPython
141 del IPython
142
142
143 #-------------------------------------------------------------------------
143 #-------------------------------------------------------------------------
144 # Command line handling
144 # Command line handling
145
145
146 # Valid command line options (uses DPyGetOpt syntax, like Perl's
146 # Valid command line options (uses DPyGetOpt syntax, like Perl's
147 # GetOpt::Long)
147 # GetOpt::Long)
148
148
149 # Any key not listed here gets deleted even if in the file (like session
149 # 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.
150 # or profile). That's deliberate, to maintain the rc namespace clean.
151
151
152 # Each set of options appears twice: under _conv only the names are
152 # 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
153 # listed, indicating which type they must be converted to when reading the
154 # ipythonrc file. And under DPyGetOpt they are listed with the regular
154 # ipythonrc file. And under DPyGetOpt they are listed with the regular
155 # DPyGetOpt syntax (=s,=i,:f,etc).
155 # DPyGetOpt syntax (=s,=i,:f,etc).
156
156
157 # Make sure there's a space before each end of line (they get auto-joined!)
157 # Make sure there's a space before each end of line (they get auto-joined!)
158 cmdline_opts = ('autocall=i autoindent! automagic! banner! cache_size|cs=i '
158 cmdline_opts = ('autocall=i autoindent! automagic! banner! cache_size|cs=i '
159 'c=s classic|cl color_info! colors=s confirm_exit! '
159 'c=s classic|cl color_info! colors=s confirm_exit! '
160 'debug! deep_reload! editor=s log|l messages! nosep '
160 'debug! deep_reload! editor=s log|l messages! nosep '
161 'object_info_string_level=i pdb! '
161 'object_info_string_level=i pdb! '
162 'pprint! prompt_in1|pi1=s prompt_in2|pi2=s prompt_out|po=s '
162 'pprint! prompt_in1|pi1=s prompt_in2|pi2=s prompt_out|po=s '
163 'pydb! '
163 'pydb! '
164 'pylab_import_all! '
164 'pylab_import_all! '
165 'quick screen_length|sl=i prompts_pad_left=i '
165 'quick screen_length|sl=i prompts_pad_left=i '
166 'logfile|lf=s logplay|lp=s profile|p=s '
166 'logfile|lf=s logplay|lp=s profile|p=s '
167 'readline! readline_merge_completions! '
167 'readline! readline_merge_completions! '
168 'readline_omit__names! '
168 'readline_omit__names! '
169 'rcfile=s separate_in|si=s separate_out|so=s '
169 'rcfile=s separate_in|si=s separate_out|so=s '
170 'separate_out2|so2=s xmode=s wildcards_case_sensitive! '
170 'separate_out2|so2=s xmode=s wildcards_case_sensitive! '
171 'magic_docstrings system_verbose! '
171 'magic_docstrings system_verbose! '
172 'multi_line_specials! '
172 'multi_line_specials! '
173 'term_title! wxversion=s '
173 'term_title! wxversion=s '
174 'autoedit_syntax!')
174 'autoedit_syntax!')
175
175
176 # Options that can *only* appear at the cmd line (not in rcfiles).
176 # Options that can *only* appear at the cmd line (not in rcfiles).
177
177
178 cmdline_only = ('help interact|i ipythondir=s Version upgrade '
178 cmdline_only = ('help interact|i ipythondir=s Version upgrade '
179 'gthread! qthread! q4thread! wthread! tkthread! pylab! tk! '
179 'gthread! qthread! q4thread! wthread! tkthread! pylab! tk! '
180 # 'twisted!' # disabled for now.
180 # 'twisted!' # disabled for now.
181 )
181 )
182
182
183 # Build the actual name list to be used by DPyGetOpt
183 # Build the actual name list to be used by DPyGetOpt
184 opts_names = qw(cmdline_opts) + qw(cmdline_only)
184 opts_names = qw(cmdline_opts) + qw(cmdline_only)
185
185
186 # Set sensible command line defaults.
186 # Set sensible command line defaults.
187 # This should have everything from cmdline_opts and cmdline_only
187 # This should have everything from cmdline_opts and cmdline_only
188 opts_def = Struct(autocall = 1,
188 opts_def = Struct(autocall = 1,
189 autoedit_syntax = 0,
189 autoedit_syntax = 0,
190 autoindent = 0,
190 autoindent = 0,
191 automagic = 1,
191 automagic = 1,
192 autoexec = [],
192 autoexec = [],
193 banner = 1,
193 banner = 1,
194 c = '',
194 c = '',
195 cache_size = 1000,
195 cache_size = 1000,
196 classic = 0,
196 classic = 0,
197 color_info = 0,
197 color_info = 0,
198 colors = 'NoColor',
198 colors = 'NoColor',
199 confirm_exit = 1,
199 confirm_exit = 1,
200 debug = 0,
200 debug = 0,
201 deep_reload = 0,
201 deep_reload = 0,
202 editor = '0',
202 editor = '0',
203 gthread = 0,
203 gthread = 0,
204 help = 0,
204 help = 0,
205 interact = 0,
205 interact = 0,
206 ipythondir = ipythondir_def,
206 ipythondir = ipythondir_def,
207 log = 0,
207 log = 0,
208 logfile = '',
208 logfile = '',
209 logplay = '',
209 logplay = '',
210 messages = 1,
210 messages = 1,
211 multi_line_specials = 1,
211 multi_line_specials = 1,
212 nosep = 0,
212 nosep = 0,
213 object_info_string_level = 0,
213 object_info_string_level = 0,
214 pdb = 0,
214 pdb = 0,
215 pprint = 0,
215 pprint = 0,
216 profile = '',
216 profile = '',
217 prompt_in1 = 'In [\\#]: ',
217 prompt_in1 = 'In [\\#]: ',
218 prompt_in2 = ' .\\D.: ',
218 prompt_in2 = ' .\\D.: ',
219 prompt_out = 'Out[\\#]: ',
219 prompt_out = 'Out[\\#]: ',
220 prompts_pad_left = 1,
220 prompts_pad_left = 1,
221 pydb = 0,
221 pydb = 0,
222 pylab = 0,
222 pylab = 0,
223 pylab_import_all = 1,
223 pylab_import_all = 1,
224 q4thread = 0,
224 q4thread = 0,
225 qthread = 0,
225 qthread = 0,
226 quick = 0,
226 quick = 0,
227 quiet = 0,
227 quiet = 0,
228 rcfile = 'ipythonrc' + rc_suffix,
228 rcfile = 'ipythonrc' + rc_suffix,
229 readline = 1,
229 readline = 1,
230 readline_merge_completions = 1,
230 readline_merge_completions = 1,
231 readline_omit__names = 0,
231 readline_omit__names = 0,
232 screen_length = 0,
232 screen_length = 0,
233 separate_in = '\n',
233 separate_in = '\n',
234 separate_out = '\n',
234 separate_out = '\n',
235 separate_out2 = '',
235 separate_out2 = '',
236 system_header = 'IPython system call: ',
236 system_header = 'IPython system call: ',
237 system_verbose = 0,
237 system_verbose = 0,
238 term_title = 1,
238 term_title = 1,
239 tk = 0,
239 tk = 0,
240 #twisted= 0, # disabled for now
240 #twisted= 0, # disabled for now
241 upgrade = 0,
241 upgrade = 0,
242 Version = 0,
242 Version = 0,
243 wildcards_case_sensitive = 1,
243 wildcards_case_sensitive = 1,
244 wthread = 0,
244 wthread = 0,
245 wxversion = '0',
245 wxversion = '0',
246 xmode = 'Context',
246 xmode = 'Context',
247 magic_docstrings = 0, # undocumented, for doc generation
247 magic_docstrings = 0, # undocumented, for doc generation
248 )
248 )
249
249
250 # Things that will *only* appear in rcfiles (not at the command line).
250 # Things that will *only* appear in rcfiles (not at the command line).
251 # Make sure there's a space before each end of line (they get auto-joined!)
251 # Make sure there's a space before each end of line (they get auto-joined!)
252 rcfile_opts = { qwflat: 'include import_mod import_all execfile ',
252 rcfile_opts = { qwflat: 'include import_mod import_all execfile ',
253 qw_lol: 'import_some ',
253 qw_lol: 'import_some ',
254 # for things with embedded whitespace:
254 # for things with embedded whitespace:
255 list_strings:'execute alias readline_parse_and_bind ',
255 list_strings:'execute alias readline_parse_and_bind ',
256 # Regular strings need no conversion:
256 # Regular strings need no conversion:
257 None:'readline_remove_delims ',
257 None:'readline_remove_delims ',
258 }
258 }
259 # Default values for these
259 # Default values for these
260 rc_def = Struct(include = [],
260 rc_def = Struct(include = [],
261 import_mod = [],
261 import_mod = [],
262 import_all = [],
262 import_all = [],
263 import_some = [[]],
263 import_some = [[]],
264 execute = [],
264 execute = [],
265 execfile = [],
265 execfile = [],
266 alias = [],
266 alias = [],
267 readline_parse_and_bind = [],
267 readline_parse_and_bind = [],
268 readline_remove_delims = '',
268 readline_remove_delims = '',
269 )
269 )
270
270
271 # Build the type conversion dictionary from the above tables:
271 # Build the type conversion dictionary from the above tables:
272 typeconv = rcfile_opts.copy()
272 typeconv = rcfile_opts.copy()
273 typeconv.update(optstr2types(cmdline_opts))
273 typeconv.update(optstr2types(cmdline_opts))
274
274
275 # FIXME: the None key appears in both, put that back together by hand. Ugly!
275 # FIXME: the None key appears in both, put that back together by hand. Ugly!
276 typeconv[None] += ' ' + rcfile_opts[None]
276 typeconv[None] += ' ' + rcfile_opts[None]
277
277
278 # Remove quotes at ends of all strings (used to protect spaces)
278 # Remove quotes at ends of all strings (used to protect spaces)
279 typeconv[unquote_ends] = typeconv[None]
279 typeconv[unquote_ends] = typeconv[None]
280 del typeconv[None]
280 del typeconv[None]
281
281
282 # Build the list we'll use to make all config decisions with defaults:
282 # Build the list we'll use to make all config decisions with defaults:
283 opts_all = opts_def.copy()
283 opts_all = opts_def.copy()
284 opts_all.update(rc_def)
284 opts_all.update(rc_def)
285
285
286 # Build conflict resolver for recursive loading of config files:
286 # Build conflict resolver for recursive loading of config files:
287 # - preserve means the outermost file maintains the value, it is not
287 # - preserve means the outermost file maintains the value, it is not
288 # overwritten if an included file has the same key.
288 # overwritten if an included file has the same key.
289 # - add_flip applies + to the two values, so it better make sense to add
289 # - add_flip applies + to the two values, so it better make sense to add
290 # those types of keys. But it flips them first so that things loaded
290 # those types of keys. But it flips them first so that things loaded
291 # deeper in the inclusion chain have lower precedence.
291 # deeper in the inclusion chain have lower precedence.
292 conflict = {'preserve': ' '.join([ typeconv[int],
292 conflict = {'preserve': ' '.join([ typeconv[int],
293 typeconv[unquote_ends] ]),
293 typeconv[unquote_ends] ]),
294 'add_flip': ' '.join([ typeconv[qwflat],
294 'add_flip': ' '.join([ typeconv[qwflat],
295 typeconv[qw_lol],
295 typeconv[qw_lol],
296 typeconv[list_strings] ])
296 typeconv[list_strings] ])
297 }
297 }
298
298
299 # Now actually process the command line
299 # Now actually process the command line
300 getopt = DPyGetOpt.DPyGetOpt()
300 getopt = DPyGetOpt.DPyGetOpt()
301 getopt.setIgnoreCase(0)
301 getopt.setIgnoreCase(0)
302
302
303 getopt.parseConfiguration(opts_names)
303 getopt.parseConfiguration(opts_names)
304
304
305 try:
305 try:
306 getopt.processArguments(argv)
306 getopt.processArguments(argv)
307 except DPyGetOpt.ArgumentError, exc:
307 except DPyGetOpt.ArgumentError, exc:
308 print cmd_line_usage
308 print cmd_line_usage
309 warn('\nError in Arguments: "%s"' % exc)
309 warn('\nError in Arguments: "%s"' % exc)
310 sys.exit(1)
310 sys.exit(1)
311
311
312 # convert the options dict to a struct for much lighter syntax later
312 # convert the options dict to a struct for much lighter syntax later
313 opts = Struct(getopt.optionValues)
313 opts = Struct(getopt.optionValues)
314 args = getopt.freeValues
314 args = getopt.freeValues
315
315
316 # this is the struct (which has default values at this point) with which
316 # this is the struct (which has default values at this point) with which
317 # we make all decisions:
317 # we make all decisions:
318 opts_all.update(opts)
318 opts_all.update(opts)
319
319
320 # Options that force an immediate exit
320 # Options that force an immediate exit
321 if opts_all.help:
321 if opts_all.help:
322 page(cmd_line_usage)
322 page(cmd_line_usage)
323 sys.exit()
323 sys.exit()
324
324
325 if opts_all.Version:
325 if opts_all.Version:
326 print Release.version
326 print Release.version
327 sys.exit()
327 sys.exit()
328
328
329 if opts_all.magic_docstrings:
329 if opts_all.magic_docstrings:
330 IP.magic_magic('-latex')
330 IP.magic_magic('-latex')
331 sys.exit()
331 sys.exit()
332
332
333 # add personal ipythondir to sys.path so that users can put things in
333 # add personal ipythondir to sys.path so that users can put things in
334 # there for customization
334 # there for customization
335 sys.path.append(os.path.abspath(opts_all.ipythondir))
335 sys.path.append(os.path.abspath(opts_all.ipythondir))
336
336
337 # Create user config directory if it doesn't exist. This must be done
337 # Create user config directory if it doesn't exist. This must be done
338 # *after* getting the cmd line options.
338 # *after* getting the cmd line options.
339 if not os.path.isdir(opts_all.ipythondir):
339 if not os.path.isdir(opts_all.ipythondir):
340 IP.user_setup(opts_all.ipythondir,rc_suffix,'install')
340 IP.user_setup(opts_all.ipythondir,rc_suffix,'install')
341
341
342 # upgrade user config files while preserving a copy of the originals
342 # upgrade user config files while preserving a copy of the originals
343 if opts_all.upgrade:
343 if opts_all.upgrade:
344 IP.user_setup(opts_all.ipythondir,rc_suffix,'upgrade')
344 IP.user_setup(opts_all.ipythondir,rc_suffix,'upgrade')
345
345
346 # check mutually exclusive options in the *original* command line
346 # check mutually exclusive options in the *original* command line
347 mutex_opts(opts,[qw('log logfile'),qw('rcfile profile'),
347 mutex_opts(opts,[qw('log logfile'),qw('rcfile profile'),
348 qw('classic profile'),qw('classic rcfile')])
348 qw('classic profile'),qw('classic rcfile')])
349
349
350 #---------------------------------------------------------------------------
350 #---------------------------------------------------------------------------
351 # Log replay
351 # Log replay
352
352
353 # if -logplay, we need to 'become' the other session. That basically means
353 # if -logplay, we need to 'become' the other session. That basically means
354 # replacing the current command line environment with that of the old
354 # replacing the current command line environment with that of the old
355 # session and moving on.
355 # session and moving on.
356
356
357 # this is needed so that later we know we're in session reload mode, as
357 # this is needed so that later we know we're in session reload mode, as
358 # opts_all will get overwritten:
358 # opts_all will get overwritten:
359 load_logplay = 0
359 load_logplay = 0
360
360
361 if opts_all.logplay:
361 if opts_all.logplay:
362 load_logplay = opts_all.logplay
362 load_logplay = opts_all.logplay
363 opts_debug_save = opts_all.debug
363 opts_debug_save = opts_all.debug
364 try:
364 try:
365 logplay = open(opts_all.logplay)
365 logplay = open(opts_all.logplay)
366 except IOError:
366 except IOError:
367 if opts_all.debug: IP.InteractiveTB()
367 if opts_all.debug: IP.InteractiveTB()
368 warn('Could not open logplay file '+`opts_all.logplay`)
368 warn('Could not open logplay file '+`opts_all.logplay`)
369 # restore state as if nothing had happened and move on, but make
369 # restore state as if nothing had happened and move on, but make
370 # sure that later we don't try to actually load the session file
370 # sure that later we don't try to actually load the session file
371 logplay = None
371 logplay = None
372 load_logplay = 0
372 load_logplay = 0
373 del opts_all.logplay
373 del opts_all.logplay
374 else:
374 else:
375 try:
375 try:
376 logplay.readline()
376 logplay.readline()
377 logplay.readline();
377 logplay.readline();
378 # this reloads that session's command line
378 # this reloads that session's command line
379 cmd = logplay.readline()[6:]
379 cmd = logplay.readline()[6:]
380 exec cmd
380 exec cmd
381 # restore the true debug flag given so that the process of
381 # restore the true debug flag given so that the process of
382 # session loading itself can be monitored.
382 # session loading itself can be monitored.
383 opts.debug = opts_debug_save
383 opts.debug = opts_debug_save
384 # save the logplay flag so later we don't overwrite the log
384 # save the logplay flag so later we don't overwrite the log
385 opts.logplay = load_logplay
385 opts.logplay = load_logplay
386 # now we must update our own structure with defaults
386 # now we must update our own structure with defaults
387 opts_all.update(opts)
387 opts_all.update(opts)
388 # now load args
388 # now load args
389 cmd = logplay.readline()[6:]
389 cmd = logplay.readline()[6:]
390 exec cmd
390 exec cmd
391 logplay.close()
391 logplay.close()
392 except:
392 except:
393 logplay.close()
393 logplay.close()
394 if opts_all.debug: IP.InteractiveTB()
394 if opts_all.debug: IP.InteractiveTB()
395 warn("Logplay file lacking full configuration information.\n"
395 warn("Logplay file lacking full configuration information.\n"
396 "I'll try to read it, but some things may not work.")
396 "I'll try to read it, but some things may not work.")
397
397
398 #-------------------------------------------------------------------------
398 #-------------------------------------------------------------------------
399 # set up output traps: catch all output from files, being run, modules
399 # set up output traps: catch all output from files, being run, modules
400 # loaded, etc. Then give it to the user in a clean form at the end.
400 # loaded, etc. Then give it to the user in a clean form at the end.
401
401
402 msg_out = 'Output messages. '
402 msg_out = 'Output messages. '
403 msg_err = 'Error messages. '
403 msg_err = 'Error messages. '
404 msg_sep = '\n'
404 msg_sep = '\n'
405 msg = Struct(config = OutputTrap('Configuration Loader',msg_out,
405 msg = Struct(config = OutputTrap('Configuration Loader',msg_out,
406 msg_err,msg_sep,debug,
406 msg_err,msg_sep,debug,
407 quiet_out=1),
407 quiet_out=1),
408 user_exec = OutputTrap('User File Execution',msg_out,
408 user_exec = OutputTrap('User File Execution',msg_out,
409 msg_err,msg_sep,debug),
409 msg_err,msg_sep,debug),
410 logplay = OutputTrap('Log Loader',msg_out,
410 logplay = OutputTrap('Log Loader',msg_out,
411 msg_err,msg_sep,debug),
411 msg_err,msg_sep,debug),
412 summary = ''
412 summary = ''
413 )
413 )
414
414
415 #-------------------------------------------------------------------------
415 #-------------------------------------------------------------------------
416 # Process user ipythonrc-type configuration files
416 # Process user ipythonrc-type configuration files
417
417
418 # turn on output trapping and log to msg.config
418 # turn on output trapping and log to msg.config
419 # remember that with debug on, trapping is actually disabled
419 # remember that with debug on, trapping is actually disabled
420 msg.config.trap_all()
420 msg.config.trap_all()
421
421
422 # look for rcfile in current or default directory
422 # look for rcfile in current or default directory
423 try:
423 try:
424 opts_all.rcfile = filefind(opts_all.rcfile,opts_all.ipythondir)
424 opts_all.rcfile = filefind(opts_all.rcfile,opts_all.ipythondir)
425 except IOError:
425 except IOError:
426 if opts_all.debug: IP.InteractiveTB()
426 if opts_all.debug: IP.InteractiveTB()
427 warn('Configuration file %s not found. Ignoring request.'
427 warn('Configuration file %s not found. Ignoring request.'
428 % (opts_all.rcfile) )
428 % (opts_all.rcfile) )
429
429
430 # 'profiles' are a shorthand notation for config filenames
430 # 'profiles' are a shorthand notation for config filenames
431 profile_handled_by_legacy = False
431 profile_handled_by_legacy = False
432 if opts_all.profile:
432 if opts_all.profile:
433
433
434 try:
434 try:
435 opts_all.rcfile = filefind('ipythonrc-' + opts_all.profile
435 opts_all.rcfile = filefind('ipythonrc-' + opts_all.profile
436 + rc_suffix,
436 + rc_suffix,
437 opts_all.ipythondir)
437 opts_all.ipythondir)
438 profile_handled_by_legacy = True
438 profile_handled_by_legacy = True
439 except IOError:
439 except IOError:
440 if opts_all.debug: IP.InteractiveTB()
440 if opts_all.debug: IP.InteractiveTB()
441 opts.profile = '' # remove profile from options if invalid
441 opts.profile = '' # remove profile from options if invalid
442 # We won't warn anymore, primary method is ipy_profile_PROFNAME
442 # We won't warn anymore, primary method is ipy_profile_PROFNAME
443 # which does trigger a warning.
443 # which does trigger a warning.
444
444
445 # load the config file
445 # load the config file
446 rcfiledata = None
446 rcfiledata = None
447 if opts_all.quick:
447 if opts_all.quick:
448 print 'Launching IPython in quick mode. No config file read.'
448 print 'Launching IPython in quick mode. No config file read.'
449 elif opts_all.rcfile:
449 elif opts_all.rcfile:
450 try:
450 try:
451 cfg_loader = ConfigLoader(conflict)
451 cfg_loader = ConfigLoader(conflict)
452 rcfiledata = cfg_loader.load(opts_all.rcfile,typeconv,
452 rcfiledata = cfg_loader.load(opts_all.rcfile,typeconv,
453 'include',opts_all.ipythondir,
453 'include',opts_all.ipythondir,
454 purge = 1,
454 purge = 1,
455 unique = conflict['preserve'])
455 unique = conflict['preserve'])
456 except:
456 except:
457 IP.InteractiveTB()
457 IP.InteractiveTB()
458 warn('Problems loading configuration file '+
458 warn('Problems loading configuration file '+
459 `opts_all.rcfile`+
459 `opts_all.rcfile`+
460 '\nStarting with default -bare bones- configuration.')
460 '\nStarting with default -bare bones- configuration.')
461 else:
461 else:
462 warn('No valid configuration file found in either currrent directory\n'+
462 warn('No valid configuration file found in either currrent directory\n'+
463 'or in the IPython config. directory: '+`opts_all.ipythondir`+
463 'or in the IPython config. directory: '+`opts_all.ipythondir`+
464 '\nProceeding with internal defaults.')
464 '\nProceeding with internal defaults.')
465
465
466 #------------------------------------------------------------------------
466 #------------------------------------------------------------------------
467 # Set exception handlers in mode requested by user.
467 # Set exception handlers in mode requested by user.
468 otrap = OutputTrap(trap_out=1) # trap messages from magic_xmode
468 otrap = OutputTrap(trap_out=1) # trap messages from magic_xmode
469 IP.magic_xmode(opts_all.xmode)
469 IP.magic_xmode(opts_all.xmode)
470 otrap.release_out()
470 otrap.release_out()
471
471
472 #------------------------------------------------------------------------
472 #------------------------------------------------------------------------
473 # Execute user config
473 # Execute user config
474
474
475 # Create a valid config structure with the right precedence order:
475 # Create a valid config structure with the right precedence order:
476 # defaults < rcfile < command line. This needs to be in the instance, so
476 # defaults < rcfile < command line. This needs to be in the instance, so
477 # that method calls below that rely on it find it.
477 # that method calls below that rely on it find it.
478 IP.rc = rc_def.copy()
478 IP.rc = rc_def.copy()
479
479
480 # Work with a local alias inside this routine to avoid unnecessary
480 # Work with a local alias inside this routine to avoid unnecessary
481 # attribute lookups.
481 # attribute lookups.
482 IP_rc = IP.rc
482 IP_rc = IP.rc
483
483
484 IP_rc.update(opts_def)
484 IP_rc.update(opts_def)
485 if rcfiledata:
485 if rcfiledata:
486 # now we can update
486 # now we can update
487 IP_rc.update(rcfiledata)
487 IP_rc.update(rcfiledata)
488 IP_rc.update(opts)
488 IP_rc.update(opts)
489 IP_rc.update(rc_override)
489 IP_rc.update(rc_override)
490
490
491 # Store the original cmd line for reference:
491 # Store the original cmd line for reference:
492 IP_rc.opts = opts
492 IP_rc.opts = opts
493 IP_rc.args = args
493 IP_rc.args = args
494
494
495 # create a *runtime* Struct like rc for holding parameters which may be
495 # create a *runtime* Struct like rc for holding parameters which may be
496 # created and/or modified by runtime user extensions.
496 # created and/or modified by runtime user extensions.
497 IP.runtime_rc = Struct()
497 IP.runtime_rc = Struct()
498
498
499 # from this point on, all config should be handled through IP_rc,
499 # from this point on, all config should be handled through IP_rc,
500 # opts* shouldn't be used anymore.
500 # opts* shouldn't be used anymore.
501
501
502
502
503 # update IP_rc with some special things that need manual
503 # update IP_rc with some special things that need manual
504 # tweaks. Basically options which affect other options. I guess this
504 # tweaks. Basically options which affect other options. I guess this
505 # should just be written so that options are fully orthogonal and we
505 # should just be written so that options are fully orthogonal and we
506 # wouldn't worry about this stuff!
506 # wouldn't worry about this stuff!
507
507
508 if IP_rc.classic:
508 if IP_rc.classic:
509 IP_rc.quick = 1
509 IP_rc.quick = 1
510 IP_rc.cache_size = 0
510 IP_rc.cache_size = 0
511 IP_rc.pprint = 0
511 IP_rc.pprint = 0
512 IP_rc.prompt_in1 = '>>> '
512 IP_rc.prompt_in1 = '>>> '
513 IP_rc.prompt_in2 = '... '
513 IP_rc.prompt_in2 = '... '
514 IP_rc.prompt_out = ''
514 IP_rc.prompt_out = ''
515 IP_rc.separate_in = IP_rc.separate_out = IP_rc.separate_out2 = '0'
515 IP_rc.separate_in = IP_rc.separate_out = IP_rc.separate_out2 = '0'
516 IP_rc.colors = 'NoColor'
516 IP_rc.colors = 'NoColor'
517 IP_rc.xmode = 'Plain'
517 IP_rc.xmode = 'Plain'
518
518
519 IP.pre_config_initialization()
519 IP.pre_config_initialization()
520 # configure readline
520 # configure readline
521
521
522 # update exception handlers with rc file status
522 # update exception handlers with rc file status
523 otrap.trap_out() # I don't want these messages ever.
523 otrap.trap_out() # I don't want these messages ever.
524 IP.magic_xmode(IP_rc.xmode)
524 IP.magic_xmode(IP_rc.xmode)
525 otrap.release_out()
525 otrap.release_out()
526
526
527 # activate logging if requested and not reloading a log
527 # activate logging if requested and not reloading a log
528 if IP_rc.logplay:
528 if IP_rc.logplay:
529 IP.magic_logstart(IP_rc.logplay + ' append')
529 IP.magic_logstart(IP_rc.logplay + ' append')
530 elif IP_rc.logfile:
530 elif IP_rc.logfile:
531 IP.magic_logstart(IP_rc.logfile)
531 IP.magic_logstart(IP_rc.logfile)
532 elif IP_rc.log:
532 elif IP_rc.log:
533 IP.magic_logstart()
533 IP.magic_logstart()
534
534
535 # find user editor so that it we don't have to look it up constantly
535 # find user editor so that it we don't have to look it up constantly
536 if IP_rc.editor.strip()=='0':
536 if IP_rc.editor.strip()=='0':
537 try:
537 try:
538 ed = os.environ['EDITOR']
538 ed = os.environ['EDITOR']
539 except KeyError:
539 except KeyError:
540 if os.name == 'posix':
540 if os.name == 'posix':
541 ed = 'vi' # the only one guaranteed to be there!
541 ed = 'vi' # the only one guaranteed to be there!
542 else:
542 else:
543 ed = 'notepad' # same in Windows!
543 ed = 'notepad' # same in Windows!
544 IP_rc.editor = ed
544 IP_rc.editor = ed
545
545
546 # Keep track of whether this is an embedded instance or not (useful for
546 # Keep track of whether this is an embedded instance or not (useful for
547 # post-mortems).
547 # post-mortems).
548 IP_rc.embedded = IP.embedded
548 IP_rc.embedded = IP.embedded
549
549
550 # Recursive reload
550 # Recursive reload
551 try:
551 try:
552 from IPython.lib import deepreload
552 from IPython.lib import deepreload
553 if IP_rc.deep_reload:
553 if IP_rc.deep_reload:
554 __builtin__.reload = deepreload.reload
554 __builtin__.reload = deepreload.reload
555 else:
555 else:
556 __builtin__.dreload = deepreload.reload
556 __builtin__.dreload = deepreload.reload
557 del deepreload
557 del deepreload
558 except ImportError:
558 except ImportError:
559 pass
559 pass
560
560
561 # Save the current state of our namespace so that the interactive shell
561 # Save the current state of our namespace so that the interactive shell
562 # can later know which variables have been created by us from config files
562 # can later know which variables have been created by us from config files
563 # and loading. This way, loading a file (in any way) is treated just like
563 # and loading. This way, loading a file (in any way) is treated just like
564 # defining things on the command line, and %who works as expected.
564 # defining things on the command line, and %who works as expected.
565
565
566 # DON'T do anything that affects the namespace beyond this point!
566 # DON'T do anything that affects the namespace beyond this point!
567 IP.internal_ns.update(__main__.__dict__)
567 IP.internal_ns.update(__main__.__dict__)
568
568
569 #IP.internal_ns.update(locals()) # so our stuff doesn't show up in %who
569 #IP.internal_ns.update(locals()) # so our stuff doesn't show up in %who
570
570
571 # Now run through the different sections of the users's config
571 # Now run through the different sections of the users's config
572 if IP_rc.debug:
572 if IP_rc.debug:
573 print 'Trying to execute the following configuration structure:'
573 print 'Trying to execute the following configuration structure:'
574 print '(Things listed first are deeper in the inclusion tree and get'
574 print '(Things listed first are deeper in the inclusion tree and get'
575 print 'loaded first).\n'
575 print 'loaded first).\n'
576 pprint(IP_rc.__dict__)
576 pprint(IP_rc.__dict__)
577
577
578 for mod in IP_rc.import_mod:
578 for mod in IP_rc.import_mod:
579 try:
579 try:
580 exec 'import '+mod in IP.user_ns
580 exec 'import '+mod in IP.user_ns
581 except :
581 except :
582 IP.InteractiveTB()
582 IP.InteractiveTB()
583 import_fail_info(mod)
583 import_fail_info(mod)
584
584
585 for mod_fn in IP_rc.import_some:
585 for mod_fn in IP_rc.import_some:
586 if not mod_fn == []:
586 if not mod_fn == []:
587 mod,fn = mod_fn[0],','.join(mod_fn[1:])
587 mod,fn = mod_fn[0],','.join(mod_fn[1:])
588 try:
588 try:
589 exec 'from '+mod+' import '+fn in IP.user_ns
589 exec 'from '+mod+' import '+fn in IP.user_ns
590 except :
590 except :
591 IP.InteractiveTB()
591 IP.InteractiveTB()
592 import_fail_info(mod,fn)
592 import_fail_info(mod,fn)
593
593
594 for mod in IP_rc.import_all:
594 for mod in IP_rc.import_all:
595 try:
595 try:
596 exec 'from '+mod+' import *' in IP.user_ns
596 exec 'from '+mod+' import *' in IP.user_ns
597 except :
597 except :
598 IP.InteractiveTB()
598 IP.InteractiveTB()
599 import_fail_info(mod)
599 import_fail_info(mod)
600
600
601 for code in IP_rc.execute:
601 for code in IP_rc.execute:
602 try:
602 try:
603 exec code in IP.user_ns
603 exec code in IP.user_ns
604 except:
604 except:
605 IP.InteractiveTB()
605 IP.InteractiveTB()
606 warn('Failure executing code: ' + `code`)
606 warn('Failure executing code: ' + `code`)
607
607
608 # Execute the files the user wants in ipythonrc
608 # Execute the files the user wants in ipythonrc
609 for file in IP_rc.execfile:
609 for file in IP_rc.execfile:
610 try:
610 try:
611 file = filefind(file,sys.path+[IPython_dir])
611 file = filefind(file,sys.path+[IPython_dir])
612 except IOError:
612 except IOError:
613 warn(itpl('File $file not found. Skipping it.'))
613 warn(itpl('File $file not found. Skipping it.'))
614 else:
614 else:
615 IP.safe_execfile(os.path.expanduser(file),IP.user_ns)
615 IP.safe_execfile(os.path.expanduser(file),IP.user_ns)
616
616
617 # finally, try importing ipy_*_conf for final configuration
617 # finally, try importing ipy_*_conf for final configuration
618 try:
618 try:
619 import ipy_system_conf
619 import ipy_system_conf
620 except ImportError:
620 except ImportError:
621 if opts_all.debug: IP.InteractiveTB()
621 if opts_all.debug: IP.InteractiveTB()
622 warn("Could not import 'ipy_system_conf'")
622 warn("Could not import 'ipy_system_conf'")
623 except:
623 except:
624 IP.InteractiveTB()
624 IP.InteractiveTB()
625 import_fail_info('ipy_system_conf')
625 import_fail_info('ipy_system_conf')
626
626
627 # only import prof module if ipythonrc-PROF was not found
627 # only import prof module if ipythonrc-PROF was not found
628 if opts_all.profile and not profile_handled_by_legacy:
628 if opts_all.profile and not profile_handled_by_legacy:
629 profmodname = 'ipy_profile_' + opts_all.profile
629 profmodname = 'ipy_profile_' + opts_all.profile
630 try:
630 try:
631 force_import(profmodname)
631 force_import(profmodname)
632 except:
632 except:
633 IP.InteractiveTB()
633 IP.InteractiveTB()
634 print "Error importing",profmodname,\
634 print "Error importing",profmodname,\
635 "- perhaps you should run %upgrade?"
635 "- perhaps you should run %upgrade?"
636 import_fail_info(profmodname)
636 import_fail_info(profmodname)
637 else:
637 else:
638 opts.profile = opts_all.profile
638 opts.profile = opts_all.profile
639 else:
639 else:
640 force_import('ipy_profile_none')
640 force_import('ipy_profile_none')
641 # XXX - this is wrong: ipy_user_conf should not be loaded unconditionally,
641 # XXX - this is wrong: ipy_user_conf should not be loaded unconditionally,
642 # since the user could have specified a config file path by hand.
642 # since the user could have specified a config file path by hand.
643 try:
643 try:
644 force_import('ipy_user_conf')
644 force_import('ipy_user_conf')
645 except:
645 except:
646 conf = opts_all.ipythondir + "/ipy_user_conf.py"
646 conf = opts_all.ipythondir + "/ipy_user_conf.py"
647 IP.InteractiveTB()
647 IP.InteractiveTB()
648 if not os.path.isfile(conf):
648 if not os.path.isfile(conf):
649 warn(conf + ' does not exist, please run %upgrade!')
649 warn(conf + ' does not exist, please run %upgrade!')
650
650
651 import_fail_info("ipy_user_conf")
651 import_fail_info("ipy_user_conf")
652
652
653 # Define the history file for saving commands in between sessions
653 # Define the history file for saving commands in between sessions
654 try:
654 try:
655 histfname = 'history-%s' % opts.profile
655 histfname = 'history-%s' % opts.profile
656 except AttributeError:
656 except AttributeError:
657 histfname = 'history'
657 histfname = 'history'
658 IP.histfile = os.path.join(opts_all.ipythondir,histfname)
658 IP.histfile = os.path.join(opts_all.ipythondir,histfname)
659
659
660 # finally, push the argv to options again to ensure highest priority
660 # finally, push the argv to options again to ensure highest priority
661 IP_rc.update(opts)
661 IP_rc.update(opts)
662
662
663 # release stdout and stderr and save config log into a global summary
663 # release stdout and stderr and save config log into a global summary
664 msg.config.release_all()
664 msg.config.release_all()
665 if IP_rc.messages:
665 if IP_rc.messages:
666 msg.summary += msg.config.summary_all()
666 msg.summary += msg.config.summary_all()
667
667
668 #------------------------------------------------------------------------
668 #------------------------------------------------------------------------
669 # Setup interactive session
669 # Setup interactive session
670
670
671 # Now we should be fully configured. We can then execute files or load
671 # Now we should be fully configured. We can then execute files or load
672 # things only needed for interactive use. Then we'll open the shell.
672 # things only needed for interactive use. Then we'll open the shell.
673
673
674 # Take a snapshot of the user namespace before opening the shell. That way
674 # Take a snapshot of the user namespace before opening the shell. That way
675 # we'll be able to identify which things were interactively defined and
675 # we'll be able to identify which things were interactively defined and
676 # which were defined through config files.
676 # which were defined through config files.
677 IP.user_config_ns.update(IP.user_ns)
677 IP.user_config_ns.update(IP.user_ns)
678
678
679 # Force reading a file as if it were a session log. Slower but safer.
679 # Force reading a file as if it were a session log. Slower but safer.
680 if load_logplay:
680 if load_logplay:
681 print 'Replaying log...'
681 print 'Replaying log...'
682 try:
682 try:
683 if IP_rc.debug:
683 if IP_rc.debug:
684 logplay_quiet = 0
684 logplay_quiet = 0
685 else:
685 else:
686 logplay_quiet = 1
686 logplay_quiet = 1
687
687
688 msg.logplay.trap_all()
688 msg.logplay.trap_all()
689 IP.safe_execfile(load_logplay,IP.user_ns,
689 IP.safe_execfile(load_logplay,IP.user_ns,
690 islog = 1, quiet = logplay_quiet)
690 islog = 1, quiet = logplay_quiet)
691 msg.logplay.release_all()
691 msg.logplay.release_all()
692 if IP_rc.messages:
692 if IP_rc.messages:
693 msg.summary += msg.logplay.summary_all()
693 msg.summary += msg.logplay.summary_all()
694 except:
694 except:
695 warn('Problems replaying logfile %s.' % load_logplay)
695 warn('Problems replaying logfile %s.' % load_logplay)
696 IP.InteractiveTB()
696 IP.InteractiveTB()
697
697
698 # Load remaining files in command line
698 # Load remaining files in command line
699 msg.user_exec.trap_all()
699 msg.user_exec.trap_all()
700
700
701 # Do NOT execute files named in the command line as scripts to be loaded
701 # Do NOT execute files named in the command line as scripts to be loaded
702 # by embedded instances. Doing so has the potential for an infinite
702 # by embedded instances. Doing so has the potential for an infinite
703 # recursion if there are exceptions thrown in the process.
703 # recursion if there are exceptions thrown in the process.
704
704
705 # XXX FIXME: the execution of user files should be moved out to after
705 # XXX FIXME: the execution of user files should be moved out to after
706 # ipython is fully initialized, just as if they were run via %run at the
706 # ipython is fully initialized, just as if they were run via %run at the
707 # ipython prompt. This would also give them the benefit of ipython's
707 # ipython prompt. This would also give them the benefit of ipython's
708 # nice tracebacks.
708 # nice tracebacks.
709
709
710 if (not embedded and IP_rc.args and
710 if (not embedded and IP_rc.args and
711 not IP_rc.args[0].lower().endswith('.ipy')):
711 not IP_rc.args[0].lower().endswith('.ipy')):
712 name_save = IP.user_ns['__name__']
712 name_save = IP.user_ns['__name__']
713 IP.user_ns['__name__'] = '__main__'
713 IP.user_ns['__name__'] = '__main__'
714 # Set our own excepthook in case the user code tries to call it
714 # Set our own excepthook in case the user code tries to call it
715 # directly. This prevents triggering the IPython crash handler.
715 # directly. This prevents triggering the IPython crash handler.
716 old_excepthook,sys.excepthook = sys.excepthook, IP.excepthook
716 old_excepthook,sys.excepthook = sys.excepthook, IP.excepthook
717
717
718 save_argv = sys.argv[1:] # save it for later restoring
718 save_argv = sys.argv[1:] # save it for later restoring
719
719
720 sys.argv = args
720 sys.argv = args
721
721
722 try:
722 try:
723 IP.safe_execfile(args[0], IP.user_ns)
723 IP.safe_execfile(args[0], IP.user_ns)
724 finally:
724 finally:
725 # Reset our crash handler in place
725 # Reset our crash handler in place
726 sys.excepthook = old_excepthook
726 sys.excepthook = old_excepthook
727 sys.argv[:] = save_argv
727 sys.argv[:] = save_argv
728 IP.user_ns['__name__'] = name_save
728 IP.user_ns['__name__'] = name_save
729
729
730 msg.user_exec.release_all()
730 msg.user_exec.release_all()
731
731
732 if IP_rc.messages:
732 if IP_rc.messages:
733 msg.summary += msg.user_exec.summary_all()
733 msg.summary += msg.user_exec.summary_all()
734
734
735 # since we can't specify a null string on the cmd line, 0 is the equivalent:
735 # since we can't specify a null string on the cmd line, 0 is the equivalent:
736 if IP_rc.nosep:
736 if IP_rc.nosep:
737 IP_rc.separate_in = IP_rc.separate_out = IP_rc.separate_out2 = '0'
737 IP_rc.separate_in = IP_rc.separate_out = IP_rc.separate_out2 = '0'
738 if IP_rc.separate_in == '0': IP_rc.separate_in = ''
738 if IP_rc.separate_in == '0': IP_rc.separate_in = ''
739 if IP_rc.separate_out == '0': IP_rc.separate_out = ''
739 if IP_rc.separate_out == '0': IP_rc.separate_out = ''
740 if IP_rc.separate_out2 == '0': IP_rc.separate_out2 = ''
740 if IP_rc.separate_out2 == '0': IP_rc.separate_out2 = ''
741 IP_rc.separate_in = IP_rc.separate_in.replace('\\n','\n')
741 IP_rc.separate_in = IP_rc.separate_in.replace('\\n','\n')
742 IP_rc.separate_out = IP_rc.separate_out.replace('\\n','\n')
742 IP_rc.separate_out = IP_rc.separate_out.replace('\\n','\n')
743 IP_rc.separate_out2 = IP_rc.separate_out2.replace('\\n','\n')
743 IP_rc.separate_out2 = IP_rc.separate_out2.replace('\\n','\n')
744
744
745 # Determine how many lines at the bottom of the screen are needed for
745 # Determine how many lines at the bottom of the screen are needed for
746 # showing prompts, so we can know wheter long strings are to be printed or
746 # showing prompts, so we can know wheter long strings are to be printed or
747 # paged:
747 # paged:
748 num_lines_bot = IP_rc.separate_in.count('\n')+1
748 num_lines_bot = IP_rc.separate_in.count('\n')+1
749 IP_rc.screen_length = IP_rc.screen_length - num_lines_bot
749 IP_rc.screen_length = IP_rc.screen_length - num_lines_bot
750
750
751 # configure startup banner
751 # configure startup banner
752 if IP_rc.c: # regular python doesn't print the banner with -c
752 if IP_rc.c: # regular python doesn't print the banner with -c
753 IP_rc.banner = 0
753 IP_rc.banner = 0
754 if IP_rc.banner:
754 if IP_rc.banner:
755 BANN_P = IP.BANNER_PARTS
755 BANN_P = IP.BANNER_PARTS
756 else:
756 else:
757 BANN_P = []
757 BANN_P = []
758
758
759 if IP_rc.profile: BANN_P.append('IPython profile: %s\n' % IP_rc.profile)
759 if IP_rc.profile: BANN_P.append('IPython profile: %s\n' % IP_rc.profile)
760
760
761 # add message log (possibly empty)
761 # add message log (possibly empty)
762 if msg.summary: BANN_P.append(msg.summary)
762 if msg.summary: BANN_P.append(msg.summary)
763 # Final banner is a string
763 # Final banner is a string
764 IP.BANNER = '\n'.join(BANN_P)
764 IP.BANNER = '\n'.join(BANN_P)
765
765
766 # Finalize the IPython instance. This assumes the rc structure is fully
766 # Finalize the IPython instance. This assumes the rc structure is fully
767 # in place.
767 # in place.
768 IP.post_config_initialization()
768 IP.post_config_initialization()
769
769
770 return IP
770 return IP
771 #************************ end of file <ipmaker.py> **************************
771 #************************ end of file <ipmaker.py> **************************
@@ -1,171 +1,171 b''
1 # encoding: utf-8
1 # encoding: utf-8
2
2
3 """Magic command interface for interactive parallel work."""
3 """Magic command interface for interactive parallel work."""
4
4
5 __docformat__ = "restructuredtext en"
5 __docformat__ = "restructuredtext en"
6
6
7 #-------------------------------------------------------------------------------
7 #-------------------------------------------------------------------------------
8 # Copyright (C) 2008 The IPython Development Team
8 # Copyright (C) 2008 The IPython Development Team
9 #
9 #
10 # Distributed under the terms of the BSD License. The full license is in
10 # Distributed under the terms of the BSD License. The full license is in
11 # the file COPYING, distributed as part of this software.
11 # the file COPYING, distributed as part of this software.
12 #-------------------------------------------------------------------------------
12 #-------------------------------------------------------------------------------
13
13
14 #-------------------------------------------------------------------------------
14 #-------------------------------------------------------------------------------
15 # Imports
15 # Imports
16 #-------------------------------------------------------------------------------
16 #-------------------------------------------------------------------------------
17
17
18 import new
18 import new
19
19
20 from IPython.iplib import InteractiveShell
20 from IPython.core.iplib import InteractiveShell
21 from IPython.Shell import MTInteractiveShell
21 from IPython.Shell import MTInteractiveShell
22
22
23 from twisted.internet.defer import Deferred
23 from twisted.internet.defer import Deferred
24
24
25
25
26 #-------------------------------------------------------------------------------
26 #-------------------------------------------------------------------------------
27 # Definitions of magic functions for use with IPython
27 # Definitions of magic functions for use with IPython
28 #-------------------------------------------------------------------------------
28 #-------------------------------------------------------------------------------
29
29
30 NO_ACTIVE_CONTROLLER = """
30 NO_ACTIVE_CONTROLLER = """
31 Error: No Controller is activated
31 Error: No Controller is activated
32 Use activate() on a RemoteController object to activate it for magics.
32 Use activate() on a RemoteController object to activate it for magics.
33 """
33 """
34
34
35 def magic_result(self,parameter_s=''):
35 def magic_result(self,parameter_s=''):
36 """Print the result of command i on all engines of the active controller.
36 """Print the result of command i on all engines of the active controller.
37
37
38 To activate a controller in IPython, first create it and then call
38 To activate a controller in IPython, first create it and then call
39 the activate() method.
39 the activate() method.
40
40
41 Then you can do the following:
41 Then you can do the following:
42
42
43 >>> result # Print the latest result
43 >>> result # Print the latest result
44 Printing result...
44 Printing result...
45 [127.0.0.1:0] In [1]: b = 10
45 [127.0.0.1:0] In [1]: b = 10
46 [127.0.0.1:1] In [1]: b = 10
46 [127.0.0.1:1] In [1]: b = 10
47
47
48 >>> result 0 # Print result 0
48 >>> result 0 # Print result 0
49 In [14]: result 0
49 In [14]: result 0
50 Printing result...
50 Printing result...
51 [127.0.0.1:0] In [0]: a = 5
51 [127.0.0.1:0] In [0]: a = 5
52 [127.0.0.1:1] In [0]: a = 5
52 [127.0.0.1:1] In [0]: a = 5
53 """
53 """
54 try:
54 try:
55 activeController = __IPYTHON__.activeController
55 activeController = __IPYTHON__.activeController
56 except AttributeError:
56 except AttributeError:
57 print NO_ACTIVE_CONTROLLER
57 print NO_ACTIVE_CONTROLLER
58 else:
58 else:
59 try:
59 try:
60 index = int(parameter_s)
60 index = int(parameter_s)
61 except:
61 except:
62 index = None
62 index = None
63 result = activeController.get_result(index)
63 result = activeController.get_result(index)
64 return result
64 return result
65
65
66 def magic_px(self,parameter_s=''):
66 def magic_px(self,parameter_s=''):
67 """Executes the given python command on the active IPython Controller.
67 """Executes the given python command on the active IPython Controller.
68
68
69 To activate a Controller in IPython, first create it and then call
69 To activate a Controller in IPython, first create it and then call
70 the activate() method.
70 the activate() method.
71
71
72 Then you can do the following:
72 Then you can do the following:
73
73
74 >>> %px a = 5 # Runs a = 5 on all nodes
74 >>> %px a = 5 # Runs a = 5 on all nodes
75 """
75 """
76
76
77 try:
77 try:
78 activeController = __IPYTHON__.activeController
78 activeController = __IPYTHON__.activeController
79 except AttributeError:
79 except AttributeError:
80 print NO_ACTIVE_CONTROLLER
80 print NO_ACTIVE_CONTROLLER
81 else:
81 else:
82 print "Parallel execution on engines: %s" % activeController.targets
82 print "Parallel execution on engines: %s" % activeController.targets
83 result = activeController.execute(parameter_s)
83 result = activeController.execute(parameter_s)
84 return result
84 return result
85
85
86 def pxrunsource(self, source, filename="<input>", symbol="single"):
86 def pxrunsource(self, source, filename="<input>", symbol="single"):
87
87
88 try:
88 try:
89 code = self.compile(source, filename, symbol)
89 code = self.compile(source, filename, symbol)
90 except (OverflowError, SyntaxError, ValueError):
90 except (OverflowError, SyntaxError, ValueError):
91 # Case 1
91 # Case 1
92 self.showsyntaxerror(filename)
92 self.showsyntaxerror(filename)
93 return None
93 return None
94
94
95 if code is None:
95 if code is None:
96 # Case 2
96 # Case 2
97 return True
97 return True
98
98
99 # Case 3
99 # Case 3
100 # Because autopx is enabled, we now call executeAll or disable autopx if
100 # Because autopx is enabled, we now call executeAll or disable autopx if
101 # %autopx or autopx has been called
101 # %autopx or autopx has been called
102 if '_ip.magic("%autopx' in source or '_ip.magic("autopx' in source:
102 if '_ip.magic("%autopx' in source or '_ip.magic("autopx' in source:
103 _disable_autopx(self)
103 _disable_autopx(self)
104 return False
104 return False
105 else:
105 else:
106 try:
106 try:
107 result = self.activeController.execute(source)
107 result = self.activeController.execute(source)
108 except:
108 except:
109 self.showtraceback()
109 self.showtraceback()
110 else:
110 else:
111 print result.__repr__()
111 print result.__repr__()
112 return False
112 return False
113
113
114 def magic_autopx(self, parameter_s=''):
114 def magic_autopx(self, parameter_s=''):
115 """Toggles auto parallel mode for the active IPython Controller.
115 """Toggles auto parallel mode for the active IPython Controller.
116
116
117 To activate a Controller in IPython, first create it and then call
117 To activate a Controller in IPython, first create it and then call
118 the activate() method.
118 the activate() method.
119
119
120 Then you can do the following:
120 Then you can do the following:
121
121
122 >>> %autopx # Now all commands are executed in parallel
122 >>> %autopx # Now all commands are executed in parallel
123 Auto Parallel Enabled
123 Auto Parallel Enabled
124 Type %autopx to disable
124 Type %autopx to disable
125 ...
125 ...
126 >>> %autopx # Now all commands are locally executed
126 >>> %autopx # Now all commands are locally executed
127 Auto Parallel Disabled
127 Auto Parallel Disabled
128 """
128 """
129
129
130 if hasattr(self, 'autopx'):
130 if hasattr(self, 'autopx'):
131 if self.autopx == True:
131 if self.autopx == True:
132 _disable_autopx(self)
132 _disable_autopx(self)
133 else:
133 else:
134 _enable_autopx(self)
134 _enable_autopx(self)
135 else:
135 else:
136 _enable_autopx(self)
136 _enable_autopx(self)
137
137
138 def _enable_autopx(self):
138 def _enable_autopx(self):
139 """Enable %autopx mode by saving the original runsource and installing
139 """Enable %autopx mode by saving the original runsource and installing
140 pxrunsource.
140 pxrunsource.
141 """
141 """
142 try:
142 try:
143 activeController = __IPYTHON__.activeController
143 activeController = __IPYTHON__.activeController
144 except AttributeError:
144 except AttributeError:
145 print "No active RemoteController found, use RemoteController.activate()."
145 print "No active RemoteController found, use RemoteController.activate()."
146 else:
146 else:
147 self._original_runsource = self.runsource
147 self._original_runsource = self.runsource
148 self.runsource = new.instancemethod(pxrunsource, self, self.__class__)
148 self.runsource = new.instancemethod(pxrunsource, self, self.__class__)
149 self.autopx = True
149 self.autopx = True
150 print "Auto Parallel Enabled\nType %autopx to disable"
150 print "Auto Parallel Enabled\nType %autopx to disable"
151
151
152 def _disable_autopx(self):
152 def _disable_autopx(self):
153 """Disable %autopx by restoring the original runsource."""
153 """Disable %autopx by restoring the original runsource."""
154 if hasattr(self, 'autopx'):
154 if hasattr(self, 'autopx'):
155 if self.autopx == True:
155 if self.autopx == True:
156 self.runsource = self._original_runsource
156 self.runsource = self._original_runsource
157 self.autopx = False
157 self.autopx = False
158 print "Auto Parallel Disabled"
158 print "Auto Parallel Disabled"
159
159
160 # Add the new magic function to the class dict:
160 # Add the new magic function to the class dict:
161
161
162 InteractiveShell.magic_result = magic_result
162 InteractiveShell.magic_result = magic_result
163 InteractiveShell.magic_px = magic_px
163 InteractiveShell.magic_px = magic_px
164 InteractiveShell.magic_autopx = magic_autopx
164 InteractiveShell.magic_autopx = magic_autopx
165
165
166 # And remove the global name to keep global namespace clean. Don't worry, the
166 # And remove the global name to keep global namespace clean. Don't worry, the
167 # copy bound to IPython stays, we're just removing the global name.
167 # copy bound to IPython stays, we're just removing the global name.
168 del magic_result
168 del magic_result
169 del magic_px
169 del magic_px
170 del magic_autopx
170 del magic_autopx
171
171
@@ -1,813 +1,813 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3
3
4 """Start an IPython cluster = (controller + engines)."""
4 """Start an IPython cluster = (controller + engines)."""
5
5
6 #-----------------------------------------------------------------------------
6 #-----------------------------------------------------------------------------
7 # Copyright (C) 2008 The IPython Development Team
7 # Copyright (C) 2008 The IPython Development Team
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 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Imports
14 # Imports
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16
16
17 import os
17 import os
18 import re
18 import re
19 import sys
19 import sys
20 import signal
20 import signal
21 import tempfile
21 import tempfile
22 pjoin = os.path.join
22 pjoin = os.path.join
23
23
24 from twisted.internet import reactor, defer
24 from twisted.internet import reactor, defer
25 from twisted.internet.protocol import ProcessProtocol
25 from twisted.internet.protocol import ProcessProtocol
26 from twisted.internet.error import ProcessDone, ProcessTerminated
26 from twisted.internet.error import ProcessDone, ProcessTerminated
27 from twisted.internet.utils import getProcessOutput
27 from twisted.internet.utils import getProcessOutput
28 from twisted.python import failure, log
28 from twisted.python import failure, log
29
29
30 from IPython.external import argparse
30 from IPython.external import argparse
31 from IPython.external import Itpl
31 from IPython.external import Itpl
32 from IPython.utils.genutils import (
32 from IPython.utils.genutils import (
33 get_ipython_dir,
33 get_ipython_dir,
34 get_log_dir,
34 get_log_dir,
35 get_security_dir,
35 get_security_dir,
36 num_cpus
36 num_cpus
37 )
37 )
38 from IPython.kernel.fcutil import have_crypto
38 from IPython.kernel.fcutil import have_crypto
39
39
40 # Create various ipython directories if they don't exist.
40 # Create various ipython directories if they don't exist.
41 # This must be done before IPython.kernel.config is imported.
41 # This must be done before IPython.kernel.config is imported.
42 from IPython.iplib import user_setup
42 from IPython.core.iplib import user_setup
43 if os.name == 'posix':
43 if os.name == 'posix':
44 rc_suffix = ''
44 rc_suffix = ''
45 else:
45 else:
46 rc_suffix = '.ini'
46 rc_suffix = '.ini'
47 user_setup(get_ipython_dir(), rc_suffix, mode='install', interactive=False)
47 user_setup(get_ipython_dir(), rc_suffix, mode='install', interactive=False)
48 get_log_dir()
48 get_log_dir()
49 get_security_dir()
49 get_security_dir()
50
50
51 from IPython.kernel.config import config_manager as kernel_config_manager
51 from IPython.kernel.config import config_manager as kernel_config_manager
52 from IPython.kernel.error import SecurityError, FileTimeoutError
52 from IPython.kernel.error import SecurityError, FileTimeoutError
53 from IPython.kernel.fcutil import have_crypto
53 from IPython.kernel.fcutil import have_crypto
54 from IPython.kernel.twistedutil import gatherBoth, wait_for_file
54 from IPython.kernel.twistedutil import gatherBoth, wait_for_file
55 from IPython.kernel.util import printer
55 from IPython.kernel.util import printer
56
56
57 #-----------------------------------------------------------------------------
57 #-----------------------------------------------------------------------------
58 # General process handling code
58 # General process handling code
59 #-----------------------------------------------------------------------------
59 #-----------------------------------------------------------------------------
60
60
61
61
62 class ProcessStateError(Exception):
62 class ProcessStateError(Exception):
63 pass
63 pass
64
64
65 class UnknownStatus(Exception):
65 class UnknownStatus(Exception):
66 pass
66 pass
67
67
68 class LauncherProcessProtocol(ProcessProtocol):
68 class LauncherProcessProtocol(ProcessProtocol):
69 """
69 """
70 A ProcessProtocol to go with the ProcessLauncher.
70 A ProcessProtocol to go with the ProcessLauncher.
71 """
71 """
72 def __init__(self, process_launcher):
72 def __init__(self, process_launcher):
73 self.process_launcher = process_launcher
73 self.process_launcher = process_launcher
74
74
75 def connectionMade(self):
75 def connectionMade(self):
76 self.process_launcher.fire_start_deferred(self.transport.pid)
76 self.process_launcher.fire_start_deferred(self.transport.pid)
77
77
78 def processEnded(self, status):
78 def processEnded(self, status):
79 value = status.value
79 value = status.value
80 if isinstance(value, ProcessDone):
80 if isinstance(value, ProcessDone):
81 self.process_launcher.fire_stop_deferred(0)
81 self.process_launcher.fire_stop_deferred(0)
82 elif isinstance(value, ProcessTerminated):
82 elif isinstance(value, ProcessTerminated):
83 self.process_launcher.fire_stop_deferred(
83 self.process_launcher.fire_stop_deferred(
84 {'exit_code':value.exitCode,
84 {'exit_code':value.exitCode,
85 'signal':value.signal,
85 'signal':value.signal,
86 'status':value.status
86 'status':value.status
87 }
87 }
88 )
88 )
89 else:
89 else:
90 raise UnknownStatus("unknown exit status, this is probably a bug in Twisted")
90 raise UnknownStatus("unknown exit status, this is probably a bug in Twisted")
91
91
92 def outReceived(self, data):
92 def outReceived(self, data):
93 log.msg(data)
93 log.msg(data)
94
94
95 def errReceived(self, data):
95 def errReceived(self, data):
96 log.err(data)
96 log.err(data)
97
97
98 class ProcessLauncher(object):
98 class ProcessLauncher(object):
99 """
99 """
100 Start and stop an external process in an asynchronous manner.
100 Start and stop an external process in an asynchronous manner.
101
101
102 Currently this uses deferreds to notify other parties of process state
102 Currently this uses deferreds to notify other parties of process state
103 changes. This is an awkward design and should be moved to using
103 changes. This is an awkward design and should be moved to using
104 a formal NotificationCenter.
104 a formal NotificationCenter.
105 """
105 """
106 def __init__(self, cmd_and_args):
106 def __init__(self, cmd_and_args):
107 self.cmd = cmd_and_args[0]
107 self.cmd = cmd_and_args[0]
108 self.args = cmd_and_args
108 self.args = cmd_and_args
109 self._reset()
109 self._reset()
110
110
111 def _reset(self):
111 def _reset(self):
112 self.process_protocol = None
112 self.process_protocol = None
113 self.pid = None
113 self.pid = None
114 self.start_deferred = None
114 self.start_deferred = None
115 self.stop_deferreds = []
115 self.stop_deferreds = []
116 self.state = 'before' # before, running, or after
116 self.state = 'before' # before, running, or after
117
117
118 @property
118 @property
119 def running(self):
119 def running(self):
120 if self.state == 'running':
120 if self.state == 'running':
121 return True
121 return True
122 else:
122 else:
123 return False
123 return False
124
124
125 def fire_start_deferred(self, pid):
125 def fire_start_deferred(self, pid):
126 self.pid = pid
126 self.pid = pid
127 self.state = 'running'
127 self.state = 'running'
128 log.msg('Process %r has started with pid=%i' % (self.args, pid))
128 log.msg('Process %r has started with pid=%i' % (self.args, pid))
129 self.start_deferred.callback(pid)
129 self.start_deferred.callback(pid)
130
130
131 def start(self):
131 def start(self):
132 if self.state == 'before':
132 if self.state == 'before':
133 self.process_protocol = LauncherProcessProtocol(self)
133 self.process_protocol = LauncherProcessProtocol(self)
134 self.start_deferred = defer.Deferred()
134 self.start_deferred = defer.Deferred()
135 self.process_transport = reactor.spawnProcess(
135 self.process_transport = reactor.spawnProcess(
136 self.process_protocol,
136 self.process_protocol,
137 self.cmd,
137 self.cmd,
138 self.args,
138 self.args,
139 env=os.environ
139 env=os.environ
140 )
140 )
141 return self.start_deferred
141 return self.start_deferred
142 else:
142 else:
143 s = 'the process has already been started and has state: %r' % \
143 s = 'the process has already been started and has state: %r' % \
144 self.state
144 self.state
145 return defer.fail(ProcessStateError(s))
145 return defer.fail(ProcessStateError(s))
146
146
147 def get_stop_deferred(self):
147 def get_stop_deferred(self):
148 if self.state == 'running' or self.state == 'before':
148 if self.state == 'running' or self.state == 'before':
149 d = defer.Deferred()
149 d = defer.Deferred()
150 self.stop_deferreds.append(d)
150 self.stop_deferreds.append(d)
151 return d
151 return d
152 else:
152 else:
153 s = 'this process is already complete'
153 s = 'this process is already complete'
154 return defer.fail(ProcessStateError(s))
154 return defer.fail(ProcessStateError(s))
155
155
156 def fire_stop_deferred(self, exit_code):
156 def fire_stop_deferred(self, exit_code):
157 log.msg('Process %r has stopped with %r' % (self.args, exit_code))
157 log.msg('Process %r has stopped with %r' % (self.args, exit_code))
158 self.state = 'after'
158 self.state = 'after'
159 for d in self.stop_deferreds:
159 for d in self.stop_deferreds:
160 d.callback(exit_code)
160 d.callback(exit_code)
161
161
162 def signal(self, sig):
162 def signal(self, sig):
163 """
163 """
164 Send a signal to the process.
164 Send a signal to the process.
165
165
166 The argument sig can be ('KILL','INT', etc.) or any signal number.
166 The argument sig can be ('KILL','INT', etc.) or any signal number.
167 """
167 """
168 if self.state == 'running':
168 if self.state == 'running':
169 self.process_transport.signalProcess(sig)
169 self.process_transport.signalProcess(sig)
170
170
171 # def __del__(self):
171 # def __del__(self):
172 # self.signal('KILL')
172 # self.signal('KILL')
173
173
174 def interrupt_then_kill(self, delay=1.0):
174 def interrupt_then_kill(self, delay=1.0):
175 self.signal('INT')
175 self.signal('INT')
176 reactor.callLater(delay, self.signal, 'KILL')
176 reactor.callLater(delay, self.signal, 'KILL')
177
177
178
178
179 #-----------------------------------------------------------------------------
179 #-----------------------------------------------------------------------------
180 # Code for launching controller and engines
180 # Code for launching controller and engines
181 #-----------------------------------------------------------------------------
181 #-----------------------------------------------------------------------------
182
182
183
183
184 class ControllerLauncher(ProcessLauncher):
184 class ControllerLauncher(ProcessLauncher):
185
185
186 def __init__(self, extra_args=None):
186 def __init__(self, extra_args=None):
187 if sys.platform == 'win32':
187 if sys.platform == 'win32':
188 # This logic is needed because the ipcontroller script doesn't
188 # This logic is needed because the ipcontroller script doesn't
189 # always get installed in the same way or in the same location.
189 # always get installed in the same way or in the same location.
190 from IPython.kernel.scripts import ipcontroller
190 from IPython.kernel.scripts import ipcontroller
191 script_location = ipcontroller.__file__.replace('.pyc', '.py')
191 script_location = ipcontroller.__file__.replace('.pyc', '.py')
192 # The -u option here turns on unbuffered output, which is required
192 # The -u option here turns on unbuffered output, which is required
193 # on Win32 to prevent wierd conflict and problems with Twisted.
193 # on Win32 to prevent wierd conflict and problems with Twisted.
194 # Also, use sys.executable to make sure we are picking up the
194 # Also, use sys.executable to make sure we are picking up the
195 # right python exe.
195 # right python exe.
196 args = [sys.executable, '-u', script_location]
196 args = [sys.executable, '-u', script_location]
197 else:
197 else:
198 args = ['ipcontroller']
198 args = ['ipcontroller']
199 self.extra_args = extra_args
199 self.extra_args = extra_args
200 if extra_args is not None:
200 if extra_args is not None:
201 args.extend(extra_args)
201 args.extend(extra_args)
202
202
203 ProcessLauncher.__init__(self, args)
203 ProcessLauncher.__init__(self, args)
204
204
205
205
206 class EngineLauncher(ProcessLauncher):
206 class EngineLauncher(ProcessLauncher):
207
207
208 def __init__(self, extra_args=None):
208 def __init__(self, extra_args=None):
209 if sys.platform == 'win32':
209 if sys.platform == 'win32':
210 # This logic is needed because the ipcontroller script doesn't
210 # This logic is needed because the ipcontroller script doesn't
211 # always get installed in the same way or in the same location.
211 # always get installed in the same way or in the same location.
212 from IPython.kernel.scripts import ipengine
212 from IPython.kernel.scripts import ipengine
213 script_location = ipengine.__file__.replace('.pyc', '.py')
213 script_location = ipengine.__file__.replace('.pyc', '.py')
214 # The -u option here turns on unbuffered output, which is required
214 # The -u option here turns on unbuffered output, which is required
215 # on Win32 to prevent wierd conflict and problems with Twisted.
215 # on Win32 to prevent wierd conflict and problems with Twisted.
216 # Also, use sys.executable to make sure we are picking up the
216 # Also, use sys.executable to make sure we are picking up the
217 # right python exe.
217 # right python exe.
218 args = [sys.executable, '-u', script_location]
218 args = [sys.executable, '-u', script_location]
219 else:
219 else:
220 args = ['ipengine']
220 args = ['ipengine']
221 self.extra_args = extra_args
221 self.extra_args = extra_args
222 if extra_args is not None:
222 if extra_args is not None:
223 args.extend(extra_args)
223 args.extend(extra_args)
224
224
225 ProcessLauncher.__init__(self, args)
225 ProcessLauncher.__init__(self, args)
226
226
227
227
228 class LocalEngineSet(object):
228 class LocalEngineSet(object):
229
229
230 def __init__(self, extra_args=None):
230 def __init__(self, extra_args=None):
231 self.extra_args = extra_args
231 self.extra_args = extra_args
232 self.launchers = []
232 self.launchers = []
233
233
234 def start(self, n):
234 def start(self, n):
235 dlist = []
235 dlist = []
236 for i in range(n):
236 for i in range(n):
237 el = EngineLauncher(extra_args=self.extra_args)
237 el = EngineLauncher(extra_args=self.extra_args)
238 d = el.start()
238 d = el.start()
239 self.launchers.append(el)
239 self.launchers.append(el)
240 dlist.append(d)
240 dlist.append(d)
241 dfinal = gatherBoth(dlist, consumeErrors=True)
241 dfinal = gatherBoth(dlist, consumeErrors=True)
242 dfinal.addCallback(self._handle_start)
242 dfinal.addCallback(self._handle_start)
243 return dfinal
243 return dfinal
244
244
245 def _handle_start(self, r):
245 def _handle_start(self, r):
246 log.msg('Engines started with pids: %r' % r)
246 log.msg('Engines started with pids: %r' % r)
247 return r
247 return r
248
248
249 def _handle_stop(self, r):
249 def _handle_stop(self, r):
250 log.msg('Engines received signal: %r' % r)
250 log.msg('Engines received signal: %r' % r)
251 return r
251 return r
252
252
253 def signal(self, sig):
253 def signal(self, sig):
254 dlist = []
254 dlist = []
255 for el in self.launchers:
255 for el in self.launchers:
256 d = el.get_stop_deferred()
256 d = el.get_stop_deferred()
257 dlist.append(d)
257 dlist.append(d)
258 el.signal(sig)
258 el.signal(sig)
259 dfinal = gatherBoth(dlist, consumeErrors=True)
259 dfinal = gatherBoth(dlist, consumeErrors=True)
260 dfinal.addCallback(self._handle_stop)
260 dfinal.addCallback(self._handle_stop)
261 return dfinal
261 return dfinal
262
262
263 def interrupt_then_kill(self, delay=1.0):
263 def interrupt_then_kill(self, delay=1.0):
264 dlist = []
264 dlist = []
265 for el in self.launchers:
265 for el in self.launchers:
266 d = el.get_stop_deferred()
266 d = el.get_stop_deferred()
267 dlist.append(d)
267 dlist.append(d)
268 el.interrupt_then_kill(delay)
268 el.interrupt_then_kill(delay)
269 dfinal = gatherBoth(dlist, consumeErrors=True)
269 dfinal = gatherBoth(dlist, consumeErrors=True)
270 dfinal.addCallback(self._handle_stop)
270 dfinal.addCallback(self._handle_stop)
271 return dfinal
271 return dfinal
272
272
273
273
274 class BatchEngineSet(object):
274 class BatchEngineSet(object):
275
275
276 # Subclasses must fill these in. See PBSEngineSet
276 # Subclasses must fill these in. See PBSEngineSet
277 submit_command = ''
277 submit_command = ''
278 delete_command = ''
278 delete_command = ''
279 job_id_regexp = ''
279 job_id_regexp = ''
280
280
281 def __init__(self, template_file, **kwargs):
281 def __init__(self, template_file, **kwargs):
282 self.template_file = template_file
282 self.template_file = template_file
283 self.context = {}
283 self.context = {}
284 self.context.update(kwargs)
284 self.context.update(kwargs)
285 self.batch_file = self.template_file+'-run'
285 self.batch_file = self.template_file+'-run'
286
286
287 def parse_job_id(self, output):
287 def parse_job_id(self, output):
288 m = re.match(self.job_id_regexp, output)
288 m = re.match(self.job_id_regexp, output)
289 if m is not None:
289 if m is not None:
290 job_id = m.group()
290 job_id = m.group()
291 else:
291 else:
292 raise Exception("job id couldn't be determined: %s" % output)
292 raise Exception("job id couldn't be determined: %s" % output)
293 self.job_id = job_id
293 self.job_id = job_id
294 log.msg('Job started with job id: %r' % job_id)
294 log.msg('Job started with job id: %r' % job_id)
295 return job_id
295 return job_id
296
296
297 def write_batch_script(self, n):
297 def write_batch_script(self, n):
298 self.context['n'] = n
298 self.context['n'] = n
299 template = open(self.template_file, 'r').read()
299 template = open(self.template_file, 'r').read()
300 log.msg('Using template for batch script: %s' % self.template_file)
300 log.msg('Using template for batch script: %s' % self.template_file)
301 script_as_string = Itpl.itplns(template, self.context)
301 script_as_string = Itpl.itplns(template, self.context)
302 log.msg('Writing instantiated batch script: %s' % self.batch_file)
302 log.msg('Writing instantiated batch script: %s' % self.batch_file)
303 f = open(self.batch_file,'w')
303 f = open(self.batch_file,'w')
304 f.write(script_as_string)
304 f.write(script_as_string)
305 f.close()
305 f.close()
306
306
307 def handle_error(self, f):
307 def handle_error(self, f):
308 f.printTraceback()
308 f.printTraceback()
309 f.raiseException()
309 f.raiseException()
310
310
311 def start(self, n):
311 def start(self, n):
312 self.write_batch_script(n)
312 self.write_batch_script(n)
313 d = getProcessOutput(self.submit_command,
313 d = getProcessOutput(self.submit_command,
314 [self.batch_file],env=os.environ)
314 [self.batch_file],env=os.environ)
315 d.addCallback(self.parse_job_id)
315 d.addCallback(self.parse_job_id)
316 d.addErrback(self.handle_error)
316 d.addErrback(self.handle_error)
317 return d
317 return d
318
318
319 def kill(self):
319 def kill(self):
320 d = getProcessOutput(self.delete_command,
320 d = getProcessOutput(self.delete_command,
321 [self.job_id],env=os.environ)
321 [self.job_id],env=os.environ)
322 return d
322 return d
323
323
324 class PBSEngineSet(BatchEngineSet):
324 class PBSEngineSet(BatchEngineSet):
325
325
326 submit_command = 'qsub'
326 submit_command = 'qsub'
327 delete_command = 'qdel'
327 delete_command = 'qdel'
328 job_id_regexp = '\d+'
328 job_id_regexp = '\d+'
329
329
330 def __init__(self, template_file, **kwargs):
330 def __init__(self, template_file, **kwargs):
331 BatchEngineSet.__init__(self, template_file, **kwargs)
331 BatchEngineSet.__init__(self, template_file, **kwargs)
332
332
333
333
334 sshx_template="""#!/bin/sh
334 sshx_template="""#!/bin/sh
335 "$@" &> /dev/null &
335 "$@" &> /dev/null &
336 echo $!
336 echo $!
337 """
337 """
338
338
339 engine_killer_template="""#!/bin/sh
339 engine_killer_template="""#!/bin/sh
340 ps -fu `whoami` | grep '[i]pengine' | awk '{print $2}' | xargs kill -TERM
340 ps -fu `whoami` | grep '[i]pengine' | awk '{print $2}' | xargs kill -TERM
341 """
341 """
342
342
343 class SSHEngineSet(object):
343 class SSHEngineSet(object):
344 sshx_template=sshx_template
344 sshx_template=sshx_template
345 engine_killer_template=engine_killer_template
345 engine_killer_template=engine_killer_template
346
346
347 def __init__(self, engine_hosts, sshx=None, ipengine="ipengine"):
347 def __init__(self, engine_hosts, sshx=None, ipengine="ipengine"):
348 """Start a controller on localhost and engines using ssh.
348 """Start a controller on localhost and engines using ssh.
349
349
350 The engine_hosts argument is a dict with hostnames as keys and
350 The engine_hosts argument is a dict with hostnames as keys and
351 the number of engine (int) as values. sshx is the name of a local
351 the number of engine (int) as values. sshx is the name of a local
352 file that will be used to run remote commands. This file is used
352 file that will be used to run remote commands. This file is used
353 to setup the environment properly.
353 to setup the environment properly.
354 """
354 """
355
355
356 self.temp_dir = tempfile.gettempdir()
356 self.temp_dir = tempfile.gettempdir()
357 if sshx is not None:
357 if sshx is not None:
358 self.sshx = sshx
358 self.sshx = sshx
359 else:
359 else:
360 # Write the sshx.sh file locally from our template.
360 # Write the sshx.sh file locally from our template.
361 self.sshx = os.path.join(
361 self.sshx = os.path.join(
362 self.temp_dir,
362 self.temp_dir,
363 '%s-main-sshx.sh' % os.environ['USER']
363 '%s-main-sshx.sh' % os.environ['USER']
364 )
364 )
365 f = open(self.sshx, 'w')
365 f = open(self.sshx, 'w')
366 f.writelines(self.sshx_template)
366 f.writelines(self.sshx_template)
367 f.close()
367 f.close()
368 self.engine_command = ipengine
368 self.engine_command = ipengine
369 self.engine_hosts = engine_hosts
369 self.engine_hosts = engine_hosts
370 # Write the engine killer script file locally from our template.
370 # Write the engine killer script file locally from our template.
371 self.engine_killer = os.path.join(
371 self.engine_killer = os.path.join(
372 self.temp_dir,
372 self.temp_dir,
373 '%s-local-engine_killer.sh' % os.environ['USER']
373 '%s-local-engine_killer.sh' % os.environ['USER']
374 )
374 )
375 f = open(self.engine_killer, 'w')
375 f = open(self.engine_killer, 'w')
376 f.writelines(self.engine_killer_template)
376 f.writelines(self.engine_killer_template)
377 f.close()
377 f.close()
378
378
379 def start(self, send_furl=False):
379 def start(self, send_furl=False):
380 dlist = []
380 dlist = []
381 for host in self.engine_hosts.keys():
381 for host in self.engine_hosts.keys():
382 count = self.engine_hosts[host]
382 count = self.engine_hosts[host]
383 d = self._start(host, count, send_furl)
383 d = self._start(host, count, send_furl)
384 dlist.append(d)
384 dlist.append(d)
385 return gatherBoth(dlist, consumeErrors=True)
385 return gatherBoth(dlist, consumeErrors=True)
386
386
387 def _start(self, hostname, count=1, send_furl=False):
387 def _start(self, hostname, count=1, send_furl=False):
388 if send_furl:
388 if send_furl:
389 d = self._scp_furl(hostname)
389 d = self._scp_furl(hostname)
390 else:
390 else:
391 d = defer.succeed(None)
391 d = defer.succeed(None)
392 d.addCallback(lambda r: self._scp_sshx(hostname))
392 d.addCallback(lambda r: self._scp_sshx(hostname))
393 d.addCallback(lambda r: self._ssh_engine(hostname, count))
393 d.addCallback(lambda r: self._ssh_engine(hostname, count))
394 return d
394 return d
395
395
396 def _scp_furl(self, hostname):
396 def _scp_furl(self, hostname):
397 scp_cmd = "scp ~/.ipython/security/ipcontroller-engine.furl %s:.ipython/security/" % (hostname)
397 scp_cmd = "scp ~/.ipython/security/ipcontroller-engine.furl %s:.ipython/security/" % (hostname)
398 cmd_list = scp_cmd.split()
398 cmd_list = scp_cmd.split()
399 cmd_list[1] = os.path.expanduser(cmd_list[1])
399 cmd_list[1] = os.path.expanduser(cmd_list[1])
400 log.msg('Copying furl file: %s' % scp_cmd)
400 log.msg('Copying furl file: %s' % scp_cmd)
401 d = getProcessOutput(cmd_list[0], cmd_list[1:], env=os.environ)
401 d = getProcessOutput(cmd_list[0], cmd_list[1:], env=os.environ)
402 return d
402 return d
403
403
404 def _scp_sshx(self, hostname):
404 def _scp_sshx(self, hostname):
405 scp_cmd = "scp %s %s:%s/%s-sshx.sh" % (
405 scp_cmd = "scp %s %s:%s/%s-sshx.sh" % (
406 self.sshx, hostname,
406 self.sshx, hostname,
407 self.temp_dir, os.environ['USER']
407 self.temp_dir, os.environ['USER']
408 )
408 )
409 print
409 print
410 log.msg("Copying sshx: %s" % scp_cmd)
410 log.msg("Copying sshx: %s" % scp_cmd)
411 sshx_scp = scp_cmd.split()
411 sshx_scp = scp_cmd.split()
412 d = getProcessOutput(sshx_scp[0], sshx_scp[1:], env=os.environ)
412 d = getProcessOutput(sshx_scp[0], sshx_scp[1:], env=os.environ)
413 return d
413 return d
414
414
415 def _ssh_engine(self, hostname, count):
415 def _ssh_engine(self, hostname, count):
416 exec_engine = "ssh %s sh %s/%s-sshx.sh %s" % (
416 exec_engine = "ssh %s sh %s/%s-sshx.sh %s" % (
417 hostname, self.temp_dir,
417 hostname, self.temp_dir,
418 os.environ['USER'], self.engine_command
418 os.environ['USER'], self.engine_command
419 )
419 )
420 cmds = exec_engine.split()
420 cmds = exec_engine.split()
421 dlist = []
421 dlist = []
422 log.msg("about to start engines...")
422 log.msg("about to start engines...")
423 for i in range(count):
423 for i in range(count):
424 log.msg('Starting engines: %s' % exec_engine)
424 log.msg('Starting engines: %s' % exec_engine)
425 d = getProcessOutput(cmds[0], cmds[1:], env=os.environ)
425 d = getProcessOutput(cmds[0], cmds[1:], env=os.environ)
426 dlist.append(d)
426 dlist.append(d)
427 return gatherBoth(dlist, consumeErrors=True)
427 return gatherBoth(dlist, consumeErrors=True)
428
428
429 def kill(self):
429 def kill(self):
430 dlist = []
430 dlist = []
431 for host in self.engine_hosts.keys():
431 for host in self.engine_hosts.keys():
432 d = self._killall(host)
432 d = self._killall(host)
433 dlist.append(d)
433 dlist.append(d)
434 return gatherBoth(dlist, consumeErrors=True)
434 return gatherBoth(dlist, consumeErrors=True)
435
435
436 def _killall(self, hostname):
436 def _killall(self, hostname):
437 d = self._scp_engine_killer(hostname)
437 d = self._scp_engine_killer(hostname)
438 d.addCallback(lambda r: self._ssh_kill(hostname))
438 d.addCallback(lambda r: self._ssh_kill(hostname))
439 # d.addErrback(self._exec_err)
439 # d.addErrback(self._exec_err)
440 return d
440 return d
441
441
442 def _scp_engine_killer(self, hostname):
442 def _scp_engine_killer(self, hostname):
443 scp_cmd = "scp %s %s:%s/%s-engine_killer.sh" % (
443 scp_cmd = "scp %s %s:%s/%s-engine_killer.sh" % (
444 self.engine_killer,
444 self.engine_killer,
445 hostname,
445 hostname,
446 self.temp_dir,
446 self.temp_dir,
447 os.environ['USER']
447 os.environ['USER']
448 )
448 )
449 cmds = scp_cmd.split()
449 cmds = scp_cmd.split()
450 log.msg('Copying engine_killer: %s' % scp_cmd)
450 log.msg('Copying engine_killer: %s' % scp_cmd)
451 d = getProcessOutput(cmds[0], cmds[1:], env=os.environ)
451 d = getProcessOutput(cmds[0], cmds[1:], env=os.environ)
452 return d
452 return d
453
453
454 def _ssh_kill(self, hostname):
454 def _ssh_kill(self, hostname):
455 kill_cmd = "ssh %s sh %s/%s-engine_killer.sh" % (
455 kill_cmd = "ssh %s sh %s/%s-engine_killer.sh" % (
456 hostname,
456 hostname,
457 self.temp_dir,
457 self.temp_dir,
458 os.environ['USER']
458 os.environ['USER']
459 )
459 )
460 log.msg('Killing engine: %s' % kill_cmd)
460 log.msg('Killing engine: %s' % kill_cmd)
461 kill_cmd = kill_cmd.split()
461 kill_cmd = kill_cmd.split()
462 d = getProcessOutput(kill_cmd[0], kill_cmd[1:], env=os.environ)
462 d = getProcessOutput(kill_cmd[0], kill_cmd[1:], env=os.environ)
463 return d
463 return d
464
464
465 def _exec_err(self, r):
465 def _exec_err(self, r):
466 log.msg(r)
466 log.msg(r)
467
467
468 #-----------------------------------------------------------------------------
468 #-----------------------------------------------------------------------------
469 # Main functions for the different types of clusters
469 # Main functions for the different types of clusters
470 #-----------------------------------------------------------------------------
470 #-----------------------------------------------------------------------------
471
471
472 # TODO:
472 # TODO:
473 # The logic in these codes should be moved into classes like LocalCluster
473 # The logic in these codes should be moved into classes like LocalCluster
474 # MpirunCluster, PBSCluster, etc. This would remove alot of the duplications.
474 # MpirunCluster, PBSCluster, etc. This would remove alot of the duplications.
475 # The main functions should then just parse the command line arguments, create
475 # The main functions should then just parse the command line arguments, create
476 # the appropriate class and call a 'start' method.
476 # the appropriate class and call a 'start' method.
477
477
478
478
479 def check_security(args, cont_args):
479 def check_security(args, cont_args):
480 """Check to see if we should run with SSL support."""
480 """Check to see if we should run with SSL support."""
481 if (not args.x or not args.y) and not have_crypto:
481 if (not args.x or not args.y) and not have_crypto:
482 log.err("""
482 log.err("""
483 OpenSSL/pyOpenSSL is not available, so we can't run in secure mode.
483 OpenSSL/pyOpenSSL is not available, so we can't run in secure mode.
484 Try running ipcluster with the -xy flags: ipcluster local -xy -n 4""")
484 Try running ipcluster with the -xy flags: ipcluster local -xy -n 4""")
485 reactor.stop()
485 reactor.stop()
486 return False
486 return False
487 if args.x:
487 if args.x:
488 cont_args.append('-x')
488 cont_args.append('-x')
489 if args.y:
489 if args.y:
490 cont_args.append('-y')
490 cont_args.append('-y')
491 return True
491 return True
492
492
493
493
494 def check_reuse(args, cont_args):
494 def check_reuse(args, cont_args):
495 """Check to see if we should try to resuse FURL files."""
495 """Check to see if we should try to resuse FURL files."""
496 if args.r:
496 if args.r:
497 cont_args.append('-r')
497 cont_args.append('-r')
498 if args.client_port == 0 or args.engine_port == 0:
498 if args.client_port == 0 or args.engine_port == 0:
499 log.err("""
499 log.err("""
500 To reuse FURL files, you must also set the client and engine ports using
500 To reuse FURL files, you must also set the client and engine ports using
501 the --client-port and --engine-port options.""")
501 the --client-port and --engine-port options.""")
502 reactor.stop()
502 reactor.stop()
503 return False
503 return False
504 cont_args.append('--client-port=%i' % args.client_port)
504 cont_args.append('--client-port=%i' % args.client_port)
505 cont_args.append('--engine-port=%i' % args.engine_port)
505 cont_args.append('--engine-port=%i' % args.engine_port)
506 return True
506 return True
507
507
508
508
509 def _err_and_stop(f):
509 def _err_and_stop(f):
510 """Errback to log a failure and halt the reactor on a fatal error."""
510 """Errback to log a failure and halt the reactor on a fatal error."""
511 log.err(f)
511 log.err(f)
512 reactor.stop()
512 reactor.stop()
513
513
514
514
515 def _delay_start(cont_pid, start_engines, furl_file, reuse):
515 def _delay_start(cont_pid, start_engines, furl_file, reuse):
516 """Wait for controller to create FURL files and the start the engines."""
516 """Wait for controller to create FURL files and the start the engines."""
517 if not reuse:
517 if not reuse:
518 if os.path.isfile(furl_file):
518 if os.path.isfile(furl_file):
519 os.unlink(furl_file)
519 os.unlink(furl_file)
520 log.msg('Waiting for controller to finish starting...')
520 log.msg('Waiting for controller to finish starting...')
521 d = wait_for_file(furl_file, delay=0.2, max_tries=50)
521 d = wait_for_file(furl_file, delay=0.2, max_tries=50)
522 d.addCallback(lambda _: log.msg('Controller started'))
522 d.addCallback(lambda _: log.msg('Controller started'))
523 d.addCallback(lambda _: start_engines(cont_pid))
523 d.addCallback(lambda _: start_engines(cont_pid))
524 return d
524 return d
525
525
526
526
527 def main_local(args):
527 def main_local(args):
528 cont_args = []
528 cont_args = []
529 cont_args.append('--logfile=%s' % pjoin(args.logdir,'ipcontroller'))
529 cont_args.append('--logfile=%s' % pjoin(args.logdir,'ipcontroller'))
530
530
531 # Check security settings before proceeding
531 # Check security settings before proceeding
532 if not check_security(args, cont_args):
532 if not check_security(args, cont_args):
533 return
533 return
534
534
535 # See if we are reusing FURL files
535 # See if we are reusing FURL files
536 if not check_reuse(args, cont_args):
536 if not check_reuse(args, cont_args):
537 return
537 return
538
538
539 cl = ControllerLauncher(extra_args=cont_args)
539 cl = ControllerLauncher(extra_args=cont_args)
540 dstart = cl.start()
540 dstart = cl.start()
541 def start_engines(cont_pid):
541 def start_engines(cont_pid):
542 engine_args = []
542 engine_args = []
543 engine_args.append('--logfile=%s' % \
543 engine_args.append('--logfile=%s' % \
544 pjoin(args.logdir,'ipengine%s-' % cont_pid))
544 pjoin(args.logdir,'ipengine%s-' % cont_pid))
545 eset = LocalEngineSet(extra_args=engine_args)
545 eset = LocalEngineSet(extra_args=engine_args)
546 def shutdown(signum, frame):
546 def shutdown(signum, frame):
547 log.msg('Stopping local cluster')
547 log.msg('Stopping local cluster')
548 # We are still playing with the times here, but these seem
548 # We are still playing with the times here, but these seem
549 # to be reliable in allowing everything to exit cleanly.
549 # to be reliable in allowing everything to exit cleanly.
550 eset.interrupt_then_kill(0.5)
550 eset.interrupt_then_kill(0.5)
551 cl.interrupt_then_kill(0.5)
551 cl.interrupt_then_kill(0.5)
552 reactor.callLater(1.0, reactor.stop)
552 reactor.callLater(1.0, reactor.stop)
553 signal.signal(signal.SIGINT,shutdown)
553 signal.signal(signal.SIGINT,shutdown)
554 d = eset.start(args.n)
554 d = eset.start(args.n)
555 return d
555 return d
556 config = kernel_config_manager.get_config_obj()
556 config = kernel_config_manager.get_config_obj()
557 furl_file = config['controller']['engine_furl_file']
557 furl_file = config['controller']['engine_furl_file']
558 dstart.addCallback(_delay_start, start_engines, furl_file, args.r)
558 dstart.addCallback(_delay_start, start_engines, furl_file, args.r)
559 dstart.addErrback(_err_and_stop)
559 dstart.addErrback(_err_and_stop)
560
560
561
561
562 def main_mpi(args):
562 def main_mpi(args):
563 cont_args = []
563 cont_args = []
564 cont_args.append('--logfile=%s' % pjoin(args.logdir,'ipcontroller'))
564 cont_args.append('--logfile=%s' % pjoin(args.logdir,'ipcontroller'))
565
565
566 # Check security settings before proceeding
566 # Check security settings before proceeding
567 if not check_security(args, cont_args):
567 if not check_security(args, cont_args):
568 return
568 return
569
569
570 # See if we are reusing FURL files
570 # See if we are reusing FURL files
571 if not check_reuse(args, cont_args):
571 if not check_reuse(args, cont_args):
572 return
572 return
573
573
574 cl = ControllerLauncher(extra_args=cont_args)
574 cl = ControllerLauncher(extra_args=cont_args)
575 dstart = cl.start()
575 dstart = cl.start()
576 def start_engines(cont_pid):
576 def start_engines(cont_pid):
577 raw_args = [args.cmd]
577 raw_args = [args.cmd]
578 raw_args.extend(['-n',str(args.n)])
578 raw_args.extend(['-n',str(args.n)])
579 raw_args.append('ipengine')
579 raw_args.append('ipengine')
580 raw_args.append('-l')
580 raw_args.append('-l')
581 raw_args.append(pjoin(args.logdir,'ipengine%s-' % cont_pid))
581 raw_args.append(pjoin(args.logdir,'ipengine%s-' % cont_pid))
582 if args.mpi:
582 if args.mpi:
583 raw_args.append('--mpi=%s' % args.mpi)
583 raw_args.append('--mpi=%s' % args.mpi)
584 eset = ProcessLauncher(raw_args)
584 eset = ProcessLauncher(raw_args)
585 def shutdown(signum, frame):
585 def shutdown(signum, frame):
586 log.msg('Stopping local cluster')
586 log.msg('Stopping local cluster')
587 # We are still playing with the times here, but these seem
587 # We are still playing with the times here, but these seem
588 # to be reliable in allowing everything to exit cleanly.
588 # to be reliable in allowing everything to exit cleanly.
589 eset.interrupt_then_kill(1.0)
589 eset.interrupt_then_kill(1.0)
590 cl.interrupt_then_kill(1.0)
590 cl.interrupt_then_kill(1.0)
591 reactor.callLater(2.0, reactor.stop)
591 reactor.callLater(2.0, reactor.stop)
592 signal.signal(signal.SIGINT,shutdown)
592 signal.signal(signal.SIGINT,shutdown)
593 d = eset.start()
593 d = eset.start()
594 return d
594 return d
595 config = kernel_config_manager.get_config_obj()
595 config = kernel_config_manager.get_config_obj()
596 furl_file = config['controller']['engine_furl_file']
596 furl_file = config['controller']['engine_furl_file']
597 dstart.addCallback(_delay_start, start_engines, furl_file, args.r)
597 dstart.addCallback(_delay_start, start_engines, furl_file, args.r)
598 dstart.addErrback(_err_and_stop)
598 dstart.addErrback(_err_and_stop)
599
599
600
600
601 def main_pbs(args):
601 def main_pbs(args):
602 cont_args = []
602 cont_args = []
603 cont_args.append('--logfile=%s' % pjoin(args.logdir,'ipcontroller'))
603 cont_args.append('--logfile=%s' % pjoin(args.logdir,'ipcontroller'))
604
604
605 # Check security settings before proceeding
605 # Check security settings before proceeding
606 if not check_security(args, cont_args):
606 if not check_security(args, cont_args):
607 return
607 return
608
608
609 # See if we are reusing FURL files
609 # See if we are reusing FURL files
610 if not check_reuse(args, cont_args):
610 if not check_reuse(args, cont_args):
611 return
611 return
612
612
613 cl = ControllerLauncher(extra_args=cont_args)
613 cl = ControllerLauncher(extra_args=cont_args)
614 dstart = cl.start()
614 dstart = cl.start()
615 def start_engines(r):
615 def start_engines(r):
616 pbs_set = PBSEngineSet(args.pbsscript)
616 pbs_set = PBSEngineSet(args.pbsscript)
617 def shutdown(signum, frame):
617 def shutdown(signum, frame):
618 log.msg('Stopping pbs cluster')
618 log.msg('Stopping pbs cluster')
619 d = pbs_set.kill()
619 d = pbs_set.kill()
620 d.addBoth(lambda _: cl.interrupt_then_kill(1.0))
620 d.addBoth(lambda _: cl.interrupt_then_kill(1.0))
621 d.addBoth(lambda _: reactor.callLater(2.0, reactor.stop))
621 d.addBoth(lambda _: reactor.callLater(2.0, reactor.stop))
622 signal.signal(signal.SIGINT,shutdown)
622 signal.signal(signal.SIGINT,shutdown)
623 d = pbs_set.start(args.n)
623 d = pbs_set.start(args.n)
624 return d
624 return d
625 config = kernel_config_manager.get_config_obj()
625 config = kernel_config_manager.get_config_obj()
626 furl_file = config['controller']['engine_furl_file']
626 furl_file = config['controller']['engine_furl_file']
627 dstart.addCallback(_delay_start, start_engines, furl_file, args.r)
627 dstart.addCallback(_delay_start, start_engines, furl_file, args.r)
628 dstart.addErrback(_err_and_stop)
628 dstart.addErrback(_err_and_stop)
629
629
630
630
631 def main_ssh(args):
631 def main_ssh(args):
632 """Start a controller on localhost and engines using ssh.
632 """Start a controller on localhost and engines using ssh.
633
633
634 Your clusterfile should look like::
634 Your clusterfile should look like::
635
635
636 send_furl = False # True, if you want
636 send_furl = False # True, if you want
637 engines = {
637 engines = {
638 'engine_host1' : engine_count,
638 'engine_host1' : engine_count,
639 'engine_host2' : engine_count2
639 'engine_host2' : engine_count2
640 }
640 }
641 """
641 """
642 clusterfile = {}
642 clusterfile = {}
643 execfile(args.clusterfile, clusterfile)
643 execfile(args.clusterfile, clusterfile)
644 if not clusterfile.has_key('send_furl'):
644 if not clusterfile.has_key('send_furl'):
645 clusterfile['send_furl'] = False
645 clusterfile['send_furl'] = False
646
646
647 cont_args = []
647 cont_args = []
648 cont_args.append('--logfile=%s' % pjoin(args.logdir,'ipcontroller'))
648 cont_args.append('--logfile=%s' % pjoin(args.logdir,'ipcontroller'))
649
649
650 # Check security settings before proceeding
650 # Check security settings before proceeding
651 if not check_security(args, cont_args):
651 if not check_security(args, cont_args):
652 return
652 return
653
653
654 # See if we are reusing FURL files
654 # See if we are reusing FURL files
655 if not check_reuse(args, cont_args):
655 if not check_reuse(args, cont_args):
656 return
656 return
657
657
658 cl = ControllerLauncher(extra_args=cont_args)
658 cl = ControllerLauncher(extra_args=cont_args)
659 dstart = cl.start()
659 dstart = cl.start()
660 def start_engines(cont_pid):
660 def start_engines(cont_pid):
661 ssh_set = SSHEngineSet(clusterfile['engines'], sshx=args.sshx)
661 ssh_set = SSHEngineSet(clusterfile['engines'], sshx=args.sshx)
662 def shutdown(signum, frame):
662 def shutdown(signum, frame):
663 d = ssh_set.kill()
663 d = ssh_set.kill()
664 cl.interrupt_then_kill(1.0)
664 cl.interrupt_then_kill(1.0)
665 reactor.callLater(2.0, reactor.stop)
665 reactor.callLater(2.0, reactor.stop)
666 signal.signal(signal.SIGINT,shutdown)
666 signal.signal(signal.SIGINT,shutdown)
667 d = ssh_set.start(clusterfile['send_furl'])
667 d = ssh_set.start(clusterfile['send_furl'])
668 return d
668 return d
669 config = kernel_config_manager.get_config_obj()
669 config = kernel_config_manager.get_config_obj()
670 furl_file = config['controller']['engine_furl_file']
670 furl_file = config['controller']['engine_furl_file']
671 dstart.addCallback(_delay_start, start_engines, furl_file, args.r)
671 dstart.addCallback(_delay_start, start_engines, furl_file, args.r)
672 dstart.addErrback(_err_and_stop)
672 dstart.addErrback(_err_and_stop)
673
673
674
674
675 def get_args():
675 def get_args():
676 base_parser = argparse.ArgumentParser(add_help=False)
676 base_parser = argparse.ArgumentParser(add_help=False)
677 base_parser.add_argument(
677 base_parser.add_argument(
678 '-r',
678 '-r',
679 action='store_true',
679 action='store_true',
680 dest='r',
680 dest='r',
681 help='try to reuse FURL files. Use with --client-port and --engine-port'
681 help='try to reuse FURL files. Use with --client-port and --engine-port'
682 )
682 )
683 base_parser.add_argument(
683 base_parser.add_argument(
684 '--client-port',
684 '--client-port',
685 type=int,
685 type=int,
686 dest='client_port',
686 dest='client_port',
687 help='the port the controller will listen on for client connections',
687 help='the port the controller will listen on for client connections',
688 default=0
688 default=0
689 )
689 )
690 base_parser.add_argument(
690 base_parser.add_argument(
691 '--engine-port',
691 '--engine-port',
692 type=int,
692 type=int,
693 dest='engine_port',
693 dest='engine_port',
694 help='the port the controller will listen on for engine connections',
694 help='the port the controller will listen on for engine connections',
695 default=0
695 default=0
696 )
696 )
697 base_parser.add_argument(
697 base_parser.add_argument(
698 '-x',
698 '-x',
699 action='store_true',
699 action='store_true',
700 dest='x',
700 dest='x',
701 help='turn off client security'
701 help='turn off client security'
702 )
702 )
703 base_parser.add_argument(
703 base_parser.add_argument(
704 '-y',
704 '-y',
705 action='store_true',
705 action='store_true',
706 dest='y',
706 dest='y',
707 help='turn off engine security'
707 help='turn off engine security'
708 )
708 )
709 base_parser.add_argument(
709 base_parser.add_argument(
710 "--logdir",
710 "--logdir",
711 type=str,
711 type=str,
712 dest="logdir",
712 dest="logdir",
713 help="directory to put log files (default=$IPYTHONDIR/log)",
713 help="directory to put log files (default=$IPYTHONDIR/log)",
714 default=pjoin(get_ipython_dir(),'log')
714 default=pjoin(get_ipython_dir(),'log')
715 )
715 )
716 base_parser.add_argument(
716 base_parser.add_argument(
717 "-n",
717 "-n",
718 "--num",
718 "--num",
719 type=int,
719 type=int,
720 dest="n",
720 dest="n",
721 default=2,
721 default=2,
722 help="the number of engines to start"
722 help="the number of engines to start"
723 )
723 )
724
724
725 parser = argparse.ArgumentParser(
725 parser = argparse.ArgumentParser(
726 description='IPython cluster startup. This starts a controller and\
726 description='IPython cluster startup. This starts a controller and\
727 engines using various approaches. Use the IPYTHONDIR environment\
727 engines using various approaches. Use the IPYTHONDIR environment\
728 variable to change your IPython directory from the default of\
728 variable to change your IPython directory from the default of\
729 .ipython or _ipython. The log and security subdirectories of your\
729 .ipython or _ipython. The log and security subdirectories of your\
730 IPython directory will be used by this script for log files and\
730 IPython directory will be used by this script for log files and\
731 security files.'
731 security files.'
732 )
732 )
733 subparsers = parser.add_subparsers(
733 subparsers = parser.add_subparsers(
734 help='available cluster types. For help, do "ipcluster TYPE --help"')
734 help='available cluster types. For help, do "ipcluster TYPE --help"')
735
735
736 parser_local = subparsers.add_parser(
736 parser_local = subparsers.add_parser(
737 'local',
737 'local',
738 help='run a local cluster',
738 help='run a local cluster',
739 parents=[base_parser]
739 parents=[base_parser]
740 )
740 )
741 parser_local.set_defaults(func=main_local)
741 parser_local.set_defaults(func=main_local)
742
742
743 parser_mpirun = subparsers.add_parser(
743 parser_mpirun = subparsers.add_parser(
744 'mpirun',
744 'mpirun',
745 help='run a cluster using mpirun (mpiexec also works)',
745 help='run a cluster using mpirun (mpiexec also works)',
746 parents=[base_parser]
746 parents=[base_parser]
747 )
747 )
748 parser_mpirun.add_argument(
748 parser_mpirun.add_argument(
749 "--mpi",
749 "--mpi",
750 type=str,
750 type=str,
751 dest="mpi", # Don't put a default here to allow no MPI support
751 dest="mpi", # Don't put a default here to allow no MPI support
752 help="how to call MPI_Init (default=mpi4py)"
752 help="how to call MPI_Init (default=mpi4py)"
753 )
753 )
754 parser_mpirun.set_defaults(func=main_mpi, cmd='mpirun')
754 parser_mpirun.set_defaults(func=main_mpi, cmd='mpirun')
755
755
756 parser_mpiexec = subparsers.add_parser(
756 parser_mpiexec = subparsers.add_parser(
757 'mpiexec',
757 'mpiexec',
758 help='run a cluster using mpiexec (mpirun also works)',
758 help='run a cluster using mpiexec (mpirun also works)',
759 parents=[base_parser]
759 parents=[base_parser]
760 )
760 )
761 parser_mpiexec.add_argument(
761 parser_mpiexec.add_argument(
762 "--mpi",
762 "--mpi",
763 type=str,
763 type=str,
764 dest="mpi", # Don't put a default here to allow no MPI support
764 dest="mpi", # Don't put a default here to allow no MPI support
765 help="how to call MPI_Init (default=mpi4py)"
765 help="how to call MPI_Init (default=mpi4py)"
766 )
766 )
767 parser_mpiexec.set_defaults(func=main_mpi, cmd='mpiexec')
767 parser_mpiexec.set_defaults(func=main_mpi, cmd='mpiexec')
768
768
769 parser_pbs = subparsers.add_parser(
769 parser_pbs = subparsers.add_parser(
770 'pbs',
770 'pbs',
771 help='run a pbs cluster',
771 help='run a pbs cluster',
772 parents=[base_parser]
772 parents=[base_parser]
773 )
773 )
774 parser_pbs.add_argument(
774 parser_pbs.add_argument(
775 '--pbs-script',
775 '--pbs-script',
776 type=str,
776 type=str,
777 dest='pbsscript',
777 dest='pbsscript',
778 help='PBS script template',
778 help='PBS script template',
779 default='pbs.template'
779 default='pbs.template'
780 )
780 )
781 parser_pbs.set_defaults(func=main_pbs)
781 parser_pbs.set_defaults(func=main_pbs)
782
782
783 parser_ssh = subparsers.add_parser(
783 parser_ssh = subparsers.add_parser(
784 'ssh',
784 'ssh',
785 help='run a cluster using ssh, should have ssh-keys setup',
785 help='run a cluster using ssh, should have ssh-keys setup',
786 parents=[base_parser]
786 parents=[base_parser]
787 )
787 )
788 parser_ssh.add_argument(
788 parser_ssh.add_argument(
789 '--clusterfile',
789 '--clusterfile',
790 type=str,
790 type=str,
791 dest='clusterfile',
791 dest='clusterfile',
792 help='python file describing the cluster',
792 help='python file describing the cluster',
793 default='clusterfile.py',
793 default='clusterfile.py',
794 )
794 )
795 parser_ssh.add_argument(
795 parser_ssh.add_argument(
796 '--sshx',
796 '--sshx',
797 type=str,
797 type=str,
798 dest='sshx',
798 dest='sshx',
799 help='sshx launcher helper'
799 help='sshx launcher helper'
800 )
800 )
801 parser_ssh.set_defaults(func=main_ssh)
801 parser_ssh.set_defaults(func=main_ssh)
802
802
803 args = parser.parse_args()
803 args = parser.parse_args()
804 return args
804 return args
805
805
806 def main():
806 def main():
807 args = get_args()
807 args = get_args()
808 reactor.callWhenRunning(args.func, args)
808 reactor.callWhenRunning(args.func, args)
809 log.startLogging(sys.stdout)
809 log.startLogging(sys.stdout)
810 reactor.run()
810 reactor.run()
811
811
812 if __name__ == '__main__':
812 if __name__ == '__main__':
813 main()
813 main()
@@ -1,416 +1,416 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3
3
4 """The IPython controller."""
4 """The IPython controller."""
5
5
6 __docformat__ = "restructuredtext en"
6 __docformat__ = "restructuredtext en"
7
7
8 #-------------------------------------------------------------------------------
8 #-------------------------------------------------------------------------------
9 # Copyright (C) 2008 The IPython Development Team
9 # Copyright (C) 2008 The IPython Development Team
10 #
10 #
11 # Distributed under the terms of the BSD License. The full license is in
11 # Distributed under the terms of the BSD License. The full license is in
12 # the file COPYING, distributed as part of this software.
12 # the file COPYING, distributed as part of this software.
13 #-------------------------------------------------------------------------------
13 #-------------------------------------------------------------------------------
14
14
15 #-------------------------------------------------------------------------------
15 #-------------------------------------------------------------------------------
16 # Imports
16 # Imports
17 #-------------------------------------------------------------------------------
17 #-------------------------------------------------------------------------------
18
18
19 # Python looks for an empty string at the beginning of sys.path to enable
19 # Python looks for an empty string at the beginning of sys.path to enable
20 # importing from the cwd.
20 # importing from the cwd.
21 import sys
21 import sys
22 sys.path.insert(0, '')
22 sys.path.insert(0, '')
23
23
24 from optparse import OptionParser
24 from optparse import OptionParser
25 import os
25 import os
26 import time
26 import time
27 import tempfile
27 import tempfile
28
28
29 from twisted.application import internet, service
29 from twisted.application import internet, service
30 from twisted.internet import reactor, error, defer
30 from twisted.internet import reactor, error, defer
31 from twisted.python import log
31 from twisted.python import log
32
32
33 from IPython.kernel.fcutil import Tub, UnauthenticatedTub, have_crypto
33 from IPython.kernel.fcutil import Tub, UnauthenticatedTub, have_crypto
34
34
35 # from IPython.tools import growl
35 # from IPython.tools import growl
36 # growl.start("IPython1 Controller")
36 # growl.start("IPython1 Controller")
37
37
38 from IPython.kernel.error import SecurityError
38 from IPython.kernel.error import SecurityError
39 from IPython.kernel import controllerservice
39 from IPython.kernel import controllerservice
40 from IPython.kernel.fcutil import check_furl_file_security
40 from IPython.kernel.fcutil import check_furl_file_security
41
41
42 # Create various ipython directories if they don't exist.
42 # Create various ipython directories if they don't exist.
43 # This must be done before IPython.kernel.config is imported.
43 # This must be done before IPython.kernel.config is imported.
44 from IPython.iplib import user_setup
44 from IPython.core.iplib import user_setup
45 from IPython.utils.genutils import get_ipython_dir, get_log_dir, get_security_dir
45 from IPython.utils.genutils import get_ipython_dir, get_log_dir, get_security_dir
46 if os.name == 'posix':
46 if os.name == 'posix':
47 rc_suffix = ''
47 rc_suffix = ''
48 else:
48 else:
49 rc_suffix = '.ini'
49 rc_suffix = '.ini'
50 user_setup(get_ipython_dir(), rc_suffix, mode='install', interactive=False)
50 user_setup(get_ipython_dir(), rc_suffix, mode='install', interactive=False)
51 get_log_dir()
51 get_log_dir()
52 get_security_dir()
52 get_security_dir()
53
53
54 from IPython.kernel.config import config_manager as kernel_config_manager
54 from IPython.kernel.config import config_manager as kernel_config_manager
55 from IPython.config.cutils import import_item
55 from IPython.config.cutils import import_item
56
56
57
57
58 #-------------------------------------------------------------------------------
58 #-------------------------------------------------------------------------------
59 # Code
59 # Code
60 #-------------------------------------------------------------------------------
60 #-------------------------------------------------------------------------------
61
61
62 def get_temp_furlfile(filename):
62 def get_temp_furlfile(filename):
63 return tempfile.mktemp(dir=os.path.dirname(filename),
63 return tempfile.mktemp(dir=os.path.dirname(filename),
64 prefix=os.path.basename(filename))
64 prefix=os.path.basename(filename))
65
65
66 def make_tub(ip, port, secure, cert_file):
66 def make_tub(ip, port, secure, cert_file):
67 """
67 """
68 Create a listening tub given an ip, port, and cert_file location.
68 Create a listening tub given an ip, port, and cert_file location.
69
69
70 :Parameters:
70 :Parameters:
71 ip : str
71 ip : str
72 The ip address that the tub should listen on. Empty means all
72 The ip address that the tub should listen on. Empty means all
73 port : int
73 port : int
74 The port that the tub should listen on. A value of 0 means
74 The port that the tub should listen on. A value of 0 means
75 pick a random port
75 pick a random port
76 secure: boolean
76 secure: boolean
77 Will the connection be secure (in the foolscap sense)
77 Will the connection be secure (in the foolscap sense)
78 cert_file:
78 cert_file:
79 A filename of a file to be used for theSSL certificate
79 A filename of a file to be used for theSSL certificate
80 """
80 """
81 if secure:
81 if secure:
82 if have_crypto:
82 if have_crypto:
83 tub = Tub(certFile=cert_file)
83 tub = Tub(certFile=cert_file)
84 else:
84 else:
85 raise SecurityError("""
85 raise SecurityError("""
86 OpenSSL/pyOpenSSL is not available, so we can't run in secure mode.
86 OpenSSL/pyOpenSSL is not available, so we can't run in secure mode.
87 Try running without security using 'ipcontroller -xy'.
87 Try running without security using 'ipcontroller -xy'.
88 """)
88 """)
89 else:
89 else:
90 tub = UnauthenticatedTub()
90 tub = UnauthenticatedTub()
91
91
92 # Set the strport based on the ip and port and start listening
92 # Set the strport based on the ip and port and start listening
93 if ip == '':
93 if ip == '':
94 strport = "tcp:%i" % port
94 strport = "tcp:%i" % port
95 else:
95 else:
96 strport = "tcp:%i:interface=%s" % (port, ip)
96 strport = "tcp:%i:interface=%s" % (port, ip)
97 listener = tub.listenOn(strport)
97 listener = tub.listenOn(strport)
98
98
99 return tub, listener
99 return tub, listener
100
100
101 def make_client_service(controller_service, config):
101 def make_client_service(controller_service, config):
102 """
102 """
103 Create a service that will listen for clients.
103 Create a service that will listen for clients.
104
104
105 This service is simply a `foolscap.Tub` instance that has a set of Referenceables
105 This service is simply a `foolscap.Tub` instance that has a set of Referenceables
106 registered with it.
106 registered with it.
107 """
107 """
108
108
109 # Now create the foolscap tub
109 # Now create the foolscap tub
110 ip = config['controller']['client_tub']['ip']
110 ip = config['controller']['client_tub']['ip']
111 port = config['controller']['client_tub'].as_int('port')
111 port = config['controller']['client_tub'].as_int('port')
112 location = config['controller']['client_tub']['location']
112 location = config['controller']['client_tub']['location']
113 secure = config['controller']['client_tub']['secure']
113 secure = config['controller']['client_tub']['secure']
114 cert_file = config['controller']['client_tub']['cert_file']
114 cert_file = config['controller']['client_tub']['cert_file']
115 client_tub, client_listener = make_tub(ip, port, secure, cert_file)
115 client_tub, client_listener = make_tub(ip, port, secure, cert_file)
116
116
117 # Set the location in the trivial case of localhost
117 # Set the location in the trivial case of localhost
118 if ip == 'localhost' or ip == '127.0.0.1':
118 if ip == 'localhost' or ip == '127.0.0.1':
119 location = "127.0.0.1"
119 location = "127.0.0.1"
120
120
121 if not secure:
121 if not secure:
122 log.msg("WARNING: you are running the controller with no client security")
122 log.msg("WARNING: you are running the controller with no client security")
123
123
124 def set_location_and_register():
124 def set_location_and_register():
125 """Set the location for the tub and return a deferred."""
125 """Set the location for the tub and return a deferred."""
126
126
127 def register(empty, ref, furl_file):
127 def register(empty, ref, furl_file):
128 # We create and then move to make sure that when the file
128 # We create and then move to make sure that when the file
129 # appears to other processes, the buffer has the flushed
129 # appears to other processes, the buffer has the flushed
130 # and the file has been closed
130 # and the file has been closed
131 temp_furl_file = get_temp_furlfile(furl_file)
131 temp_furl_file = get_temp_furlfile(furl_file)
132 client_tub.registerReference(ref, furlFile=temp_furl_file)
132 client_tub.registerReference(ref, furlFile=temp_furl_file)
133 os.rename(temp_furl_file, furl_file)
133 os.rename(temp_furl_file, furl_file)
134
134
135 if location == '':
135 if location == '':
136 d = client_tub.setLocationAutomatically()
136 d = client_tub.setLocationAutomatically()
137 else:
137 else:
138 d = defer.maybeDeferred(client_tub.setLocation, "%s:%i" % (location, client_listener.getPortnum()))
138 d = defer.maybeDeferred(client_tub.setLocation, "%s:%i" % (location, client_listener.getPortnum()))
139
139
140 for ciname, ci in config['controller']['controller_interfaces'].iteritems():
140 for ciname, ci in config['controller']['controller_interfaces'].iteritems():
141 log.msg("Adapting Controller to interface: %s" % ciname)
141 log.msg("Adapting Controller to interface: %s" % ciname)
142 furl_file = ci['furl_file']
142 furl_file = ci['furl_file']
143 log.msg("Saving furl for interface [%s] to file: %s" % (ciname, furl_file))
143 log.msg("Saving furl for interface [%s] to file: %s" % (ciname, furl_file))
144 check_furl_file_security(furl_file, secure)
144 check_furl_file_security(furl_file, secure)
145 adapted_controller = import_item(ci['controller_interface'])(controller_service)
145 adapted_controller = import_item(ci['controller_interface'])(controller_service)
146 d.addCallback(register, import_item(ci['fc_interface'])(adapted_controller),
146 d.addCallback(register, import_item(ci['fc_interface'])(adapted_controller),
147 furl_file=ci['furl_file'])
147 furl_file=ci['furl_file'])
148
148
149 reactor.callWhenRunning(set_location_and_register)
149 reactor.callWhenRunning(set_location_and_register)
150 return client_tub
150 return client_tub
151
151
152
152
153 def make_engine_service(controller_service, config):
153 def make_engine_service(controller_service, config):
154 """
154 """
155 Create a service that will listen for engines.
155 Create a service that will listen for engines.
156
156
157 This service is simply a `foolscap.Tub` instance that has a set of Referenceables
157 This service is simply a `foolscap.Tub` instance that has a set of Referenceables
158 registered with it.
158 registered with it.
159 """
159 """
160
160
161 # Now create the foolscap tub
161 # Now create the foolscap tub
162 ip = config['controller']['engine_tub']['ip']
162 ip = config['controller']['engine_tub']['ip']
163 port = config['controller']['engine_tub'].as_int('port')
163 port = config['controller']['engine_tub'].as_int('port')
164 location = config['controller']['engine_tub']['location']
164 location = config['controller']['engine_tub']['location']
165 secure = config['controller']['engine_tub']['secure']
165 secure = config['controller']['engine_tub']['secure']
166 cert_file = config['controller']['engine_tub']['cert_file']
166 cert_file = config['controller']['engine_tub']['cert_file']
167 engine_tub, engine_listener = make_tub(ip, port, secure, cert_file)
167 engine_tub, engine_listener = make_tub(ip, port, secure, cert_file)
168
168
169 # Set the location in the trivial case of localhost
169 # Set the location in the trivial case of localhost
170 if ip == 'localhost' or ip == '127.0.0.1':
170 if ip == 'localhost' or ip == '127.0.0.1':
171 location = "127.0.0.1"
171 location = "127.0.0.1"
172
172
173 if not secure:
173 if not secure:
174 log.msg("WARNING: you are running the controller with no engine security")
174 log.msg("WARNING: you are running the controller with no engine security")
175
175
176 def set_location_and_register():
176 def set_location_and_register():
177 """Set the location for the tub and return a deferred."""
177 """Set the location for the tub and return a deferred."""
178
178
179 def register(empty, ref, furl_file):
179 def register(empty, ref, furl_file):
180 # We create and then move to make sure that when the file
180 # We create and then move to make sure that when the file
181 # appears to other processes, the buffer has the flushed
181 # appears to other processes, the buffer has the flushed
182 # and the file has been closed
182 # and the file has been closed
183 temp_furl_file = get_temp_furlfile(furl_file)
183 temp_furl_file = get_temp_furlfile(furl_file)
184 engine_tub.registerReference(ref, furlFile=temp_furl_file)
184 engine_tub.registerReference(ref, furlFile=temp_furl_file)
185 os.rename(temp_furl_file, furl_file)
185 os.rename(temp_furl_file, furl_file)
186
186
187 if location == '':
187 if location == '':
188 d = engine_tub.setLocationAutomatically()
188 d = engine_tub.setLocationAutomatically()
189 else:
189 else:
190 d = defer.maybeDeferred(engine_tub.setLocation, "%s:%i" % (location, engine_listener.getPortnum()))
190 d = defer.maybeDeferred(engine_tub.setLocation, "%s:%i" % (location, engine_listener.getPortnum()))
191
191
192 furl_file = config['controller']['engine_furl_file']
192 furl_file = config['controller']['engine_furl_file']
193 engine_fc_interface = import_item(config['controller']['engine_fc_interface'])
193 engine_fc_interface = import_item(config['controller']['engine_fc_interface'])
194 log.msg("Saving furl for the engine to file: %s" % furl_file)
194 log.msg("Saving furl for the engine to file: %s" % furl_file)
195 check_furl_file_security(furl_file, secure)
195 check_furl_file_security(furl_file, secure)
196 fc_controller = engine_fc_interface(controller_service)
196 fc_controller = engine_fc_interface(controller_service)
197 d.addCallback(register, fc_controller, furl_file=furl_file)
197 d.addCallback(register, fc_controller, furl_file=furl_file)
198
198
199 reactor.callWhenRunning(set_location_and_register)
199 reactor.callWhenRunning(set_location_and_register)
200 return engine_tub
200 return engine_tub
201
201
202 def start_controller():
202 def start_controller():
203 """
203 """
204 Start the controller by creating the service hierarchy and starting the reactor.
204 Start the controller by creating the service hierarchy and starting the reactor.
205
205
206 This method does the following:
206 This method does the following:
207
207
208 * It starts the controller logging
208 * It starts the controller logging
209 * In execute an import statement for the controller
209 * In execute an import statement for the controller
210 * It creates 2 `foolscap.Tub` instances for the client and the engines
210 * It creates 2 `foolscap.Tub` instances for the client and the engines
211 and registers `foolscap.Referenceables` with the tubs to expose the
211 and registers `foolscap.Referenceables` with the tubs to expose the
212 controller to engines and clients.
212 controller to engines and clients.
213 """
213 """
214 config = kernel_config_manager.get_config_obj()
214 config = kernel_config_manager.get_config_obj()
215
215
216 # Start logging
216 # Start logging
217 logfile = config['controller']['logfile']
217 logfile = config['controller']['logfile']
218 if logfile:
218 if logfile:
219 logfile = logfile + str(os.getpid()) + '.log'
219 logfile = logfile + str(os.getpid()) + '.log'
220 try:
220 try:
221 openLogFile = open(logfile, 'w')
221 openLogFile = open(logfile, 'w')
222 except:
222 except:
223 openLogFile = sys.stdout
223 openLogFile = sys.stdout
224 else:
224 else:
225 openLogFile = sys.stdout
225 openLogFile = sys.stdout
226 log.startLogging(openLogFile)
226 log.startLogging(openLogFile)
227
227
228 # Execute any user defined import statements
228 # Execute any user defined import statements
229 cis = config['controller']['import_statement']
229 cis = config['controller']['import_statement']
230 if cis:
230 if cis:
231 try:
231 try:
232 exec cis in globals(), locals()
232 exec cis in globals(), locals()
233 except:
233 except:
234 log.msg("Error running import_statement: %s" % cis)
234 log.msg("Error running import_statement: %s" % cis)
235
235
236 # Delete old furl files unless the reuse_furls is set
236 # Delete old furl files unless the reuse_furls is set
237 reuse = config['controller']['reuse_furls']
237 reuse = config['controller']['reuse_furls']
238 if not reuse:
238 if not reuse:
239 paths = (config['controller']['engine_furl_file'],
239 paths = (config['controller']['engine_furl_file'],
240 config['controller']['controller_interfaces']['task']['furl_file'],
240 config['controller']['controller_interfaces']['task']['furl_file'],
241 config['controller']['controller_interfaces']['multiengine']['furl_file']
241 config['controller']['controller_interfaces']['multiengine']['furl_file']
242 )
242 )
243 for p in paths:
243 for p in paths:
244 if os.path.isfile(p):
244 if os.path.isfile(p):
245 os.remove(p)
245 os.remove(p)
246
246
247 # Create the service hierarchy
247 # Create the service hierarchy
248 main_service = service.MultiService()
248 main_service = service.MultiService()
249 # The controller service
249 # The controller service
250 controller_service = controllerservice.ControllerService()
250 controller_service = controllerservice.ControllerService()
251 controller_service.setServiceParent(main_service)
251 controller_service.setServiceParent(main_service)
252 # The client tub and all its refereceables
252 # The client tub and all its refereceables
253 client_service = make_client_service(controller_service, config)
253 client_service = make_client_service(controller_service, config)
254 client_service.setServiceParent(main_service)
254 client_service.setServiceParent(main_service)
255 # The engine tub
255 # The engine tub
256 engine_service = make_engine_service(controller_service, config)
256 engine_service = make_engine_service(controller_service, config)
257 engine_service.setServiceParent(main_service)
257 engine_service.setServiceParent(main_service)
258 # Start the controller service and set things running
258 # Start the controller service and set things running
259 main_service.startService()
259 main_service.startService()
260 reactor.run()
260 reactor.run()
261
261
262 def init_config():
262 def init_config():
263 """
263 """
264 Initialize the configuration using default and command line options.
264 Initialize the configuration using default and command line options.
265 """
265 """
266
266
267 parser = OptionParser("""ipcontroller [options]
267 parser = OptionParser("""ipcontroller [options]
268
268
269 Start an IPython controller.
269 Start an IPython controller.
270
270
271 Use the IPYTHONDIR environment variable to change your IPython directory
271 Use the IPYTHONDIR environment variable to change your IPython directory
272 from the default of .ipython or _ipython. The log and security
272 from the default of .ipython or _ipython. The log and security
273 subdirectories of your IPython directory will be used by this script
273 subdirectories of your IPython directory will be used by this script
274 for log files and security files.""")
274 for log files and security files.""")
275
275
276 # Client related options
276 # Client related options
277 parser.add_option(
277 parser.add_option(
278 "--client-ip",
278 "--client-ip",
279 type="string",
279 type="string",
280 dest="client_ip",
280 dest="client_ip",
281 help="the IP address or hostname the controller will listen on for client connections"
281 help="the IP address or hostname the controller will listen on for client connections"
282 )
282 )
283 parser.add_option(
283 parser.add_option(
284 "--client-port",
284 "--client-port",
285 type="int",
285 type="int",
286 dest="client_port",
286 dest="client_port",
287 help="the port the controller will listen on for client connections"
287 help="the port the controller will listen on for client connections"
288 )
288 )
289 parser.add_option(
289 parser.add_option(
290 '--client-location',
290 '--client-location',
291 type="string",
291 type="string",
292 dest="client_location",
292 dest="client_location",
293 help="hostname or ip for clients to connect to"
293 help="hostname or ip for clients to connect to"
294 )
294 )
295 parser.add_option(
295 parser.add_option(
296 "-x",
296 "-x",
297 action="store_false",
297 action="store_false",
298 dest="client_secure",
298 dest="client_secure",
299 help="turn off all client security"
299 help="turn off all client security"
300 )
300 )
301 parser.add_option(
301 parser.add_option(
302 '--client-cert-file',
302 '--client-cert-file',
303 type="string",
303 type="string",
304 dest="client_cert_file",
304 dest="client_cert_file",
305 help="file to store the client SSL certificate"
305 help="file to store the client SSL certificate"
306 )
306 )
307 parser.add_option(
307 parser.add_option(
308 '--task-furl-file',
308 '--task-furl-file',
309 type="string",
309 type="string",
310 dest="task_furl_file",
310 dest="task_furl_file",
311 help="file to store the FURL for task clients to connect with"
311 help="file to store the FURL for task clients to connect with"
312 )
312 )
313 parser.add_option(
313 parser.add_option(
314 '--multiengine-furl-file',
314 '--multiengine-furl-file',
315 type="string",
315 type="string",
316 dest="multiengine_furl_file",
316 dest="multiengine_furl_file",
317 help="file to store the FURL for multiengine clients to connect with"
317 help="file to store the FURL for multiengine clients to connect with"
318 )
318 )
319 # Engine related options
319 # Engine related options
320 parser.add_option(
320 parser.add_option(
321 "--engine-ip",
321 "--engine-ip",
322 type="string",
322 type="string",
323 dest="engine_ip",
323 dest="engine_ip",
324 help="the IP address or hostname the controller will listen on for engine connections"
324 help="the IP address or hostname the controller will listen on for engine connections"
325 )
325 )
326 parser.add_option(
326 parser.add_option(
327 "--engine-port",
327 "--engine-port",
328 type="int",
328 type="int",
329 dest="engine_port",
329 dest="engine_port",
330 help="the port the controller will listen on for engine connections"
330 help="the port the controller will listen on for engine connections"
331 )
331 )
332 parser.add_option(
332 parser.add_option(
333 '--engine-location',
333 '--engine-location',
334 type="string",
334 type="string",
335 dest="engine_location",
335 dest="engine_location",
336 help="hostname or ip for engines to connect to"
336 help="hostname or ip for engines to connect to"
337 )
337 )
338 parser.add_option(
338 parser.add_option(
339 "-y",
339 "-y",
340 action="store_false",
340 action="store_false",
341 dest="engine_secure",
341 dest="engine_secure",
342 help="turn off all engine security"
342 help="turn off all engine security"
343 )
343 )
344 parser.add_option(
344 parser.add_option(
345 '--engine-cert-file',
345 '--engine-cert-file',
346 type="string",
346 type="string",
347 dest="engine_cert_file",
347 dest="engine_cert_file",
348 help="file to store the engine SSL certificate"
348 help="file to store the engine SSL certificate"
349 )
349 )
350 parser.add_option(
350 parser.add_option(
351 '--engine-furl-file',
351 '--engine-furl-file',
352 type="string",
352 type="string",
353 dest="engine_furl_file",
353 dest="engine_furl_file",
354 help="file to store the FURL for engines to connect with"
354 help="file to store the FURL for engines to connect with"
355 )
355 )
356 parser.add_option(
356 parser.add_option(
357 "-l", "--logfile",
357 "-l", "--logfile",
358 type="string",
358 type="string",
359 dest="logfile",
359 dest="logfile",
360 help="log file name (default is stdout)"
360 help="log file name (default is stdout)"
361 )
361 )
362 parser.add_option(
362 parser.add_option(
363 "-r",
363 "-r",
364 action="store_true",
364 action="store_true",
365 dest="reuse_furls",
365 dest="reuse_furls",
366 help="try to reuse all furl files"
366 help="try to reuse all furl files"
367 )
367 )
368
368
369 (options, args) = parser.parse_args()
369 (options, args) = parser.parse_args()
370
370
371 config = kernel_config_manager.get_config_obj()
371 config = kernel_config_manager.get_config_obj()
372
372
373 # Update with command line options
373 # Update with command line options
374 if options.client_ip is not None:
374 if options.client_ip is not None:
375 config['controller']['client_tub']['ip'] = options.client_ip
375 config['controller']['client_tub']['ip'] = options.client_ip
376 if options.client_port is not None:
376 if options.client_port is not None:
377 config['controller']['client_tub']['port'] = options.client_port
377 config['controller']['client_tub']['port'] = options.client_port
378 if options.client_location is not None:
378 if options.client_location is not None:
379 config['controller']['client_tub']['location'] = options.client_location
379 config['controller']['client_tub']['location'] = options.client_location
380 if options.client_secure is not None:
380 if options.client_secure is not None:
381 config['controller']['client_tub']['secure'] = options.client_secure
381 config['controller']['client_tub']['secure'] = options.client_secure
382 if options.client_cert_file is not None:
382 if options.client_cert_file is not None:
383 config['controller']['client_tub']['cert_file'] = options.client_cert_file
383 config['controller']['client_tub']['cert_file'] = options.client_cert_file
384 if options.task_furl_file is not None:
384 if options.task_furl_file is not None:
385 config['controller']['controller_interfaces']['task']['furl_file'] = options.task_furl_file
385 config['controller']['controller_interfaces']['task']['furl_file'] = options.task_furl_file
386 if options.multiengine_furl_file is not None:
386 if options.multiengine_furl_file is not None:
387 config['controller']['controller_interfaces']['multiengine']['furl_file'] = options.multiengine_furl_file
387 config['controller']['controller_interfaces']['multiengine']['furl_file'] = options.multiengine_furl_file
388 if options.engine_ip is not None:
388 if options.engine_ip is not None:
389 config['controller']['engine_tub']['ip'] = options.engine_ip
389 config['controller']['engine_tub']['ip'] = options.engine_ip
390 if options.engine_port is not None:
390 if options.engine_port is not None:
391 config['controller']['engine_tub']['port'] = options.engine_port
391 config['controller']['engine_tub']['port'] = options.engine_port
392 if options.engine_location is not None:
392 if options.engine_location is not None:
393 config['controller']['engine_tub']['location'] = options.engine_location
393 config['controller']['engine_tub']['location'] = options.engine_location
394 if options.engine_secure is not None:
394 if options.engine_secure is not None:
395 config['controller']['engine_tub']['secure'] = options.engine_secure
395 config['controller']['engine_tub']['secure'] = options.engine_secure
396 if options.engine_cert_file is not None:
396 if options.engine_cert_file is not None:
397 config['controller']['engine_tub']['cert_file'] = options.engine_cert_file
397 config['controller']['engine_tub']['cert_file'] = options.engine_cert_file
398 if options.engine_furl_file is not None:
398 if options.engine_furl_file is not None:
399 config['controller']['engine_furl_file'] = options.engine_furl_file
399 config['controller']['engine_furl_file'] = options.engine_furl_file
400 if options.reuse_furls is not None:
400 if options.reuse_furls is not None:
401 config['controller']['reuse_furls'] = options.reuse_furls
401 config['controller']['reuse_furls'] = options.reuse_furls
402
402
403 if options.logfile is not None:
403 if options.logfile is not None:
404 config['controller']['logfile'] = options.logfile
404 config['controller']['logfile'] = options.logfile
405
405
406 kernel_config_manager.update_config_obj(config)
406 kernel_config_manager.update_config_obj(config)
407
407
408 def main():
408 def main():
409 """
409 """
410 After creating the configuration information, start the controller.
410 After creating the configuration information, start the controller.
411 """
411 """
412 init_config()
412 init_config()
413 start_controller()
413 start_controller()
414
414
415 if __name__ == "__main__":
415 if __name__ == "__main__":
416 main()
416 main()
@@ -1,193 +1,193 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3
3
4 """Start the IPython Engine."""
4 """Start the IPython Engine."""
5
5
6 __docformat__ = "restructuredtext en"
6 __docformat__ = "restructuredtext en"
7
7
8 #-------------------------------------------------------------------------------
8 #-------------------------------------------------------------------------------
9 # Copyright (C) 2008 The IPython Development Team
9 # Copyright (C) 2008 The IPython Development Team
10 #
10 #
11 # Distributed under the terms of the BSD License. The full license is in
11 # Distributed under the terms of the BSD License. The full license is in
12 # the file COPYING, distributed as part of this software.
12 # the file COPYING, distributed as part of this software.
13 #-------------------------------------------------------------------------------
13 #-------------------------------------------------------------------------------
14
14
15 #-------------------------------------------------------------------------------
15 #-------------------------------------------------------------------------------
16 # Imports
16 # Imports
17 #-------------------------------------------------------------------------------
17 #-------------------------------------------------------------------------------
18
18
19 # Python looks for an empty string at the beginning of sys.path to enable
19 # Python looks for an empty string at the beginning of sys.path to enable
20 # importing from the cwd.
20 # importing from the cwd.
21 import sys
21 import sys
22 sys.path.insert(0, '')
22 sys.path.insert(0, '')
23
23
24 from optparse import OptionParser
24 from optparse import OptionParser
25 import os
25 import os
26
26
27 from twisted.application import service
27 from twisted.application import service
28 from twisted.internet import reactor
28 from twisted.internet import reactor
29 from twisted.python import log
29 from twisted.python import log
30
30
31 from IPython.kernel.fcutil import Tub, UnauthenticatedTub
31 from IPython.kernel.fcutil import Tub, UnauthenticatedTub
32
32
33 from IPython.kernel.core.config import config_manager as core_config_manager
33 from IPython.kernel.core.config import config_manager as core_config_manager
34 from IPython.config.cutils import import_item
34 from IPython.config.cutils import import_item
35 from IPython.kernel.engineservice import EngineService
35 from IPython.kernel.engineservice import EngineService
36
36
37 # Create various ipython directories if they don't exist.
37 # Create various ipython directories if they don't exist.
38 # This must be done before IPython.kernel.config is imported.
38 # This must be done before IPython.kernel.config is imported.
39 from IPython.iplib import user_setup
39 from IPython.core.iplib import user_setup
40 from IPython.utils.genutils import get_ipython_dir, get_log_dir, get_security_dir
40 from IPython.utils.genutils import get_ipython_dir, get_log_dir, get_security_dir
41 if os.name == 'posix':
41 if os.name == 'posix':
42 rc_suffix = ''
42 rc_suffix = ''
43 else:
43 else:
44 rc_suffix = '.ini'
44 rc_suffix = '.ini'
45 user_setup(get_ipython_dir(), rc_suffix, mode='install', interactive=False)
45 user_setup(get_ipython_dir(), rc_suffix, mode='install', interactive=False)
46 get_log_dir()
46 get_log_dir()
47 get_security_dir()
47 get_security_dir()
48
48
49 from IPython.kernel.config import config_manager as kernel_config_manager
49 from IPython.kernel.config import config_manager as kernel_config_manager
50 from IPython.kernel.engineconnector import EngineConnector
50 from IPython.kernel.engineconnector import EngineConnector
51
51
52
52
53 #-------------------------------------------------------------------------------
53 #-------------------------------------------------------------------------------
54 # Code
54 # Code
55 #-------------------------------------------------------------------------------
55 #-------------------------------------------------------------------------------
56
56
57 def start_engine():
57 def start_engine():
58 """
58 """
59 Start the engine, by creating it and starting the Twisted reactor.
59 Start the engine, by creating it and starting the Twisted reactor.
60
60
61 This method does:
61 This method does:
62
62
63 * If it exists, runs the `mpi_import_statement` to call `MPI_Init`
63 * If it exists, runs the `mpi_import_statement` to call `MPI_Init`
64 * Starts the engine logging
64 * Starts the engine logging
65 * Creates an IPython shell and wraps it in an `EngineService`
65 * Creates an IPython shell and wraps it in an `EngineService`
66 * Creates a `foolscap.Tub` to use in connecting to a controller.
66 * Creates a `foolscap.Tub` to use in connecting to a controller.
67 * Uses the tub and the `EngineService` along with a Foolscap URL
67 * Uses the tub and the `EngineService` along with a Foolscap URL
68 (or FURL) to connect to the controller and register the engine
68 (or FURL) to connect to the controller and register the engine
69 with the controller
69 with the controller
70 """
70 """
71 kernel_config = kernel_config_manager.get_config_obj()
71 kernel_config = kernel_config_manager.get_config_obj()
72 core_config = core_config_manager.get_config_obj()
72 core_config = core_config_manager.get_config_obj()
73
73
74
74
75 # Execute the mpi import statement that needs to call MPI_Init
75 # Execute the mpi import statement that needs to call MPI_Init
76 global mpi
76 global mpi
77 mpikey = kernel_config['mpi']['default']
77 mpikey = kernel_config['mpi']['default']
78 mpi_import_statement = kernel_config['mpi'].get(mpikey, None)
78 mpi_import_statement = kernel_config['mpi'].get(mpikey, None)
79 if mpi_import_statement is not None:
79 if mpi_import_statement is not None:
80 try:
80 try:
81 exec mpi_import_statement in globals()
81 exec mpi_import_statement in globals()
82 except:
82 except:
83 mpi = None
83 mpi = None
84 else:
84 else:
85 mpi = None
85 mpi = None
86
86
87 # Start logging
87 # Start logging
88 logfile = kernel_config['engine']['logfile']
88 logfile = kernel_config['engine']['logfile']
89 if logfile:
89 if logfile:
90 logfile = logfile + str(os.getpid()) + '.log'
90 logfile = logfile + str(os.getpid()) + '.log'
91 try:
91 try:
92 openLogFile = open(logfile, 'w')
92 openLogFile = open(logfile, 'w')
93 except:
93 except:
94 openLogFile = sys.stdout
94 openLogFile = sys.stdout
95 else:
95 else:
96 openLogFile = sys.stdout
96 openLogFile = sys.stdout
97 log.startLogging(openLogFile)
97 log.startLogging(openLogFile)
98
98
99 # Create the underlying shell class and EngineService
99 # Create the underlying shell class and EngineService
100 shell_class = import_item(core_config['shell']['shell_class'])
100 shell_class = import_item(core_config['shell']['shell_class'])
101 engine_service = EngineService(shell_class, mpi=mpi)
101 engine_service = EngineService(shell_class, mpi=mpi)
102 shell_import_statement = core_config['shell']['import_statement']
102 shell_import_statement = core_config['shell']['import_statement']
103 if shell_import_statement:
103 if shell_import_statement:
104 try:
104 try:
105 engine_service.execute(shell_import_statement)
105 engine_service.execute(shell_import_statement)
106 except:
106 except:
107 log.msg("Error running import_statement: %s" % shell_import_statement)
107 log.msg("Error running import_statement: %s" % shell_import_statement)
108
108
109 # Create the service hierarchy
109 # Create the service hierarchy
110 main_service = service.MultiService()
110 main_service = service.MultiService()
111 engine_service.setServiceParent(main_service)
111 engine_service.setServiceParent(main_service)
112 tub_service = Tub()
112 tub_service = Tub()
113 tub_service.setServiceParent(main_service)
113 tub_service.setServiceParent(main_service)
114 # This needs to be called before the connection is initiated
114 # This needs to be called before the connection is initiated
115 main_service.startService()
115 main_service.startService()
116
116
117 # This initiates the connection to the controller and calls
117 # This initiates the connection to the controller and calls
118 # register_engine to tell the controller we are ready to do work
118 # register_engine to tell the controller we are ready to do work
119 engine_connector = EngineConnector(tub_service)
119 engine_connector = EngineConnector(tub_service)
120 furl_file = kernel_config['engine']['furl_file']
120 furl_file = kernel_config['engine']['furl_file']
121 log.msg("Using furl file: %s" % furl_file)
121 log.msg("Using furl file: %s" % furl_file)
122
122
123 def call_connect(engine_service, furl_file):
123 def call_connect(engine_service, furl_file):
124 d = engine_connector.connect_to_controller(engine_service, furl_file)
124 d = engine_connector.connect_to_controller(engine_service, furl_file)
125 def handle_error(f):
125 def handle_error(f):
126 # If this print statement is replaced by a log.err(f) I get
126 # If this print statement is replaced by a log.err(f) I get
127 # an unhandled error, which makes no sense. I shouldn't have
127 # an unhandled error, which makes no sense. I shouldn't have
128 # to use a print statement here. My only thought is that
128 # to use a print statement here. My only thought is that
129 # at the beginning of the process the logging is still starting up
129 # at the beginning of the process the logging is still starting up
130 print "error connecting to controller:", f.getErrorMessage()
130 print "error connecting to controller:", f.getErrorMessage()
131 reactor.callLater(0.1, reactor.stop)
131 reactor.callLater(0.1, reactor.stop)
132 d.addErrback(handle_error)
132 d.addErrback(handle_error)
133
133
134 reactor.callWhenRunning(call_connect, engine_service, furl_file)
134 reactor.callWhenRunning(call_connect, engine_service, furl_file)
135 reactor.run()
135 reactor.run()
136
136
137
137
138 def init_config():
138 def init_config():
139 """
139 """
140 Initialize the configuration using default and command line options.
140 Initialize the configuration using default and command line options.
141 """
141 """
142
142
143 parser = OptionParser("""ipengine [options]
143 parser = OptionParser("""ipengine [options]
144
144
145 Start an IPython engine.
145 Start an IPython engine.
146
146
147 Use the IPYTHONDIR environment variable to change your IPython directory
147 Use the IPYTHONDIR environment variable to change your IPython directory
148 from the default of .ipython or _ipython. The log and security
148 from the default of .ipython or _ipython. The log and security
149 subdirectories of your IPython directory will be used by this script
149 subdirectories of your IPython directory will be used by this script
150 for log files and security files.""")
150 for log files and security files.""")
151
151
152 parser.add_option(
152 parser.add_option(
153 "--furl-file",
153 "--furl-file",
154 type="string",
154 type="string",
155 dest="furl_file",
155 dest="furl_file",
156 help="The filename containing the FURL of the controller"
156 help="The filename containing the FURL of the controller"
157 )
157 )
158 parser.add_option(
158 parser.add_option(
159 "--mpi",
159 "--mpi",
160 type="string",
160 type="string",
161 dest="mpi",
161 dest="mpi",
162 help="How to enable MPI (mpi4py, pytrilinos, or empty string to disable)"
162 help="How to enable MPI (mpi4py, pytrilinos, or empty string to disable)"
163 )
163 )
164 parser.add_option(
164 parser.add_option(
165 "-l",
165 "-l",
166 "--logfile",
166 "--logfile",
167 type="string",
167 type="string",
168 dest="logfile",
168 dest="logfile",
169 help="log file name (default is stdout)"
169 help="log file name (default is stdout)"
170 )
170 )
171
171
172 (options, args) = parser.parse_args()
172 (options, args) = parser.parse_args()
173
173
174 kernel_config = kernel_config_manager.get_config_obj()
174 kernel_config = kernel_config_manager.get_config_obj()
175 # Now override with command line options
175 # Now override with command line options
176 if options.furl_file is not None:
176 if options.furl_file is not None:
177 kernel_config['engine']['furl_file'] = options.furl_file
177 kernel_config['engine']['furl_file'] = options.furl_file
178 if options.logfile is not None:
178 if options.logfile is not None:
179 kernel_config['engine']['logfile'] = options.logfile
179 kernel_config['engine']['logfile'] = options.logfile
180 if options.mpi is not None:
180 if options.mpi is not None:
181 kernel_config['mpi']['default'] = options.mpi
181 kernel_config['mpi']['default'] = options.mpi
182
182
183
183
184 def main():
184 def main():
185 """
185 """
186 After creating the configuration information, start the engine.
186 After creating the configuration information, start the engine.
187 """
187 """
188 init_config()
188 init_config()
189 start_engine()
189 start_engine()
190
190
191
191
192 if __name__ == "__main__":
192 if __name__ == "__main__":
193 main()
193 main()
@@ -1,74 +1,74 b''
1 # Set this prefix to where you want to install the plugin
1 # Set this prefix to where you want to install the plugin
2 PREFIX=/usr/local
2 PREFIX=/usr/local
3
3
4 NOSE0=nosetests -vs --with-doctest --doctest-tests --detailed-errors
4 NOSE0=nosetests -vs --with-doctest --doctest-tests --detailed-errors
5 NOSE=nosetests -vvs --with-ipdoctest --doctest-tests --doctest-extension=txt \
5 NOSE=nosetests -vvs --with-ipdoctest --doctest-tests --doctest-extension=txt \
6 --detailed-errors
6 --detailed-errors
7
7
8 SRC=ipdoctest.py setup.py ../decorators.py
8 SRC=ipdoctest.py setup.py ../decorators.py
9
9
10 # Default target for clean 'make'
10 # Default target for clean 'make'
11 default: iplib
11 default: iplib
12
12
13 # The actual plugin installation
13 # The actual plugin installation
14 plugin: IPython_doctest_plugin.egg-info
14 plugin: IPython_doctest_plugin.egg-info
15
15
16 # Simple targets that test one thing
16 # Simple targets that test one thing
17 simple: plugin simple.py
17 simple: plugin simple.py
18 $(NOSE) simple.py
18 $(NOSE) simple.py
19
19
20 dtest: plugin dtexample.py
20 dtest: plugin dtexample.py
21 $(NOSE) dtexample.py
21 $(NOSE) dtexample.py
22
22
23 rtest: plugin test_refs.py
23 rtest: plugin test_refs.py
24 $(NOSE) test_refs.py
24 $(NOSE) test_refs.py
25
25
26 test: plugin dtexample.py
26 test: plugin dtexample.py
27 $(NOSE) dtexample.py test*.py test*.txt
27 $(NOSE) dtexample.py test*.py test*.txt
28
28
29 deb: plugin dtexample.py
29 deb: plugin dtexample.py
30 $(NOSE) test_combo.txt
30 $(NOSE) test_combo.txt
31
31
32 # IPython tests
32 # IPython tests
33 deco:
33 deco:
34 $(NOSE0) IPython.testing.decorators
34 $(NOSE0) IPython.testing.decorators
35
35
36 magic: plugin
36 magic: plugin
37 $(NOSE) IPython.Magic
37 $(NOSE) IPython.Magic
38
38
39 excolors: plugin
39 excolors: plugin
40 $(NOSE) IPython.core.excolors
40 $(NOSE) IPython.core.excolors
41
41
42 iplib: plugin
42 iplib: plugin
43 $(NOSE) IPython.iplib
43 $(NOSE) IPython.core.iplib
44
44
45 strd: plugin
45 strd: plugin
46 $(NOSE) IPython.strdispatch
46 $(NOSE) IPython.strdispatch
47
47
48 engine: plugin
48 engine: plugin
49 $(NOSE) IPython.kernel
49 $(NOSE) IPython.kernel
50
50
51 tf: plugin
51 tf: plugin
52 $(NOSE) IPython.config.traitlets
52 $(NOSE) IPython.config.traitlets
53
53
54 # All of ipython itself
54 # All of ipython itself
55 ipython: plugin
55 ipython: plugin
56 $(NOSE) IPython
56 $(NOSE) IPython
57
57
58
58
59 # Combined targets
59 # Combined targets
60 sr: rtest strd
60 sr: rtest strd
61
61
62 base: dtest rtest test strd deco
62 base: dtest rtest test strd deco
63
63
64 quick: base iplib ipipe
64 quick: base iplib ipipe
65
65
66 all: base ipython
66 all: base ipython
67
67
68 # Main plugin and cleanup
68 # Main plugin and cleanup
69 IPython_doctest_plugin.egg-info: $(SRC)
69 IPython_doctest_plugin.egg-info: $(SRC)
70 python setup.py install --prefix=$(PREFIX)
70 python setup.py install --prefix=$(PREFIX)
71 touch $@
71 touch $@
72
72
73 clean:
73 clean:
74 rm -rf IPython_doctest_plugin.egg-info *~ *pyc build/ dist/
74 rm -rf IPython_doctest_plugin.egg-info *~ *pyc build/ dist/
@@ -1,909 +1,909 b''
1 """Nose Plugin that supports IPython doctests.
1 """Nose Plugin that supports IPython doctests.
2
2
3 Limitations:
3 Limitations:
4
4
5 - When generating examples for use as doctests, make sure that you have
5 - When generating examples for use as doctests, make sure that you have
6 pretty-printing OFF. This can be done either by starting ipython with the
6 pretty-printing OFF. This can be done either by starting ipython with the
7 flag '--nopprint', by setting pprint to 0 in your ipythonrc file, or by
7 flag '--nopprint', by setting pprint to 0 in your ipythonrc file, or by
8 interactively disabling it with %Pprint. This is required so that IPython
8 interactively disabling it with %Pprint. This is required so that IPython
9 output matches that of normal Python, which is used by doctest for internal
9 output matches that of normal Python, which is used by doctest for internal
10 execution.
10 execution.
11
11
12 - Do not rely on specific prompt numbers for results (such as using
12 - Do not rely on specific prompt numbers for results (such as using
13 '_34==True', for example). For IPython tests run via an external process the
13 '_34==True', for example). For IPython tests run via an external process the
14 prompt numbers may be different, and IPython tests run as normal python code
14 prompt numbers may be different, and IPython tests run as normal python code
15 won't even have these special _NN variables set at all.
15 won't even have these special _NN variables set at all.
16 """
16 """
17
17
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19 # Module imports
19 # Module imports
20
20
21 # From the standard library
21 # From the standard library
22 import __builtin__
22 import __builtin__
23 import commands
23 import commands
24 import doctest
24 import doctest
25 import inspect
25 import inspect
26 import logging
26 import logging
27 import os
27 import os
28 import re
28 import re
29 import sys
29 import sys
30 import traceback
30 import traceback
31 import unittest
31 import unittest
32
32
33 from inspect import getmodule
33 from inspect import getmodule
34 from StringIO import StringIO
34 from StringIO import StringIO
35
35
36 # We are overriding the default doctest runner, so we need to import a few
36 # We are overriding the default doctest runner, so we need to import a few
37 # things from doctest directly
37 # things from doctest directly
38 from doctest import (REPORTING_FLAGS, REPORT_ONLY_FIRST_FAILURE,
38 from doctest import (REPORTING_FLAGS, REPORT_ONLY_FIRST_FAILURE,
39 _unittest_reportflags, DocTestRunner,
39 _unittest_reportflags, DocTestRunner,
40 _extract_future_flags, pdb, _OutputRedirectingPdb,
40 _extract_future_flags, pdb, _OutputRedirectingPdb,
41 _exception_traceback,
41 _exception_traceback,
42 linecache)
42 linecache)
43
43
44 # Third-party modules
44 # Third-party modules
45 import nose.core
45 import nose.core
46
46
47 from nose.plugins import doctests, Plugin
47 from nose.plugins import doctests, Plugin
48 from nose.util import anyp, getpackage, test_address, resolve_name, tolist
48 from nose.util import anyp, getpackage, test_address, resolve_name, tolist
49
49
50 #-----------------------------------------------------------------------------
50 #-----------------------------------------------------------------------------
51 # Module globals and other constants
51 # Module globals and other constants
52
52
53 log = logging.getLogger(__name__)
53 log = logging.getLogger(__name__)
54
54
55 ###########################################################################
55 ###########################################################################
56 # *** HACK ***
56 # *** HACK ***
57 # We must start our own ipython object and heavily muck with it so that all the
57 # We must start our own ipython object and heavily muck with it so that all the
58 # modifications IPython makes to system behavior don't send the doctest
58 # modifications IPython makes to system behavior don't send the doctest
59 # machinery into a fit. This code should be considered a gross hack, but it
59 # machinery into a fit. This code should be considered a gross hack, but it
60 # gets the job done.
60 # gets the job done.
61
61
62 def default_argv():
62 def default_argv():
63 """Return a valid default argv for creating testing instances of ipython"""
63 """Return a valid default argv for creating testing instances of ipython"""
64
64
65 # Get the install directory for the user configuration and tell ipython to
65 # Get the install directory for the user configuration and tell ipython to
66 # use the default profile from there.
66 # use the default profile from there.
67 from IPython import UserConfig
67 from IPython import UserConfig
68 ipcdir = os.path.dirname(UserConfig.__file__)
68 ipcdir = os.path.dirname(UserConfig.__file__)
69 #ipconf = os.path.join(ipcdir,'ipy_user_conf.py')
69 #ipconf = os.path.join(ipcdir,'ipy_user_conf.py')
70 ipconf = os.path.join(ipcdir,'ipythonrc')
70 ipconf = os.path.join(ipcdir,'ipythonrc')
71 #print 'conf:',ipconf # dbg
71 #print 'conf:',ipconf # dbg
72
72
73 return ['--colors=NoColor','--noterm_title','-rcfile=%s' % ipconf]
73 return ['--colors=NoColor','--noterm_title','-rcfile=%s' % ipconf]
74
74
75
75
76 # Hack to modify the %run command so we can sync the user's namespace with the
76 # Hack to modify the %run command so we can sync the user's namespace with the
77 # test globals. Once we move over to a clean magic system, this will be done
77 # test globals. Once we move over to a clean magic system, this will be done
78 # with much less ugliness.
78 # with much less ugliness.
79
79
80 class py_file_finder(object):
80 class py_file_finder(object):
81 def __init__(self,test_filename):
81 def __init__(self,test_filename):
82 self.test_filename = test_filename
82 self.test_filename = test_filename
83
83
84 def __call__(self,name):
84 def __call__(self,name):
85 from IPython.utils.genutils import get_py_filename
85 from IPython.utils.genutils import get_py_filename
86 try:
86 try:
87 return get_py_filename(name)
87 return get_py_filename(name)
88 except IOError:
88 except IOError:
89 test_dir = os.path.dirname(self.test_filename)
89 test_dir = os.path.dirname(self.test_filename)
90 new_path = os.path.join(test_dir,name)
90 new_path = os.path.join(test_dir,name)
91 return get_py_filename(new_path)
91 return get_py_filename(new_path)
92
92
93
93
94 def _run_ns_sync(self,arg_s,runner=None):
94 def _run_ns_sync(self,arg_s,runner=None):
95 """Modified version of %run that syncs testing namespaces.
95 """Modified version of %run that syncs testing namespaces.
96
96
97 This is strictly needed for running doctests that call %run.
97 This is strictly needed for running doctests that call %run.
98 """
98 """
99
99
100 # When tests call %run directly (not via doctest) these function attributes
100 # When tests call %run directly (not via doctest) these function attributes
101 # are not set
101 # are not set
102 try:
102 try:
103 fname = _run_ns_sync.test_filename
103 fname = _run_ns_sync.test_filename
104 except AttributeError:
104 except AttributeError:
105 fname = arg_s
105 fname = arg_s
106
106
107 finder = py_file_finder(fname)
107 finder = py_file_finder(fname)
108 out = _ip.IP.magic_run_ori(arg_s,runner,finder)
108 out = _ip.IP.magic_run_ori(arg_s,runner,finder)
109
109
110 # Simliarly, there is no test_globs when a test is NOT a doctest
110 # Simliarly, there is no test_globs when a test is NOT a doctest
111 if hasattr(_run_ns_sync,'test_globs'):
111 if hasattr(_run_ns_sync,'test_globs'):
112 _run_ns_sync.test_globs.update(_ip.user_ns)
112 _run_ns_sync.test_globs.update(_ip.user_ns)
113 return out
113 return out
114
114
115
115
116 class ipnsdict(dict):
116 class ipnsdict(dict):
117 """A special subclass of dict for use as an IPython namespace in doctests.
117 """A special subclass of dict for use as an IPython namespace in doctests.
118
118
119 This subclass adds a simple checkpointing capability so that when testing
119 This subclass adds a simple checkpointing capability so that when testing
120 machinery clears it (we use it as the test execution context), it doesn't
120 machinery clears it (we use it as the test execution context), it doesn't
121 get completely destroyed.
121 get completely destroyed.
122 """
122 """
123
123
124 def __init__(self,*a):
124 def __init__(self,*a):
125 dict.__init__(self,*a)
125 dict.__init__(self,*a)
126 self._savedict = {}
126 self._savedict = {}
127
127
128 def clear(self):
128 def clear(self):
129 dict.clear(self)
129 dict.clear(self)
130 self.update(self._savedict)
130 self.update(self._savedict)
131
131
132 def _checkpoint(self):
132 def _checkpoint(self):
133 self._savedict.clear()
133 self._savedict.clear()
134 self._savedict.update(self)
134 self._savedict.update(self)
135
135
136 def update(self,other):
136 def update(self,other):
137 self._checkpoint()
137 self._checkpoint()
138 dict.update(self,other)
138 dict.update(self,other)
139
139
140 # If '_' is in the namespace, python won't set it when executing code,
140 # If '_' is in the namespace, python won't set it when executing code,
141 # and we have examples that test it. So we ensure that the namespace
141 # and we have examples that test it. So we ensure that the namespace
142 # is always 'clean' of it before it's used for test code execution.
142 # is always 'clean' of it before it's used for test code execution.
143 self.pop('_',None)
143 self.pop('_',None)
144
144
145 # The builtins namespace must *always* be the real __builtin__ module,
145 # The builtins namespace must *always* be the real __builtin__ module,
146 # else weird stuff happens. The main ipython code does have provisions
146 # else weird stuff happens. The main ipython code does have provisions
147 # to ensure this after %run, but since in this class we do some
147 # to ensure this after %run, but since in this class we do some
148 # aggressive low-level cleaning of the execution namespace, we need to
148 # aggressive low-level cleaning of the execution namespace, we need to
149 # correct for that ourselves, to ensure consitency with the 'real'
149 # correct for that ourselves, to ensure consitency with the 'real'
150 # ipython.
150 # ipython.
151 self['__builtins__'] = __builtin__
151 self['__builtins__'] = __builtin__
152
152
153
153
154 def start_ipython():
154 def start_ipython():
155 """Start a global IPython shell, which we need for IPython-specific syntax.
155 """Start a global IPython shell, which we need for IPython-specific syntax.
156 """
156 """
157
157
158 # This function should only ever run once!
158 # This function should only ever run once!
159 if hasattr(start_ipython,'already_called'):
159 if hasattr(start_ipython,'already_called'):
160 return
160 return
161 start_ipython.already_called = True
161 start_ipython.already_called = True
162
162
163 # Ok, first time we're called, go ahead
163 # Ok, first time we're called, go ahead
164 import new
164 import new
165
165
166 import IPython
166 import IPython
167 from IPython.core import ipapi
167 from IPython.core import ipapi
168
168
169 def xsys(cmd):
169 def xsys(cmd):
170 """Execute a command and print its output.
170 """Execute a command and print its output.
171
171
172 This is just a convenience function to replace the IPython system call
172 This is just a convenience function to replace the IPython system call
173 with one that is more doctest-friendly.
173 with one that is more doctest-friendly.
174 """
174 """
175 cmd = _ip.IP.var_expand(cmd,depth=1)
175 cmd = _ip.IP.var_expand(cmd,depth=1)
176 sys.stdout.write(commands.getoutput(cmd))
176 sys.stdout.write(commands.getoutput(cmd))
177 sys.stdout.flush()
177 sys.stdout.flush()
178
178
179 # Store certain global objects that IPython modifies
179 # Store certain global objects that IPython modifies
180 _displayhook = sys.displayhook
180 _displayhook = sys.displayhook
181 _excepthook = sys.excepthook
181 _excepthook = sys.excepthook
182 _main = sys.modules.get('__main__')
182 _main = sys.modules.get('__main__')
183
183
184 argv = default_argv()
184 argv = default_argv()
185
185
186 # Start IPython instance. We customize it to start with minimal frills.
186 # Start IPython instance. We customize it to start with minimal frills.
187 user_ns,global_ns = ipapi.make_user_namespaces(ipnsdict(),dict())
187 user_ns,global_ns = ipapi.make_user_namespaces(ipnsdict(),dict())
188 IPython.Shell.IPShell(argv,user_ns,global_ns)
188 IPython.Shell.IPShell(argv,user_ns,global_ns)
189
189
190 # Deactivate the various python system hooks added by ipython for
190 # Deactivate the various python system hooks added by ipython for
191 # interactive convenience so we don't confuse the doctest system
191 # interactive convenience so we don't confuse the doctest system
192 sys.modules['__main__'] = _main
192 sys.modules['__main__'] = _main
193 sys.displayhook = _displayhook
193 sys.displayhook = _displayhook
194 sys.excepthook = _excepthook
194 sys.excepthook = _excepthook
195
195
196 # So that ipython magics and aliases can be doctested (they work by making
196 # So that ipython magics and aliases can be doctested (they work by making
197 # a call into a global _ip object)
197 # a call into a global _ip object)
198 _ip = IPython.ipapi.get()
198 _ip = ipapi.get()
199 __builtin__._ip = _ip
199 __builtin__._ip = _ip
200
200
201 # Modify the IPython system call with one that uses getoutput, so that we
201 # Modify the IPython system call with one that uses getoutput, so that we
202 # can capture subcommands and print them to Python's stdout, otherwise the
202 # can capture subcommands and print them to Python's stdout, otherwise the
203 # doctest machinery would miss them.
203 # doctest machinery would miss them.
204 _ip.system = xsys
204 _ip.system = xsys
205
205
206 # Also patch our %run function in.
206 # Also patch our %run function in.
207 im = new.instancemethod(_run_ns_sync,_ip.IP, _ip.IP.__class__)
207 im = new.instancemethod(_run_ns_sync,_ip.IP, _ip.IP.__class__)
208 _ip.IP.magic_run_ori = _ip.IP.magic_run
208 _ip.IP.magic_run_ori = _ip.IP.magic_run
209 _ip.IP.magic_run = im
209 _ip.IP.magic_run = im
210
210
211 # The start call MUST be made here. I'm not sure yet why it doesn't work if
211 # The start call MUST be made here. I'm not sure yet why it doesn't work if
212 # it is made later, at plugin initialization time, but in all my tests, that's
212 # it is made later, at plugin initialization time, but in all my tests, that's
213 # the case.
213 # the case.
214 start_ipython()
214 start_ipython()
215
215
216 # *** END HACK ***
216 # *** END HACK ***
217 ###########################################################################
217 ###########################################################################
218
218
219 # Classes and functions
219 # Classes and functions
220
220
221 def is_extension_module(filename):
221 def is_extension_module(filename):
222 """Return whether the given filename is an extension module.
222 """Return whether the given filename is an extension module.
223
223
224 This simply checks that the extension is either .so or .pyd.
224 This simply checks that the extension is either .so or .pyd.
225 """
225 """
226 return os.path.splitext(filename)[1].lower() in ('.so','.pyd')
226 return os.path.splitext(filename)[1].lower() in ('.so','.pyd')
227
227
228
228
229 class DocTestSkip(object):
229 class DocTestSkip(object):
230 """Object wrapper for doctests to be skipped."""
230 """Object wrapper for doctests to be skipped."""
231
231
232 ds_skip = """Doctest to skip.
232 ds_skip = """Doctest to skip.
233 >>> 1 #doctest: +SKIP
233 >>> 1 #doctest: +SKIP
234 """
234 """
235
235
236 def __init__(self,obj):
236 def __init__(self,obj):
237 self.obj = obj
237 self.obj = obj
238
238
239 def __getattribute__(self,key):
239 def __getattribute__(self,key):
240 if key == '__doc__':
240 if key == '__doc__':
241 return DocTestSkip.ds_skip
241 return DocTestSkip.ds_skip
242 else:
242 else:
243 return getattr(object.__getattribute__(self,'obj'),key)
243 return getattr(object.__getattribute__(self,'obj'),key)
244
244
245 # Modified version of the one in the stdlib, that fixes a python bug (doctests
245 # Modified version of the one in the stdlib, that fixes a python bug (doctests
246 # not found in extension modules, http://bugs.python.org/issue3158)
246 # not found in extension modules, http://bugs.python.org/issue3158)
247 class DocTestFinder(doctest.DocTestFinder):
247 class DocTestFinder(doctest.DocTestFinder):
248
248
249 def _from_module(self, module, object):
249 def _from_module(self, module, object):
250 """
250 """
251 Return true if the given object is defined in the given
251 Return true if the given object is defined in the given
252 module.
252 module.
253 """
253 """
254 if module is None:
254 if module is None:
255 return True
255 return True
256 elif inspect.isfunction(object):
256 elif inspect.isfunction(object):
257 return module.__dict__ is object.func_globals
257 return module.__dict__ is object.func_globals
258 elif inspect.isbuiltin(object):
258 elif inspect.isbuiltin(object):
259 return module.__name__ == object.__module__
259 return module.__name__ == object.__module__
260 elif inspect.isclass(object):
260 elif inspect.isclass(object):
261 return module.__name__ == object.__module__
261 return module.__name__ == object.__module__
262 elif inspect.ismethod(object):
262 elif inspect.ismethod(object):
263 # This one may be a bug in cython that fails to correctly set the
263 # This one may be a bug in cython that fails to correctly set the
264 # __module__ attribute of methods, but since the same error is easy
264 # __module__ attribute of methods, but since the same error is easy
265 # to make by extension code writers, having this safety in place
265 # to make by extension code writers, having this safety in place
266 # isn't such a bad idea
266 # isn't such a bad idea
267 return module.__name__ == object.im_class.__module__
267 return module.__name__ == object.im_class.__module__
268 elif inspect.getmodule(object) is not None:
268 elif inspect.getmodule(object) is not None:
269 return module is inspect.getmodule(object)
269 return module is inspect.getmodule(object)
270 elif hasattr(object, '__module__'):
270 elif hasattr(object, '__module__'):
271 return module.__name__ == object.__module__
271 return module.__name__ == object.__module__
272 elif isinstance(object, property):
272 elif isinstance(object, property):
273 return True # [XX] no way not be sure.
273 return True # [XX] no way not be sure.
274 else:
274 else:
275 raise ValueError("object must be a class or function")
275 raise ValueError("object must be a class or function")
276
276
277 def _find(self, tests, obj, name, module, source_lines, globs, seen):
277 def _find(self, tests, obj, name, module, source_lines, globs, seen):
278 """
278 """
279 Find tests for the given object and any contained objects, and
279 Find tests for the given object and any contained objects, and
280 add them to `tests`.
280 add them to `tests`.
281 """
281 """
282
282
283 if hasattr(obj,"skip_doctest"):
283 if hasattr(obj,"skip_doctest"):
284 #print 'SKIPPING DOCTEST FOR:',obj # dbg
284 #print 'SKIPPING DOCTEST FOR:',obj # dbg
285 obj = DocTestSkip(obj)
285 obj = DocTestSkip(obj)
286
286
287 doctest.DocTestFinder._find(self,tests, obj, name, module,
287 doctest.DocTestFinder._find(self,tests, obj, name, module,
288 source_lines, globs, seen)
288 source_lines, globs, seen)
289
289
290 # Below we re-run pieces of the above method with manual modifications,
290 # Below we re-run pieces of the above method with manual modifications,
291 # because the original code is buggy and fails to correctly identify
291 # because the original code is buggy and fails to correctly identify
292 # doctests in extension modules.
292 # doctests in extension modules.
293
293
294 # Local shorthands
294 # Local shorthands
295 from inspect import isroutine, isclass, ismodule
295 from inspect import isroutine, isclass, ismodule
296
296
297 # Look for tests in a module's contained objects.
297 # Look for tests in a module's contained objects.
298 if inspect.ismodule(obj) and self._recurse:
298 if inspect.ismodule(obj) and self._recurse:
299 for valname, val in obj.__dict__.items():
299 for valname, val in obj.__dict__.items():
300 valname1 = '%s.%s' % (name, valname)
300 valname1 = '%s.%s' % (name, valname)
301 if ( (isroutine(val) or isclass(val))
301 if ( (isroutine(val) or isclass(val))
302 and self._from_module(module, val) ):
302 and self._from_module(module, val) ):
303
303
304 self._find(tests, val, valname1, module, source_lines,
304 self._find(tests, val, valname1, module, source_lines,
305 globs, seen)
305 globs, seen)
306
306
307 # Look for tests in a class's contained objects.
307 # Look for tests in a class's contained objects.
308 if inspect.isclass(obj) and self._recurse:
308 if inspect.isclass(obj) and self._recurse:
309 #print 'RECURSE into class:',obj # dbg
309 #print 'RECURSE into class:',obj # dbg
310 for valname, val in obj.__dict__.items():
310 for valname, val in obj.__dict__.items():
311 # Special handling for staticmethod/classmethod.
311 # Special handling for staticmethod/classmethod.
312 if isinstance(val, staticmethod):
312 if isinstance(val, staticmethod):
313 val = getattr(obj, valname)
313 val = getattr(obj, valname)
314 if isinstance(val, classmethod):
314 if isinstance(val, classmethod):
315 val = getattr(obj, valname).im_func
315 val = getattr(obj, valname).im_func
316
316
317 # Recurse to methods, properties, and nested classes.
317 # Recurse to methods, properties, and nested classes.
318 if ((inspect.isfunction(val) or inspect.isclass(val) or
318 if ((inspect.isfunction(val) or inspect.isclass(val) or
319 inspect.ismethod(val) or
319 inspect.ismethod(val) or
320 isinstance(val, property)) and
320 isinstance(val, property)) and
321 self._from_module(module, val)):
321 self._from_module(module, val)):
322 valname = '%s.%s' % (name, valname)
322 valname = '%s.%s' % (name, valname)
323 self._find(tests, val, valname, module, source_lines,
323 self._find(tests, val, valname, module, source_lines,
324 globs, seen)
324 globs, seen)
325
325
326
326
327 class IPDoctestOutputChecker(doctest.OutputChecker):
327 class IPDoctestOutputChecker(doctest.OutputChecker):
328 """Second-chance checker with support for random tests.
328 """Second-chance checker with support for random tests.
329
329
330 If the default comparison doesn't pass, this checker looks in the expected
330 If the default comparison doesn't pass, this checker looks in the expected
331 output string for flags that tell us to ignore the output.
331 output string for flags that tell us to ignore the output.
332 """
332 """
333
333
334 random_re = re.compile(r'#\s*random\s+')
334 random_re = re.compile(r'#\s*random\s+')
335
335
336 def check_output(self, want, got, optionflags):
336 def check_output(self, want, got, optionflags):
337 """Check output, accepting special markers embedded in the output.
337 """Check output, accepting special markers embedded in the output.
338
338
339 If the output didn't pass the default validation but the special string
339 If the output didn't pass the default validation but the special string
340 '#random' is included, we accept it."""
340 '#random' is included, we accept it."""
341
341
342 # Let the original tester verify first, in case people have valid tests
342 # Let the original tester verify first, in case people have valid tests
343 # that happen to have a comment saying '#random' embedded in.
343 # that happen to have a comment saying '#random' embedded in.
344 ret = doctest.OutputChecker.check_output(self, want, got,
344 ret = doctest.OutputChecker.check_output(self, want, got,
345 optionflags)
345 optionflags)
346 if not ret and self.random_re.search(want):
346 if not ret and self.random_re.search(want):
347 #print >> sys.stderr, 'RANDOM OK:',want # dbg
347 #print >> sys.stderr, 'RANDOM OK:',want # dbg
348 return True
348 return True
349
349
350 return ret
350 return ret
351
351
352
352
353 class DocTestCase(doctests.DocTestCase):
353 class DocTestCase(doctests.DocTestCase):
354 """Proxy for DocTestCase: provides an address() method that
354 """Proxy for DocTestCase: provides an address() method that
355 returns the correct address for the doctest case. Otherwise
355 returns the correct address for the doctest case. Otherwise
356 acts as a proxy to the test case. To provide hints for address(),
356 acts as a proxy to the test case. To provide hints for address(),
357 an obj may also be passed -- this will be used as the test object
357 an obj may also be passed -- this will be used as the test object
358 for purposes of determining the test address, if it is provided.
358 for purposes of determining the test address, if it is provided.
359 """
359 """
360
360
361 # Note: this method was taken from numpy's nosetester module.
361 # Note: this method was taken from numpy's nosetester module.
362
362
363 # Subclass nose.plugins.doctests.DocTestCase to work around a bug in
363 # Subclass nose.plugins.doctests.DocTestCase to work around a bug in
364 # its constructor that blocks non-default arguments from being passed
364 # its constructor that blocks non-default arguments from being passed
365 # down into doctest.DocTestCase
365 # down into doctest.DocTestCase
366
366
367 def __init__(self, test, optionflags=0, setUp=None, tearDown=None,
367 def __init__(self, test, optionflags=0, setUp=None, tearDown=None,
368 checker=None, obj=None, result_var='_'):
368 checker=None, obj=None, result_var='_'):
369 self._result_var = result_var
369 self._result_var = result_var
370 doctests.DocTestCase.__init__(self, test,
370 doctests.DocTestCase.__init__(self, test,
371 optionflags=optionflags,
371 optionflags=optionflags,
372 setUp=setUp, tearDown=tearDown,
372 setUp=setUp, tearDown=tearDown,
373 checker=checker)
373 checker=checker)
374 # Now we must actually copy the original constructor from the stdlib
374 # Now we must actually copy the original constructor from the stdlib
375 # doctest class, because we can't call it directly and a bug in nose
375 # doctest class, because we can't call it directly and a bug in nose
376 # means it never gets passed the right arguments.
376 # means it never gets passed the right arguments.
377
377
378 self._dt_optionflags = optionflags
378 self._dt_optionflags = optionflags
379 self._dt_checker = checker
379 self._dt_checker = checker
380 self._dt_test = test
380 self._dt_test = test
381 self._dt_setUp = setUp
381 self._dt_setUp = setUp
382 self._dt_tearDown = tearDown
382 self._dt_tearDown = tearDown
383
383
384 # XXX - store this runner once in the object!
384 # XXX - store this runner once in the object!
385 runner = IPDocTestRunner(optionflags=optionflags,
385 runner = IPDocTestRunner(optionflags=optionflags,
386 checker=checker, verbose=False)
386 checker=checker, verbose=False)
387 self._dt_runner = runner
387 self._dt_runner = runner
388
388
389
389
390 # Each doctest should remember what directory it was loaded from...
390 # Each doctest should remember what directory it was loaded from...
391 self._ori_dir = os.getcwd()
391 self._ori_dir = os.getcwd()
392
392
393 # Modified runTest from the default stdlib
393 # Modified runTest from the default stdlib
394 def runTest(self):
394 def runTest(self):
395 test = self._dt_test
395 test = self._dt_test
396 runner = self._dt_runner
396 runner = self._dt_runner
397
397
398 old = sys.stdout
398 old = sys.stdout
399 new = StringIO()
399 new = StringIO()
400 optionflags = self._dt_optionflags
400 optionflags = self._dt_optionflags
401
401
402 if not (optionflags & REPORTING_FLAGS):
402 if not (optionflags & REPORTING_FLAGS):
403 # The option flags don't include any reporting flags,
403 # The option flags don't include any reporting flags,
404 # so add the default reporting flags
404 # so add the default reporting flags
405 optionflags |= _unittest_reportflags
405 optionflags |= _unittest_reportflags
406
406
407 try:
407 try:
408 # Save our current directory and switch out to the one where the
408 # Save our current directory and switch out to the one where the
409 # test was originally created, in case another doctest did a
409 # test was originally created, in case another doctest did a
410 # directory change. We'll restore this in the finally clause.
410 # directory change. We'll restore this in the finally clause.
411 curdir = os.getcwd()
411 curdir = os.getcwd()
412 os.chdir(self._ori_dir)
412 os.chdir(self._ori_dir)
413
413
414 runner.DIVIDER = "-"*70
414 runner.DIVIDER = "-"*70
415 failures, tries = runner.run(test,out=new.write,
415 failures, tries = runner.run(test,out=new.write,
416 clear_globs=False)
416 clear_globs=False)
417 finally:
417 finally:
418 sys.stdout = old
418 sys.stdout = old
419 os.chdir(curdir)
419 os.chdir(curdir)
420
420
421 if failures:
421 if failures:
422 raise self.failureException(self.format_failure(new.getvalue()))
422 raise self.failureException(self.format_failure(new.getvalue()))
423
423
424 def setUp(self):
424 def setUp(self):
425 """Modified test setup that syncs with ipython namespace"""
425 """Modified test setup that syncs with ipython namespace"""
426
426
427 if isinstance(self._dt_test.examples[0],IPExample):
427 if isinstance(self._dt_test.examples[0],IPExample):
428 # for IPython examples *only*, we swap the globals with the ipython
428 # for IPython examples *only*, we swap the globals with the ipython
429 # namespace, after updating it with the globals (which doctest
429 # namespace, after updating it with the globals (which doctest
430 # fills with the necessary info from the module being tested).
430 # fills with the necessary info from the module being tested).
431 _ip.IP.user_ns.update(self._dt_test.globs)
431 _ip.IP.user_ns.update(self._dt_test.globs)
432 self._dt_test.globs = _ip.IP.user_ns
432 self._dt_test.globs = _ip.IP.user_ns
433
433
434 doctests.DocTestCase.setUp(self)
434 doctests.DocTestCase.setUp(self)
435
435
436
436
437 # A simple subclassing of the original with a different class name, so we can
437 # A simple subclassing of the original with a different class name, so we can
438 # distinguish and treat differently IPython examples from pure python ones.
438 # distinguish and treat differently IPython examples from pure python ones.
439 class IPExample(doctest.Example): pass
439 class IPExample(doctest.Example): pass
440
440
441
441
442 class IPExternalExample(doctest.Example):
442 class IPExternalExample(doctest.Example):
443 """Doctest examples to be run in an external process."""
443 """Doctest examples to be run in an external process."""
444
444
445 def __init__(self, source, want, exc_msg=None, lineno=0, indent=0,
445 def __init__(self, source, want, exc_msg=None, lineno=0, indent=0,
446 options=None):
446 options=None):
447 # Parent constructor
447 # Parent constructor
448 doctest.Example.__init__(self,source,want,exc_msg,lineno,indent,options)
448 doctest.Example.__init__(self,source,want,exc_msg,lineno,indent,options)
449
449
450 # An EXTRA newline is needed to prevent pexpect hangs
450 # An EXTRA newline is needed to prevent pexpect hangs
451 self.source += '\n'
451 self.source += '\n'
452
452
453
453
454 class IPDocTestParser(doctest.DocTestParser):
454 class IPDocTestParser(doctest.DocTestParser):
455 """
455 """
456 A class used to parse strings containing doctest examples.
456 A class used to parse strings containing doctest examples.
457
457
458 Note: This is a version modified to properly recognize IPython input and
458 Note: This is a version modified to properly recognize IPython input and
459 convert any IPython examples into valid Python ones.
459 convert any IPython examples into valid Python ones.
460 """
460 """
461 # This regular expression is used to find doctest examples in a
461 # This regular expression is used to find doctest examples in a
462 # string. It defines three groups: `source` is the source code
462 # string. It defines three groups: `source` is the source code
463 # (including leading indentation and prompts); `indent` is the
463 # (including leading indentation and prompts); `indent` is the
464 # indentation of the first (PS1) line of the source code; and
464 # indentation of the first (PS1) line of the source code; and
465 # `want` is the expected output (including leading indentation).
465 # `want` is the expected output (including leading indentation).
466
466
467 # Classic Python prompts or default IPython ones
467 # Classic Python prompts or default IPython ones
468 _PS1_PY = r'>>>'
468 _PS1_PY = r'>>>'
469 _PS2_PY = r'\.\.\.'
469 _PS2_PY = r'\.\.\.'
470
470
471 _PS1_IP = r'In\ \[\d+\]:'
471 _PS1_IP = r'In\ \[\d+\]:'
472 _PS2_IP = r'\ \ \ \.\.\.+:'
472 _PS2_IP = r'\ \ \ \.\.\.+:'
473
473
474 _RE_TPL = r'''
474 _RE_TPL = r'''
475 # Source consists of a PS1 line followed by zero or more PS2 lines.
475 # Source consists of a PS1 line followed by zero or more PS2 lines.
476 (?P<source>
476 (?P<source>
477 (?:^(?P<indent> [ ]*) (?P<ps1> %s) .*) # PS1 line
477 (?:^(?P<indent> [ ]*) (?P<ps1> %s) .*) # PS1 line
478 (?:\n [ ]* (?P<ps2> %s) .*)*) # PS2 lines
478 (?:\n [ ]* (?P<ps2> %s) .*)*) # PS2 lines
479 \n? # a newline
479 \n? # a newline
480 # Want consists of any non-blank lines that do not start with PS1.
480 # Want consists of any non-blank lines that do not start with PS1.
481 (?P<want> (?:(?![ ]*$) # Not a blank line
481 (?P<want> (?:(?![ ]*$) # Not a blank line
482 (?![ ]*%s) # Not a line starting with PS1
482 (?![ ]*%s) # Not a line starting with PS1
483 (?![ ]*%s) # Not a line starting with PS2
483 (?![ ]*%s) # Not a line starting with PS2
484 .*$\n? # But any other line
484 .*$\n? # But any other line
485 )*)
485 )*)
486 '''
486 '''
487
487
488 _EXAMPLE_RE_PY = re.compile( _RE_TPL % (_PS1_PY,_PS2_PY,_PS1_PY,_PS2_PY),
488 _EXAMPLE_RE_PY = re.compile( _RE_TPL % (_PS1_PY,_PS2_PY,_PS1_PY,_PS2_PY),
489 re.MULTILINE | re.VERBOSE)
489 re.MULTILINE | re.VERBOSE)
490
490
491 _EXAMPLE_RE_IP = re.compile( _RE_TPL % (_PS1_IP,_PS2_IP,_PS1_IP,_PS2_IP),
491 _EXAMPLE_RE_IP = re.compile( _RE_TPL % (_PS1_IP,_PS2_IP,_PS1_IP,_PS2_IP),
492 re.MULTILINE | re.VERBOSE)
492 re.MULTILINE | re.VERBOSE)
493
493
494 # Mark a test as being fully random. In this case, we simply append the
494 # Mark a test as being fully random. In this case, we simply append the
495 # random marker ('#random') to each individual example's output. This way
495 # random marker ('#random') to each individual example's output. This way
496 # we don't need to modify any other code.
496 # we don't need to modify any other code.
497 _RANDOM_TEST = re.compile(r'#\s*all-random\s+')
497 _RANDOM_TEST = re.compile(r'#\s*all-random\s+')
498
498
499 # Mark tests to be executed in an external process - currently unsupported.
499 # Mark tests to be executed in an external process - currently unsupported.
500 _EXTERNAL_IP = re.compile(r'#\s*ipdoctest:\s*EXTERNAL')
500 _EXTERNAL_IP = re.compile(r'#\s*ipdoctest:\s*EXTERNAL')
501
501
502 def ip2py(self,source):
502 def ip2py(self,source):
503 """Convert input IPython source into valid Python."""
503 """Convert input IPython source into valid Python."""
504 out = []
504 out = []
505 newline = out.append
505 newline = out.append
506 #print 'IPSRC:\n',source,'\n###' # dbg
506 #print 'IPSRC:\n',source,'\n###' # dbg
507 # The input source must be first stripped of all bracketing whitespace
507 # The input source must be first stripped of all bracketing whitespace
508 # and turned into lines, so it looks to the parser like regular user
508 # and turned into lines, so it looks to the parser like regular user
509 # input
509 # input
510 for lnum,line in enumerate(source.strip().splitlines()):
510 for lnum,line in enumerate(source.strip().splitlines()):
511 newline(_ip.IP.prefilter(line,lnum>0))
511 newline(_ip.IP.prefilter(line,lnum>0))
512 newline('') # ensure a closing newline, needed by doctest
512 newline('') # ensure a closing newline, needed by doctest
513 #print "PYSRC:", '\n'.join(out) # dbg
513 #print "PYSRC:", '\n'.join(out) # dbg
514 return '\n'.join(out)
514 return '\n'.join(out)
515
515
516 def parse(self, string, name='<string>'):
516 def parse(self, string, name='<string>'):
517 """
517 """
518 Divide the given string into examples and intervening text,
518 Divide the given string into examples and intervening text,
519 and return them as a list of alternating Examples and strings.
519 and return them as a list of alternating Examples and strings.
520 Line numbers for the Examples are 0-based. The optional
520 Line numbers for the Examples are 0-based. The optional
521 argument `name` is a name identifying this string, and is only
521 argument `name` is a name identifying this string, and is only
522 used for error messages.
522 used for error messages.
523 """
523 """
524
524
525 #print 'Parse string:\n',string # dbg
525 #print 'Parse string:\n',string # dbg
526
526
527 string = string.expandtabs()
527 string = string.expandtabs()
528 # If all lines begin with the same indentation, then strip it.
528 # If all lines begin with the same indentation, then strip it.
529 min_indent = self._min_indent(string)
529 min_indent = self._min_indent(string)
530 if min_indent > 0:
530 if min_indent > 0:
531 string = '\n'.join([l[min_indent:] for l in string.split('\n')])
531 string = '\n'.join([l[min_indent:] for l in string.split('\n')])
532
532
533 output = []
533 output = []
534 charno, lineno = 0, 0
534 charno, lineno = 0, 0
535
535
536 # We make 'all random' tests by adding the '# random' mark to every
536 # We make 'all random' tests by adding the '# random' mark to every
537 # block of output in the test.
537 # block of output in the test.
538 if self._RANDOM_TEST.search(string):
538 if self._RANDOM_TEST.search(string):
539 random_marker = '\n# random'
539 random_marker = '\n# random'
540 else:
540 else:
541 random_marker = ''
541 random_marker = ''
542
542
543 # Whether to convert the input from ipython to python syntax
543 # Whether to convert the input from ipython to python syntax
544 ip2py = False
544 ip2py = False
545 # Find all doctest examples in the string. First, try them as Python
545 # Find all doctest examples in the string. First, try them as Python
546 # examples, then as IPython ones
546 # examples, then as IPython ones
547 terms = list(self._EXAMPLE_RE_PY.finditer(string))
547 terms = list(self._EXAMPLE_RE_PY.finditer(string))
548 if terms:
548 if terms:
549 # Normal Python example
549 # Normal Python example
550 #print '-'*70 # dbg
550 #print '-'*70 # dbg
551 #print 'PyExample, Source:\n',string # dbg
551 #print 'PyExample, Source:\n',string # dbg
552 #print '-'*70 # dbg
552 #print '-'*70 # dbg
553 Example = doctest.Example
553 Example = doctest.Example
554 else:
554 else:
555 # It's an ipython example. Note that IPExamples are run
555 # It's an ipython example. Note that IPExamples are run
556 # in-process, so their syntax must be turned into valid python.
556 # in-process, so their syntax must be turned into valid python.
557 # IPExternalExamples are run out-of-process (via pexpect) so they
557 # IPExternalExamples are run out-of-process (via pexpect) so they
558 # don't need any filtering (a real ipython will be executing them).
558 # don't need any filtering (a real ipython will be executing them).
559 terms = list(self._EXAMPLE_RE_IP.finditer(string))
559 terms = list(self._EXAMPLE_RE_IP.finditer(string))
560 if self._EXTERNAL_IP.search(string):
560 if self._EXTERNAL_IP.search(string):
561 #print '-'*70 # dbg
561 #print '-'*70 # dbg
562 #print 'IPExternalExample, Source:\n',string # dbg
562 #print 'IPExternalExample, Source:\n',string # dbg
563 #print '-'*70 # dbg
563 #print '-'*70 # dbg
564 Example = IPExternalExample
564 Example = IPExternalExample
565 else:
565 else:
566 #print '-'*70 # dbg
566 #print '-'*70 # dbg
567 #print 'IPExample, Source:\n',string # dbg
567 #print 'IPExample, Source:\n',string # dbg
568 #print '-'*70 # dbg
568 #print '-'*70 # dbg
569 Example = IPExample
569 Example = IPExample
570 ip2py = True
570 ip2py = True
571
571
572 for m in terms:
572 for m in terms:
573 # Add the pre-example text to `output`.
573 # Add the pre-example text to `output`.
574 output.append(string[charno:m.start()])
574 output.append(string[charno:m.start()])
575 # Update lineno (lines before this example)
575 # Update lineno (lines before this example)
576 lineno += string.count('\n', charno, m.start())
576 lineno += string.count('\n', charno, m.start())
577 # Extract info from the regexp match.
577 # Extract info from the regexp match.
578 (source, options, want, exc_msg) = \
578 (source, options, want, exc_msg) = \
579 self._parse_example(m, name, lineno,ip2py)
579 self._parse_example(m, name, lineno,ip2py)
580
580
581 # Append the random-output marker (it defaults to empty in most
581 # Append the random-output marker (it defaults to empty in most
582 # cases, it's only non-empty for 'all-random' tests):
582 # cases, it's only non-empty for 'all-random' tests):
583 want += random_marker
583 want += random_marker
584
584
585 if Example is IPExternalExample:
585 if Example is IPExternalExample:
586 options[doctest.NORMALIZE_WHITESPACE] = True
586 options[doctest.NORMALIZE_WHITESPACE] = True
587 want += '\n'
587 want += '\n'
588
588
589 # Create an Example, and add it to the list.
589 # Create an Example, and add it to the list.
590 if not self._IS_BLANK_OR_COMMENT(source):
590 if not self._IS_BLANK_OR_COMMENT(source):
591 output.append(Example(source, want, exc_msg,
591 output.append(Example(source, want, exc_msg,
592 lineno=lineno,
592 lineno=lineno,
593 indent=min_indent+len(m.group('indent')),
593 indent=min_indent+len(m.group('indent')),
594 options=options))
594 options=options))
595 # Update lineno (lines inside this example)
595 # Update lineno (lines inside this example)
596 lineno += string.count('\n', m.start(), m.end())
596 lineno += string.count('\n', m.start(), m.end())
597 # Update charno.
597 # Update charno.
598 charno = m.end()
598 charno = m.end()
599 # Add any remaining post-example text to `output`.
599 # Add any remaining post-example text to `output`.
600 output.append(string[charno:])
600 output.append(string[charno:])
601 return output
601 return output
602
602
603 def _parse_example(self, m, name, lineno,ip2py=False):
603 def _parse_example(self, m, name, lineno,ip2py=False):
604 """
604 """
605 Given a regular expression match from `_EXAMPLE_RE` (`m`),
605 Given a regular expression match from `_EXAMPLE_RE` (`m`),
606 return a pair `(source, want)`, where `source` is the matched
606 return a pair `(source, want)`, where `source` is the matched
607 example's source code (with prompts and indentation stripped);
607 example's source code (with prompts and indentation stripped);
608 and `want` is the example's expected output (with indentation
608 and `want` is the example's expected output (with indentation
609 stripped).
609 stripped).
610
610
611 `name` is the string's name, and `lineno` is the line number
611 `name` is the string's name, and `lineno` is the line number
612 where the example starts; both are used for error messages.
612 where the example starts; both are used for error messages.
613
613
614 Optional:
614 Optional:
615 `ip2py`: if true, filter the input via IPython to convert the syntax
615 `ip2py`: if true, filter the input via IPython to convert the syntax
616 into valid python.
616 into valid python.
617 """
617 """
618
618
619 # Get the example's indentation level.
619 # Get the example's indentation level.
620 indent = len(m.group('indent'))
620 indent = len(m.group('indent'))
621
621
622 # Divide source into lines; check that they're properly
622 # Divide source into lines; check that they're properly
623 # indented; and then strip their indentation & prompts.
623 # indented; and then strip their indentation & prompts.
624 source_lines = m.group('source').split('\n')
624 source_lines = m.group('source').split('\n')
625
625
626 # We're using variable-length input prompts
626 # We're using variable-length input prompts
627 ps1 = m.group('ps1')
627 ps1 = m.group('ps1')
628 ps2 = m.group('ps2')
628 ps2 = m.group('ps2')
629 ps1_len = len(ps1)
629 ps1_len = len(ps1)
630
630
631 self._check_prompt_blank(source_lines, indent, name, lineno,ps1_len)
631 self._check_prompt_blank(source_lines, indent, name, lineno,ps1_len)
632 if ps2:
632 if ps2:
633 self._check_prefix(source_lines[1:], ' '*indent + ps2, name, lineno)
633 self._check_prefix(source_lines[1:], ' '*indent + ps2, name, lineno)
634
634
635 source = '\n'.join([sl[indent+ps1_len+1:] for sl in source_lines])
635 source = '\n'.join([sl[indent+ps1_len+1:] for sl in source_lines])
636
636
637 if ip2py:
637 if ip2py:
638 # Convert source input from IPython into valid Python syntax
638 # Convert source input from IPython into valid Python syntax
639 source = self.ip2py(source)
639 source = self.ip2py(source)
640
640
641 # Divide want into lines; check that it's properly indented; and
641 # Divide want into lines; check that it's properly indented; and
642 # then strip the indentation. Spaces before the last newline should
642 # then strip the indentation. Spaces before the last newline should
643 # be preserved, so plain rstrip() isn't good enough.
643 # be preserved, so plain rstrip() isn't good enough.
644 want = m.group('want')
644 want = m.group('want')
645 want_lines = want.split('\n')
645 want_lines = want.split('\n')
646 if len(want_lines) > 1 and re.match(r' *$', want_lines[-1]):
646 if len(want_lines) > 1 and re.match(r' *$', want_lines[-1]):
647 del want_lines[-1] # forget final newline & spaces after it
647 del want_lines[-1] # forget final newline & spaces after it
648 self._check_prefix(want_lines, ' '*indent, name,
648 self._check_prefix(want_lines, ' '*indent, name,
649 lineno + len(source_lines))
649 lineno + len(source_lines))
650
650
651 # Remove ipython output prompt that might be present in the first line
651 # Remove ipython output prompt that might be present in the first line
652 want_lines[0] = re.sub(r'Out\[\d+\]: \s*?\n?','',want_lines[0])
652 want_lines[0] = re.sub(r'Out\[\d+\]: \s*?\n?','',want_lines[0])
653
653
654 want = '\n'.join([wl[indent:] for wl in want_lines])
654 want = '\n'.join([wl[indent:] for wl in want_lines])
655
655
656 # If `want` contains a traceback message, then extract it.
656 # If `want` contains a traceback message, then extract it.
657 m = self._EXCEPTION_RE.match(want)
657 m = self._EXCEPTION_RE.match(want)
658 if m:
658 if m:
659 exc_msg = m.group('msg')
659 exc_msg = m.group('msg')
660 else:
660 else:
661 exc_msg = None
661 exc_msg = None
662
662
663 # Extract options from the source.
663 # Extract options from the source.
664 options = self._find_options(source, name, lineno)
664 options = self._find_options(source, name, lineno)
665
665
666 return source, options, want, exc_msg
666 return source, options, want, exc_msg
667
667
668 def _check_prompt_blank(self, lines, indent, name, lineno, ps1_len):
668 def _check_prompt_blank(self, lines, indent, name, lineno, ps1_len):
669 """
669 """
670 Given the lines of a source string (including prompts and
670 Given the lines of a source string (including prompts and
671 leading indentation), check to make sure that every prompt is
671 leading indentation), check to make sure that every prompt is
672 followed by a space character. If any line is not followed by
672 followed by a space character. If any line is not followed by
673 a space character, then raise ValueError.
673 a space character, then raise ValueError.
674
674
675 Note: IPython-modified version which takes the input prompt length as a
675 Note: IPython-modified version which takes the input prompt length as a
676 parameter, so that prompts of variable length can be dealt with.
676 parameter, so that prompts of variable length can be dealt with.
677 """
677 """
678 space_idx = indent+ps1_len
678 space_idx = indent+ps1_len
679 min_len = space_idx+1
679 min_len = space_idx+1
680 for i, line in enumerate(lines):
680 for i, line in enumerate(lines):
681 if len(line) >= min_len and line[space_idx] != ' ':
681 if len(line) >= min_len and line[space_idx] != ' ':
682 raise ValueError('line %r of the docstring for %s '
682 raise ValueError('line %r of the docstring for %s '
683 'lacks blank after %s: %r' %
683 'lacks blank after %s: %r' %
684 (lineno+i+1, name,
684 (lineno+i+1, name,
685 line[indent:space_idx], line))
685 line[indent:space_idx], line))
686
686
687
687
688 SKIP = doctest.register_optionflag('SKIP')
688 SKIP = doctest.register_optionflag('SKIP')
689
689
690
690
691 class IPDocTestRunner(doctest.DocTestRunner,object):
691 class IPDocTestRunner(doctest.DocTestRunner,object):
692 """Test runner that synchronizes the IPython namespace with test globals.
692 """Test runner that synchronizes the IPython namespace with test globals.
693 """
693 """
694
694
695 def run(self, test, compileflags=None, out=None, clear_globs=True):
695 def run(self, test, compileflags=None, out=None, clear_globs=True):
696
696
697 # Hack: ipython needs access to the execution context of the example,
697 # Hack: ipython needs access to the execution context of the example,
698 # so that it can propagate user variables loaded by %run into
698 # so that it can propagate user variables loaded by %run into
699 # test.globs. We put them here into our modified %run as a function
699 # test.globs. We put them here into our modified %run as a function
700 # attribute. Our new %run will then only make the namespace update
700 # attribute. Our new %run will then only make the namespace update
701 # when called (rather than unconconditionally updating test.globs here
701 # when called (rather than unconconditionally updating test.globs here
702 # for all examples, most of which won't be calling %run anyway).
702 # for all examples, most of which won't be calling %run anyway).
703 _run_ns_sync.test_globs = test.globs
703 _run_ns_sync.test_globs = test.globs
704 _run_ns_sync.test_filename = test.filename
704 _run_ns_sync.test_filename = test.filename
705
705
706 return super(IPDocTestRunner,self).run(test,
706 return super(IPDocTestRunner,self).run(test,
707 compileflags,out,clear_globs)
707 compileflags,out,clear_globs)
708
708
709
709
710 class DocFileCase(doctest.DocFileCase):
710 class DocFileCase(doctest.DocFileCase):
711 """Overrides to provide filename
711 """Overrides to provide filename
712 """
712 """
713 def address(self):
713 def address(self):
714 return (self._dt_test.filename, None, None)
714 return (self._dt_test.filename, None, None)
715
715
716
716
717 class ExtensionDoctest(doctests.Doctest):
717 class ExtensionDoctest(doctests.Doctest):
718 """Nose Plugin that supports doctests in extension modules.
718 """Nose Plugin that supports doctests in extension modules.
719 """
719 """
720 name = 'extdoctest' # call nosetests with --with-extdoctest
720 name = 'extdoctest' # call nosetests with --with-extdoctest
721 enabled = True
721 enabled = True
722
722
723 def __init__(self,exclude_patterns=None):
723 def __init__(self,exclude_patterns=None):
724 """Create a new ExtensionDoctest plugin.
724 """Create a new ExtensionDoctest plugin.
725
725
726 Parameters
726 Parameters
727 ----------
727 ----------
728
728
729 exclude_patterns : sequence of strings, optional
729 exclude_patterns : sequence of strings, optional
730 These patterns are compiled as regular expressions, subsequently used
730 These patterns are compiled as regular expressions, subsequently used
731 to exclude any filename which matches them from inclusion in the test
731 to exclude any filename which matches them from inclusion in the test
732 suite (using pattern.search(), NOT pattern.match() ).
732 suite (using pattern.search(), NOT pattern.match() ).
733 """
733 """
734
734
735 if exclude_patterns is None:
735 if exclude_patterns is None:
736 exclude_patterns = []
736 exclude_patterns = []
737 self.exclude_patterns = map(re.compile,exclude_patterns)
737 self.exclude_patterns = map(re.compile,exclude_patterns)
738 doctests.Doctest.__init__(self)
738 doctests.Doctest.__init__(self)
739
739
740 def options(self, parser, env=os.environ):
740 def options(self, parser, env=os.environ):
741 Plugin.options(self, parser, env)
741 Plugin.options(self, parser, env)
742 parser.add_option('--doctest-tests', action='store_true',
742 parser.add_option('--doctest-tests', action='store_true',
743 dest='doctest_tests',
743 dest='doctest_tests',
744 default=env.get('NOSE_DOCTEST_TESTS',True),
744 default=env.get('NOSE_DOCTEST_TESTS',True),
745 help="Also look for doctests in test modules. "
745 help="Also look for doctests in test modules. "
746 "Note that classes, methods and functions should "
746 "Note that classes, methods and functions should "
747 "have either doctests or non-doctest tests, "
747 "have either doctests or non-doctest tests, "
748 "not both. [NOSE_DOCTEST_TESTS]")
748 "not both. [NOSE_DOCTEST_TESTS]")
749 parser.add_option('--doctest-extension', action="append",
749 parser.add_option('--doctest-extension', action="append",
750 dest="doctestExtension",
750 dest="doctestExtension",
751 help="Also look for doctests in files with "
751 help="Also look for doctests in files with "
752 "this extension [NOSE_DOCTEST_EXTENSION]")
752 "this extension [NOSE_DOCTEST_EXTENSION]")
753 # Set the default as a list, if given in env; otherwise
753 # Set the default as a list, if given in env; otherwise
754 # an additional value set on the command line will cause
754 # an additional value set on the command line will cause
755 # an error.
755 # an error.
756 env_setting = env.get('NOSE_DOCTEST_EXTENSION')
756 env_setting = env.get('NOSE_DOCTEST_EXTENSION')
757 if env_setting is not None:
757 if env_setting is not None:
758 parser.set_defaults(doctestExtension=tolist(env_setting))
758 parser.set_defaults(doctestExtension=tolist(env_setting))
759
759
760
760
761 def configure(self, options, config):
761 def configure(self, options, config):
762 Plugin.configure(self, options, config)
762 Plugin.configure(self, options, config)
763 self.doctest_tests = options.doctest_tests
763 self.doctest_tests = options.doctest_tests
764 self.extension = tolist(options.doctestExtension)
764 self.extension = tolist(options.doctestExtension)
765
765
766 self.parser = doctest.DocTestParser()
766 self.parser = doctest.DocTestParser()
767 self.finder = DocTestFinder()
767 self.finder = DocTestFinder()
768 self.checker = IPDoctestOutputChecker()
768 self.checker = IPDoctestOutputChecker()
769 self.globs = None
769 self.globs = None
770 self.extraglobs = None
770 self.extraglobs = None
771
771
772
772
773 def loadTestsFromExtensionModule(self,filename):
773 def loadTestsFromExtensionModule(self,filename):
774 bpath,mod = os.path.split(filename)
774 bpath,mod = os.path.split(filename)
775 modname = os.path.splitext(mod)[0]
775 modname = os.path.splitext(mod)[0]
776 try:
776 try:
777 sys.path.append(bpath)
777 sys.path.append(bpath)
778 module = __import__(modname)
778 module = __import__(modname)
779 tests = list(self.loadTestsFromModule(module))
779 tests = list(self.loadTestsFromModule(module))
780 finally:
780 finally:
781 sys.path.pop()
781 sys.path.pop()
782 return tests
782 return tests
783
783
784 # NOTE: the method below is almost a copy of the original one in nose, with
784 # NOTE: the method below is almost a copy of the original one in nose, with
785 # a few modifications to control output checking.
785 # a few modifications to control output checking.
786
786
787 def loadTestsFromModule(self, module):
787 def loadTestsFromModule(self, module):
788 #print '*** ipdoctest - lTM',module # dbg
788 #print '*** ipdoctest - lTM',module # dbg
789
789
790 if not self.matches(module.__name__):
790 if not self.matches(module.__name__):
791 log.debug("Doctest doesn't want module %s", module)
791 log.debug("Doctest doesn't want module %s", module)
792 return
792 return
793
793
794 tests = self.finder.find(module,globs=self.globs,
794 tests = self.finder.find(module,globs=self.globs,
795 extraglobs=self.extraglobs)
795 extraglobs=self.extraglobs)
796 if not tests:
796 if not tests:
797 return
797 return
798
798
799 # always use whitespace and ellipsis options
799 # always use whitespace and ellipsis options
800 optionflags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS
800 optionflags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS
801
801
802 tests.sort()
802 tests.sort()
803 module_file = module.__file__
803 module_file = module.__file__
804 if module_file[-4:] in ('.pyc', '.pyo'):
804 if module_file[-4:] in ('.pyc', '.pyo'):
805 module_file = module_file[:-1]
805 module_file = module_file[:-1]
806 for test in tests:
806 for test in tests:
807 if not test.examples:
807 if not test.examples:
808 continue
808 continue
809 if not test.filename:
809 if not test.filename:
810 test.filename = module_file
810 test.filename = module_file
811
811
812 yield DocTestCase(test,
812 yield DocTestCase(test,
813 optionflags=optionflags,
813 optionflags=optionflags,
814 checker=self.checker)
814 checker=self.checker)
815
815
816
816
817 def loadTestsFromFile(self, filename):
817 def loadTestsFromFile(self, filename):
818 if is_extension_module(filename):
818 if is_extension_module(filename):
819 for t in self.loadTestsFromExtensionModule(filename):
819 for t in self.loadTestsFromExtensionModule(filename):
820 yield t
820 yield t
821 else:
821 else:
822 if self.extension and anyp(filename.endswith, self.extension):
822 if self.extension and anyp(filename.endswith, self.extension):
823 name = os.path.basename(filename)
823 name = os.path.basename(filename)
824 dh = open(filename)
824 dh = open(filename)
825 try:
825 try:
826 doc = dh.read()
826 doc = dh.read()
827 finally:
827 finally:
828 dh.close()
828 dh.close()
829 test = self.parser.get_doctest(
829 test = self.parser.get_doctest(
830 doc, globs={'__file__': filename}, name=name,
830 doc, globs={'__file__': filename}, name=name,
831 filename=filename, lineno=0)
831 filename=filename, lineno=0)
832 if test.examples:
832 if test.examples:
833 #print 'FileCase:',test.examples # dbg
833 #print 'FileCase:',test.examples # dbg
834 yield DocFileCase(test)
834 yield DocFileCase(test)
835 else:
835 else:
836 yield False # no tests to load
836 yield False # no tests to load
837
837
838 def wantFile(self,filename):
838 def wantFile(self,filename):
839 """Return whether the given filename should be scanned for tests.
839 """Return whether the given filename should be scanned for tests.
840
840
841 Modified version that accepts extension modules as valid containers for
841 Modified version that accepts extension modules as valid containers for
842 doctests.
842 doctests.
843 """
843 """
844 # print '*** ipdoctest- wantFile:',filename # dbg
844 # print '*** ipdoctest- wantFile:',filename # dbg
845
845
846 for pat in self.exclude_patterns:
846 for pat in self.exclude_patterns:
847 if pat.search(filename):
847 if pat.search(filename):
848 # print '###>>> SKIP:',filename # dbg
848 # print '###>>> SKIP:',filename # dbg
849 return False
849 return False
850
850
851 if is_extension_module(filename):
851 if is_extension_module(filename):
852 return True
852 return True
853 else:
853 else:
854 return doctests.Doctest.wantFile(self,filename)
854 return doctests.Doctest.wantFile(self,filename)
855
855
856
856
857 class IPythonDoctest(ExtensionDoctest):
857 class IPythonDoctest(ExtensionDoctest):
858 """Nose Plugin that supports doctests in extension modules.
858 """Nose Plugin that supports doctests in extension modules.
859 """
859 """
860 name = 'ipdoctest' # call nosetests with --with-ipdoctest
860 name = 'ipdoctest' # call nosetests with --with-ipdoctest
861 enabled = True
861 enabled = True
862
862
863 def makeTest(self, obj, parent):
863 def makeTest(self, obj, parent):
864 """Look for doctests in the given object, which will be a
864 """Look for doctests in the given object, which will be a
865 function, method or class.
865 function, method or class.
866 """
866 """
867 # always use whitespace and ellipsis options
867 # always use whitespace and ellipsis options
868 optionflags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS
868 optionflags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS
869
869
870 doctests = self.finder.find(obj, module=getmodule(parent))
870 doctests = self.finder.find(obj, module=getmodule(parent))
871 if doctests:
871 if doctests:
872 for test in doctests:
872 for test in doctests:
873 if len(test.examples) == 0:
873 if len(test.examples) == 0:
874 continue
874 continue
875
875
876 yield DocTestCase(test, obj=obj,
876 yield DocTestCase(test, obj=obj,
877 optionflags=optionflags,
877 optionflags=optionflags,
878 checker=self.checker)
878 checker=self.checker)
879
879
880 def options(self, parser, env=os.environ):
880 def options(self, parser, env=os.environ):
881 Plugin.options(self, parser, env)
881 Plugin.options(self, parser, env)
882 parser.add_option('--ipdoctest-tests', action='store_true',
882 parser.add_option('--ipdoctest-tests', action='store_true',
883 dest='ipdoctest_tests',
883 dest='ipdoctest_tests',
884 default=env.get('NOSE_IPDOCTEST_TESTS',True),
884 default=env.get('NOSE_IPDOCTEST_TESTS',True),
885 help="Also look for doctests in test modules. "
885 help="Also look for doctests in test modules. "
886 "Note that classes, methods and functions should "
886 "Note that classes, methods and functions should "
887 "have either doctests or non-doctest tests, "
887 "have either doctests or non-doctest tests, "
888 "not both. [NOSE_IPDOCTEST_TESTS]")
888 "not both. [NOSE_IPDOCTEST_TESTS]")
889 parser.add_option('--ipdoctest-extension', action="append",
889 parser.add_option('--ipdoctest-extension', action="append",
890 dest="ipdoctest_extension",
890 dest="ipdoctest_extension",
891 help="Also look for doctests in files with "
891 help="Also look for doctests in files with "
892 "this extension [NOSE_IPDOCTEST_EXTENSION]")
892 "this extension [NOSE_IPDOCTEST_EXTENSION]")
893 # Set the default as a list, if given in env; otherwise
893 # Set the default as a list, if given in env; otherwise
894 # an additional value set on the command line will cause
894 # an additional value set on the command line will cause
895 # an error.
895 # an error.
896 env_setting = env.get('NOSE_IPDOCTEST_EXTENSION')
896 env_setting = env.get('NOSE_IPDOCTEST_EXTENSION')
897 if env_setting is not None:
897 if env_setting is not None:
898 parser.set_defaults(ipdoctest_extension=tolist(env_setting))
898 parser.set_defaults(ipdoctest_extension=tolist(env_setting))
899
899
900 def configure(self, options, config):
900 def configure(self, options, config):
901 Plugin.configure(self, options, config)
901 Plugin.configure(self, options, config)
902 self.doctest_tests = options.ipdoctest_tests
902 self.doctest_tests = options.ipdoctest_tests
903 self.extension = tolist(options.ipdoctest_extension)
903 self.extension = tolist(options.ipdoctest_extension)
904
904
905 self.parser = IPDocTestParser()
905 self.parser = IPDocTestParser()
906 self.finder = DocTestFinder(parser=self.parser)
906 self.finder = DocTestFinder(parser=self.parser)
907 self.checker = IPDoctestOutputChecker()
907 self.checker = IPDoctestOutputChecker()
908 self.globs = None
908 self.globs = None
909 self.extraglobs = None
909 self.extraglobs = None
@@ -1,252 +1,255 b''
1 =============================
1 =============================
2 IPython module reorganization
2 IPython module reorganization
3 =============================
3 =============================
4
4
5 Currently, IPython has many top-level modules that serve many different purposes.
5 Currently, IPython has many top-level modules that serve many different purposes.
6 The lack of organization make it very difficult for developers to work on IPython
6 The lack of organization make it very difficult for developers to work on IPython
7 and understand its design. This document contains notes about how we will reorganize
7 and understand its design. This document contains notes about how we will reorganize
8 the modules into sub-packages.
8 the modules into sub-packages.
9
9
10 .. warning::
10 .. warning::
11
11
12 This effort will possibly break third party packages that use IPython as
12 This effort will possibly break third party packages that use IPython as
13 a library or hack on the IPython internals.
13 a library or hack on the IPython internals.
14
14
15 .. warning::
15 .. warning::
16
16
17 This effort will result in the removal from IPython of certain modules
17 This effort will result in the removal from IPython of certain modules
18 that are not used anymore, don't currently work, are unmaintained, etc.
18 that are not used anymore, don't currently work, are unmaintained, etc.
19
19
20
20
21 Current subpackges
21 Current subpackges
22 ==================
22 ==================
23
23
24 IPython currently has the following sub-packages:
24 IPython currently has the following sub-packages:
25
25
26 * :mod:`IPython.config`
26 * :mod:`IPython.config`
27
27
28 * :mod:`IPython.Extensions`
28 * :mod:`IPython.Extensions`
29
29
30 * :mod:`IPython.external`
30 * :mod:`IPython.external`
31
31
32 * :mod:`IPython.frontend`
32 * :mod:`IPython.frontend`
33
33
34 * :mod:`IPython.gui`
34 * :mod:`IPython.gui`
35
35
36 * :mod:`IPython.kernel`
36 * :mod:`IPython.kernel`
37
37
38 * :mod:`IPython.testing`
38 * :mod:`IPython.testing`
39
39
40 * :mod:`IPython.tests`
40 * :mod:`IPython.tests`
41
41
42 * :mod:`IPython.tools`
42 * :mod:`IPython.tools`
43
43
44 * :mod:`IPython.UserConfig`
44 * :mod:`IPython.UserConfig`
45
45
46 New Subpackages to be created
46 New Subpackages to be created
47 =============================
47 =============================
48
48
49 We propose to create the following new sub-packages:
49 We propose to create the following new sub-packages:
50
50
51 * :mod:`IPython.core`. This sub-package will contain the core of the IPython
51 * :mod:`IPython.core`. This sub-package will contain the core of the IPython
52 interpreter, but none of its extended capabilities.
52 interpreter, but none of its extended capabilities.
53
53
54 * :mod:`IPython.lib`. IPython has many extended capabilities that are not part
54 * :mod:`IPython.lib`. IPython has many extended capabilities that are not part
55 of the IPython core. These things will go here. Any better names than
55 of the IPython core. These things will go here. Any better names than
56 :mod:`IPython.lib`?
56 :mod:`IPython.lib`?
57
57
58 * :mod:`IPython.utils`. This sub-package will contain anything that might
58 * :mod:`IPython.utils`. This sub-package will contain anything that might
59 eventually be found in the Python standard library, like things in
59 eventually be found in the Python standard library, like things in
60 :mod:`genutils`. Each sub-module in this sub-package should contain
60 :mod:`genutils`. Each sub-module in this sub-package should contain
61 functions and classes that serve a single purpose.
61 functions and classes that serve a single purpose.
62
62
63 * :mod:`IPython.deathrow`. This is for code that is untested and/or rotting
63 * :mod:`IPython.deathrow`. This is for code that is untested and/or rotting
64 and needs to be removed from IPython. Eventually all this code will either
64 and needs to be removed from IPython. Eventually all this code will either
65 i) be revived by someone willing to maintain it with tests and docs and
65 i) be revived by someone willing to maintain it with tests and docs and
66 re-included into IPython or 2) be removed from IPython proper, but put into
66 re-included into IPython or 2) be removed from IPython proper, but put into
67 a separate top-level (not IPython) package that we keep around. No new code
67 a separate top-level (not IPython) package that we keep around. No new code
68 will be allowed here.
68 will be allowed here.
69
69
70 * :mod:`IPython.quarantine`. This is for code that doesn't meet IPython's
70 * :mod:`IPython.quarantine`. This is for code that doesn't meet IPython's
71 standards, but that we plan on keeping. To be moved out of this sub-package
71 standards, but that we plan on keeping. To be moved out of this sub-package
72 a module needs to have a maintainer, tests and documentation.
72 a module needs to have a maintainer, tests and documentation.
73
73
74 Prodecure
74 Prodecure
75 =========
75 =========
76
76
77 1. Move the file to its new location with its new name.
77 1. Move the file to its new location with its new name.
78 2. Rename all import statements to reflect the change.
78 2. Rename all import statements to reflect the change.
79 3. Run PyFlakes on each changes module.
79 3. Run PyFlakes on each changes module.
80 3. Add tests/test_imports.py to test it.
80 3. Add tests/test_imports.py to test it.
81
81
82 Need to modify iptests to properly skip modules that are no longer top
82 Need to modify iptests to properly skip modules that are no longer top
83 level modules.
83 level modules.
84
84
85 Need to update the top level IPython/__init__.py file.
85 Need to update the top level IPython/__init__.py file.
86
86
87 Where things will be moved
87 Where things will be moved
88 ==========================
88 ==========================
89
89
90 * :file:`background_jobs.py`. Move to :file:`IPython/lib/backgroundjobs.py`.
90 * :file:`background_jobs.py`. Move to :file:`IPython/lib/backgroundjobs.py`.
91
91
92 * :file:`ColorANSI.py`. Move to :file:`IPython/utils/coloransi.py`.
92 * :file:`ColorANSI.py`. Move to :file:`IPython/utils/coloransi.py`.
93
93
94 * :file:`completer.py`. Move to :file:`IPython/core/completer.py`.
94 * :file:`completer.py`. Move to :file:`IPython/core/completer.py`.
95
95
96 * :file:`ConfigLoader.py`. Move to :file:`IPython/config/configloader.py`.
96 * :file:`ConfigLoader.py`. Move to :file:`IPython/config/configloader.py`.
97
97
98 * :file:`CrashHandler.py`. Move to :file:`IPython/core/crashhandler`.
98 * :file:`CrashHandler.py`. Move to :file:`IPython/core/crashhandler`.
99
99
100 * :file:`Debugger.py`. Move to :file:`IPython/core/debugger.py`.
100 * :file:`Debugger.py`. Move to :file:`IPython/core/debugger.py`.
101
101
102 * :file:`deep_reload.py`. Move to :file:`IPython/lib/deepreload.py`.
102 * :file:`deep_reload.py`. Move to :file:`IPython/lib/deepreload.py`.
103
103
104 * :file:`demo.py`. Move to :file:`IPython/lib/demo.py`.
104 * :file:`demo.py`. Move to :file:`IPython/lib/demo.py`.
105
105
106 * :file:`DPyGetOpt.py`. Move to :mod:`IPython.utils` and replace with newer options parser.
106 * :file:`DPyGetOpt.py`. Move to :mod:`IPython.utils` and replace with newer options parser.
107
107
108 * :file:`dtutils.py`. Move to :file:`IPython.deathrow`.
108 * :file:`dtutils.py`. Move to :file:`IPython.deathrow`.
109
109
110 * :file:`excolors.py`. Move to :file:`IPython.core` or :file:`IPython.config`.
110 * :file:`excolors.py`. Move to :file:`IPython.core` or :file:`IPython.config`.
111 Maybe move to :mod:`IPython.lib` or :mod:`IPython.python`?
111 Maybe move to :mod:`IPython.lib` or :mod:`IPython.python`?
112
112
113 * :file:`FakeModule.py`. Move to :file:`IPython/core/fakemodule.py`.
113 * :file:`FakeModule.py`. Move to :file:`IPython/core/fakemodule.py`.
114
114
115 * :file:`generics.py`. Move to :file:`IPython.python`.
115 * :file:`generics.py`. Move to :file:`IPython.python`.
116
116
117 * :file:`genutils.py`. Move to :file:`IPython.utils`.
117 * :file:`genutils.py`. Move to :file:`IPython.utils`.
118
118
119 * :file:`Gnuplot2.py`. Move to :file:`IPython.sandbox`.
119 * :file:`Gnuplot2.py`. Move to :file:`IPython.sandbox`.
120
120
121 * :file:`GnuplotInteractive.py`. Move to :file:`IPython.sandbox`.
121 * :file:`GnuplotInteractive.py`. Move to :file:`IPython.sandbox`.
122
122
123 * :file:`GnuplotRuntime.py`. Move to :file:`IPython.sandbox`.
123 * :file:`GnuplotRuntime.py`. Move to :file:`IPython.sandbox`.
124
124
125 * :file:`numutils.py`. Move to :file:`IPython.sandbox`.
125 * :file:`numutils.py`. Move to :file:`IPython.sandbox`.
126
126
127 * :file:`twshell.py`. Move to :file:`IPython.sandbox`.
127 * :file:`twshell.py`. Move to :file:`IPython.sandbox`.
128
128
129 * :file:`Extensions`. This needs to be gone through separately. Minimally,
129 * :file:`Extensions`. This needs to be gone through separately. Minimally,
130 the package should be renamed to :file:`extensions`.
130 the package should be renamed to :file:`extensions`.
131
131
132 * :file:`history.py`. Move to :file:`IPython.core`.
132 * :file:`history.py`. Move to :file:`IPython.core`.
133
133
134 * :file:`hooks.py`. Move to :file:`IPython.core`.
134 * :file:`hooks.py`. Move to :file:`IPython.core`.
135
135
136 * :file:`ipapi.py`. Move to :file:`IPython.core`.
137
138
136
139
137 * :file:`Itpl.py`. Remove. Version already in :file:`IPython.external`.
140 * :file:`Itpl.py`. Remove. Version already in :file:`IPython.external`.
138
141
139 * :file:`Logger.py`. Move to :file:`IPython/core/logger.py`.
142 * :file:`Logger.py`. Move to :file:`IPython/core/logger.py`.
140
143
141 * :file:`Magic.py`. Move to :file:`IPython/core/magic.py`.
144 * :file:`Magic.py`. Move to :file:`IPython/core/magic.py`.
142
145
143 * :file:`OInspect.py`. Move to :file:`IPython/core/oinspect.py`.
146 * :file:`OInspect.py`. Move to :file:`IPython/core/oinspect.py`.
144
147
145 * :file:`OutputTrap.py`. Move to :file:`IPython/core/outputtrap.py`.
148 * :file:`OutputTrap.py`. Move to :file:`IPython/core/outputtrap.py`.
146
149
147 * :file:`Prompts.py`. Move to :file:`IPython/core/prompts.py` or
150 * :file:`Prompts.py`. Move to :file:`IPython/core/prompts.py` or
148 :file:`IPython/frontend/prompts.py`.
151 :file:`IPython/frontend/prompts.py`.
149
152
150 * :file:`PyColorize.py`. Replace with pygments? If not, move to
153 * :file:`PyColorize.py`. Replace with pygments? If not, move to
151 :file:`IPython/core/pycolorize.py`. Maybe move to :mod:`IPython.lib` or
154 :file:`IPython/core/pycolorize.py`. Maybe move to :mod:`IPython.lib` or
152 :mod:`IPython.python`?
155 :mod:`IPython.python`?
153
156
154 * :file:`Release.py`. Move to ??? or remove?
157 * :file:`Release.py`. Move to ??? or remove?
155
158
156 * :file:`Shell.py`. Move to :file:`IPython.core.shell.py` or
159 * :file:`Shell.py`. Move to :file:`IPython.core.shell.py` or
157 :file:`IPython/frontend/shell.py`.
160 :file:`IPython/frontend/shell.py`.
158
161
159 * :file:`UserConfig`. Move to a subdirectory of :file:`IPython.config`.
162 * :file:`UserConfig`. Move to a subdirectory of :file:`IPython.config`.
160
163
161
164
162
165
163
166
164 * :file:`config`. Good where it is!
167 * :file:`config`. Good where it is!
165
168
166 * :file:`external`. Good where it is!
169 * :file:`external`. Good where it is!
167
170
168 * :file:`frontend`. Good where it is!
171 * :file:`frontend`. Good where it is!
169
172
170
173
171
174
172 * :file:`gui`. Eventually this should be moved to a subdir of
175 * :file:`gui`. Eventually this should be moved to a subdir of
173 :file:`IPython.frontend`.
176 :file:`IPython.frontend`.
174
177
175
178
176
179
177
180
178
181
179 * :file:`ipapi.py`. Move to :file:`IPython.core`.
182
180
183
181 * :file:`iplib.py`. Move to :file:`IPython.core`.
184 * :file:`iplib.py`. Move to :file:`IPython.core`.
182
185
183 * :file:`ipmaker.py`: Move to :file:`IPython.core`.
186 * :file:`ipmaker.py`: Move to :file:`IPython.core`.
184
187
185 * :file:`ipstruct.py`. Move to :file:`IPython.python`.
188 * :file:`ipstruct.py`. Move to :file:`IPython.python`.
186
189
187 * :file:`irunner.py`. Move to :file:`IPython.scripts`.
190 * :file:`irunner.py`. Move to :file:`IPython.scripts`.
188
191
189 * :file:`kernel`. Good where it is.
192 * :file:`kernel`. Good where it is.
190
193
191 * :file:`macro.py`. Move to :file:`IPython.core`.
194 * :file:`macro.py`. Move to :file:`IPython.core`.
192
195
193
196
194
197
195 * :file:`platutils.py`. Move to :file:`IPython.python`.
198 * :file:`platutils.py`. Move to :file:`IPython.python`.
196
199
197 * :file:`platutils_dummy.py`. Move to :file:`IPython.python`.
200 * :file:`platutils_dummy.py`. Move to :file:`IPython.python`.
198
201
199 * :file:`platutils_posix.py`. Move to :file:`IPython.python`.
202 * :file:`platutils_posix.py`. Move to :file:`IPython.python`.
200
203
201 * :file:`platutils_win32.py`. Move to :file:`IPython.python`.
204 * :file:`platutils_win32.py`. Move to :file:`IPython.python`.
202
205
203 * :file:`prefilter.py`: Move to :file:`IPython.core`.
206 * :file:`prefilter.py`: Move to :file:`IPython.core`.
204
207
205 * :file:`rlineimpl.py`. Move to :file:`IPython.core`.
208 * :file:`rlineimpl.py`. Move to :file:`IPython.core`.
206
209
207 * :file:`shadowns.py`. Move to :file:`IPython.core`.
210 * :file:`shadowns.py`. Move to :file:`IPython.core`.
208
211
209 * :file:`shellglobals.py`. Move to :file:`IPython.core`.
212 * :file:`shellglobals.py`. Move to :file:`IPython.core`.
210
213
211 * :file:`strdispatch.py`. Move to :file:`IPython.python`.
214 * :file:`strdispatch.py`. Move to :file:`IPython.python`.
212
215
213 * :file:`testing`. Good where it is.
216 * :file:`testing`. Good where it is.
214
217
215 * :file:`tests`. Good where it is.
218 * :file:`tests`. Good where it is.
216
219
217 * :file:`tools`. Things in here need to be looked at and moved elsewhere like
220 * :file:`tools`. Things in here need to be looked at and moved elsewhere like
218 :file:`IPython.python`.
221 :file:`IPython.python`.
219
222
220 * :file:`twshell.py`. Move to :file:`IPython.sandbox`.
223 * :file:`twshell.py`. Move to :file:`IPython.sandbox`.
221
224
222 * :file:`ultraTB.py`. Move to :file:`IPython/core/ultratb.py`.
225 * :file:`ultraTB.py`. Move to :file:`IPython/core/ultratb.py`.
223
226
224 * :file:`upgrade_dir.py`. Move to :file:`IPython/python/upgradedir.py`.
227 * :file:`upgrade_dir.py`. Move to :file:`IPython/python/upgradedir.py`.
225
228
226 * :file:`usage.py`. Move to :file:`IPython.core`.
229 * :file:`usage.py`. Move to :file:`IPython.core`.
227
230
228 * :file:`wildcard.py`. Move to :file:`IPython.python` or :file:`IPython.core`.
231 * :file:`wildcard.py`. Move to :file:`IPython.python` or :file:`IPython.core`.
229
232
230 * :file:`winconsole.py`. Move to :file:`IPython.lib`.
233 * :file:`winconsole.py`. Move to :file:`IPython.lib`.
231
234
232 Other things
235 Other things
233 ============
236 ============
234
237
235 When these files are moved around, a number of other things will happen at the same time:
238 When these files are moved around, a number of other things will happen at the same time:
236
239
237 1. Test files will be created for each module in IPython. Minimally, all
240 1. Test files will be created for each module in IPython. Minimally, all
238 modules will be imported as a part of the test. This will serve as a
241 modules will be imported as a part of the test. This will serve as a
239 test of the module reorganization. These tests will be put into new
242 test of the module reorganization. These tests will be put into new
240 :file:`tests` subdirectories that each package will have.
243 :file:`tests` subdirectories that each package will have.
241
244
242 2. PyFlakes and other code checkers will be run to look for problems.
245 2. PyFlakes and other code checkers will be run to look for problems.
243
246
244 3. Modules will be renamed to comply with PEP 8 naming conventions: all
247 3. Modules will be renamed to comply with PEP 8 naming conventions: all
245 lowercase and no special characters like ``-`` or ``_``.
248 lowercase and no special characters like ``-`` or ``_``.
246
249
247 4. Existing tests will be moved to the appropriate :file:`tests`
250 4. Existing tests will be moved to the appropriate :file:`tests`
248 subdirectories.
251 subdirectories.
249
252
250
253
251
254
252
255
General Comments 0
You need to be logged in to leave comments. Login now