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