##// END OF EJS Templates
Rename globlist to shellglob
Takafumi Arakaki -
Show More
@@ -1,1036 +1,1036 b''
1 """Implementation of execution-related magic functions.
1 """Implementation of execution-related magic functions.
2 """
2 """
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4 # Copyright (c) 2012 The IPython Development Team.
4 # Copyright (c) 2012 The IPython Development Team.
5 #
5 #
6 # Distributed under the terms of the Modified BSD License.
6 # Distributed under the terms of the Modified BSD License.
7 #
7 #
8 # The full license is in the file COPYING.txt, distributed with this software.
8 # The full license is in the file COPYING.txt, distributed with this software.
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Imports
12 # Imports
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 # Stdlib
15 # Stdlib
16 import __builtin__ as builtin_mod
16 import __builtin__ as builtin_mod
17 import bdb
17 import bdb
18 import os
18 import os
19 import sys
19 import sys
20 import time
20 import time
21 from StringIO import StringIO
21 from StringIO import StringIO
22
22
23 # cProfile was added in Python2.5
23 # cProfile was added in Python2.5
24 try:
24 try:
25 import cProfile as profile
25 import cProfile as profile
26 import pstats
26 import pstats
27 except ImportError:
27 except ImportError:
28 # profile isn't bundled by default in Debian for license reasons
28 # profile isn't bundled by default in Debian for license reasons
29 try:
29 try:
30 import profile, pstats
30 import profile, pstats
31 except ImportError:
31 except ImportError:
32 profile = pstats = None
32 profile = pstats = None
33
33
34 # Our own packages
34 # Our own packages
35 from IPython.core import debugger, oinspect
35 from IPython.core import debugger, oinspect
36 from IPython.core import magic_arguments
36 from IPython.core import magic_arguments
37 from IPython.core import page
37 from IPython.core import page
38 from IPython.core.error import UsageError
38 from IPython.core.error import UsageError
39 from IPython.core.macro import Macro
39 from IPython.core.macro import Macro
40 from IPython.core.magic import (Magics, magics_class, line_magic, cell_magic,
40 from IPython.core.magic import (Magics, magics_class, line_magic, cell_magic,
41 line_cell_magic, on_off, needs_local_scope)
41 line_cell_magic, on_off, needs_local_scope)
42 from IPython.testing.skipdoctest import skip_doctest
42 from IPython.testing.skipdoctest import skip_doctest
43 from IPython.utils import py3compat
43 from IPython.utils import py3compat
44 from IPython.utils.io import capture_output
44 from IPython.utils.io import capture_output
45 from IPython.utils.ipstruct import Struct
45 from IPython.utils.ipstruct import Struct
46 from IPython.utils.module_paths import find_mod
46 from IPython.utils.module_paths import find_mod
47 from IPython.utils.path import get_py_filename, unquote_filename, globlist
47 from IPython.utils.path import get_py_filename, unquote_filename, shellglob
48 from IPython.utils.timing import clock, clock2
48 from IPython.utils.timing import clock, clock2
49 from IPython.utils.warn import warn, error
49 from IPython.utils.warn import warn, error
50
50
51
51
52 #-----------------------------------------------------------------------------
52 #-----------------------------------------------------------------------------
53 # Magic implementation classes
53 # Magic implementation classes
54 #-----------------------------------------------------------------------------
54 #-----------------------------------------------------------------------------
55
55
56 @magics_class
56 @magics_class
57 class ExecutionMagics(Magics):
57 class ExecutionMagics(Magics):
58 """Magics related to code execution, debugging, profiling, etc.
58 """Magics related to code execution, debugging, profiling, etc.
59
59
60 """
60 """
61
61
62 def __init__(self, shell):
62 def __init__(self, shell):
63 super(ExecutionMagics, self).__init__(shell)
63 super(ExecutionMagics, self).__init__(shell)
64 if profile is None:
64 if profile is None:
65 self.prun = self.profile_missing_notice
65 self.prun = self.profile_missing_notice
66 # Default execution function used to actually run user code.
66 # Default execution function used to actually run user code.
67 self.default_runner = None
67 self.default_runner = None
68
68
69 def profile_missing_notice(self, *args, **kwargs):
69 def profile_missing_notice(self, *args, **kwargs):
70 error("""\
70 error("""\
71 The profile module could not be found. It has been removed from the standard
71 The profile module could not be found. It has been removed from the standard
72 python packages because of its non-free license. To use profiling, install the
72 python packages because of its non-free license. To use profiling, install the
73 python-profiler package from non-free.""")
73 python-profiler package from non-free.""")
74
74
75 @skip_doctest
75 @skip_doctest
76 @line_cell_magic
76 @line_cell_magic
77 def prun(self, parameter_s='', cell=None, user_mode=True,
77 def prun(self, parameter_s='', cell=None, user_mode=True,
78 opts=None,arg_lst=None,prog_ns=None):
78 opts=None,arg_lst=None,prog_ns=None):
79
79
80 """Run a statement through the python code profiler.
80 """Run a statement through the python code profiler.
81
81
82 Usage, in line mode:
82 Usage, in line mode:
83 %prun [options] statement
83 %prun [options] statement
84
84
85 Usage, in cell mode:
85 Usage, in cell mode:
86 %%prun [options] [statement]
86 %%prun [options] [statement]
87 code...
87 code...
88 code...
88 code...
89
89
90 In cell mode, the additional code lines are appended to the (possibly
90 In cell mode, the additional code lines are appended to the (possibly
91 empty) statement in the first line. Cell mode allows you to easily
91 empty) statement in the first line. Cell mode allows you to easily
92 profile multiline blocks without having to put them in a separate
92 profile multiline blocks without having to put them in a separate
93 function.
93 function.
94
94
95 The given statement (which doesn't require quote marks) is run via the
95 The given statement (which doesn't require quote marks) is run via the
96 python profiler in a manner similar to the profile.run() function.
96 python profiler in a manner similar to the profile.run() function.
97 Namespaces are internally managed to work correctly; profile.run
97 Namespaces are internally managed to work correctly; profile.run
98 cannot be used in IPython because it makes certain assumptions about
98 cannot be used in IPython because it makes certain assumptions about
99 namespaces which do not hold under IPython.
99 namespaces which do not hold under IPython.
100
100
101 Options:
101 Options:
102
102
103 -l <limit>: you can place restrictions on what or how much of the
103 -l <limit>: you can place restrictions on what or how much of the
104 profile gets printed. The limit value can be:
104 profile gets printed. The limit value can be:
105
105
106 * A string: only information for function names containing this string
106 * A string: only information for function names containing this string
107 is printed.
107 is printed.
108
108
109 * An integer: only these many lines are printed.
109 * An integer: only these many lines are printed.
110
110
111 * A float (between 0 and 1): this fraction of the report is printed
111 * A float (between 0 and 1): this fraction of the report is printed
112 (for example, use a limit of 0.4 to see the topmost 40% only).
112 (for example, use a limit of 0.4 to see the topmost 40% only).
113
113
114 You can combine several limits with repeated use of the option. For
114 You can combine several limits with repeated use of the option. For
115 example, '-l __init__ -l 5' will print only the topmost 5 lines of
115 example, '-l __init__ -l 5' will print only the topmost 5 lines of
116 information about class constructors.
116 information about class constructors.
117
117
118 -r: return the pstats.Stats object generated by the profiling. This
118 -r: return the pstats.Stats object generated by the profiling. This
119 object has all the information about the profile in it, and you can
119 object has all the information about the profile in it, and you can
120 later use it for further analysis or in other functions.
120 later use it for further analysis or in other functions.
121
121
122 -s <key>: sort profile by given key. You can provide more than one key
122 -s <key>: sort profile by given key. You can provide more than one key
123 by using the option several times: '-s key1 -s key2 -s key3...'. The
123 by using the option several times: '-s key1 -s key2 -s key3...'. The
124 default sorting key is 'time'.
124 default sorting key is 'time'.
125
125
126 The following is copied verbatim from the profile documentation
126 The following is copied verbatim from the profile documentation
127 referenced below:
127 referenced below:
128
128
129 When more than one key is provided, additional keys are used as
129 When more than one key is provided, additional keys are used as
130 secondary criteria when the there is equality in all keys selected
130 secondary criteria when the there is equality in all keys selected
131 before them.
131 before them.
132
132
133 Abbreviations can be used for any key names, as long as the
133 Abbreviations can be used for any key names, as long as the
134 abbreviation is unambiguous. The following are the keys currently
134 abbreviation is unambiguous. The following are the keys currently
135 defined:
135 defined:
136
136
137 Valid Arg Meaning
137 Valid Arg Meaning
138 "calls" call count
138 "calls" call count
139 "cumulative" cumulative time
139 "cumulative" cumulative time
140 "file" file name
140 "file" file name
141 "module" file name
141 "module" file name
142 "pcalls" primitive call count
142 "pcalls" primitive call count
143 "line" line number
143 "line" line number
144 "name" function name
144 "name" function name
145 "nfl" name/file/line
145 "nfl" name/file/line
146 "stdname" standard name
146 "stdname" standard name
147 "time" internal time
147 "time" internal time
148
148
149 Note that all sorts on statistics are in descending order (placing
149 Note that all sorts on statistics are in descending order (placing
150 most time consuming items first), where as name, file, and line number
150 most time consuming items first), where as name, file, and line number
151 searches are in ascending order (i.e., alphabetical). The subtle
151 searches are in ascending order (i.e., alphabetical). The subtle
152 distinction between "nfl" and "stdname" is that the standard name is a
152 distinction between "nfl" and "stdname" is that the standard name is a
153 sort of the name as printed, which means that the embedded line
153 sort of the name as printed, which means that the embedded line
154 numbers get compared in an odd way. For example, lines 3, 20, and 40
154 numbers get compared in an odd way. For example, lines 3, 20, and 40
155 would (if the file names were the same) appear in the string order
155 would (if the file names were the same) appear in the string order
156 "20" "3" and "40". In contrast, "nfl" does a numeric compare of the
156 "20" "3" and "40". In contrast, "nfl" does a numeric compare of the
157 line numbers. In fact, sort_stats("nfl") is the same as
157 line numbers. In fact, sort_stats("nfl") is the same as
158 sort_stats("name", "file", "line").
158 sort_stats("name", "file", "line").
159
159
160 -T <filename>: save profile results as shown on screen to a text
160 -T <filename>: save profile results as shown on screen to a text
161 file. The profile is still shown on screen.
161 file. The profile is still shown on screen.
162
162
163 -D <filename>: save (via dump_stats) profile statistics to given
163 -D <filename>: save (via dump_stats) profile statistics to given
164 filename. This data is in a format understood by the pstats module, and
164 filename. This data is in a format understood by the pstats module, and
165 is generated by a call to the dump_stats() method of profile
165 is generated by a call to the dump_stats() method of profile
166 objects. The profile is still shown on screen.
166 objects. The profile is still shown on screen.
167
167
168 -q: suppress output to the pager. Best used with -T and/or -D above.
168 -q: suppress output to the pager. Best used with -T and/or -D above.
169
169
170 If you want to run complete programs under the profiler's control, use
170 If you want to run complete programs under the profiler's control, use
171 '%run -p [prof_opts] filename.py [args to program]' where prof_opts
171 '%run -p [prof_opts] filename.py [args to program]' where prof_opts
172 contains profiler specific options as described here.
172 contains profiler specific options as described here.
173
173
174 You can read the complete documentation for the profile module with::
174 You can read the complete documentation for the profile module with::
175
175
176 In [1]: import profile; profile.help()
176 In [1]: import profile; profile.help()
177 """
177 """
178
178
179 opts_def = Struct(D=[''],l=[],s=['time'],T=[''])
179 opts_def = Struct(D=[''],l=[],s=['time'],T=[''])
180
180
181 if user_mode: # regular user call
181 if user_mode: # regular user call
182 opts,arg_str = self.parse_options(parameter_s,'D:l:rs:T:q',
182 opts,arg_str = self.parse_options(parameter_s,'D:l:rs:T:q',
183 list_all=True, posix=False)
183 list_all=True, posix=False)
184 namespace = self.shell.user_ns
184 namespace = self.shell.user_ns
185 if cell is not None:
185 if cell is not None:
186 arg_str += '\n' + cell
186 arg_str += '\n' + cell
187 else: # called to run a program by %run -p
187 else: # called to run a program by %run -p
188 try:
188 try:
189 filename = get_py_filename(arg_lst[0])
189 filename = get_py_filename(arg_lst[0])
190 except IOError as e:
190 except IOError as e:
191 try:
191 try:
192 msg = str(e)
192 msg = str(e)
193 except UnicodeError:
193 except UnicodeError:
194 msg = e.message
194 msg = e.message
195 error(msg)
195 error(msg)
196 return
196 return
197
197
198 arg_str = 'execfile(filename,prog_ns)'
198 arg_str = 'execfile(filename,prog_ns)'
199 namespace = {
199 namespace = {
200 'execfile': self.shell.safe_execfile,
200 'execfile': self.shell.safe_execfile,
201 'prog_ns': prog_ns,
201 'prog_ns': prog_ns,
202 'filename': filename
202 'filename': filename
203 }
203 }
204
204
205 opts.merge(opts_def)
205 opts.merge(opts_def)
206
206
207 prof = profile.Profile()
207 prof = profile.Profile()
208 try:
208 try:
209 prof = prof.runctx(arg_str,namespace,namespace)
209 prof = prof.runctx(arg_str,namespace,namespace)
210 sys_exit = ''
210 sys_exit = ''
211 except SystemExit:
211 except SystemExit:
212 sys_exit = """*** SystemExit exception caught in code being profiled."""
212 sys_exit = """*** SystemExit exception caught in code being profiled."""
213
213
214 stats = pstats.Stats(prof).strip_dirs().sort_stats(*opts.s)
214 stats = pstats.Stats(prof).strip_dirs().sort_stats(*opts.s)
215
215
216 lims = opts.l
216 lims = opts.l
217 if lims:
217 if lims:
218 lims = [] # rebuild lims with ints/floats/strings
218 lims = [] # rebuild lims with ints/floats/strings
219 for lim in opts.l:
219 for lim in opts.l:
220 try:
220 try:
221 lims.append(int(lim))
221 lims.append(int(lim))
222 except ValueError:
222 except ValueError:
223 try:
223 try:
224 lims.append(float(lim))
224 lims.append(float(lim))
225 except ValueError:
225 except ValueError:
226 lims.append(lim)
226 lims.append(lim)
227
227
228 # Trap output.
228 # Trap output.
229 stdout_trap = StringIO()
229 stdout_trap = StringIO()
230
230
231 if hasattr(stats,'stream'):
231 if hasattr(stats,'stream'):
232 # In newer versions of python, the stats object has a 'stream'
232 # In newer versions of python, the stats object has a 'stream'
233 # attribute to write into.
233 # attribute to write into.
234 stats.stream = stdout_trap
234 stats.stream = stdout_trap
235 stats.print_stats(*lims)
235 stats.print_stats(*lims)
236 else:
236 else:
237 # For older versions, we manually redirect stdout during printing
237 # For older versions, we manually redirect stdout during printing
238 sys_stdout = sys.stdout
238 sys_stdout = sys.stdout
239 try:
239 try:
240 sys.stdout = stdout_trap
240 sys.stdout = stdout_trap
241 stats.print_stats(*lims)
241 stats.print_stats(*lims)
242 finally:
242 finally:
243 sys.stdout = sys_stdout
243 sys.stdout = sys_stdout
244
244
245 output = stdout_trap.getvalue()
245 output = stdout_trap.getvalue()
246 output = output.rstrip()
246 output = output.rstrip()
247
247
248 if 'q' not in opts:
248 if 'q' not in opts:
249 page.page(output)
249 page.page(output)
250 print sys_exit,
250 print sys_exit,
251
251
252 dump_file = opts.D[0]
252 dump_file = opts.D[0]
253 text_file = opts.T[0]
253 text_file = opts.T[0]
254 if dump_file:
254 if dump_file:
255 dump_file = unquote_filename(dump_file)
255 dump_file = unquote_filename(dump_file)
256 prof.dump_stats(dump_file)
256 prof.dump_stats(dump_file)
257 print '\n*** Profile stats marshalled to file',\
257 print '\n*** Profile stats marshalled to file',\
258 repr(dump_file)+'.',sys_exit
258 repr(dump_file)+'.',sys_exit
259 if text_file:
259 if text_file:
260 text_file = unquote_filename(text_file)
260 text_file = unquote_filename(text_file)
261 pfile = open(text_file,'w')
261 pfile = open(text_file,'w')
262 pfile.write(output)
262 pfile.write(output)
263 pfile.close()
263 pfile.close()
264 print '\n*** Profile printout saved to text file',\
264 print '\n*** Profile printout saved to text file',\
265 repr(text_file)+'.',sys_exit
265 repr(text_file)+'.',sys_exit
266
266
267 if opts.has_key('r'):
267 if opts.has_key('r'):
268 return stats
268 return stats
269 else:
269 else:
270 return None
270 return None
271
271
272 @line_magic
272 @line_magic
273 def pdb(self, parameter_s=''):
273 def pdb(self, parameter_s=''):
274 """Control the automatic calling of the pdb interactive debugger.
274 """Control the automatic calling of the pdb interactive debugger.
275
275
276 Call as '%pdb on', '%pdb 1', '%pdb off' or '%pdb 0'. If called without
276 Call as '%pdb on', '%pdb 1', '%pdb off' or '%pdb 0'. If called without
277 argument it works as a toggle.
277 argument it works as a toggle.
278
278
279 When an exception is triggered, IPython can optionally call the
279 When an exception is triggered, IPython can optionally call the
280 interactive pdb debugger after the traceback printout. %pdb toggles
280 interactive pdb debugger after the traceback printout. %pdb toggles
281 this feature on and off.
281 this feature on and off.
282
282
283 The initial state of this feature is set in your configuration
283 The initial state of this feature is set in your configuration
284 file (the option is ``InteractiveShell.pdb``).
284 file (the option is ``InteractiveShell.pdb``).
285
285
286 If you want to just activate the debugger AFTER an exception has fired,
286 If you want to just activate the debugger AFTER an exception has fired,
287 without having to type '%pdb on' and rerunning your code, you can use
287 without having to type '%pdb on' and rerunning your code, you can use
288 the %debug magic."""
288 the %debug magic."""
289
289
290 par = parameter_s.strip().lower()
290 par = parameter_s.strip().lower()
291
291
292 if par:
292 if par:
293 try:
293 try:
294 new_pdb = {'off':0,'0':0,'on':1,'1':1}[par]
294 new_pdb = {'off':0,'0':0,'on':1,'1':1}[par]
295 except KeyError:
295 except KeyError:
296 print ('Incorrect argument. Use on/1, off/0, '
296 print ('Incorrect argument. Use on/1, off/0, '
297 'or nothing for a toggle.')
297 'or nothing for a toggle.')
298 return
298 return
299 else:
299 else:
300 # toggle
300 # toggle
301 new_pdb = not self.shell.call_pdb
301 new_pdb = not self.shell.call_pdb
302
302
303 # set on the shell
303 # set on the shell
304 self.shell.call_pdb = new_pdb
304 self.shell.call_pdb = new_pdb
305 print 'Automatic pdb calling has been turned',on_off(new_pdb)
305 print 'Automatic pdb calling has been turned',on_off(new_pdb)
306
306
307 @line_magic
307 @line_magic
308 def debug(self, parameter_s=''):
308 def debug(self, parameter_s=''):
309 """Activate the interactive debugger in post-mortem mode.
309 """Activate the interactive debugger in post-mortem mode.
310
310
311 If an exception has just occurred, this lets you inspect its stack
311 If an exception has just occurred, this lets you inspect its stack
312 frames interactively. Note that this will always work only on the last
312 frames interactively. Note that this will always work only on the last
313 traceback that occurred, so you must call this quickly after an
313 traceback that occurred, so you must call this quickly after an
314 exception that you wish to inspect has fired, because if another one
314 exception that you wish to inspect has fired, because if another one
315 occurs, it clobbers the previous one.
315 occurs, it clobbers the previous one.
316
316
317 If you want IPython to automatically do this on every exception, see
317 If you want IPython to automatically do this on every exception, see
318 the %pdb magic for more details.
318 the %pdb magic for more details.
319 """
319 """
320 self.shell.debugger(force=True)
320 self.shell.debugger(force=True)
321
321
322 @line_magic
322 @line_magic
323 def tb(self, s):
323 def tb(self, s):
324 """Print the last traceback with the currently active exception mode.
324 """Print the last traceback with the currently active exception mode.
325
325
326 See %xmode for changing exception reporting modes."""
326 See %xmode for changing exception reporting modes."""
327 self.shell.showtraceback()
327 self.shell.showtraceback()
328
328
329 @skip_doctest
329 @skip_doctest
330 @line_magic
330 @line_magic
331 def run(self, parameter_s='', runner=None,
331 def run(self, parameter_s='', runner=None,
332 file_finder=get_py_filename):
332 file_finder=get_py_filename):
333 """Run the named file inside IPython as a program.
333 """Run the named file inside IPython as a program.
334
334
335 Usage:\\
335 Usage:\\
336 %run [-n -i -t [-N<N>] -d [-b<N>] -p [profile options] -G] file [args]
336 %run [-n -i -t [-N<N>] -d [-b<N>] -p [profile options] -G] file [args]
337
337
338 Parameters after the filename are passed as command-line arguments to
338 Parameters after the filename are passed as command-line arguments to
339 the program (put in sys.argv). Then, control returns to IPython's
339 the program (put in sys.argv). Then, control returns to IPython's
340 prompt.
340 prompt.
341
341
342 This is similar to running at a system prompt:\\
342 This is similar to running at a system prompt:\\
343 $ python file args\\
343 $ python file args\\
344 but with the advantage of giving you IPython's tracebacks, and of
344 but with the advantage of giving you IPython's tracebacks, and of
345 loading all variables into your interactive namespace for further use
345 loading all variables into your interactive namespace for further use
346 (unless -p is used, see below).
346 (unless -p is used, see below).
347
347
348 The file is executed in a namespace initially consisting only of
348 The file is executed in a namespace initially consisting only of
349 __name__=='__main__' and sys.argv constructed as indicated. It thus
349 __name__=='__main__' and sys.argv constructed as indicated. It thus
350 sees its environment as if it were being run as a stand-alone program
350 sees its environment as if it were being run as a stand-alone program
351 (except for sharing global objects such as previously imported
351 (except for sharing global objects such as previously imported
352 modules). But after execution, the IPython interactive namespace gets
352 modules). But after execution, the IPython interactive namespace gets
353 updated with all variables defined in the program (except for __name__
353 updated with all variables defined in the program (except for __name__
354 and sys.argv). This allows for very convenient loading of code for
354 and sys.argv). This allows for very convenient loading of code for
355 interactive work, while giving each program a 'clean sheet' to run in.
355 interactive work, while giving each program a 'clean sheet' to run in.
356
356
357 Arguments are expanded using shell-like glob match. Patterns
357 Arguments are expanded using shell-like glob match. Patterns
358 '*', '?', '[seq]' and '[!seq]' can be used. Additionally,
358 '*', '?', '[seq]' and '[!seq]' can be used. Additionally,
359 tilde '~' will be expanded into user's home directory. Unlike
359 tilde '~' will be expanded into user's home directory. Unlike
360 real shells, quotation does not suppress expansions. Use back
360 real shells, quotation does not suppress expansions. Use back
361 slash (e.g., '\\*') to suppress expansions. To completely
361 slash (e.g., '\\*') to suppress expansions. To completely
362 disable these expansions, you can use -G flag.
362 disable these expansions, you can use -G flag.
363
363
364 Options:
364 Options:
365
365
366 -n: __name__ is NOT set to '__main__', but to the running file's name
366 -n: __name__ is NOT set to '__main__', but to the running file's name
367 without extension (as python does under import). This allows running
367 without extension (as python does under import). This allows running
368 scripts and reloading the definitions in them without calling code
368 scripts and reloading the definitions in them without calling code
369 protected by an ' if __name__ == "__main__" ' clause.
369 protected by an ' if __name__ == "__main__" ' clause.
370
370
371 -i: run the file in IPython's namespace instead of an empty one. This
371 -i: run the file in IPython's namespace instead of an empty one. This
372 is useful if you are experimenting with code written in a text editor
372 is useful if you are experimenting with code written in a text editor
373 which depends on variables defined interactively.
373 which depends on variables defined interactively.
374
374
375 -e: ignore sys.exit() calls or SystemExit exceptions in the script
375 -e: ignore sys.exit() calls or SystemExit exceptions in the script
376 being run. This is particularly useful if IPython is being used to
376 being run. This is particularly useful if IPython is being used to
377 run unittests, which always exit with a sys.exit() call. In such
377 run unittests, which always exit with a sys.exit() call. In such
378 cases you are interested in the output of the test results, not in
378 cases you are interested in the output of the test results, not in
379 seeing a traceback of the unittest module.
379 seeing a traceback of the unittest module.
380
380
381 -t: print timing information at the end of the run. IPython will give
381 -t: print timing information at the end of the run. IPython will give
382 you an estimated CPU time consumption for your script, which under
382 you an estimated CPU time consumption for your script, which under
383 Unix uses the resource module to avoid the wraparound problems of
383 Unix uses the resource module to avoid the wraparound problems of
384 time.clock(). Under Unix, an estimate of time spent on system tasks
384 time.clock(). Under Unix, an estimate of time spent on system tasks
385 is also given (for Windows platforms this is reported as 0.0).
385 is also given (for Windows platforms this is reported as 0.0).
386
386
387 If -t is given, an additional -N<N> option can be given, where <N>
387 If -t is given, an additional -N<N> option can be given, where <N>
388 must be an integer indicating how many times you want the script to
388 must be an integer indicating how many times you want the script to
389 run. The final timing report will include total and per run results.
389 run. The final timing report will include total and per run results.
390
390
391 For example (testing the script uniq_stable.py)::
391 For example (testing the script uniq_stable.py)::
392
392
393 In [1]: run -t uniq_stable
393 In [1]: run -t uniq_stable
394
394
395 IPython CPU timings (estimated):\\
395 IPython CPU timings (estimated):\\
396 User : 0.19597 s.\\
396 User : 0.19597 s.\\
397 System: 0.0 s.\\
397 System: 0.0 s.\\
398
398
399 In [2]: run -t -N5 uniq_stable
399 In [2]: run -t -N5 uniq_stable
400
400
401 IPython CPU timings (estimated):\\
401 IPython CPU timings (estimated):\\
402 Total runs performed: 5\\
402 Total runs performed: 5\\
403 Times : Total Per run\\
403 Times : Total Per run\\
404 User : 0.910862 s, 0.1821724 s.\\
404 User : 0.910862 s, 0.1821724 s.\\
405 System: 0.0 s, 0.0 s.
405 System: 0.0 s, 0.0 s.
406
406
407 -d: run your program under the control of pdb, the Python debugger.
407 -d: run your program under the control of pdb, the Python debugger.
408 This allows you to execute your program step by step, watch variables,
408 This allows you to execute your program step by step, watch variables,
409 etc. Internally, what IPython does is similar to calling:
409 etc. Internally, what IPython does is similar to calling:
410
410
411 pdb.run('execfile("YOURFILENAME")')
411 pdb.run('execfile("YOURFILENAME")')
412
412
413 with a breakpoint set on line 1 of your file. You can change the line
413 with a breakpoint set on line 1 of your file. You can change the line
414 number for this automatic breakpoint to be <N> by using the -bN option
414 number for this automatic breakpoint to be <N> by using the -bN option
415 (where N must be an integer). For example::
415 (where N must be an integer). For example::
416
416
417 %run -d -b40 myscript
417 %run -d -b40 myscript
418
418
419 will set the first breakpoint at line 40 in myscript.py. Note that
419 will set the first breakpoint at line 40 in myscript.py. Note that
420 the first breakpoint must be set on a line which actually does
420 the first breakpoint must be set on a line which actually does
421 something (not a comment or docstring) for it to stop execution.
421 something (not a comment or docstring) for it to stop execution.
422
422
423 When the pdb debugger starts, you will see a (Pdb) prompt. You must
423 When the pdb debugger starts, you will see a (Pdb) prompt. You must
424 first enter 'c' (without quotes) to start execution up to the first
424 first enter 'c' (without quotes) to start execution up to the first
425 breakpoint.
425 breakpoint.
426
426
427 Entering 'help' gives information about the use of the debugger. You
427 Entering 'help' gives information about the use of the debugger. You
428 can easily see pdb's full documentation with "import pdb;pdb.help()"
428 can easily see pdb's full documentation with "import pdb;pdb.help()"
429 at a prompt.
429 at a prompt.
430
430
431 -p: run program under the control of the Python profiler module (which
431 -p: run program under the control of the Python profiler module (which
432 prints a detailed report of execution times, function calls, etc).
432 prints a detailed report of execution times, function calls, etc).
433
433
434 You can pass other options after -p which affect the behavior of the
434 You can pass other options after -p which affect the behavior of the
435 profiler itself. See the docs for %prun for details.
435 profiler itself. See the docs for %prun for details.
436
436
437 In this mode, the program's variables do NOT propagate back to the
437 In this mode, the program's variables do NOT propagate back to the
438 IPython interactive namespace (because they remain in the namespace
438 IPython interactive namespace (because they remain in the namespace
439 where the profiler executes them).
439 where the profiler executes them).
440
440
441 Internally this triggers a call to %prun, see its documentation for
441 Internally this triggers a call to %prun, see its documentation for
442 details on the options available specifically for profiling.
442 details on the options available specifically for profiling.
443
443
444 There is one special usage for which the text above doesn't apply:
444 There is one special usage for which the text above doesn't apply:
445 if the filename ends with .ipy, the file is run as ipython script,
445 if the filename ends with .ipy, the file is run as ipython script,
446 just as if the commands were written on IPython prompt.
446 just as if the commands were written on IPython prompt.
447
447
448 -m: specify module name to load instead of script path. Similar to
448 -m: specify module name to load instead of script path. Similar to
449 the -m option for the python interpreter. Use this option last if you
449 the -m option for the python interpreter. Use this option last if you
450 want to combine with other %run options. Unlike the python interpreter
450 want to combine with other %run options. Unlike the python interpreter
451 only source modules are allowed no .pyc or .pyo files.
451 only source modules are allowed no .pyc or .pyo files.
452 For example::
452 For example::
453
453
454 %run -m example
454 %run -m example
455
455
456 will run the example module.
456 will run the example module.
457
457
458 -G: disable shell-like glob expansion of arguments.
458 -G: disable shell-like glob expansion of arguments.
459
459
460 """
460 """
461
461
462 # get arguments and set sys.argv for program to be run.
462 # get arguments and set sys.argv for program to be run.
463 opts, arg_lst = self.parse_options(parameter_s,
463 opts, arg_lst = self.parse_options(parameter_s,
464 'nidtN:b:pD:l:rs:T:em:G',
464 'nidtN:b:pD:l:rs:T:em:G',
465 mode='list', list_all=1)
465 mode='list', list_all=1)
466 if "m" in opts:
466 if "m" in opts:
467 modulename = opts["m"][0]
467 modulename = opts["m"][0]
468 modpath = find_mod(modulename)
468 modpath = find_mod(modulename)
469 if modpath is None:
469 if modpath is None:
470 warn('%r is not a valid modulename on sys.path'%modulename)
470 warn('%r is not a valid modulename on sys.path'%modulename)
471 return
471 return
472 arg_lst = [modpath] + arg_lst
472 arg_lst = [modpath] + arg_lst
473 try:
473 try:
474 filename = file_finder(arg_lst[0])
474 filename = file_finder(arg_lst[0])
475 except IndexError:
475 except IndexError:
476 warn('you must provide at least a filename.')
476 warn('you must provide at least a filename.')
477 print '\n%run:\n', oinspect.getdoc(self.run)
477 print '\n%run:\n', oinspect.getdoc(self.run)
478 return
478 return
479 except IOError as e:
479 except IOError as e:
480 try:
480 try:
481 msg = str(e)
481 msg = str(e)
482 except UnicodeError:
482 except UnicodeError:
483 msg = e.message
483 msg = e.message
484 error(msg)
484 error(msg)
485 return
485 return
486
486
487 if filename.lower().endswith('.ipy'):
487 if filename.lower().endswith('.ipy'):
488 self.shell.safe_execfile_ipy(filename)
488 self.shell.safe_execfile_ipy(filename)
489 return
489 return
490
490
491 # Control the response to exit() calls made by the script being run
491 # Control the response to exit() calls made by the script being run
492 exit_ignore = 'e' in opts
492 exit_ignore = 'e' in opts
493
493
494 # Make sure that the running script gets a proper sys.argv as if it
494 # Make sure that the running script gets a proper sys.argv as if it
495 # were run from a system shell.
495 # were run from a system shell.
496 save_argv = sys.argv # save it for later restoring
496 save_argv = sys.argv # save it for later restoring
497
497
498 if 'G' in opts:
498 if 'G' in opts:
499 args = arg_lst[1:]
499 args = arg_lst[1:]
500 else:
500 else:
501 # tilde and glob expansion
501 # tilde and glob expansion
502 args = globlist(map(os.path.expanduser, arg_lst[1:]))
502 args = shellglob(map(os.path.expanduser, arg_lst[1:]))
503
503
504 sys.argv = [filename] + args # put in the proper filename
504 sys.argv = [filename] + args # put in the proper filename
505 # protect sys.argv from potential unicode strings on Python 2:
505 # protect sys.argv from potential unicode strings on Python 2:
506 if not py3compat.PY3:
506 if not py3compat.PY3:
507 sys.argv = [ py3compat.cast_bytes(a) for a in sys.argv ]
507 sys.argv = [ py3compat.cast_bytes(a) for a in sys.argv ]
508
508
509 if 'i' in opts:
509 if 'i' in opts:
510 # Run in user's interactive namespace
510 # Run in user's interactive namespace
511 prog_ns = self.shell.user_ns
511 prog_ns = self.shell.user_ns
512 __name__save = self.shell.user_ns['__name__']
512 __name__save = self.shell.user_ns['__name__']
513 prog_ns['__name__'] = '__main__'
513 prog_ns['__name__'] = '__main__'
514 main_mod = self.shell.new_main_mod(prog_ns)
514 main_mod = self.shell.new_main_mod(prog_ns)
515 else:
515 else:
516 # Run in a fresh, empty namespace
516 # Run in a fresh, empty namespace
517 if 'n' in opts:
517 if 'n' in opts:
518 name = os.path.splitext(os.path.basename(filename))[0]
518 name = os.path.splitext(os.path.basename(filename))[0]
519 else:
519 else:
520 name = '__main__'
520 name = '__main__'
521
521
522 main_mod = self.shell.new_main_mod()
522 main_mod = self.shell.new_main_mod()
523 prog_ns = main_mod.__dict__
523 prog_ns = main_mod.__dict__
524 prog_ns['__name__'] = name
524 prog_ns['__name__'] = name
525
525
526 # Since '%run foo' emulates 'python foo.py' at the cmd line, we must
526 # Since '%run foo' emulates 'python foo.py' at the cmd line, we must
527 # set the __file__ global in the script's namespace
527 # set the __file__ global in the script's namespace
528 prog_ns['__file__'] = filename
528 prog_ns['__file__'] = filename
529
529
530 # pickle fix. See interactiveshell for an explanation. But we need to
530 # pickle fix. See interactiveshell for an explanation. But we need to
531 # make sure that, if we overwrite __main__, we replace it at the end
531 # make sure that, if we overwrite __main__, we replace it at the end
532 main_mod_name = prog_ns['__name__']
532 main_mod_name = prog_ns['__name__']
533
533
534 if main_mod_name == '__main__':
534 if main_mod_name == '__main__':
535 restore_main = sys.modules['__main__']
535 restore_main = sys.modules['__main__']
536 else:
536 else:
537 restore_main = False
537 restore_main = False
538
538
539 # This needs to be undone at the end to prevent holding references to
539 # This needs to be undone at the end to prevent holding references to
540 # every single object ever created.
540 # every single object ever created.
541 sys.modules[main_mod_name] = main_mod
541 sys.modules[main_mod_name] = main_mod
542
542
543 try:
543 try:
544 stats = None
544 stats = None
545 with self.shell.readline_no_record:
545 with self.shell.readline_no_record:
546 if 'p' in opts:
546 if 'p' in opts:
547 stats = self.prun('', None, False, opts, arg_lst, prog_ns)
547 stats = self.prun('', None, False, opts, arg_lst, prog_ns)
548 else:
548 else:
549 if 'd' in opts:
549 if 'd' in opts:
550 deb = debugger.Pdb(self.shell.colors)
550 deb = debugger.Pdb(self.shell.colors)
551 # reset Breakpoint state, which is moronically kept
551 # reset Breakpoint state, which is moronically kept
552 # in a class
552 # in a class
553 bdb.Breakpoint.next = 1
553 bdb.Breakpoint.next = 1
554 bdb.Breakpoint.bplist = {}
554 bdb.Breakpoint.bplist = {}
555 bdb.Breakpoint.bpbynumber = [None]
555 bdb.Breakpoint.bpbynumber = [None]
556 # Set an initial breakpoint to stop execution
556 # Set an initial breakpoint to stop execution
557 maxtries = 10
557 maxtries = 10
558 bp = int(opts.get('b', [1])[0])
558 bp = int(opts.get('b', [1])[0])
559 checkline = deb.checkline(filename, bp)
559 checkline = deb.checkline(filename, bp)
560 if not checkline:
560 if not checkline:
561 for bp in range(bp + 1, bp + maxtries + 1):
561 for bp in range(bp + 1, bp + maxtries + 1):
562 if deb.checkline(filename, bp):
562 if deb.checkline(filename, bp):
563 break
563 break
564 else:
564 else:
565 msg = ("\nI failed to find a valid line to set "
565 msg = ("\nI failed to find a valid line to set "
566 "a breakpoint\n"
566 "a breakpoint\n"
567 "after trying up to line: %s.\n"
567 "after trying up to line: %s.\n"
568 "Please set a valid breakpoint manually "
568 "Please set a valid breakpoint manually "
569 "with the -b option." % bp)
569 "with the -b option." % bp)
570 error(msg)
570 error(msg)
571 return
571 return
572 # if we find a good linenumber, set the breakpoint
572 # if we find a good linenumber, set the breakpoint
573 deb.do_break('%s:%s' % (filename, bp))
573 deb.do_break('%s:%s' % (filename, bp))
574 # Start file run
574 # Start file run
575 print "NOTE: Enter 'c' at the",
575 print "NOTE: Enter 'c' at the",
576 print "%s prompt to start your script." % deb.prompt
576 print "%s prompt to start your script." % deb.prompt
577 ns = {'execfile': py3compat.execfile, 'prog_ns': prog_ns}
577 ns = {'execfile': py3compat.execfile, 'prog_ns': prog_ns}
578 try:
578 try:
579 deb.run('execfile("%s", prog_ns)' % filename, ns)
579 deb.run('execfile("%s", prog_ns)' % filename, ns)
580
580
581 except:
581 except:
582 etype, value, tb = sys.exc_info()
582 etype, value, tb = sys.exc_info()
583 # Skip three frames in the traceback: the %run one,
583 # Skip three frames in the traceback: the %run one,
584 # one inside bdb.py, and the command-line typed by the
584 # one inside bdb.py, and the command-line typed by the
585 # user (run by exec in pdb itself).
585 # user (run by exec in pdb itself).
586 self.shell.InteractiveTB(etype, value, tb, tb_offset=3)
586 self.shell.InteractiveTB(etype, value, tb, tb_offset=3)
587 else:
587 else:
588 if runner is None:
588 if runner is None:
589 runner = self.default_runner
589 runner = self.default_runner
590 if runner is None:
590 if runner is None:
591 runner = self.shell.safe_execfile
591 runner = self.shell.safe_execfile
592 if 't' in opts:
592 if 't' in opts:
593 # timed execution
593 # timed execution
594 try:
594 try:
595 nruns = int(opts['N'][0])
595 nruns = int(opts['N'][0])
596 if nruns < 1:
596 if nruns < 1:
597 error('Number of runs must be >=1')
597 error('Number of runs must be >=1')
598 return
598 return
599 except (KeyError):
599 except (KeyError):
600 nruns = 1
600 nruns = 1
601 twall0 = time.time()
601 twall0 = time.time()
602 if nruns == 1:
602 if nruns == 1:
603 t0 = clock2()
603 t0 = clock2()
604 runner(filename, prog_ns, prog_ns,
604 runner(filename, prog_ns, prog_ns,
605 exit_ignore=exit_ignore)
605 exit_ignore=exit_ignore)
606 t1 = clock2()
606 t1 = clock2()
607 t_usr = t1[0] - t0[0]
607 t_usr = t1[0] - t0[0]
608 t_sys = t1[1] - t0[1]
608 t_sys = t1[1] - t0[1]
609 print "\nIPython CPU timings (estimated):"
609 print "\nIPython CPU timings (estimated):"
610 print " User : %10.2f s." % t_usr
610 print " User : %10.2f s." % t_usr
611 print " System : %10.2f s." % t_sys
611 print " System : %10.2f s." % t_sys
612 else:
612 else:
613 runs = range(nruns)
613 runs = range(nruns)
614 t0 = clock2()
614 t0 = clock2()
615 for nr in runs:
615 for nr in runs:
616 runner(filename, prog_ns, prog_ns,
616 runner(filename, prog_ns, prog_ns,
617 exit_ignore=exit_ignore)
617 exit_ignore=exit_ignore)
618 t1 = clock2()
618 t1 = clock2()
619 t_usr = t1[0] - t0[0]
619 t_usr = t1[0] - t0[0]
620 t_sys = t1[1] - t0[1]
620 t_sys = t1[1] - t0[1]
621 print "\nIPython CPU timings (estimated):"
621 print "\nIPython CPU timings (estimated):"
622 print "Total runs performed:", nruns
622 print "Total runs performed:", nruns
623 print " Times : %10.2f %10.2f" % ('Total', 'Per run')
623 print " Times : %10.2f %10.2f" % ('Total', 'Per run')
624 print " User : %10.2f s, %10.2f s." % (t_usr, t_usr / nruns)
624 print " User : %10.2f s, %10.2f s." % (t_usr, t_usr / nruns)
625 print " System : %10.2f s, %10.2f s." % (t_sys, t_sys / nruns)
625 print " System : %10.2f s, %10.2f s." % (t_sys, t_sys / nruns)
626 twall1 = time.time()
626 twall1 = time.time()
627 print "Wall time: %10.2f s." % (twall1 - twall0)
627 print "Wall time: %10.2f s." % (twall1 - twall0)
628
628
629 else:
629 else:
630 # regular execution
630 # regular execution
631 runner(filename, prog_ns, prog_ns, exit_ignore=exit_ignore)
631 runner(filename, prog_ns, prog_ns, exit_ignore=exit_ignore)
632
632
633 if 'i' in opts:
633 if 'i' in opts:
634 self.shell.user_ns['__name__'] = __name__save
634 self.shell.user_ns['__name__'] = __name__save
635 else:
635 else:
636 # The shell MUST hold a reference to prog_ns so after %run
636 # The shell MUST hold a reference to prog_ns so after %run
637 # exits, the python deletion mechanism doesn't zero it out
637 # exits, the python deletion mechanism doesn't zero it out
638 # (leaving dangling references).
638 # (leaving dangling references).
639 self.shell.cache_main_mod(prog_ns, filename)
639 self.shell.cache_main_mod(prog_ns, filename)
640 # update IPython interactive namespace
640 # update IPython interactive namespace
641
641
642 # Some forms of read errors on the file may mean the
642 # Some forms of read errors on the file may mean the
643 # __name__ key was never set; using pop we don't have to
643 # __name__ key was never set; using pop we don't have to
644 # worry about a possible KeyError.
644 # worry about a possible KeyError.
645 prog_ns.pop('__name__', None)
645 prog_ns.pop('__name__', None)
646
646
647 self.shell.user_ns.update(prog_ns)
647 self.shell.user_ns.update(prog_ns)
648 finally:
648 finally:
649 # It's a bit of a mystery why, but __builtins__ can change from
649 # It's a bit of a mystery why, but __builtins__ can change from
650 # being a module to becoming a dict missing some key data after
650 # being a module to becoming a dict missing some key data after
651 # %run. As best I can see, this is NOT something IPython is doing
651 # %run. As best I can see, this is NOT something IPython is doing
652 # at all, and similar problems have been reported before:
652 # at all, and similar problems have been reported before:
653 # http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-10/0188.html
653 # http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-10/0188.html
654 # Since this seems to be done by the interpreter itself, the best
654 # Since this seems to be done by the interpreter itself, the best
655 # we can do is to at least restore __builtins__ for the user on
655 # we can do is to at least restore __builtins__ for the user on
656 # exit.
656 # exit.
657 self.shell.user_ns['__builtins__'] = builtin_mod
657 self.shell.user_ns['__builtins__'] = builtin_mod
658
658
659 # Ensure key global structures are restored
659 # Ensure key global structures are restored
660 sys.argv = save_argv
660 sys.argv = save_argv
661 if restore_main:
661 if restore_main:
662 sys.modules['__main__'] = restore_main
662 sys.modules['__main__'] = restore_main
663 else:
663 else:
664 # Remove from sys.modules the reference to main_mod we'd
664 # Remove from sys.modules the reference to main_mod we'd
665 # added. Otherwise it will trap references to objects
665 # added. Otherwise it will trap references to objects
666 # contained therein.
666 # contained therein.
667 del sys.modules[main_mod_name]
667 del sys.modules[main_mod_name]
668
668
669 return stats
669 return stats
670
670
671 @skip_doctest
671 @skip_doctest
672 @line_cell_magic
672 @line_cell_magic
673 def timeit(self, line='', cell=None):
673 def timeit(self, line='', cell=None):
674 """Time execution of a Python statement or expression
674 """Time execution of a Python statement or expression
675
675
676 Usage, in line mode:
676 Usage, in line mode:
677 %timeit [-n<N> -r<R> [-t|-c]] statement
677 %timeit [-n<N> -r<R> [-t|-c]] statement
678 or in cell mode:
678 or in cell mode:
679 %%timeit [-n<N> -r<R> [-t|-c]] setup_code
679 %%timeit [-n<N> -r<R> [-t|-c]] setup_code
680 code
680 code
681 code...
681 code...
682
682
683 Time execution of a Python statement or expression using the timeit
683 Time execution of a Python statement or expression using the timeit
684 module. This function can be used both as a line and cell magic:
684 module. This function can be used both as a line and cell magic:
685
685
686 - In line mode you can time a single-line statement (though multiple
686 - In line mode you can time a single-line statement (though multiple
687 ones can be chained with using semicolons).
687 ones can be chained with using semicolons).
688
688
689 - In cell mode, the statement in the first line is used as setup code
689 - In cell mode, the statement in the first line is used as setup code
690 (executed but not timed) and the body of the cell is timed. The cell
690 (executed but not timed) and the body of the cell is timed. The cell
691 body has access to any variables created in the setup code.
691 body has access to any variables created in the setup code.
692
692
693 Options:
693 Options:
694 -n<N>: execute the given statement <N> times in a loop. If this value
694 -n<N>: execute the given statement <N> times in a loop. If this value
695 is not given, a fitting value is chosen.
695 is not given, a fitting value is chosen.
696
696
697 -r<R>: repeat the loop iteration <R> times and take the best result.
697 -r<R>: repeat the loop iteration <R> times and take the best result.
698 Default: 3
698 Default: 3
699
699
700 -t: use time.time to measure the time, which is the default on Unix.
700 -t: use time.time to measure the time, which is the default on Unix.
701 This function measures wall time.
701 This function measures wall time.
702
702
703 -c: use time.clock to measure the time, which is the default on
703 -c: use time.clock to measure the time, which is the default on
704 Windows and measures wall time. On Unix, resource.getrusage is used
704 Windows and measures wall time. On Unix, resource.getrusage is used
705 instead and returns the CPU user time.
705 instead and returns the CPU user time.
706
706
707 -p<P>: use a precision of <P> digits to display the timing result.
707 -p<P>: use a precision of <P> digits to display the timing result.
708 Default: 3
708 Default: 3
709
709
710
710
711 Examples
711 Examples
712 --------
712 --------
713 ::
713 ::
714
714
715 In [1]: %timeit pass
715 In [1]: %timeit pass
716 10000000 loops, best of 3: 53.3 ns per loop
716 10000000 loops, best of 3: 53.3 ns per loop
717
717
718 In [2]: u = None
718 In [2]: u = None
719
719
720 In [3]: %timeit u is None
720 In [3]: %timeit u is None
721 10000000 loops, best of 3: 184 ns per loop
721 10000000 loops, best of 3: 184 ns per loop
722
722
723 In [4]: %timeit -r 4 u == None
723 In [4]: %timeit -r 4 u == None
724 1000000 loops, best of 4: 242 ns per loop
724 1000000 loops, best of 4: 242 ns per loop
725
725
726 In [5]: import time
726 In [5]: import time
727
727
728 In [6]: %timeit -n1 time.sleep(2)
728 In [6]: %timeit -n1 time.sleep(2)
729 1 loops, best of 3: 2 s per loop
729 1 loops, best of 3: 2 s per loop
730
730
731
731
732 The times reported by %timeit will be slightly higher than those
732 The times reported by %timeit will be slightly higher than those
733 reported by the timeit.py script when variables are accessed. This is
733 reported by the timeit.py script when variables are accessed. This is
734 due to the fact that %timeit executes the statement in the namespace
734 due to the fact that %timeit executes the statement in the namespace
735 of the shell, compared with timeit.py, which uses a single setup
735 of the shell, compared with timeit.py, which uses a single setup
736 statement to import function or create variables. Generally, the bias
736 statement to import function or create variables. Generally, the bias
737 does not matter as long as results from timeit.py are not mixed with
737 does not matter as long as results from timeit.py are not mixed with
738 those from %timeit."""
738 those from %timeit."""
739
739
740 import timeit
740 import timeit
741 import math
741 import math
742
742
743 # XXX: Unfortunately the unicode 'micro' symbol can cause problems in
743 # XXX: Unfortunately the unicode 'micro' symbol can cause problems in
744 # certain terminals. Until we figure out a robust way of
744 # certain terminals. Until we figure out a robust way of
745 # auto-detecting if the terminal can deal with it, use plain 'us' for
745 # auto-detecting if the terminal can deal with it, use plain 'us' for
746 # microseconds. I am really NOT happy about disabling the proper
746 # microseconds. I am really NOT happy about disabling the proper
747 # 'micro' prefix, but crashing is worse... If anyone knows what the
747 # 'micro' prefix, but crashing is worse... If anyone knows what the
748 # right solution for this is, I'm all ears...
748 # right solution for this is, I'm all ears...
749 #
749 #
750 # Note: using
750 # Note: using
751 #
751 #
752 # s = u'\xb5'
752 # s = u'\xb5'
753 # s.encode(sys.getdefaultencoding())
753 # s.encode(sys.getdefaultencoding())
754 #
754 #
755 # is not sufficient, as I've seen terminals where that fails but
755 # is not sufficient, as I've seen terminals where that fails but
756 # print s
756 # print s
757 #
757 #
758 # succeeds
758 # succeeds
759 #
759 #
760 # See bug: https://bugs.launchpad.net/ipython/+bug/348466
760 # See bug: https://bugs.launchpad.net/ipython/+bug/348466
761
761
762 #units = [u"s", u"ms",u'\xb5',"ns"]
762 #units = [u"s", u"ms",u'\xb5',"ns"]
763 units = [u"s", u"ms",u'us',"ns"]
763 units = [u"s", u"ms",u'us',"ns"]
764
764
765 scaling = [1, 1e3, 1e6, 1e9]
765 scaling = [1, 1e3, 1e6, 1e9]
766
766
767 opts, stmt = self.parse_options(line,'n:r:tcp:',
767 opts, stmt = self.parse_options(line,'n:r:tcp:',
768 posix=False, strict=False)
768 posix=False, strict=False)
769 if stmt == "" and cell is None:
769 if stmt == "" and cell is None:
770 return
770 return
771 timefunc = timeit.default_timer
771 timefunc = timeit.default_timer
772 number = int(getattr(opts, "n", 0))
772 number = int(getattr(opts, "n", 0))
773 repeat = int(getattr(opts, "r", timeit.default_repeat))
773 repeat = int(getattr(opts, "r", timeit.default_repeat))
774 precision = int(getattr(opts, "p", 3))
774 precision = int(getattr(opts, "p", 3))
775 if hasattr(opts, "t"):
775 if hasattr(opts, "t"):
776 timefunc = time.time
776 timefunc = time.time
777 if hasattr(opts, "c"):
777 if hasattr(opts, "c"):
778 timefunc = clock
778 timefunc = clock
779
779
780 timer = timeit.Timer(timer=timefunc)
780 timer = timeit.Timer(timer=timefunc)
781 # this code has tight coupling to the inner workings of timeit.Timer,
781 # this code has tight coupling to the inner workings of timeit.Timer,
782 # but is there a better way to achieve that the code stmt has access
782 # but is there a better way to achieve that the code stmt has access
783 # to the shell namespace?
783 # to the shell namespace?
784 transform = self.shell.input_splitter.transform_cell
784 transform = self.shell.input_splitter.transform_cell
785 if cell is None:
785 if cell is None:
786 # called as line magic
786 # called as line magic
787 setup = 'pass'
787 setup = 'pass'
788 stmt = timeit.reindent(transform(stmt), 8)
788 stmt = timeit.reindent(transform(stmt), 8)
789 else:
789 else:
790 setup = timeit.reindent(transform(stmt), 4)
790 setup = timeit.reindent(transform(stmt), 4)
791 stmt = timeit.reindent(transform(cell), 8)
791 stmt = timeit.reindent(transform(cell), 8)
792
792
793 # From Python 3.3, this template uses new-style string formatting.
793 # From Python 3.3, this template uses new-style string formatting.
794 if sys.version_info >= (3, 3):
794 if sys.version_info >= (3, 3):
795 src = timeit.template.format(stmt=stmt, setup=setup)
795 src = timeit.template.format(stmt=stmt, setup=setup)
796 else:
796 else:
797 src = timeit.template % dict(stmt=stmt, setup=setup)
797 src = timeit.template % dict(stmt=stmt, setup=setup)
798
798
799 # Track compilation time so it can be reported if too long
799 # Track compilation time so it can be reported if too long
800 # Minimum time above which compilation time will be reported
800 # Minimum time above which compilation time will be reported
801 tc_min = 0.1
801 tc_min = 0.1
802
802
803 t0 = clock()
803 t0 = clock()
804 code = compile(src, "<magic-timeit>", "exec")
804 code = compile(src, "<magic-timeit>", "exec")
805 tc = clock()-t0
805 tc = clock()-t0
806
806
807 ns = {}
807 ns = {}
808 exec code in self.shell.user_ns, ns
808 exec code in self.shell.user_ns, ns
809 timer.inner = ns["inner"]
809 timer.inner = ns["inner"]
810
810
811 if number == 0:
811 if number == 0:
812 # determine number so that 0.2 <= total time < 2.0
812 # determine number so that 0.2 <= total time < 2.0
813 number = 1
813 number = 1
814 for i in range(1, 10):
814 for i in range(1, 10):
815 if timer.timeit(number) >= 0.2:
815 if timer.timeit(number) >= 0.2:
816 break
816 break
817 number *= 10
817 number *= 10
818
818
819 best = min(timer.repeat(repeat, number)) / number
819 best = min(timer.repeat(repeat, number)) / number
820
820
821 if best > 0.0 and best < 1000.0:
821 if best > 0.0 and best < 1000.0:
822 order = min(-int(math.floor(math.log10(best)) // 3), 3)
822 order = min(-int(math.floor(math.log10(best)) // 3), 3)
823 elif best >= 1000.0:
823 elif best >= 1000.0:
824 order = 0
824 order = 0
825 else:
825 else:
826 order = 3
826 order = 3
827 print u"%d loops, best of %d: %.*g %s per loop" % (number, repeat,
827 print u"%d loops, best of %d: %.*g %s per loop" % (number, repeat,
828 precision,
828 precision,
829 best * scaling[order],
829 best * scaling[order],
830 units[order])
830 units[order])
831 if tc > tc_min:
831 if tc > tc_min:
832 print "Compiler time: %.2f s" % tc
832 print "Compiler time: %.2f s" % tc
833
833
834 @skip_doctest
834 @skip_doctest
835 @needs_local_scope
835 @needs_local_scope
836 @line_magic
836 @line_magic
837 def time(self,parameter_s, user_locals):
837 def time(self,parameter_s, user_locals):
838 """Time execution of a Python statement or expression.
838 """Time execution of a Python statement or expression.
839
839
840 The CPU and wall clock times are printed, and the value of the
840 The CPU and wall clock times are printed, and the value of the
841 expression (if any) is returned. Note that under Win32, system time
841 expression (if any) is returned. Note that under Win32, system time
842 is always reported as 0, since it can not be measured.
842 is always reported as 0, since it can not be measured.
843
843
844 This function provides very basic timing functionality. In Python
844 This function provides very basic timing functionality. In Python
845 2.3, the timeit module offers more control and sophistication, so this
845 2.3, the timeit module offers more control and sophistication, so this
846 could be rewritten to use it (patches welcome).
846 could be rewritten to use it (patches welcome).
847
847
848 Examples
848 Examples
849 --------
849 --------
850 ::
850 ::
851
851
852 In [1]: time 2**128
852 In [1]: time 2**128
853 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
853 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
854 Wall time: 0.00
854 Wall time: 0.00
855 Out[1]: 340282366920938463463374607431768211456L
855 Out[1]: 340282366920938463463374607431768211456L
856
856
857 In [2]: n = 1000000
857 In [2]: n = 1000000
858
858
859 In [3]: time sum(range(n))
859 In [3]: time sum(range(n))
860 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
860 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
861 Wall time: 1.37
861 Wall time: 1.37
862 Out[3]: 499999500000L
862 Out[3]: 499999500000L
863
863
864 In [4]: time print 'hello world'
864 In [4]: time print 'hello world'
865 hello world
865 hello world
866 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
866 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
867 Wall time: 0.00
867 Wall time: 0.00
868
868
869 Note that the time needed by Python to compile the given expression
869 Note that the time needed by Python to compile the given expression
870 will be reported if it is more than 0.1s. In this example, the
870 will be reported if it is more than 0.1s. In this example, the
871 actual exponentiation is done by Python at compilation time, so while
871 actual exponentiation is done by Python at compilation time, so while
872 the expression can take a noticeable amount of time to compute, that
872 the expression can take a noticeable amount of time to compute, that
873 time is purely due to the compilation:
873 time is purely due to the compilation:
874
874
875 In [5]: time 3**9999;
875 In [5]: time 3**9999;
876 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
876 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
877 Wall time: 0.00 s
877 Wall time: 0.00 s
878
878
879 In [6]: time 3**999999;
879 In [6]: time 3**999999;
880 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
880 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
881 Wall time: 0.00 s
881 Wall time: 0.00 s
882 Compiler : 0.78 s
882 Compiler : 0.78 s
883 """
883 """
884
884
885 # fail immediately if the given expression can't be compiled
885 # fail immediately if the given expression can't be compiled
886
886
887 expr = self.shell.prefilter(parameter_s,False)
887 expr = self.shell.prefilter(parameter_s,False)
888
888
889 # Minimum time above which compilation time will be reported
889 # Minimum time above which compilation time will be reported
890 tc_min = 0.1
890 tc_min = 0.1
891
891
892 try:
892 try:
893 mode = 'eval'
893 mode = 'eval'
894 t0 = clock()
894 t0 = clock()
895 code = compile(expr,'<timed eval>',mode)
895 code = compile(expr,'<timed eval>',mode)
896 tc = clock()-t0
896 tc = clock()-t0
897 except SyntaxError:
897 except SyntaxError:
898 mode = 'exec'
898 mode = 'exec'
899 t0 = clock()
899 t0 = clock()
900 code = compile(expr,'<timed exec>',mode)
900 code = compile(expr,'<timed exec>',mode)
901 tc = clock()-t0
901 tc = clock()-t0
902 # skew measurement as little as possible
902 # skew measurement as little as possible
903 glob = self.shell.user_ns
903 glob = self.shell.user_ns
904 wtime = time.time
904 wtime = time.time
905 # time execution
905 # time execution
906 wall_st = wtime()
906 wall_st = wtime()
907 if mode=='eval':
907 if mode=='eval':
908 st = clock2()
908 st = clock2()
909 out = eval(code, glob, user_locals)
909 out = eval(code, glob, user_locals)
910 end = clock2()
910 end = clock2()
911 else:
911 else:
912 st = clock2()
912 st = clock2()
913 exec code in glob, user_locals
913 exec code in glob, user_locals
914 end = clock2()
914 end = clock2()
915 out = None
915 out = None
916 wall_end = wtime()
916 wall_end = wtime()
917 # Compute actual times and report
917 # Compute actual times and report
918 wall_time = wall_end-wall_st
918 wall_time = wall_end-wall_st
919 cpu_user = end[0]-st[0]
919 cpu_user = end[0]-st[0]
920 cpu_sys = end[1]-st[1]
920 cpu_sys = end[1]-st[1]
921 cpu_tot = cpu_user+cpu_sys
921 cpu_tot = cpu_user+cpu_sys
922 print "CPU times: user %.2f s, sys: %.2f s, total: %.2f s" % \
922 print "CPU times: user %.2f s, sys: %.2f s, total: %.2f s" % \
923 (cpu_user,cpu_sys,cpu_tot)
923 (cpu_user,cpu_sys,cpu_tot)
924 print "Wall time: %.2f s" % wall_time
924 print "Wall time: %.2f s" % wall_time
925 if tc > tc_min:
925 if tc > tc_min:
926 print "Compiler : %.2f s" % tc
926 print "Compiler : %.2f s" % tc
927 return out
927 return out
928
928
929 @skip_doctest
929 @skip_doctest
930 @line_magic
930 @line_magic
931 def macro(self, parameter_s=''):
931 def macro(self, parameter_s=''):
932 """Define a macro for future re-execution. It accepts ranges of history,
932 """Define a macro for future re-execution. It accepts ranges of history,
933 filenames or string objects.
933 filenames or string objects.
934
934
935 Usage:\\
935 Usage:\\
936 %macro [options] name n1-n2 n3-n4 ... n5 .. n6 ...
936 %macro [options] name n1-n2 n3-n4 ... n5 .. n6 ...
937
937
938 Options:
938 Options:
939
939
940 -r: use 'raw' input. By default, the 'processed' history is used,
940 -r: use 'raw' input. By default, the 'processed' history is used,
941 so that magics are loaded in their transformed version to valid
941 so that magics are loaded in their transformed version to valid
942 Python. If this option is given, the raw input as typed as the
942 Python. If this option is given, the raw input as typed as the
943 command line is used instead.
943 command line is used instead.
944
944
945 This will define a global variable called `name` which is a string
945 This will define a global variable called `name` which is a string
946 made of joining the slices and lines you specify (n1,n2,... numbers
946 made of joining the slices and lines you specify (n1,n2,... numbers
947 above) from your input history into a single string. This variable
947 above) from your input history into a single string. This variable
948 acts like an automatic function which re-executes those lines as if
948 acts like an automatic function which re-executes those lines as if
949 you had typed them. You just type 'name' at the prompt and the code
949 you had typed them. You just type 'name' at the prompt and the code
950 executes.
950 executes.
951
951
952 The syntax for indicating input ranges is described in %history.
952 The syntax for indicating input ranges is described in %history.
953
953
954 Note: as a 'hidden' feature, you can also use traditional python slice
954 Note: as a 'hidden' feature, you can also use traditional python slice
955 notation, where N:M means numbers N through M-1.
955 notation, where N:M means numbers N through M-1.
956
956
957 For example, if your history contains (%hist prints it)::
957 For example, if your history contains (%hist prints it)::
958
958
959 44: x=1
959 44: x=1
960 45: y=3
960 45: y=3
961 46: z=x+y
961 46: z=x+y
962 47: print x
962 47: print x
963 48: a=5
963 48: a=5
964 49: print 'x',x,'y',y
964 49: print 'x',x,'y',y
965
965
966 you can create a macro with lines 44 through 47 (included) and line 49
966 you can create a macro with lines 44 through 47 (included) and line 49
967 called my_macro with::
967 called my_macro with::
968
968
969 In [55]: %macro my_macro 44-47 49
969 In [55]: %macro my_macro 44-47 49
970
970
971 Now, typing `my_macro` (without quotes) will re-execute all this code
971 Now, typing `my_macro` (without quotes) will re-execute all this code
972 in one pass.
972 in one pass.
973
973
974 You don't need to give the line-numbers in order, and any given line
974 You don't need to give the line-numbers in order, and any given line
975 number can appear multiple times. You can assemble macros with any
975 number can appear multiple times. You can assemble macros with any
976 lines from your input history in any order.
976 lines from your input history in any order.
977
977
978 The macro is a simple object which holds its value in an attribute,
978 The macro is a simple object which holds its value in an attribute,
979 but IPython's display system checks for macros and executes them as
979 but IPython's display system checks for macros and executes them as
980 code instead of printing them when you type their name.
980 code instead of printing them when you type their name.
981
981
982 You can view a macro's contents by explicitly printing it with::
982 You can view a macro's contents by explicitly printing it with::
983
983
984 print macro_name
984 print macro_name
985
985
986 """
986 """
987 opts,args = self.parse_options(parameter_s,'r',mode='list')
987 opts,args = self.parse_options(parameter_s,'r',mode='list')
988 if not args: # List existing macros
988 if not args: # List existing macros
989 return sorted(k for k,v in self.shell.user_ns.iteritems() if\
989 return sorted(k for k,v in self.shell.user_ns.iteritems() if\
990 isinstance(v, Macro))
990 isinstance(v, Macro))
991 if len(args) == 1:
991 if len(args) == 1:
992 raise UsageError(
992 raise UsageError(
993 "%macro insufficient args; usage '%macro name n1-n2 n3-4...")
993 "%macro insufficient args; usage '%macro name n1-n2 n3-4...")
994 name, codefrom = args[0], " ".join(args[1:])
994 name, codefrom = args[0], " ".join(args[1:])
995
995
996 #print 'rng',ranges # dbg
996 #print 'rng',ranges # dbg
997 try:
997 try:
998 lines = self.shell.find_user_code(codefrom, 'r' in opts)
998 lines = self.shell.find_user_code(codefrom, 'r' in opts)
999 except (ValueError, TypeError) as e:
999 except (ValueError, TypeError) as e:
1000 print e.args[0]
1000 print e.args[0]
1001 return
1001 return
1002 macro = Macro(lines)
1002 macro = Macro(lines)
1003 self.shell.define_macro(name, macro)
1003 self.shell.define_macro(name, macro)
1004 print 'Macro `%s` created. To execute, type its name (without quotes).' % name
1004 print 'Macro `%s` created. To execute, type its name (without quotes).' % name
1005 print '=== Macro contents: ==='
1005 print '=== Macro contents: ==='
1006 print macro,
1006 print macro,
1007
1007
1008 @magic_arguments.magic_arguments()
1008 @magic_arguments.magic_arguments()
1009 @magic_arguments.argument('output', type=str, default='', nargs='?',
1009 @magic_arguments.argument('output', type=str, default='', nargs='?',
1010 help="""The name of the variable in which to store output.
1010 help="""The name of the variable in which to store output.
1011 This is a utils.io.CapturedIO object with stdout/err attributes
1011 This is a utils.io.CapturedIO object with stdout/err attributes
1012 for the text of the captured output.
1012 for the text of the captured output.
1013
1013
1014 CapturedOutput also has a show() method for displaying the output,
1014 CapturedOutput also has a show() method for displaying the output,
1015 and __call__ as well, so you can use that to quickly display the
1015 and __call__ as well, so you can use that to quickly display the
1016 output.
1016 output.
1017
1017
1018 If unspecified, captured output is discarded.
1018 If unspecified, captured output is discarded.
1019 """
1019 """
1020 )
1020 )
1021 @magic_arguments.argument('--no-stderr', action="store_true",
1021 @magic_arguments.argument('--no-stderr', action="store_true",
1022 help="""Don't capture stderr."""
1022 help="""Don't capture stderr."""
1023 )
1023 )
1024 @magic_arguments.argument('--no-stdout', action="store_true",
1024 @magic_arguments.argument('--no-stdout', action="store_true",
1025 help="""Don't capture stdout."""
1025 help="""Don't capture stdout."""
1026 )
1026 )
1027 @cell_magic
1027 @cell_magic
1028 def capture(self, line, cell):
1028 def capture(self, line, cell):
1029 """run the cell, capturing stdout/err"""
1029 """run the cell, capturing stdout/err"""
1030 args = magic_arguments.parse_argstring(self.capture, line)
1030 args = magic_arguments.parse_argstring(self.capture, line)
1031 out = not args.no_stdout
1031 out = not args.no_stdout
1032 err = not args.no_stderr
1032 err = not args.no_stderr
1033 with capture_output(out, err) as io:
1033 with capture_output(out, err) as io:
1034 self.shell.run_cell(cell)
1034 self.shell.run_cell(cell)
1035 if args.output:
1035 if args.output:
1036 self.shell.user_ns[args.output] = io
1036 self.shell.user_ns[args.output] = io
@@ -1,482 +1,482 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 Utilities for path handling.
3 Utilities for path handling.
4 """
4 """
5
5
6 #-----------------------------------------------------------------------------
6 #-----------------------------------------------------------------------------
7 # Copyright (C) 2008-2011 The IPython Development Team
7 # Copyright (C) 2008-2011 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 sys
18 import sys
19 import tempfile
19 import tempfile
20 import warnings
20 import warnings
21 from hashlib import md5
21 from hashlib import md5
22 import glob
22 import glob
23
23
24 import IPython
24 import IPython
25 from IPython.testing.skipdoctest import skip_doctest
25 from IPython.testing.skipdoctest import skip_doctest
26 from IPython.utils.process import system
26 from IPython.utils.process import system
27 from IPython.utils.importstring import import_item
27 from IPython.utils.importstring import import_item
28 from IPython.utils import py3compat
28 from IPython.utils import py3compat
29 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
30 # Code
30 # Code
31 #-----------------------------------------------------------------------------
31 #-----------------------------------------------------------------------------
32
32
33 fs_encoding = sys.getfilesystemencoding()
33 fs_encoding = sys.getfilesystemencoding()
34
34
35 def _get_long_path_name(path):
35 def _get_long_path_name(path):
36 """Dummy no-op."""
36 """Dummy no-op."""
37 return path
37 return path
38
38
39 def _writable_dir(path):
39 def _writable_dir(path):
40 """Whether `path` is a directory, to which the user has write access."""
40 """Whether `path` is a directory, to which the user has write access."""
41 return os.path.isdir(path) and os.access(path, os.W_OK)
41 return os.path.isdir(path) and os.access(path, os.W_OK)
42
42
43 if sys.platform == 'win32':
43 if sys.platform == 'win32':
44 @skip_doctest
44 @skip_doctest
45 def _get_long_path_name(path):
45 def _get_long_path_name(path):
46 """Get a long path name (expand ~) on Windows using ctypes.
46 """Get a long path name (expand ~) on Windows using ctypes.
47
47
48 Examples
48 Examples
49 --------
49 --------
50
50
51 >>> get_long_path_name('c:\\docume~1')
51 >>> get_long_path_name('c:\\docume~1')
52 u'c:\\\\Documents and Settings'
52 u'c:\\\\Documents and Settings'
53
53
54 """
54 """
55 try:
55 try:
56 import ctypes
56 import ctypes
57 except ImportError:
57 except ImportError:
58 raise ImportError('you need to have ctypes installed for this to work')
58 raise ImportError('you need to have ctypes installed for this to work')
59 _GetLongPathName = ctypes.windll.kernel32.GetLongPathNameW
59 _GetLongPathName = ctypes.windll.kernel32.GetLongPathNameW
60 _GetLongPathName.argtypes = [ctypes.c_wchar_p, ctypes.c_wchar_p,
60 _GetLongPathName.argtypes = [ctypes.c_wchar_p, ctypes.c_wchar_p,
61 ctypes.c_uint ]
61 ctypes.c_uint ]
62
62
63 buf = ctypes.create_unicode_buffer(260)
63 buf = ctypes.create_unicode_buffer(260)
64 rv = _GetLongPathName(path, buf, 260)
64 rv = _GetLongPathName(path, buf, 260)
65 if rv == 0 or rv > 260:
65 if rv == 0 or rv > 260:
66 return path
66 return path
67 else:
67 else:
68 return buf.value
68 return buf.value
69
69
70
70
71 def get_long_path_name(path):
71 def get_long_path_name(path):
72 """Expand a path into its long form.
72 """Expand a path into its long form.
73
73
74 On Windows this expands any ~ in the paths. On other platforms, it is
74 On Windows this expands any ~ in the paths. On other platforms, it is
75 a null operation.
75 a null operation.
76 """
76 """
77 return _get_long_path_name(path)
77 return _get_long_path_name(path)
78
78
79
79
80 def unquote_filename(name, win32=(sys.platform=='win32')):
80 def unquote_filename(name, win32=(sys.platform=='win32')):
81 """ On Windows, remove leading and trailing quotes from filenames.
81 """ On Windows, remove leading and trailing quotes from filenames.
82 """
82 """
83 if win32:
83 if win32:
84 if name.startswith(("'", '"')) and name.endswith(("'", '"')):
84 if name.startswith(("'", '"')) and name.endswith(("'", '"')):
85 name = name[1:-1]
85 name = name[1:-1]
86 return name
86 return name
87
87
88
88
89 def get_py_filename(name, force_win32=None):
89 def get_py_filename(name, force_win32=None):
90 """Return a valid python filename in the current directory.
90 """Return a valid python filename in the current directory.
91
91
92 If the given name is not a file, it adds '.py' and searches again.
92 If the given name is not a file, it adds '.py' and searches again.
93 Raises IOError with an informative message if the file isn't found.
93 Raises IOError with an informative message if the file isn't found.
94
94
95 On Windows, apply Windows semantics to the filename. In particular, remove
95 On Windows, apply Windows semantics to the filename. In particular, remove
96 any quoting that has been applied to it. This option can be forced for
96 any quoting that has been applied to it. This option can be forced for
97 testing purposes.
97 testing purposes.
98 """
98 """
99
99
100 name = os.path.expanduser(name)
100 name = os.path.expanduser(name)
101 if force_win32 is None:
101 if force_win32 is None:
102 win32 = (sys.platform == 'win32')
102 win32 = (sys.platform == 'win32')
103 else:
103 else:
104 win32 = force_win32
104 win32 = force_win32
105 name = unquote_filename(name, win32=win32)
105 name = unquote_filename(name, win32=win32)
106 if not os.path.isfile(name) and not name.endswith('.py'):
106 if not os.path.isfile(name) and not name.endswith('.py'):
107 name += '.py'
107 name += '.py'
108 if os.path.isfile(name):
108 if os.path.isfile(name):
109 return name
109 return name
110 else:
110 else:
111 raise IOError('File `%r` not found.' % name)
111 raise IOError('File `%r` not found.' % name)
112
112
113
113
114 def filefind(filename, path_dirs=None):
114 def filefind(filename, path_dirs=None):
115 """Find a file by looking through a sequence of paths.
115 """Find a file by looking through a sequence of paths.
116
116
117 This iterates through a sequence of paths looking for a file and returns
117 This iterates through a sequence of paths looking for a file and returns
118 the full, absolute path of the first occurence of the file. If no set of
118 the full, absolute path of the first occurence of the file. If no set of
119 path dirs is given, the filename is tested as is, after running through
119 path dirs is given, the filename is tested as is, after running through
120 :func:`expandvars` and :func:`expanduser`. Thus a simple call::
120 :func:`expandvars` and :func:`expanduser`. Thus a simple call::
121
121
122 filefind('myfile.txt')
122 filefind('myfile.txt')
123
123
124 will find the file in the current working dir, but::
124 will find the file in the current working dir, but::
125
125
126 filefind('~/myfile.txt')
126 filefind('~/myfile.txt')
127
127
128 Will find the file in the users home directory. This function does not
128 Will find the file in the users home directory. This function does not
129 automatically try any paths, such as the cwd or the user's home directory.
129 automatically try any paths, such as the cwd or the user's home directory.
130
130
131 Parameters
131 Parameters
132 ----------
132 ----------
133 filename : str
133 filename : str
134 The filename to look for.
134 The filename to look for.
135 path_dirs : str, None or sequence of str
135 path_dirs : str, None or sequence of str
136 The sequence of paths to look for the file in. If None, the filename
136 The sequence of paths to look for the file in. If None, the filename
137 need to be absolute or be in the cwd. If a string, the string is
137 need to be absolute or be in the cwd. If a string, the string is
138 put into a sequence and the searched. If a sequence, walk through
138 put into a sequence and the searched. If a sequence, walk through
139 each element and join with ``filename``, calling :func:`expandvars`
139 each element and join with ``filename``, calling :func:`expandvars`
140 and :func:`expanduser` before testing for existence.
140 and :func:`expanduser` before testing for existence.
141
141
142 Returns
142 Returns
143 -------
143 -------
144 Raises :exc:`IOError` or returns absolute path to file.
144 Raises :exc:`IOError` or returns absolute path to file.
145 """
145 """
146
146
147 # If paths are quoted, abspath gets confused, strip them...
147 # If paths are quoted, abspath gets confused, strip them...
148 filename = filename.strip('"').strip("'")
148 filename = filename.strip('"').strip("'")
149 # If the input is an absolute path, just check it exists
149 # If the input is an absolute path, just check it exists
150 if os.path.isabs(filename) and os.path.isfile(filename):
150 if os.path.isabs(filename) and os.path.isfile(filename):
151 return filename
151 return filename
152
152
153 if path_dirs is None:
153 if path_dirs is None:
154 path_dirs = ("",)
154 path_dirs = ("",)
155 elif isinstance(path_dirs, basestring):
155 elif isinstance(path_dirs, basestring):
156 path_dirs = (path_dirs,)
156 path_dirs = (path_dirs,)
157
157
158 for path in path_dirs:
158 for path in path_dirs:
159 if path == '.': path = os.getcwdu()
159 if path == '.': path = os.getcwdu()
160 testname = expand_path(os.path.join(path, filename))
160 testname = expand_path(os.path.join(path, filename))
161 if os.path.isfile(testname):
161 if os.path.isfile(testname):
162 return os.path.abspath(testname)
162 return os.path.abspath(testname)
163
163
164 raise IOError("File %r does not exist in any of the search paths: %r" %
164 raise IOError("File %r does not exist in any of the search paths: %r" %
165 (filename, path_dirs) )
165 (filename, path_dirs) )
166
166
167
167
168 class HomeDirError(Exception):
168 class HomeDirError(Exception):
169 pass
169 pass
170
170
171
171
172 def get_home_dir(require_writable=False):
172 def get_home_dir(require_writable=False):
173 """Return the 'home' directory, as a unicode string.
173 """Return the 'home' directory, as a unicode string.
174
174
175 * First, check for frozen env in case of py2exe
175 * First, check for frozen env in case of py2exe
176 * Otherwise, defer to os.path.expanduser('~')
176 * Otherwise, defer to os.path.expanduser('~')
177
177
178 See stdlib docs for how this is determined.
178 See stdlib docs for how this is determined.
179 $HOME is first priority on *ALL* platforms.
179 $HOME is first priority on *ALL* platforms.
180
180
181 Parameters
181 Parameters
182 ----------
182 ----------
183
183
184 require_writable : bool [default: False]
184 require_writable : bool [default: False]
185 if True:
185 if True:
186 guarantees the return value is a writable directory, otherwise
186 guarantees the return value is a writable directory, otherwise
187 raises HomeDirError
187 raises HomeDirError
188 if False:
188 if False:
189 The path is resolved, but it is not guaranteed to exist or be writable.
189 The path is resolved, but it is not guaranteed to exist or be writable.
190 """
190 """
191
191
192 # first, check py2exe distribution root directory for _ipython.
192 # first, check py2exe distribution root directory for _ipython.
193 # This overrides all. Normally does not exist.
193 # This overrides all. Normally does not exist.
194
194
195 if hasattr(sys, "frozen"): #Is frozen by py2exe
195 if hasattr(sys, "frozen"): #Is frozen by py2exe
196 if '\\library.zip\\' in IPython.__file__.lower():#libraries compressed to zip-file
196 if '\\library.zip\\' in IPython.__file__.lower():#libraries compressed to zip-file
197 root, rest = IPython.__file__.lower().split('library.zip')
197 root, rest = IPython.__file__.lower().split('library.zip')
198 else:
198 else:
199 root=os.path.join(os.path.split(IPython.__file__)[0],"../../")
199 root=os.path.join(os.path.split(IPython.__file__)[0],"../../")
200 root=os.path.abspath(root).rstrip('\\')
200 root=os.path.abspath(root).rstrip('\\')
201 if _writable_dir(os.path.join(root, '_ipython')):
201 if _writable_dir(os.path.join(root, '_ipython')):
202 os.environ["IPYKITROOT"] = root
202 os.environ["IPYKITROOT"] = root
203 return py3compat.cast_unicode(root, fs_encoding)
203 return py3compat.cast_unicode(root, fs_encoding)
204
204
205 homedir = os.path.expanduser('~')
205 homedir = os.path.expanduser('~')
206 # Next line will make things work even when /home/ is a symlink to
206 # Next line will make things work even when /home/ is a symlink to
207 # /usr/home as it is on FreeBSD, for example
207 # /usr/home as it is on FreeBSD, for example
208 homedir = os.path.realpath(homedir)
208 homedir = os.path.realpath(homedir)
209
209
210 if not _writable_dir(homedir) and os.name == 'nt':
210 if not _writable_dir(homedir) and os.name == 'nt':
211 # expanduser failed, use the registry to get the 'My Documents' folder.
211 # expanduser failed, use the registry to get the 'My Documents' folder.
212 try:
212 try:
213 import _winreg as wreg
213 import _winreg as wreg
214 key = wreg.OpenKey(
214 key = wreg.OpenKey(
215 wreg.HKEY_CURRENT_USER,
215 wreg.HKEY_CURRENT_USER,
216 "Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
216 "Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
217 )
217 )
218 homedir = wreg.QueryValueEx(key,'Personal')[0]
218 homedir = wreg.QueryValueEx(key,'Personal')[0]
219 key.Close()
219 key.Close()
220 except:
220 except:
221 pass
221 pass
222
222
223 if (not require_writable) or _writable_dir(homedir):
223 if (not require_writable) or _writable_dir(homedir):
224 return py3compat.cast_unicode(homedir, fs_encoding)
224 return py3compat.cast_unicode(homedir, fs_encoding)
225 else:
225 else:
226 raise HomeDirError('%s is not a writable dir, '
226 raise HomeDirError('%s is not a writable dir, '
227 'set $HOME environment variable to override' % homedir)
227 'set $HOME environment variable to override' % homedir)
228
228
229 def get_xdg_dir():
229 def get_xdg_dir():
230 """Return the XDG_CONFIG_HOME, if it is defined and exists, else None.
230 """Return the XDG_CONFIG_HOME, if it is defined and exists, else None.
231
231
232 This is only for non-OS X posix (Linux,Unix,etc.) systems.
232 This is only for non-OS X posix (Linux,Unix,etc.) systems.
233 """
233 """
234
234
235 env = os.environ
235 env = os.environ
236
236
237 if os.name == 'posix' and sys.platform != 'darwin':
237 if os.name == 'posix' and sys.platform != 'darwin':
238 # Linux, Unix, AIX, etc.
238 # Linux, Unix, AIX, etc.
239 # use ~/.config if empty OR not set
239 # use ~/.config if empty OR not set
240 xdg = env.get("XDG_CONFIG_HOME", None) or os.path.join(get_home_dir(), '.config')
240 xdg = env.get("XDG_CONFIG_HOME", None) or os.path.join(get_home_dir(), '.config')
241 if xdg and _writable_dir(xdg):
241 if xdg and _writable_dir(xdg):
242 return py3compat.cast_unicode(xdg, fs_encoding)
242 return py3compat.cast_unicode(xdg, fs_encoding)
243
243
244 return None
244 return None
245
245
246
246
247 def get_ipython_dir():
247 def get_ipython_dir():
248 """Get the IPython directory for this platform and user.
248 """Get the IPython directory for this platform and user.
249
249
250 This uses the logic in `get_home_dir` to find the home directory
250 This uses the logic in `get_home_dir` to find the home directory
251 and then adds .ipython to the end of the path.
251 and then adds .ipython to the end of the path.
252 """
252 """
253
253
254 env = os.environ
254 env = os.environ
255 pjoin = os.path.join
255 pjoin = os.path.join
256
256
257
257
258 ipdir_def = '.ipython'
258 ipdir_def = '.ipython'
259 xdg_def = 'ipython'
259 xdg_def = 'ipython'
260
260
261 home_dir = get_home_dir()
261 home_dir = get_home_dir()
262 xdg_dir = get_xdg_dir()
262 xdg_dir = get_xdg_dir()
263
263
264 # import pdb; pdb.set_trace() # dbg
264 # import pdb; pdb.set_trace() # dbg
265 if 'IPYTHON_DIR' in env:
265 if 'IPYTHON_DIR' in env:
266 warnings.warn('The environment variable IPYTHON_DIR is deprecated. '
266 warnings.warn('The environment variable IPYTHON_DIR is deprecated. '
267 'Please use IPYTHONDIR instead.')
267 'Please use IPYTHONDIR instead.')
268 ipdir = env.get('IPYTHONDIR', env.get('IPYTHON_DIR', None))
268 ipdir = env.get('IPYTHONDIR', env.get('IPYTHON_DIR', None))
269 if ipdir is None:
269 if ipdir is None:
270 # not set explicitly, use XDG_CONFIG_HOME or HOME
270 # not set explicitly, use XDG_CONFIG_HOME or HOME
271 home_ipdir = pjoin(home_dir, ipdir_def)
271 home_ipdir = pjoin(home_dir, ipdir_def)
272 if xdg_dir:
272 if xdg_dir:
273 # use XDG, as long as the user isn't already
273 # use XDG, as long as the user isn't already
274 # using $HOME/.ipython and *not* XDG/ipython
274 # using $HOME/.ipython and *not* XDG/ipython
275
275
276 xdg_ipdir = pjoin(xdg_dir, xdg_def)
276 xdg_ipdir = pjoin(xdg_dir, xdg_def)
277
277
278 if _writable_dir(xdg_ipdir) or not _writable_dir(home_ipdir):
278 if _writable_dir(xdg_ipdir) or not _writable_dir(home_ipdir):
279 ipdir = xdg_ipdir
279 ipdir = xdg_ipdir
280
280
281 if ipdir is None:
281 if ipdir is None:
282 # not using XDG
282 # not using XDG
283 ipdir = home_ipdir
283 ipdir = home_ipdir
284
284
285 ipdir = os.path.normpath(os.path.expanduser(ipdir))
285 ipdir = os.path.normpath(os.path.expanduser(ipdir))
286
286
287 if os.path.exists(ipdir) and not _writable_dir(ipdir):
287 if os.path.exists(ipdir) and not _writable_dir(ipdir):
288 # ipdir exists, but is not writable
288 # ipdir exists, but is not writable
289 warnings.warn("IPython dir '%s' is not a writable location,"
289 warnings.warn("IPython dir '%s' is not a writable location,"
290 " using a temp directory."%ipdir)
290 " using a temp directory."%ipdir)
291 ipdir = tempfile.mkdtemp()
291 ipdir = tempfile.mkdtemp()
292 elif not os.path.exists(ipdir):
292 elif not os.path.exists(ipdir):
293 parent = ipdir.rsplit(os.path.sep, 1)[0]
293 parent = ipdir.rsplit(os.path.sep, 1)[0]
294 if not _writable_dir(parent):
294 if not _writable_dir(parent):
295 # ipdir does not exist and parent isn't writable
295 # ipdir does not exist and parent isn't writable
296 warnings.warn("IPython parent '%s' is not a writable location,"
296 warnings.warn("IPython parent '%s' is not a writable location,"
297 " using a temp directory."%parent)
297 " using a temp directory."%parent)
298 ipdir = tempfile.mkdtemp()
298 ipdir = tempfile.mkdtemp()
299
299
300 return py3compat.cast_unicode(ipdir, fs_encoding)
300 return py3compat.cast_unicode(ipdir, fs_encoding)
301
301
302
302
303 def get_ipython_package_dir():
303 def get_ipython_package_dir():
304 """Get the base directory where IPython itself is installed."""
304 """Get the base directory where IPython itself is installed."""
305 ipdir = os.path.dirname(IPython.__file__)
305 ipdir = os.path.dirname(IPython.__file__)
306 return py3compat.cast_unicode(ipdir, fs_encoding)
306 return py3compat.cast_unicode(ipdir, fs_encoding)
307
307
308
308
309 def get_ipython_module_path(module_str):
309 def get_ipython_module_path(module_str):
310 """Find the path to an IPython module in this version of IPython.
310 """Find the path to an IPython module in this version of IPython.
311
311
312 This will always find the version of the module that is in this importable
312 This will always find the version of the module that is in this importable
313 IPython package. This will always return the path to the ``.py``
313 IPython package. This will always return the path to the ``.py``
314 version of the module.
314 version of the module.
315 """
315 """
316 if module_str == 'IPython':
316 if module_str == 'IPython':
317 return os.path.join(get_ipython_package_dir(), '__init__.py')
317 return os.path.join(get_ipython_package_dir(), '__init__.py')
318 mod = import_item(module_str)
318 mod = import_item(module_str)
319 the_path = mod.__file__.replace('.pyc', '.py')
319 the_path = mod.__file__.replace('.pyc', '.py')
320 the_path = the_path.replace('.pyo', '.py')
320 the_path = the_path.replace('.pyo', '.py')
321 return py3compat.cast_unicode(the_path, fs_encoding)
321 return py3compat.cast_unicode(the_path, fs_encoding)
322
322
323 def locate_profile(profile='default'):
323 def locate_profile(profile='default'):
324 """Find the path to the folder associated with a given profile.
324 """Find the path to the folder associated with a given profile.
325
325
326 I.e. find $IPYTHONDIR/profile_whatever.
326 I.e. find $IPYTHONDIR/profile_whatever.
327 """
327 """
328 from IPython.core.profiledir import ProfileDir, ProfileDirError
328 from IPython.core.profiledir import ProfileDir, ProfileDirError
329 try:
329 try:
330 pd = ProfileDir.find_profile_dir_by_name(get_ipython_dir(), profile)
330 pd = ProfileDir.find_profile_dir_by_name(get_ipython_dir(), profile)
331 except ProfileDirError:
331 except ProfileDirError:
332 # IOError makes more sense when people are expecting a path
332 # IOError makes more sense when people are expecting a path
333 raise IOError("Couldn't find profile %r" % profile)
333 raise IOError("Couldn't find profile %r" % profile)
334 return pd.location
334 return pd.location
335
335
336 def expand_path(s):
336 def expand_path(s):
337 """Expand $VARS and ~names in a string, like a shell
337 """Expand $VARS and ~names in a string, like a shell
338
338
339 :Examples:
339 :Examples:
340
340
341 In [2]: os.environ['FOO']='test'
341 In [2]: os.environ['FOO']='test'
342
342
343 In [3]: expand_path('variable FOO is $FOO')
343 In [3]: expand_path('variable FOO is $FOO')
344 Out[3]: 'variable FOO is test'
344 Out[3]: 'variable FOO is test'
345 """
345 """
346 # This is a pretty subtle hack. When expand user is given a UNC path
346 # This is a pretty subtle hack. When expand user is given a UNC path
347 # on Windows (\\server\share$\%username%), os.path.expandvars, removes
347 # on Windows (\\server\share$\%username%), os.path.expandvars, removes
348 # the $ to get (\\server\share\%username%). I think it considered $
348 # the $ to get (\\server\share\%username%). I think it considered $
349 # alone an empty var. But, we need the $ to remains there (it indicates
349 # alone an empty var. But, we need the $ to remains there (it indicates
350 # a hidden share).
350 # a hidden share).
351 if os.name=='nt':
351 if os.name=='nt':
352 s = s.replace('$\\', 'IPYTHON_TEMP')
352 s = s.replace('$\\', 'IPYTHON_TEMP')
353 s = os.path.expandvars(os.path.expanduser(s))
353 s = os.path.expandvars(os.path.expanduser(s))
354 if os.name=='nt':
354 if os.name=='nt':
355 s = s.replace('IPYTHON_TEMP', '$\\')
355 s = s.replace('IPYTHON_TEMP', '$\\')
356 return s
356 return s
357
357
358
358
359 def globlist(args):
359 def shellglob(args):
360 """
360 """
361 Do glob expansion for each element in `args` and return a flattened list.
361 Do glob expansion for each element in `args` and return a flattened list.
362
362
363 Unmatched glob pattern will remain as-is in the returned list.
363 Unmatched glob pattern will remain as-is in the returned list.
364
364
365 """
365 """
366 expanded = []
366 expanded = []
367 for a in args:
367 for a in args:
368 expanded.extend(glob.glob(a) or [a])
368 expanded.extend(glob.glob(a) or [a])
369 return expanded
369 return expanded
370
370
371
371
372 def target_outdated(target,deps):
372 def target_outdated(target,deps):
373 """Determine whether a target is out of date.
373 """Determine whether a target is out of date.
374
374
375 target_outdated(target,deps) -> 1/0
375 target_outdated(target,deps) -> 1/0
376
376
377 deps: list of filenames which MUST exist.
377 deps: list of filenames which MUST exist.
378 target: single filename which may or may not exist.
378 target: single filename which may or may not exist.
379
379
380 If target doesn't exist or is older than any file listed in deps, return
380 If target doesn't exist or is older than any file listed in deps, return
381 true, otherwise return false.
381 true, otherwise return false.
382 """
382 """
383 try:
383 try:
384 target_time = os.path.getmtime(target)
384 target_time = os.path.getmtime(target)
385 except os.error:
385 except os.error:
386 return 1
386 return 1
387 for dep in deps:
387 for dep in deps:
388 dep_time = os.path.getmtime(dep)
388 dep_time = os.path.getmtime(dep)
389 if dep_time > target_time:
389 if dep_time > target_time:
390 #print "For target",target,"Dep failed:",dep # dbg
390 #print "For target",target,"Dep failed:",dep # dbg
391 #print "times (dep,tar):",dep_time,target_time # dbg
391 #print "times (dep,tar):",dep_time,target_time # dbg
392 return 1
392 return 1
393 return 0
393 return 0
394
394
395
395
396 def target_update(target,deps,cmd):
396 def target_update(target,deps,cmd):
397 """Update a target with a given command given a list of dependencies.
397 """Update a target with a given command given a list of dependencies.
398
398
399 target_update(target,deps,cmd) -> runs cmd if target is outdated.
399 target_update(target,deps,cmd) -> runs cmd if target is outdated.
400
400
401 This is just a wrapper around target_outdated() which calls the given
401 This is just a wrapper around target_outdated() which calls the given
402 command if target is outdated."""
402 command if target is outdated."""
403
403
404 if target_outdated(target,deps):
404 if target_outdated(target,deps):
405 system(cmd)
405 system(cmd)
406
406
407 def filehash(path):
407 def filehash(path):
408 """Make an MD5 hash of a file, ignoring any differences in line
408 """Make an MD5 hash of a file, ignoring any differences in line
409 ending characters."""
409 ending characters."""
410 with open(path, "rU") as f:
410 with open(path, "rU") as f:
411 return md5(py3compat.str_to_bytes(f.read())).hexdigest()
411 return md5(py3compat.str_to_bytes(f.read())).hexdigest()
412
412
413 # If the config is unmodified from the default, we'll just delete it.
413 # If the config is unmodified from the default, we'll just delete it.
414 # These are consistent for 0.10.x, thankfully. We're not going to worry about
414 # These are consistent for 0.10.x, thankfully. We're not going to worry about
415 # older versions.
415 # older versions.
416 old_config_md5 = {'ipy_user_conf.py': 'fc108bedff4b9a00f91fa0a5999140d3',
416 old_config_md5 = {'ipy_user_conf.py': 'fc108bedff4b9a00f91fa0a5999140d3',
417 'ipythonrc': '12a68954f3403eea2eec09dc8fe5a9b5'}
417 'ipythonrc': '12a68954f3403eea2eec09dc8fe5a9b5'}
418
418
419 def check_for_old_config(ipython_dir=None):
419 def check_for_old_config(ipython_dir=None):
420 """Check for old config files, and present a warning if they exist.
420 """Check for old config files, and present a warning if they exist.
421
421
422 A link to the docs of the new config is included in the message.
422 A link to the docs of the new config is included in the message.
423
423
424 This should mitigate confusion with the transition to the new
424 This should mitigate confusion with the transition to the new
425 config system in 0.11.
425 config system in 0.11.
426 """
426 """
427 if ipython_dir is None:
427 if ipython_dir is None:
428 ipython_dir = get_ipython_dir()
428 ipython_dir = get_ipython_dir()
429
429
430 old_configs = ['ipy_user_conf.py', 'ipythonrc', 'ipython_config.py']
430 old_configs = ['ipy_user_conf.py', 'ipythonrc', 'ipython_config.py']
431 warned = False
431 warned = False
432 for cfg in old_configs:
432 for cfg in old_configs:
433 f = os.path.join(ipython_dir, cfg)
433 f = os.path.join(ipython_dir, cfg)
434 if os.path.exists(f):
434 if os.path.exists(f):
435 if filehash(f) == old_config_md5.get(cfg, ''):
435 if filehash(f) == old_config_md5.get(cfg, ''):
436 os.unlink(f)
436 os.unlink(f)
437 else:
437 else:
438 warnings.warn("Found old IPython config file %r (modified by user)"%f)
438 warnings.warn("Found old IPython config file %r (modified by user)"%f)
439 warned = True
439 warned = True
440
440
441 if warned:
441 if warned:
442 warnings.warn("""
442 warnings.warn("""
443 The IPython configuration system has changed as of 0.11, and these files will
443 The IPython configuration system has changed as of 0.11, and these files will
444 be ignored. See http://ipython.github.com/ipython-doc/dev/config for details
444 be ignored. See http://ipython.github.com/ipython-doc/dev/config for details
445 of the new config system.
445 of the new config system.
446 To start configuring IPython, do `ipython profile create`, and edit
446 To start configuring IPython, do `ipython profile create`, and edit
447 `ipython_config.py` in <ipython_dir>/profile_default.
447 `ipython_config.py` in <ipython_dir>/profile_default.
448 If you need to leave the old config files in place for an older version of
448 If you need to leave the old config files in place for an older version of
449 IPython and want to suppress this warning message, set
449 IPython and want to suppress this warning message, set
450 `c.InteractiveShellApp.ignore_old_config=True` in the new config.""")
450 `c.InteractiveShellApp.ignore_old_config=True` in the new config.""")
451
451
452 def get_security_file(filename, profile='default'):
452 def get_security_file(filename, profile='default'):
453 """Return the absolute path of a security file given by filename and profile
453 """Return the absolute path of a security file given by filename and profile
454
454
455 This allows users and developers to find security files without
455 This allows users and developers to find security files without
456 knowledge of the IPython directory structure. The search path
456 knowledge of the IPython directory structure. The search path
457 will be ['.', profile.security_dir]
457 will be ['.', profile.security_dir]
458
458
459 Parameters
459 Parameters
460 ----------
460 ----------
461
461
462 filename : str
462 filename : str
463 The file to be found. If it is passed as an absolute path, it will
463 The file to be found. If it is passed as an absolute path, it will
464 simply be returned.
464 simply be returned.
465 profile : str [default: 'default']
465 profile : str [default: 'default']
466 The name of the profile to search. Leaving this unspecified
466 The name of the profile to search. Leaving this unspecified
467 The file to be found. If it is passed as an absolute path, fname will
467 The file to be found. If it is passed as an absolute path, fname will
468 simply be returned.
468 simply be returned.
469
469
470 Returns
470 Returns
471 -------
471 -------
472 Raises :exc:`IOError` if file not found or returns absolute path to file.
472 Raises :exc:`IOError` if file not found or returns absolute path to file.
473 """
473 """
474 # import here, because profiledir also imports from utils.path
474 # import here, because profiledir also imports from utils.path
475 from IPython.core.profiledir import ProfileDir
475 from IPython.core.profiledir import ProfileDir
476 try:
476 try:
477 pd = ProfileDir.find_profile_dir_by_name(get_ipython_dir(), profile)
477 pd = ProfileDir.find_profile_dir_by_name(get_ipython_dir(), profile)
478 except Exception:
478 except Exception:
479 # will raise ProfileDirError if no such profile
479 # will raise ProfileDirError if no such profile
480 raise IOError("Profile %r not found")
480 raise IOError("Profile %r not found")
481 return filefind(filename, ['.', pd.security_dir])
481 return filefind(filename, ['.', pd.security_dir])
482
482
@@ -1,479 +1,479 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """Tests for IPython.utils.path.py"""
2 """Tests for IPython.utils.path.py"""
3
3
4 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
5 # Copyright (C) 2008-2011 The IPython Development Team
5 # Copyright (C) 2008-2011 The IPython Development Team
6 #
6 #
7 # Distributed under the terms of the BSD License. The full license is in
7 # Distributed under the terms of the BSD License. The full license is in
8 # the file COPYING, distributed as part of this software.
8 # the file COPYING, distributed as part of this software.
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Imports
12 # Imports
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 from __future__ import with_statement
15 from __future__ import with_statement
16
16
17 import os
17 import os
18 import shutil
18 import shutil
19 import sys
19 import sys
20 import tempfile
20 import tempfile
21 from io import StringIO
21 from io import StringIO
22
22
23 from os.path import join, abspath, split
23 from os.path import join, abspath, split
24
24
25 import nose.tools as nt
25 import nose.tools as nt
26
26
27 from nose import with_setup
27 from nose import with_setup
28
28
29 import IPython
29 import IPython
30 from IPython.testing import decorators as dec
30 from IPython.testing import decorators as dec
31 from IPython.testing.decorators import skip_if_not_win32, skip_win32
31 from IPython.testing.decorators import skip_if_not_win32, skip_win32
32 from IPython.testing.tools import make_tempfile, AssertPrints
32 from IPython.testing.tools import make_tempfile, AssertPrints
33 from IPython.utils import path, io
33 from IPython.utils import path, io
34 from IPython.utils import py3compat
34 from IPython.utils import py3compat
35 from IPython.utils.tempdir import TemporaryDirectory
35 from IPython.utils.tempdir import TemporaryDirectory
36
36
37 # Platform-dependent imports
37 # Platform-dependent imports
38 try:
38 try:
39 import _winreg as wreg
39 import _winreg as wreg
40 except ImportError:
40 except ImportError:
41 #Fake _winreg module on none windows platforms
41 #Fake _winreg module on none windows platforms
42 import types
42 import types
43 wr_name = "winreg" if py3compat.PY3 else "_winreg"
43 wr_name = "winreg" if py3compat.PY3 else "_winreg"
44 sys.modules[wr_name] = types.ModuleType(wr_name)
44 sys.modules[wr_name] = types.ModuleType(wr_name)
45 import _winreg as wreg
45 import _winreg as wreg
46 #Add entries that needs to be stubbed by the testing code
46 #Add entries that needs to be stubbed by the testing code
47 (wreg.OpenKey, wreg.QueryValueEx,) = (None, None)
47 (wreg.OpenKey, wreg.QueryValueEx,) = (None, None)
48
48
49 try:
49 try:
50 reload
50 reload
51 except NameError: # Python 3
51 except NameError: # Python 3
52 from imp import reload
52 from imp import reload
53
53
54 #-----------------------------------------------------------------------------
54 #-----------------------------------------------------------------------------
55 # Globals
55 # Globals
56 #-----------------------------------------------------------------------------
56 #-----------------------------------------------------------------------------
57 env = os.environ
57 env = os.environ
58 TEST_FILE_PATH = split(abspath(__file__))[0]
58 TEST_FILE_PATH = split(abspath(__file__))[0]
59 TMP_TEST_DIR = tempfile.mkdtemp()
59 TMP_TEST_DIR = tempfile.mkdtemp()
60 HOME_TEST_DIR = join(TMP_TEST_DIR, "home_test_dir")
60 HOME_TEST_DIR = join(TMP_TEST_DIR, "home_test_dir")
61 XDG_TEST_DIR = join(HOME_TEST_DIR, "xdg_test_dir")
61 XDG_TEST_DIR = join(HOME_TEST_DIR, "xdg_test_dir")
62 IP_TEST_DIR = join(HOME_TEST_DIR,'.ipython')
62 IP_TEST_DIR = join(HOME_TEST_DIR,'.ipython')
63 #
63 #
64 # Setup/teardown functions/decorators
64 # Setup/teardown functions/decorators
65 #
65 #
66
66
67 def setup():
67 def setup():
68 """Setup testenvironment for the module:
68 """Setup testenvironment for the module:
69
69
70 - Adds dummy home dir tree
70 - Adds dummy home dir tree
71 """
71 """
72 # Do not mask exceptions here. In particular, catching WindowsError is a
72 # Do not mask exceptions here. In particular, catching WindowsError is a
73 # problem because that exception is only defined on Windows...
73 # problem because that exception is only defined on Windows...
74 os.makedirs(IP_TEST_DIR)
74 os.makedirs(IP_TEST_DIR)
75 os.makedirs(os.path.join(XDG_TEST_DIR, 'ipython'))
75 os.makedirs(os.path.join(XDG_TEST_DIR, 'ipython'))
76
76
77
77
78 def teardown():
78 def teardown():
79 """Teardown testenvironment for the module:
79 """Teardown testenvironment for the module:
80
80
81 - Remove dummy home dir tree
81 - Remove dummy home dir tree
82 """
82 """
83 # Note: we remove the parent test dir, which is the root of all test
83 # Note: we remove the parent test dir, which is the root of all test
84 # subdirs we may have created. Use shutil instead of os.removedirs, so
84 # subdirs we may have created. Use shutil instead of os.removedirs, so
85 # that non-empty directories are all recursively removed.
85 # that non-empty directories are all recursively removed.
86 shutil.rmtree(TMP_TEST_DIR)
86 shutil.rmtree(TMP_TEST_DIR)
87
87
88
88
89 def setup_environment():
89 def setup_environment():
90 """Setup testenvironment for some functions that are tested
90 """Setup testenvironment for some functions that are tested
91 in this module. In particular this functions stores attributes
91 in this module. In particular this functions stores attributes
92 and other things that we need to stub in some test functions.
92 and other things that we need to stub in some test functions.
93 This needs to be done on a function level and not module level because
93 This needs to be done on a function level and not module level because
94 each testfunction needs a pristine environment.
94 each testfunction needs a pristine environment.
95 """
95 """
96 global oldstuff, platformstuff
96 global oldstuff, platformstuff
97 oldstuff = (env.copy(), os.name, sys.platform, path.get_home_dir, IPython.__file__, os.getcwd())
97 oldstuff = (env.copy(), os.name, sys.platform, path.get_home_dir, IPython.__file__, os.getcwd())
98
98
99 if os.name == 'nt':
99 if os.name == 'nt':
100 platformstuff = (wreg.OpenKey, wreg.QueryValueEx,)
100 platformstuff = (wreg.OpenKey, wreg.QueryValueEx,)
101
101
102
102
103 def teardown_environment():
103 def teardown_environment():
104 """Restore things that were remebered by the setup_environment function
104 """Restore things that were remebered by the setup_environment function
105 """
105 """
106 (oldenv, os.name, sys.platform, path.get_home_dir, IPython.__file__, old_wd) = oldstuff
106 (oldenv, os.name, sys.platform, path.get_home_dir, IPython.__file__, old_wd) = oldstuff
107 os.chdir(old_wd)
107 os.chdir(old_wd)
108 reload(path)
108 reload(path)
109
109
110 for key in env.keys():
110 for key in env.keys():
111 if key not in oldenv:
111 if key not in oldenv:
112 del env[key]
112 del env[key]
113 env.update(oldenv)
113 env.update(oldenv)
114 if hasattr(sys, 'frozen'):
114 if hasattr(sys, 'frozen'):
115 del sys.frozen
115 del sys.frozen
116 if os.name == 'nt':
116 if os.name == 'nt':
117 (wreg.OpenKey, wreg.QueryValueEx,) = platformstuff
117 (wreg.OpenKey, wreg.QueryValueEx,) = platformstuff
118
118
119 # Build decorator that uses the setup_environment/setup_environment
119 # Build decorator that uses the setup_environment/setup_environment
120 with_environment = with_setup(setup_environment, teardown_environment)
120 with_environment = with_setup(setup_environment, teardown_environment)
121
121
122 @skip_if_not_win32
122 @skip_if_not_win32
123 @with_environment
123 @with_environment
124 def test_get_home_dir_1():
124 def test_get_home_dir_1():
125 """Testcase for py2exe logic, un-compressed lib
125 """Testcase for py2exe logic, un-compressed lib
126 """
126 """
127 sys.frozen = True
127 sys.frozen = True
128
128
129 #fake filename for IPython.__init__
129 #fake filename for IPython.__init__
130 IPython.__file__ = abspath(join(HOME_TEST_DIR, "Lib/IPython/__init__.py"))
130 IPython.__file__ = abspath(join(HOME_TEST_DIR, "Lib/IPython/__init__.py"))
131
131
132 home_dir = path.get_home_dir()
132 home_dir = path.get_home_dir()
133 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR))
133 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR))
134
134
135
135
136 @skip_if_not_win32
136 @skip_if_not_win32
137 @with_environment
137 @with_environment
138 def test_get_home_dir_2():
138 def test_get_home_dir_2():
139 """Testcase for py2exe logic, compressed lib
139 """Testcase for py2exe logic, compressed lib
140 """
140 """
141 sys.frozen = True
141 sys.frozen = True
142 #fake filename for IPython.__init__
142 #fake filename for IPython.__init__
143 IPython.__file__ = abspath(join(HOME_TEST_DIR, "Library.zip/IPython/__init__.py")).lower()
143 IPython.__file__ = abspath(join(HOME_TEST_DIR, "Library.zip/IPython/__init__.py")).lower()
144
144
145 home_dir = path.get_home_dir(True)
145 home_dir = path.get_home_dir(True)
146 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR).lower())
146 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR).lower())
147
147
148
148
149 @with_environment
149 @with_environment
150 def test_get_home_dir_3():
150 def test_get_home_dir_3():
151 """get_home_dir() uses $HOME if set"""
151 """get_home_dir() uses $HOME if set"""
152 env["HOME"] = HOME_TEST_DIR
152 env["HOME"] = HOME_TEST_DIR
153 home_dir = path.get_home_dir(True)
153 home_dir = path.get_home_dir(True)
154 # get_home_dir expands symlinks
154 # get_home_dir expands symlinks
155 nt.assert_equal(home_dir, os.path.realpath(env["HOME"]))
155 nt.assert_equal(home_dir, os.path.realpath(env["HOME"]))
156
156
157
157
158 @with_environment
158 @with_environment
159 def test_get_home_dir_4():
159 def test_get_home_dir_4():
160 """get_home_dir() still works if $HOME is not set"""
160 """get_home_dir() still works if $HOME is not set"""
161
161
162 if 'HOME' in env: del env['HOME']
162 if 'HOME' in env: del env['HOME']
163 # this should still succeed, but we don't care what the answer is
163 # this should still succeed, but we don't care what the answer is
164 home = path.get_home_dir(False)
164 home = path.get_home_dir(False)
165
165
166 @with_environment
166 @with_environment
167 def test_get_home_dir_5():
167 def test_get_home_dir_5():
168 """raise HomeDirError if $HOME is specified, but not a writable dir"""
168 """raise HomeDirError if $HOME is specified, but not a writable dir"""
169 env['HOME'] = abspath(HOME_TEST_DIR+'garbage')
169 env['HOME'] = abspath(HOME_TEST_DIR+'garbage')
170 # set os.name = posix, to prevent My Documents fallback on Windows
170 # set os.name = posix, to prevent My Documents fallback on Windows
171 os.name = 'posix'
171 os.name = 'posix'
172 nt.assert_raises(path.HomeDirError, path.get_home_dir, True)
172 nt.assert_raises(path.HomeDirError, path.get_home_dir, True)
173
173
174
174
175 # Should we stub wreg fully so we can run the test on all platforms?
175 # Should we stub wreg fully so we can run the test on all platforms?
176 @skip_if_not_win32
176 @skip_if_not_win32
177 @with_environment
177 @with_environment
178 def test_get_home_dir_8():
178 def test_get_home_dir_8():
179 """Using registry hack for 'My Documents', os=='nt'
179 """Using registry hack for 'My Documents', os=='nt'
180
180
181 HOMESHARE, HOMEDRIVE, HOMEPATH, USERPROFILE and others are missing.
181 HOMESHARE, HOMEDRIVE, HOMEPATH, USERPROFILE and others are missing.
182 """
182 """
183 os.name = 'nt'
183 os.name = 'nt'
184 # Remove from stub environment all keys that may be set
184 # Remove from stub environment all keys that may be set
185 for key in ['HOME', 'HOMESHARE', 'HOMEDRIVE', 'HOMEPATH', 'USERPROFILE']:
185 for key in ['HOME', 'HOMESHARE', 'HOMEDRIVE', 'HOMEPATH', 'USERPROFILE']:
186 env.pop(key, None)
186 env.pop(key, None)
187
187
188 #Stub windows registry functions
188 #Stub windows registry functions
189 def OpenKey(x, y):
189 def OpenKey(x, y):
190 class key:
190 class key:
191 def Close(self):
191 def Close(self):
192 pass
192 pass
193 return key()
193 return key()
194 def QueryValueEx(x, y):
194 def QueryValueEx(x, y):
195 return [abspath(HOME_TEST_DIR)]
195 return [abspath(HOME_TEST_DIR)]
196
196
197 wreg.OpenKey = OpenKey
197 wreg.OpenKey = OpenKey
198 wreg.QueryValueEx = QueryValueEx
198 wreg.QueryValueEx = QueryValueEx
199
199
200 home_dir = path.get_home_dir()
200 home_dir = path.get_home_dir()
201 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR))
201 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR))
202
202
203
203
204 @with_environment
204 @with_environment
205 def test_get_ipython_dir_1():
205 def test_get_ipython_dir_1():
206 """test_get_ipython_dir_1, Testcase to see if we can call get_ipython_dir without Exceptions."""
206 """test_get_ipython_dir_1, Testcase to see if we can call get_ipython_dir without Exceptions."""
207 env_ipdir = os.path.join("someplace", ".ipython")
207 env_ipdir = os.path.join("someplace", ".ipython")
208 path._writable_dir = lambda path: True
208 path._writable_dir = lambda path: True
209 env['IPYTHONDIR'] = env_ipdir
209 env['IPYTHONDIR'] = env_ipdir
210 ipdir = path.get_ipython_dir()
210 ipdir = path.get_ipython_dir()
211 nt.assert_equal(ipdir, env_ipdir)
211 nt.assert_equal(ipdir, env_ipdir)
212
212
213
213
214 @with_environment
214 @with_environment
215 def test_get_ipython_dir_2():
215 def test_get_ipython_dir_2():
216 """test_get_ipython_dir_2, Testcase to see if we can call get_ipython_dir without Exceptions."""
216 """test_get_ipython_dir_2, Testcase to see if we can call get_ipython_dir without Exceptions."""
217 path.get_home_dir = lambda : "someplace"
217 path.get_home_dir = lambda : "someplace"
218 path.get_xdg_dir = lambda : None
218 path.get_xdg_dir = lambda : None
219 path._writable_dir = lambda path: True
219 path._writable_dir = lambda path: True
220 os.name = "posix"
220 os.name = "posix"
221 env.pop('IPYTHON_DIR', None)
221 env.pop('IPYTHON_DIR', None)
222 env.pop('IPYTHONDIR', None)
222 env.pop('IPYTHONDIR', None)
223 env.pop('XDG_CONFIG_HOME', None)
223 env.pop('XDG_CONFIG_HOME', None)
224 ipdir = path.get_ipython_dir()
224 ipdir = path.get_ipython_dir()
225 nt.assert_equal(ipdir, os.path.join("someplace", ".ipython"))
225 nt.assert_equal(ipdir, os.path.join("someplace", ".ipython"))
226
226
227 @with_environment
227 @with_environment
228 def test_get_ipython_dir_3():
228 def test_get_ipython_dir_3():
229 """test_get_ipython_dir_3, use XDG if defined, and .ipython doesn't exist."""
229 """test_get_ipython_dir_3, use XDG if defined, and .ipython doesn't exist."""
230 path.get_home_dir = lambda : "someplace"
230 path.get_home_dir = lambda : "someplace"
231 path._writable_dir = lambda path: True
231 path._writable_dir = lambda path: True
232 os.name = "posix"
232 os.name = "posix"
233 env.pop('IPYTHON_DIR', None)
233 env.pop('IPYTHON_DIR', None)
234 env.pop('IPYTHONDIR', None)
234 env.pop('IPYTHONDIR', None)
235 env['XDG_CONFIG_HOME'] = XDG_TEST_DIR
235 env['XDG_CONFIG_HOME'] = XDG_TEST_DIR
236 ipdir = path.get_ipython_dir()
236 ipdir = path.get_ipython_dir()
237 if sys.platform == "darwin":
237 if sys.platform == "darwin":
238 expected = os.path.join("someplace", ".ipython")
238 expected = os.path.join("someplace", ".ipython")
239 else:
239 else:
240 expected = os.path.join(XDG_TEST_DIR, "ipython")
240 expected = os.path.join(XDG_TEST_DIR, "ipython")
241 nt.assert_equal(ipdir, expected)
241 nt.assert_equal(ipdir, expected)
242
242
243 @with_environment
243 @with_environment
244 def test_get_ipython_dir_4():
244 def test_get_ipython_dir_4():
245 """test_get_ipython_dir_4, use XDG if both exist."""
245 """test_get_ipython_dir_4, use XDG if both exist."""
246 path.get_home_dir = lambda : HOME_TEST_DIR
246 path.get_home_dir = lambda : HOME_TEST_DIR
247 os.name = "posix"
247 os.name = "posix"
248 env.pop('IPYTHON_DIR', None)
248 env.pop('IPYTHON_DIR', None)
249 env.pop('IPYTHONDIR', None)
249 env.pop('IPYTHONDIR', None)
250 env['XDG_CONFIG_HOME'] = XDG_TEST_DIR
250 env['XDG_CONFIG_HOME'] = XDG_TEST_DIR
251 ipdir = path.get_ipython_dir()
251 ipdir = path.get_ipython_dir()
252 if sys.platform == "darwin":
252 if sys.platform == "darwin":
253 expected = os.path.join(HOME_TEST_DIR, ".ipython")
253 expected = os.path.join(HOME_TEST_DIR, ".ipython")
254 else:
254 else:
255 expected = os.path.join(XDG_TEST_DIR, "ipython")
255 expected = os.path.join(XDG_TEST_DIR, "ipython")
256 nt.assert_equal(ipdir, expected)
256 nt.assert_equal(ipdir, expected)
257
257
258 @with_environment
258 @with_environment
259 def test_get_ipython_dir_5():
259 def test_get_ipython_dir_5():
260 """test_get_ipython_dir_5, use .ipython if exists and XDG defined, but doesn't exist."""
260 """test_get_ipython_dir_5, use .ipython if exists and XDG defined, but doesn't exist."""
261 path.get_home_dir = lambda : HOME_TEST_DIR
261 path.get_home_dir = lambda : HOME_TEST_DIR
262 os.name = "posix"
262 os.name = "posix"
263 env.pop('IPYTHON_DIR', None)
263 env.pop('IPYTHON_DIR', None)
264 env.pop('IPYTHONDIR', None)
264 env.pop('IPYTHONDIR', None)
265 env['XDG_CONFIG_HOME'] = XDG_TEST_DIR
265 env['XDG_CONFIG_HOME'] = XDG_TEST_DIR
266 os.rmdir(os.path.join(XDG_TEST_DIR, 'ipython'))
266 os.rmdir(os.path.join(XDG_TEST_DIR, 'ipython'))
267 ipdir = path.get_ipython_dir()
267 ipdir = path.get_ipython_dir()
268 nt.assert_equal(ipdir, IP_TEST_DIR)
268 nt.assert_equal(ipdir, IP_TEST_DIR)
269
269
270 @with_environment
270 @with_environment
271 def test_get_ipython_dir_6():
271 def test_get_ipython_dir_6():
272 """test_get_ipython_dir_6, use XDG if defined and neither exist."""
272 """test_get_ipython_dir_6, use XDG if defined and neither exist."""
273 xdg = os.path.join(HOME_TEST_DIR, 'somexdg')
273 xdg = os.path.join(HOME_TEST_DIR, 'somexdg')
274 os.mkdir(xdg)
274 os.mkdir(xdg)
275 shutil.rmtree(os.path.join(HOME_TEST_DIR, '.ipython'))
275 shutil.rmtree(os.path.join(HOME_TEST_DIR, '.ipython'))
276 path.get_home_dir = lambda : HOME_TEST_DIR
276 path.get_home_dir = lambda : HOME_TEST_DIR
277 path.get_xdg_dir = lambda : xdg
277 path.get_xdg_dir = lambda : xdg
278 os.name = "posix"
278 os.name = "posix"
279 env.pop('IPYTHON_DIR', None)
279 env.pop('IPYTHON_DIR', None)
280 env.pop('IPYTHONDIR', None)
280 env.pop('IPYTHONDIR', None)
281 env.pop('XDG_CONFIG_HOME', None)
281 env.pop('XDG_CONFIG_HOME', None)
282 xdg_ipdir = os.path.join(xdg, "ipython")
282 xdg_ipdir = os.path.join(xdg, "ipython")
283 ipdir = path.get_ipython_dir()
283 ipdir = path.get_ipython_dir()
284 nt.assert_equal(ipdir, xdg_ipdir)
284 nt.assert_equal(ipdir, xdg_ipdir)
285
285
286 @with_environment
286 @with_environment
287 def test_get_ipython_dir_7():
287 def test_get_ipython_dir_7():
288 """test_get_ipython_dir_7, test home directory expansion on IPYTHONDIR"""
288 """test_get_ipython_dir_7, test home directory expansion on IPYTHONDIR"""
289 path._writable_dir = lambda path: True
289 path._writable_dir = lambda path: True
290 home_dir = os.path.normpath(os.path.expanduser('~'))
290 home_dir = os.path.normpath(os.path.expanduser('~'))
291 env['IPYTHONDIR'] = os.path.join('~', 'somewhere')
291 env['IPYTHONDIR'] = os.path.join('~', 'somewhere')
292 ipdir = path.get_ipython_dir()
292 ipdir = path.get_ipython_dir()
293 nt.assert_equal(ipdir, os.path.join(home_dir, 'somewhere'))
293 nt.assert_equal(ipdir, os.path.join(home_dir, 'somewhere'))
294
294
295
295
296 @with_environment
296 @with_environment
297 def test_get_xdg_dir_0():
297 def test_get_xdg_dir_0():
298 """test_get_xdg_dir_0, check xdg_dir"""
298 """test_get_xdg_dir_0, check xdg_dir"""
299 reload(path)
299 reload(path)
300 path._writable_dir = lambda path: True
300 path._writable_dir = lambda path: True
301 path.get_home_dir = lambda : 'somewhere'
301 path.get_home_dir = lambda : 'somewhere'
302 os.name = "posix"
302 os.name = "posix"
303 sys.platform = "linux2"
303 sys.platform = "linux2"
304 env.pop('IPYTHON_DIR', None)
304 env.pop('IPYTHON_DIR', None)
305 env.pop('IPYTHONDIR', None)
305 env.pop('IPYTHONDIR', None)
306 env.pop('XDG_CONFIG_HOME', None)
306 env.pop('XDG_CONFIG_HOME', None)
307
307
308 nt.assert_equal(path.get_xdg_dir(), os.path.join('somewhere', '.config'))
308 nt.assert_equal(path.get_xdg_dir(), os.path.join('somewhere', '.config'))
309
309
310
310
311 @with_environment
311 @with_environment
312 def test_get_xdg_dir_1():
312 def test_get_xdg_dir_1():
313 """test_get_xdg_dir_1, check nonexistant xdg_dir"""
313 """test_get_xdg_dir_1, check nonexistant xdg_dir"""
314 reload(path)
314 reload(path)
315 path.get_home_dir = lambda : HOME_TEST_DIR
315 path.get_home_dir = lambda : HOME_TEST_DIR
316 os.name = "posix"
316 os.name = "posix"
317 sys.platform = "linux2"
317 sys.platform = "linux2"
318 env.pop('IPYTHON_DIR', None)
318 env.pop('IPYTHON_DIR', None)
319 env.pop('IPYTHONDIR', None)
319 env.pop('IPYTHONDIR', None)
320 env.pop('XDG_CONFIG_HOME', None)
320 env.pop('XDG_CONFIG_HOME', None)
321 nt.assert_equal(path.get_xdg_dir(), None)
321 nt.assert_equal(path.get_xdg_dir(), None)
322
322
323 @with_environment
323 @with_environment
324 def test_get_xdg_dir_2():
324 def test_get_xdg_dir_2():
325 """test_get_xdg_dir_2, check xdg_dir default to ~/.config"""
325 """test_get_xdg_dir_2, check xdg_dir default to ~/.config"""
326 reload(path)
326 reload(path)
327 path.get_home_dir = lambda : HOME_TEST_DIR
327 path.get_home_dir = lambda : HOME_TEST_DIR
328 os.name = "posix"
328 os.name = "posix"
329 sys.platform = "linux2"
329 sys.platform = "linux2"
330 env.pop('IPYTHON_DIR', None)
330 env.pop('IPYTHON_DIR', None)
331 env.pop('IPYTHONDIR', None)
331 env.pop('IPYTHONDIR', None)
332 env.pop('XDG_CONFIG_HOME', None)
332 env.pop('XDG_CONFIG_HOME', None)
333 cfgdir=os.path.join(path.get_home_dir(), '.config')
333 cfgdir=os.path.join(path.get_home_dir(), '.config')
334 if not os.path.exists(cfgdir):
334 if not os.path.exists(cfgdir):
335 os.makedirs(cfgdir)
335 os.makedirs(cfgdir)
336
336
337 nt.assert_equal(path.get_xdg_dir(), cfgdir)
337 nt.assert_equal(path.get_xdg_dir(), cfgdir)
338
338
339 @with_environment
339 @with_environment
340 def test_get_xdg_dir_3():
340 def test_get_xdg_dir_3():
341 """test_get_xdg_dir_3, check xdg_dir not used on OS X"""
341 """test_get_xdg_dir_3, check xdg_dir not used on OS X"""
342 reload(path)
342 reload(path)
343 path.get_home_dir = lambda : HOME_TEST_DIR
343 path.get_home_dir = lambda : HOME_TEST_DIR
344 os.name = "posix"
344 os.name = "posix"
345 sys.platform = "darwin"
345 sys.platform = "darwin"
346 env.pop('IPYTHON_DIR', None)
346 env.pop('IPYTHON_DIR', None)
347 env.pop('IPYTHONDIR', None)
347 env.pop('IPYTHONDIR', None)
348 env.pop('XDG_CONFIG_HOME', None)
348 env.pop('XDG_CONFIG_HOME', None)
349 cfgdir=os.path.join(path.get_home_dir(), '.config')
349 cfgdir=os.path.join(path.get_home_dir(), '.config')
350 if not os.path.exists(cfgdir):
350 if not os.path.exists(cfgdir):
351 os.makedirs(cfgdir)
351 os.makedirs(cfgdir)
352
352
353 nt.assert_equal(path.get_xdg_dir(), None)
353 nt.assert_equal(path.get_xdg_dir(), None)
354
354
355 def test_filefind():
355 def test_filefind():
356 """Various tests for filefind"""
356 """Various tests for filefind"""
357 f = tempfile.NamedTemporaryFile()
357 f = tempfile.NamedTemporaryFile()
358 # print 'fname:',f.name
358 # print 'fname:',f.name
359 alt_dirs = path.get_ipython_dir()
359 alt_dirs = path.get_ipython_dir()
360 t = path.filefind(f.name, alt_dirs)
360 t = path.filefind(f.name, alt_dirs)
361 # print 'found:',t
361 # print 'found:',t
362
362
363
363
364 def test_get_ipython_package_dir():
364 def test_get_ipython_package_dir():
365 ipdir = path.get_ipython_package_dir()
365 ipdir = path.get_ipython_package_dir()
366 nt.assert_true(os.path.isdir(ipdir))
366 nt.assert_true(os.path.isdir(ipdir))
367
367
368
368
369 def test_get_ipython_module_path():
369 def test_get_ipython_module_path():
370 ipapp_path = path.get_ipython_module_path('IPython.frontend.terminal.ipapp')
370 ipapp_path = path.get_ipython_module_path('IPython.frontend.terminal.ipapp')
371 nt.assert_true(os.path.isfile(ipapp_path))
371 nt.assert_true(os.path.isfile(ipapp_path))
372
372
373
373
374 @dec.skip_if_not_win32
374 @dec.skip_if_not_win32
375 def test_get_long_path_name_win32():
375 def test_get_long_path_name_win32():
376 p = path.get_long_path_name('c:\\docume~1')
376 p = path.get_long_path_name('c:\\docume~1')
377 nt.assert_equals(p,u'c:\\Documents and Settings')
377 nt.assert_equals(p,u'c:\\Documents and Settings')
378
378
379
379
380 @dec.skip_win32
380 @dec.skip_win32
381 def test_get_long_path_name():
381 def test_get_long_path_name():
382 p = path.get_long_path_name('/usr/local')
382 p = path.get_long_path_name('/usr/local')
383 nt.assert_equals(p,'/usr/local')
383 nt.assert_equals(p,'/usr/local')
384
384
385 @dec.skip_win32 # can't create not-user-writable dir on win
385 @dec.skip_win32 # can't create not-user-writable dir on win
386 @with_environment
386 @with_environment
387 def test_not_writable_ipdir():
387 def test_not_writable_ipdir():
388 tmpdir = tempfile.mkdtemp()
388 tmpdir = tempfile.mkdtemp()
389 os.name = "posix"
389 os.name = "posix"
390 env.pop('IPYTHON_DIR', None)
390 env.pop('IPYTHON_DIR', None)
391 env.pop('IPYTHONDIR', None)
391 env.pop('IPYTHONDIR', None)
392 env.pop('XDG_CONFIG_HOME', None)
392 env.pop('XDG_CONFIG_HOME', None)
393 env['HOME'] = tmpdir
393 env['HOME'] = tmpdir
394 ipdir = os.path.join(tmpdir, '.ipython')
394 ipdir = os.path.join(tmpdir, '.ipython')
395 os.mkdir(ipdir)
395 os.mkdir(ipdir)
396 os.chmod(ipdir, 600)
396 os.chmod(ipdir, 600)
397 with AssertPrints('is not a writable location', channel='stderr'):
397 with AssertPrints('is not a writable location', channel='stderr'):
398 ipdir = path.get_ipython_dir()
398 ipdir = path.get_ipython_dir()
399 env.pop('IPYTHON_DIR', None)
399 env.pop('IPYTHON_DIR', None)
400
400
401 def test_unquote_filename():
401 def test_unquote_filename():
402 for win32 in (True, False):
402 for win32 in (True, False):
403 nt.assert_equals(path.unquote_filename('foo.py', win32=win32), 'foo.py')
403 nt.assert_equals(path.unquote_filename('foo.py', win32=win32), 'foo.py')
404 nt.assert_equals(path.unquote_filename('foo bar.py', win32=win32), 'foo bar.py')
404 nt.assert_equals(path.unquote_filename('foo bar.py', win32=win32), 'foo bar.py')
405 nt.assert_equals(path.unquote_filename('"foo.py"', win32=True), 'foo.py')
405 nt.assert_equals(path.unquote_filename('"foo.py"', win32=True), 'foo.py')
406 nt.assert_equals(path.unquote_filename('"foo bar.py"', win32=True), 'foo bar.py')
406 nt.assert_equals(path.unquote_filename('"foo bar.py"', win32=True), 'foo bar.py')
407 nt.assert_equals(path.unquote_filename("'foo.py'", win32=True), 'foo.py')
407 nt.assert_equals(path.unquote_filename("'foo.py'", win32=True), 'foo.py')
408 nt.assert_equals(path.unquote_filename("'foo bar.py'", win32=True), 'foo bar.py')
408 nt.assert_equals(path.unquote_filename("'foo bar.py'", win32=True), 'foo bar.py')
409 nt.assert_equals(path.unquote_filename('"foo.py"', win32=False), '"foo.py"')
409 nt.assert_equals(path.unquote_filename('"foo.py"', win32=False), '"foo.py"')
410 nt.assert_equals(path.unquote_filename('"foo bar.py"', win32=False), '"foo bar.py"')
410 nt.assert_equals(path.unquote_filename('"foo bar.py"', win32=False), '"foo bar.py"')
411 nt.assert_equals(path.unquote_filename("'foo.py'", win32=False), "'foo.py'")
411 nt.assert_equals(path.unquote_filename("'foo.py'", win32=False), "'foo.py'")
412 nt.assert_equals(path.unquote_filename("'foo bar.py'", win32=False), "'foo bar.py'")
412 nt.assert_equals(path.unquote_filename("'foo bar.py'", win32=False), "'foo bar.py'")
413
413
414 @with_environment
414 @with_environment
415 def test_get_py_filename():
415 def test_get_py_filename():
416 os.chdir(TMP_TEST_DIR)
416 os.chdir(TMP_TEST_DIR)
417 for win32 in (True, False):
417 for win32 in (True, False):
418 with make_tempfile('foo.py'):
418 with make_tempfile('foo.py'):
419 nt.assert_equals(path.get_py_filename('foo.py', force_win32=win32), 'foo.py')
419 nt.assert_equals(path.get_py_filename('foo.py', force_win32=win32), 'foo.py')
420 nt.assert_equals(path.get_py_filename('foo', force_win32=win32), 'foo.py')
420 nt.assert_equals(path.get_py_filename('foo', force_win32=win32), 'foo.py')
421 with make_tempfile('foo'):
421 with make_tempfile('foo'):
422 nt.assert_equals(path.get_py_filename('foo', force_win32=win32), 'foo')
422 nt.assert_equals(path.get_py_filename('foo', force_win32=win32), 'foo')
423 nt.assert_raises(IOError, path.get_py_filename, 'foo.py', force_win32=win32)
423 nt.assert_raises(IOError, path.get_py_filename, 'foo.py', force_win32=win32)
424 nt.assert_raises(IOError, path.get_py_filename, 'foo', force_win32=win32)
424 nt.assert_raises(IOError, path.get_py_filename, 'foo', force_win32=win32)
425 nt.assert_raises(IOError, path.get_py_filename, 'foo.py', force_win32=win32)
425 nt.assert_raises(IOError, path.get_py_filename, 'foo.py', force_win32=win32)
426 true_fn = 'foo with spaces.py'
426 true_fn = 'foo with spaces.py'
427 with make_tempfile(true_fn):
427 with make_tempfile(true_fn):
428 nt.assert_equals(path.get_py_filename('foo with spaces', force_win32=win32), true_fn)
428 nt.assert_equals(path.get_py_filename('foo with spaces', force_win32=win32), true_fn)
429 nt.assert_equals(path.get_py_filename('foo with spaces.py', force_win32=win32), true_fn)
429 nt.assert_equals(path.get_py_filename('foo with spaces.py', force_win32=win32), true_fn)
430 if win32:
430 if win32:
431 nt.assert_equals(path.get_py_filename('"foo with spaces.py"', force_win32=True), true_fn)
431 nt.assert_equals(path.get_py_filename('"foo with spaces.py"', force_win32=True), true_fn)
432 nt.assert_equals(path.get_py_filename("'foo with spaces.py'", force_win32=True), true_fn)
432 nt.assert_equals(path.get_py_filename("'foo with spaces.py'", force_win32=True), true_fn)
433 else:
433 else:
434 nt.assert_raises(IOError, path.get_py_filename, '"foo with spaces.py"', force_win32=False)
434 nt.assert_raises(IOError, path.get_py_filename, '"foo with spaces.py"', force_win32=False)
435 nt.assert_raises(IOError, path.get_py_filename, "'foo with spaces.py'", force_win32=False)
435 nt.assert_raises(IOError, path.get_py_filename, "'foo with spaces.py'", force_win32=False)
436
436
437 def test_unicode_in_filename():
437 def test_unicode_in_filename():
438 """When a file doesn't exist, the exception raised should be safe to call
438 """When a file doesn't exist, the exception raised should be safe to call
439 str() on - i.e. in Python 2 it must only have ASCII characters.
439 str() on - i.e. in Python 2 it must only have ASCII characters.
440
440
441 https://github.com/ipython/ipython/issues/875
441 https://github.com/ipython/ipython/issues/875
442 """
442 """
443 try:
443 try:
444 # these calls should not throw unicode encode exceptions
444 # these calls should not throw unicode encode exceptions
445 path.get_py_filename(u'fooéè.py', force_win32=False)
445 path.get_py_filename(u'fooéè.py', force_win32=False)
446 except IOError as ex:
446 except IOError as ex:
447 str(ex)
447 str(ex)
448
448
449
449
450 def test_globlist():
450 def test_shellglob():
451 """Test glob expansion for %run magic."""
451 """Test glob expansion for %run magic."""
452 filenames_start_with_a = map('a{0}'.format, range(3))
452 filenames_start_with_a = map('a{0}'.format, range(3))
453 filenames_end_with_b = map('{0}b'.format, range(3))
453 filenames_end_with_b = map('{0}b'.format, range(3))
454 filenames = filenames_start_with_a + filenames_end_with_b
454 filenames = filenames_start_with_a + filenames_end_with_b
455
455
456 with TemporaryDirectory() as td:
456 with TemporaryDirectory() as td:
457 save = os.getcwdu()
457 save = os.getcwdu()
458 try:
458 try:
459 os.chdir(td)
459 os.chdir(td)
460
460
461 # Create empty files
461 # Create empty files
462 for fname in filenames:
462 for fname in filenames:
463 open(os.path.join(td, fname), 'w').close()
463 open(os.path.join(td, fname), 'w').close()
464
464
465 def assert_match(patterns, matches):
465 def assert_match(patterns, matches):
466 # glob returns unordered list. that's why sorted is required.
466 # glob returns unordered list. that's why sorted is required.
467 nt.assert_equals(sorted(path.globlist(patterns)),
467 nt.assert_equals(sorted(path.shellglob(patterns)),
468 sorted(matches))
468 sorted(matches))
469
469
470 assert_match(['*'], filenames)
470 assert_match(['*'], filenames)
471 assert_match(['a*'], filenames_start_with_a)
471 assert_match(['a*'], filenames_start_with_a)
472 assert_match(['*c'], ['*c'])
472 assert_match(['*c'], ['*c'])
473 assert_match(['*', 'a*', '*b', '*c'],
473 assert_match(['*', 'a*', '*b', '*c'],
474 filenames
474 filenames
475 + filenames_start_with_a
475 + filenames_start_with_a
476 + filenames_end_with_b
476 + filenames_end_with_b
477 + ['*c'])
477 + ['*c'])
478 finally:
478 finally:
479 os.chdir(save)
479 os.chdir(save)
General Comments 0
You need to be logged in to leave comments. Login now