##// END OF EJS Templates
Changed get_ipython_dir to return unicode otherwise the ...
Jorgen Stenarson -
Show More
@@ -1,2167 +1,2167 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 General purpose utilities.
4 4
5 5 This is a grab-bag of stuff I find useful in most programs I write. Some of
6 6 these things are also convenient when working at the command line.
7 7
8 8 $Id: genutils.py 2998 2008-01-31 10:06:04Z vivainio $"""
9 9
10 10 #*****************************************************************************
11 11 # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu>
12 12 #
13 13 # Distributed under the terms of the BSD License. The full license is in
14 14 # the file COPYING, distributed as part of this software.
15 15 #*****************************************************************************
16 16
17 17 from IPython import Release
18 18 __author__ = '%s <%s>' % Release.authors['Fernando']
19 19 __license__ = Release.license
20 20
21 21 #****************************************************************************
22 22 # required modules from the Python standard library
23 23 import __main__
24 24 import commands
25 25 try:
26 26 import doctest
27 27 except ImportError:
28 28 pass
29 29 import os
30 30 import platform
31 31 import re
32 32 import shlex
33 33 import shutil
34 34 import subprocess
35 35 import sys
36 36 import tempfile
37 37 import time
38 38 import types
39 39 import warnings
40 40
41 41 # Curses and termios are Unix-only modules
42 42 try:
43 43 import curses
44 44 # We need termios as well, so if its import happens to raise, we bail on
45 45 # using curses altogether.
46 46 import termios
47 47 except ImportError:
48 48 USE_CURSES = False
49 49 else:
50 50 # Curses on Solaris may not be complete, so we can't use it there
51 51 USE_CURSES = hasattr(curses,'initscr')
52 52
53 53 # Other IPython utilities
54 54 import IPython
55 55 from IPython.Itpl import Itpl,itpl,printpl
56 56 from IPython import DPyGetOpt, platutils
57 57 from IPython.generics import result_display
58 58 import IPython.ipapi
59 59 from IPython.external.path import path
60 60 if os.name == "nt":
61 61 from IPython.winconsole import get_console_size
62 62
63 63 try:
64 64 set
65 65 except:
66 66 from sets import Set as set
67 67
68 68
69 69 #****************************************************************************
70 70 # Exceptions
71 71 class Error(Exception):
72 72 """Base class for exceptions in this module."""
73 73 pass
74 74
75 75 #----------------------------------------------------------------------------
76 76 class IOStream:
77 77 def __init__(self,stream,fallback):
78 78 if not hasattr(stream,'write') or not hasattr(stream,'flush'):
79 79 stream = fallback
80 80 self.stream = stream
81 81 self._swrite = stream.write
82 82 self.flush = stream.flush
83 83
84 84 def write(self,data):
85 85 try:
86 86 self._swrite(data)
87 87 except:
88 88 try:
89 89 # print handles some unicode issues which may trip a plain
90 90 # write() call. Attempt to emulate write() by using a
91 91 # trailing comma
92 92 print >> self.stream, data,
93 93 except:
94 94 # if we get here, something is seriously broken.
95 95 print >> sys.stderr, \
96 96 'ERROR - failed to write data to stream:', self.stream
97 97
98 98 def close(self):
99 99 pass
100 100
101 101
102 102 class IOTerm:
103 103 """ Term holds the file or file-like objects for handling I/O operations.
104 104
105 105 These are normally just sys.stdin, sys.stdout and sys.stderr but for
106 106 Windows they can can replaced to allow editing the strings before they are
107 107 displayed."""
108 108
109 109 # In the future, having IPython channel all its I/O operations through
110 110 # this class will make it easier to embed it into other environments which
111 111 # are not a normal terminal (such as a GUI-based shell)
112 112 def __init__(self,cin=None,cout=None,cerr=None):
113 113 self.cin = IOStream(cin,sys.stdin)
114 114 self.cout = IOStream(cout,sys.stdout)
115 115 self.cerr = IOStream(cerr,sys.stderr)
116 116
117 117 # Global variable to be used for all I/O
118 118 Term = IOTerm()
119 119
120 120 import IPython.rlineimpl as readline
121 121 # Remake Term to use the readline i/o facilities
122 122 if sys.platform == 'win32' and readline.have_readline:
123 123
124 124 Term = IOTerm(cout=readline._outputfile,cerr=readline._outputfile)
125 125
126 126
127 127 #****************************************************************************
128 128 # Generic warning/error printer, used by everything else
129 129 def warn(msg,level=2,exit_val=1):
130 130 """Standard warning printer. Gives formatting consistency.
131 131
132 132 Output is sent to Term.cerr (sys.stderr by default).
133 133
134 134 Options:
135 135
136 136 -level(2): allows finer control:
137 137 0 -> Do nothing, dummy function.
138 138 1 -> Print message.
139 139 2 -> Print 'WARNING:' + message. (Default level).
140 140 3 -> Print 'ERROR:' + message.
141 141 4 -> Print 'FATAL ERROR:' + message and trigger a sys.exit(exit_val).
142 142
143 143 -exit_val (1): exit value returned by sys.exit() for a level 4
144 144 warning. Ignored for all other levels."""
145 145
146 146 if level>0:
147 147 header = ['','','WARNING: ','ERROR: ','FATAL ERROR: ']
148 148 print >> Term.cerr, '%s%s' % (header[level],msg)
149 149 if level == 4:
150 150 print >> Term.cerr,'Exiting.\n'
151 151 sys.exit(exit_val)
152 152
153 153 def info(msg):
154 154 """Equivalent to warn(msg,level=1)."""
155 155
156 156 warn(msg,level=1)
157 157
158 158 def error(msg):
159 159 """Equivalent to warn(msg,level=3)."""
160 160
161 161 warn(msg,level=3)
162 162
163 163 def fatal(msg,exit_val=1):
164 164 """Equivalent to warn(msg,exit_val=exit_val,level=4)."""
165 165
166 166 warn(msg,exit_val=exit_val,level=4)
167 167
168 168 #---------------------------------------------------------------------------
169 169 # Debugging routines
170 170 #
171 171 def debugx(expr,pre_msg=''):
172 172 """Print the value of an expression from the caller's frame.
173 173
174 174 Takes an expression, evaluates it in the caller's frame and prints both
175 175 the given expression and the resulting value (as well as a debug mark
176 176 indicating the name of the calling function. The input must be of a form
177 177 suitable for eval().
178 178
179 179 An optional message can be passed, which will be prepended to the printed
180 180 expr->value pair."""
181 181
182 182 cf = sys._getframe(1)
183 183 print '[DBG:%s] %s%s -> %r' % (cf.f_code.co_name,pre_msg,expr,
184 184 eval(expr,cf.f_globals,cf.f_locals))
185 185
186 186 # deactivate it by uncommenting the following line, which makes it a no-op
187 187 #def debugx(expr,pre_msg=''): pass
188 188
189 189 #----------------------------------------------------------------------------
190 190 StringTypes = types.StringTypes
191 191
192 192 # Basic timing functionality
193 193
194 194 # If possible (Unix), use the resource module instead of time.clock()
195 195 try:
196 196 import resource
197 197 def clocku():
198 198 """clocku() -> floating point number
199 199
200 200 Return the *USER* CPU time in seconds since the start of the process.
201 201 This is done via a call to resource.getrusage, so it avoids the
202 202 wraparound problems in time.clock()."""
203 203
204 204 return resource.getrusage(resource.RUSAGE_SELF)[0]
205 205
206 206 def clocks():
207 207 """clocks() -> floating point number
208 208
209 209 Return the *SYSTEM* CPU time in seconds since the start of the process.
210 210 This is done via a call to resource.getrusage, so it avoids the
211 211 wraparound problems in time.clock()."""
212 212
213 213 return resource.getrusage(resource.RUSAGE_SELF)[1]
214 214
215 215 def clock():
216 216 """clock() -> floating point number
217 217
218 218 Return the *TOTAL USER+SYSTEM* CPU time in seconds since the start of
219 219 the process. This is done via a call to resource.getrusage, so it
220 220 avoids the wraparound problems in time.clock()."""
221 221
222 222 u,s = resource.getrusage(resource.RUSAGE_SELF)[:2]
223 223 return u+s
224 224
225 225 def clock2():
226 226 """clock2() -> (t_user,t_system)
227 227
228 228 Similar to clock(), but return a tuple of user/system times."""
229 229 return resource.getrusage(resource.RUSAGE_SELF)[:2]
230 230
231 231 except ImportError:
232 232 # There is no distinction of user/system time under windows, so we just use
233 233 # time.clock() for everything...
234 234 clocku = clocks = clock = time.clock
235 235 def clock2():
236 236 """Under windows, system CPU time can't be measured.
237 237
238 238 This just returns clock() and zero."""
239 239 return time.clock(),0.0
240 240
241 241 def timings_out(reps,func,*args,**kw):
242 242 """timings_out(reps,func,*args,**kw) -> (t_total,t_per_call,output)
243 243
244 244 Execute a function reps times, return a tuple with the elapsed total
245 245 CPU time in seconds, the time per call and the function's output.
246 246
247 247 Under Unix, the return value is the sum of user+system time consumed by
248 248 the process, computed via the resource module. This prevents problems
249 249 related to the wraparound effect which the time.clock() function has.
250 250
251 251 Under Windows the return value is in wall clock seconds. See the
252 252 documentation for the time module for more details."""
253 253
254 254 reps = int(reps)
255 255 assert reps >=1, 'reps must be >= 1'
256 256 if reps==1:
257 257 start = clock()
258 258 out = func(*args,**kw)
259 259 tot_time = clock()-start
260 260 else:
261 261 rng = xrange(reps-1) # the last time is executed separately to store output
262 262 start = clock()
263 263 for dummy in rng: func(*args,**kw)
264 264 out = func(*args,**kw) # one last time
265 265 tot_time = clock()-start
266 266 av_time = tot_time / reps
267 267 return tot_time,av_time,out
268 268
269 269 def timings(reps,func,*args,**kw):
270 270 """timings(reps,func,*args,**kw) -> (t_total,t_per_call)
271 271
272 272 Execute a function reps times, return a tuple with the elapsed total CPU
273 273 time in seconds and the time per call. These are just the first two values
274 274 in timings_out()."""
275 275
276 276 return timings_out(reps,func,*args,**kw)[0:2]
277 277
278 278 def timing(func,*args,**kw):
279 279 """timing(func,*args,**kw) -> t_total
280 280
281 281 Execute a function once, return the elapsed total CPU time in
282 282 seconds. This is just the first value in timings_out()."""
283 283
284 284 return timings_out(1,func,*args,**kw)[0]
285 285
286 286 #****************************************************************************
287 287 # file and system
288 288
289 289 def arg_split(s,posix=False):
290 290 """Split a command line's arguments in a shell-like manner.
291 291
292 292 This is a modified version of the standard library's shlex.split()
293 293 function, but with a default of posix=False for splitting, so that quotes
294 294 in inputs are respected."""
295 295
296 296 # XXX - there may be unicode-related problems here!!! I'm not sure that
297 297 # shlex is truly unicode-safe, so it might be necessary to do
298 298 #
299 299 # s = s.encode(sys.stdin.encoding)
300 300 #
301 301 # first, to ensure that shlex gets a normal string. Input from anyone who
302 302 # knows more about unicode and shlex than I would be good to have here...
303 303 lex = shlex.shlex(s, posix=posix)
304 304 lex.whitespace_split = True
305 305 return list(lex)
306 306
307 307 def system(cmd,verbose=0,debug=0,header=''):
308 308 """Execute a system command, return its exit status.
309 309
310 310 Options:
311 311
312 312 - verbose (0): print the command to be executed.
313 313
314 314 - debug (0): only print, do not actually execute.
315 315
316 316 - header (''): Header to print on screen prior to the executed command (it
317 317 is only prepended to the command, no newlines are added).
318 318
319 319 Note: a stateful version of this function is available through the
320 320 SystemExec class."""
321 321
322 322 stat = 0
323 323 if verbose or debug: print header+cmd
324 324 sys.stdout.flush()
325 325 if not debug: stat = os.system(cmd)
326 326 return stat
327 327
328 328 def abbrev_cwd():
329 329 """ Return abbreviated version of cwd, e.g. d:mydir """
330 330 cwd = os.getcwd().replace('\\','/')
331 331 drivepart = ''
332 332 tail = cwd
333 333 if sys.platform == 'win32':
334 334 if len(cwd) < 4:
335 335 return cwd
336 336 drivepart,tail = os.path.splitdrive(cwd)
337 337
338 338
339 339 parts = tail.split('/')
340 340 if len(parts) > 2:
341 341 tail = '/'.join(parts[-2:])
342 342
343 343 return (drivepart + (
344 344 cwd == '/' and '/' or tail))
345 345
346 346
347 347 # This function is used by ipython in a lot of places to make system calls.
348 348 # We need it to be slightly different under win32, due to the vagaries of
349 349 # 'network shares'. A win32 override is below.
350 350
351 351 def shell(cmd,verbose=0,debug=0,header=''):
352 352 """Execute a command in the system shell, always return None.
353 353
354 354 Options:
355 355
356 356 - verbose (0): print the command to be executed.
357 357
358 358 - debug (0): only print, do not actually execute.
359 359
360 360 - header (''): Header to print on screen prior to the executed command (it
361 361 is only prepended to the command, no newlines are added).
362 362
363 363 Note: this is similar to genutils.system(), but it returns None so it can
364 364 be conveniently used in interactive loops without getting the return value
365 365 (typically 0) printed many times."""
366 366
367 367 stat = 0
368 368 if verbose or debug: print header+cmd
369 369 # flush stdout so we don't mangle python's buffering
370 370 sys.stdout.flush()
371 371
372 372 if not debug:
373 373 platutils.set_term_title("IPy " + cmd)
374 374 os.system(cmd)
375 375 platutils.set_term_title("IPy " + abbrev_cwd())
376 376
377 377 # override shell() for win32 to deal with network shares
378 378 if os.name in ('nt','dos'):
379 379
380 380 shell_ori = shell
381 381
382 382 def shell(cmd,verbose=0,debug=0,header=''):
383 383 if os.getcwd().startswith(r"\\"):
384 384 path = os.getcwd()
385 385 # change to c drive (cannot be on UNC-share when issuing os.system,
386 386 # as cmd.exe cannot handle UNC addresses)
387 387 os.chdir("c:")
388 388 # issue pushd to the UNC-share and then run the command
389 389 try:
390 390 shell_ori('"pushd %s&&"'%path+cmd,verbose,debug,header)
391 391 finally:
392 392 os.chdir(path)
393 393 else:
394 394 shell_ori(cmd,verbose,debug,header)
395 395
396 396 shell.__doc__ = shell_ori.__doc__
397 397
398 398 def getoutput(cmd,verbose=0,debug=0,header='',split=0):
399 399 """Dummy substitute for perl's backquotes.
400 400
401 401 Executes a command and returns the output.
402 402
403 403 Accepts the same arguments as system(), plus:
404 404
405 405 - split(0): if true, the output is returned as a list split on newlines.
406 406
407 407 Note: a stateful version of this function is available through the
408 408 SystemExec class.
409 409
410 410 This is pretty much deprecated and rarely used,
411 411 genutils.getoutputerror may be what you need.
412 412
413 413 """
414 414
415 415 if verbose or debug: print header+cmd
416 416 if not debug:
417 417 output = os.popen(cmd).read()
418 418 # stipping last \n is here for backwards compat.
419 419 if output.endswith('\n'):
420 420 output = output[:-1]
421 421 if split:
422 422 return output.split('\n')
423 423 else:
424 424 return output
425 425
426 426 def getoutputerror(cmd,verbose=0,debug=0,header='',split=0):
427 427 """Return (standard output,standard error) of executing cmd in a shell.
428 428
429 429 Accepts the same arguments as system(), plus:
430 430
431 431 - split(0): if true, each of stdout/err is returned as a list split on
432 432 newlines.
433 433
434 434 Note: a stateful version of this function is available through the
435 435 SystemExec class."""
436 436
437 437 if verbose or debug: print header+cmd
438 438 if not cmd:
439 439 if split:
440 440 return [],[]
441 441 else:
442 442 return '',''
443 443 if not debug:
444 444 pin,pout,perr = os.popen3(cmd)
445 445 tout = pout.read().rstrip()
446 446 terr = perr.read().rstrip()
447 447 pin.close()
448 448 pout.close()
449 449 perr.close()
450 450 if split:
451 451 return tout.split('\n'),terr.split('\n')
452 452 else:
453 453 return tout,terr
454 454
455 455 # for compatibility with older naming conventions
456 456 xsys = system
457 457 bq = getoutput
458 458
459 459 class SystemExec:
460 460 """Access the system and getoutput functions through a stateful interface.
461 461
462 462 Note: here we refer to the system and getoutput functions from this
463 463 library, not the ones from the standard python library.
464 464
465 465 This class offers the system and getoutput functions as methods, but the
466 466 verbose, debug and header parameters can be set for the instance (at
467 467 creation time or later) so that they don't need to be specified on each
468 468 call.
469 469
470 470 For efficiency reasons, there's no way to override the parameters on a
471 471 per-call basis other than by setting instance attributes. If you need
472 472 local overrides, it's best to directly call system() or getoutput().
473 473
474 474 The following names are provided as alternate options:
475 475 - xsys: alias to system
476 476 - bq: alias to getoutput
477 477
478 478 An instance can then be created as:
479 479 >>> sysexec = SystemExec(verbose=1,debug=0,header='Calling: ')
480 480 """
481 481
482 482 def __init__(self,verbose=0,debug=0,header='',split=0):
483 483 """Specify the instance's values for verbose, debug and header."""
484 484 setattr_list(self,'verbose debug header split')
485 485
486 486 def system(self,cmd):
487 487 """Stateful interface to system(), with the same keyword parameters."""
488 488
489 489 system(cmd,self.verbose,self.debug,self.header)
490 490
491 491 def shell(self,cmd):
492 492 """Stateful interface to shell(), with the same keyword parameters."""
493 493
494 494 shell(cmd,self.verbose,self.debug,self.header)
495 495
496 496 xsys = system # alias
497 497
498 498 def getoutput(self,cmd):
499 499 """Stateful interface to getoutput()."""
500 500
501 501 return getoutput(cmd,self.verbose,self.debug,self.header,self.split)
502 502
503 503 def getoutputerror(self,cmd):
504 504 """Stateful interface to getoutputerror()."""
505 505
506 506 return getoutputerror(cmd,self.verbose,self.debug,self.header,self.split)
507 507
508 508 bq = getoutput # alias
509 509
510 510 #-----------------------------------------------------------------------------
511 511 def mutex_opts(dict,ex_op):
512 512 """Check for presence of mutually exclusive keys in a dict.
513 513
514 514 Call: mutex_opts(dict,[[op1a,op1b],[op2a,op2b]...]"""
515 515 for op1,op2 in ex_op:
516 516 if op1 in dict and op2 in dict:
517 517 raise ValueError,'\n*** ERROR in Arguments *** '\
518 518 'Options '+op1+' and '+op2+' are mutually exclusive.'
519 519
520 520 #-----------------------------------------------------------------------------
521 521 def get_py_filename(name):
522 522 """Return a valid python filename in the current directory.
523 523
524 524 If the given name is not a file, it adds '.py' and searches again.
525 525 Raises IOError with an informative message if the file isn't found."""
526 526
527 527 name = os.path.expanduser(name)
528 528 if not os.path.isfile(name) and not name.endswith('.py'):
529 529 name += '.py'
530 530 if os.path.isfile(name):
531 531 return name
532 532 else:
533 533 raise IOError,'File `%s` not found.' % name
534 534
535 535 #-----------------------------------------------------------------------------
536 536 def filefind(fname,alt_dirs = None):
537 537 """Return the given filename either in the current directory, if it
538 538 exists, or in a specified list of directories.
539 539
540 540 ~ expansion is done on all file and directory names.
541 541
542 542 Upon an unsuccessful search, raise an IOError exception."""
543 543
544 544 if alt_dirs is None:
545 545 try:
546 546 alt_dirs = get_home_dir()
547 547 except HomeDirError:
548 548 alt_dirs = os.getcwd()
549 549 search = [fname] + list_strings(alt_dirs)
550 550 search = map(os.path.expanduser,search)
551 551 #print 'search list for',fname,'list:',search # dbg
552 552 fname = search[0]
553 553 if os.path.isfile(fname):
554 554 return fname
555 555 for direc in search[1:]:
556 556 testname = os.path.join(direc,fname)
557 557 #print 'testname',testname # dbg
558 558 if os.path.isfile(testname):
559 559 return testname
560 560 raise IOError,'File' + `fname` + \
561 561 ' not found in current or supplied directories:' + `alt_dirs`
562 562
563 563 #----------------------------------------------------------------------------
564 564 def file_read(filename):
565 565 """Read a file and close it. Returns the file source."""
566 566 fobj = open(filename,'r');
567 567 source = fobj.read();
568 568 fobj.close()
569 569 return source
570 570
571 571 def file_readlines(filename):
572 572 """Read a file and close it. Returns the file source using readlines()."""
573 573 fobj = open(filename,'r');
574 574 lines = fobj.readlines();
575 575 fobj.close()
576 576 return lines
577 577
578 578 #----------------------------------------------------------------------------
579 579 def target_outdated(target,deps):
580 580 """Determine whether a target is out of date.
581 581
582 582 target_outdated(target,deps) -> 1/0
583 583
584 584 deps: list of filenames which MUST exist.
585 585 target: single filename which may or may not exist.
586 586
587 587 If target doesn't exist or is older than any file listed in deps, return
588 588 true, otherwise return false.
589 589 """
590 590 try:
591 591 target_time = os.path.getmtime(target)
592 592 except os.error:
593 593 return 1
594 594 for dep in deps:
595 595 dep_time = os.path.getmtime(dep)
596 596 if dep_time > target_time:
597 597 #print "For target",target,"Dep failed:",dep # dbg
598 598 #print "times (dep,tar):",dep_time,target_time # dbg
599 599 return 1
600 600 return 0
601 601
602 602 #-----------------------------------------------------------------------------
603 603 def target_update(target,deps,cmd):
604 604 """Update a target with a given command given a list of dependencies.
605 605
606 606 target_update(target,deps,cmd) -> runs cmd if target is outdated.
607 607
608 608 This is just a wrapper around target_outdated() which calls the given
609 609 command if target is outdated."""
610 610
611 611 if target_outdated(target,deps):
612 612 xsys(cmd)
613 613
614 614 #----------------------------------------------------------------------------
615 615 def unquote_ends(istr):
616 616 """Remove a single pair of quotes from the endpoints of a string."""
617 617
618 618 if not istr:
619 619 return istr
620 620 if (istr[0]=="'" and istr[-1]=="'") or \
621 621 (istr[0]=='"' and istr[-1]=='"'):
622 622 return istr[1:-1]
623 623 else:
624 624 return istr
625 625
626 626 #----------------------------------------------------------------------------
627 627 def process_cmdline(argv,names=[],defaults={},usage=''):
628 628 """ Process command-line options and arguments.
629 629
630 630 Arguments:
631 631
632 632 - argv: list of arguments, typically sys.argv.
633 633
634 634 - names: list of option names. See DPyGetOpt docs for details on options
635 635 syntax.
636 636
637 637 - defaults: dict of default values.
638 638
639 639 - usage: optional usage notice to print if a wrong argument is passed.
640 640
641 641 Return a dict of options and a list of free arguments."""
642 642
643 643 getopt = DPyGetOpt.DPyGetOpt()
644 644 getopt.setIgnoreCase(0)
645 645 getopt.parseConfiguration(names)
646 646
647 647 try:
648 648 getopt.processArguments(argv)
649 649 except DPyGetOpt.ArgumentError, exc:
650 650 print usage
651 651 warn('"%s"' % exc,level=4)
652 652
653 653 defaults.update(getopt.optionValues)
654 654 args = getopt.freeValues
655 655
656 656 return defaults,args
657 657
658 658 #----------------------------------------------------------------------------
659 659 def optstr2types(ostr):
660 660 """Convert a string of option names to a dict of type mappings.
661 661
662 662 optstr2types(str) -> {None:'string_opts',int:'int_opts',float:'float_opts'}
663 663
664 664 This is used to get the types of all the options in a string formatted
665 665 with the conventions of DPyGetOpt. The 'type' None is used for options
666 666 which are strings (they need no further conversion). This function's main
667 667 use is to get a typemap for use with read_dict().
668 668 """
669 669
670 670 typeconv = {None:'',int:'',float:''}
671 671 typemap = {'s':None,'i':int,'f':float}
672 672 opt_re = re.compile(r'([\w]*)([^:=]*:?=?)([sif]?)')
673 673
674 674 for w in ostr.split():
675 675 oname,alias,otype = opt_re.match(w).groups()
676 676 if otype == '' or alias == '!': # simple switches are integers too
677 677 otype = 'i'
678 678 typeconv[typemap[otype]] += oname + ' '
679 679 return typeconv
680 680
681 681 #----------------------------------------------------------------------------
682 682 def read_dict(filename,type_conv=None,**opt):
683 683 r"""Read a dictionary of key=value pairs from an input file, optionally
684 684 performing conversions on the resulting values.
685 685
686 686 read_dict(filename,type_conv,**opt) -> dict
687 687
688 688 Only one value per line is accepted, the format should be
689 689 # optional comments are ignored
690 690 key value\n
691 691
692 692 Args:
693 693
694 694 - type_conv: A dictionary specifying which keys need to be converted to
695 695 which types. By default all keys are read as strings. This dictionary
696 696 should have as its keys valid conversion functions for strings
697 697 (int,long,float,complex, or your own). The value for each key
698 698 (converter) should be a whitespace separated string containing the names
699 699 of all the entries in the file to be converted using that function. For
700 700 keys to be left alone, use None as the conversion function (only needed
701 701 with purge=1, see below).
702 702
703 703 - opt: dictionary with extra options as below (default in parens)
704 704
705 705 purge(0): if set to 1, all keys *not* listed in type_conv are purged out
706 706 of the dictionary to be returned. If purge is going to be used, the
707 707 set of keys to be left as strings also has to be explicitly specified
708 708 using the (non-existent) conversion function None.
709 709
710 710 fs(None): field separator. This is the key/value separator to be used
711 711 when parsing the file. The None default means any whitespace [behavior
712 712 of string.split()].
713 713
714 714 strip(0): if 1, strip string values of leading/trailinig whitespace.
715 715
716 716 warn(1): warning level if requested keys are not found in file.
717 717 - 0: silently ignore.
718 718 - 1: inform but proceed.
719 719 - 2: raise KeyError exception.
720 720
721 721 no_empty(0): if 1, remove keys with whitespace strings as a value.
722 722
723 723 unique([]): list of keys (or space separated string) which can't be
724 724 repeated. If one such key is found in the file, each new instance
725 725 overwrites the previous one. For keys not listed here, the behavior is
726 726 to make a list of all appearances.
727 727
728 728 Example:
729 729
730 730 If the input file test.ini contains (we put it in a string to keep the test
731 731 self-contained):
732 732
733 733 >>> test_ini = '''\
734 734 ... i 3
735 735 ... x 4.5
736 736 ... y 5.5
737 737 ... s hi ho'''
738 738
739 739 Then we can use it as follows:
740 740 >>> type_conv={int:'i',float:'x',None:'s'}
741 741
742 742 >>> d = read_dict(test_ini)
743 743
744 744 >>> sorted(d.items())
745 745 [('i', '3'), ('s', 'hi ho'), ('x', '4.5'), ('y', '5.5')]
746 746
747 747 >>> d = read_dict(test_ini,type_conv)
748 748
749 749 >>> sorted(d.items())
750 750 [('i', 3), ('s', 'hi ho'), ('x', 4.5), ('y', '5.5')]
751 751
752 752 >>> d = read_dict(test_ini,type_conv,purge=True)
753 753
754 754 >>> sorted(d.items())
755 755 [('i', 3), ('s', 'hi ho'), ('x', 4.5)]
756 756 """
757 757
758 758 # starting config
759 759 opt.setdefault('purge',0)
760 760 opt.setdefault('fs',None) # field sep defaults to any whitespace
761 761 opt.setdefault('strip',0)
762 762 opt.setdefault('warn',1)
763 763 opt.setdefault('no_empty',0)
764 764 opt.setdefault('unique','')
765 765 if type(opt['unique']) in StringTypes:
766 766 unique_keys = qw(opt['unique'])
767 767 elif type(opt['unique']) in (types.TupleType,types.ListType):
768 768 unique_keys = opt['unique']
769 769 else:
770 770 raise ValueError, 'Unique keys must be given as a string, List or Tuple'
771 771
772 772 dict = {}
773 773
774 774 # first read in table of values as strings
775 775 if '\n' in filename:
776 776 lines = filename.splitlines()
777 777 file = None
778 778 else:
779 779 file = open(filename,'r')
780 780 lines = file.readlines()
781 781 for line in lines:
782 782 line = line.strip()
783 783 if len(line) and line[0]=='#': continue
784 784 if len(line)>0:
785 785 lsplit = line.split(opt['fs'],1)
786 786 try:
787 787 key,val = lsplit
788 788 except ValueError:
789 789 key,val = lsplit[0],''
790 790 key = key.strip()
791 791 if opt['strip']: val = val.strip()
792 792 if val == "''" or val == '""': val = ''
793 793 if opt['no_empty'] and (val=='' or val.isspace()):
794 794 continue
795 795 # if a key is found more than once in the file, build a list
796 796 # unless it's in the 'unique' list. In that case, last found in file
797 797 # takes precedence. User beware.
798 798 try:
799 799 if dict[key] and key in unique_keys:
800 800 dict[key] = val
801 801 elif type(dict[key]) is types.ListType:
802 802 dict[key].append(val)
803 803 else:
804 804 dict[key] = [dict[key],val]
805 805 except KeyError:
806 806 dict[key] = val
807 807 # purge if requested
808 808 if opt['purge']:
809 809 accepted_keys = qwflat(type_conv.values())
810 810 for key in dict.keys():
811 811 if key in accepted_keys: continue
812 812 del(dict[key])
813 813 # now convert if requested
814 814 if type_conv==None: return dict
815 815 conversions = type_conv.keys()
816 816 try: conversions.remove(None)
817 817 except: pass
818 818 for convert in conversions:
819 819 for val in qw(type_conv[convert]):
820 820 try:
821 821 dict[val] = convert(dict[val])
822 822 except KeyError,e:
823 823 if opt['warn'] == 0:
824 824 pass
825 825 elif opt['warn'] == 1:
826 826 print >>sys.stderr, 'Warning: key',val,\
827 827 'not found in file',filename
828 828 elif opt['warn'] == 2:
829 829 raise KeyError,e
830 830 else:
831 831 raise ValueError,'Warning level must be 0,1 or 2'
832 832
833 833 return dict
834 834
835 835 #----------------------------------------------------------------------------
836 836 def flag_calls(func):
837 837 """Wrap a function to detect and flag when it gets called.
838 838
839 839 This is a decorator which takes a function and wraps it in a function with
840 840 a 'called' attribute. wrapper.called is initialized to False.
841 841
842 842 The wrapper.called attribute is set to False right before each call to the
843 843 wrapped function, so if the call fails it remains False. After the call
844 844 completes, wrapper.called is set to True and the output is returned.
845 845
846 846 Testing for truth in wrapper.called allows you to determine if a call to
847 847 func() was attempted and succeeded."""
848 848
849 849 def wrapper(*args,**kw):
850 850 wrapper.called = False
851 851 out = func(*args,**kw)
852 852 wrapper.called = True
853 853 return out
854 854
855 855 wrapper.called = False
856 856 wrapper.__doc__ = func.__doc__
857 857 return wrapper
858 858
859 859 #----------------------------------------------------------------------------
860 860 def dhook_wrap(func,*a,**k):
861 861 """Wrap a function call in a sys.displayhook controller.
862 862
863 863 Returns a wrapper around func which calls func, with all its arguments and
864 864 keywords unmodified, using the default sys.displayhook. Since IPython
865 865 modifies sys.displayhook, it breaks the behavior of certain systems that
866 866 rely on the default behavior, notably doctest.
867 867 """
868 868
869 869 def f(*a,**k):
870 870
871 871 dhook_s = sys.displayhook
872 872 sys.displayhook = sys.__displayhook__
873 873 try:
874 874 out = func(*a,**k)
875 875 finally:
876 876 sys.displayhook = dhook_s
877 877
878 878 return out
879 879
880 880 f.__doc__ = func.__doc__
881 881 return f
882 882
883 883 #----------------------------------------------------------------------------
884 884 def doctest_reload():
885 885 """Properly reload doctest to reuse it interactively.
886 886
887 887 This routine:
888 888
889 889 - reloads doctest
890 890
891 891 - resets its global 'master' attribute to None, so that multiple uses of
892 892 the module interactively don't produce cumulative reports.
893 893
894 894 - Monkeypatches its core test runner method to protect it from IPython's
895 895 modified displayhook. Doctest expects the default displayhook behavior
896 896 deep down, so our modification breaks it completely. For this reason, a
897 897 hard monkeypatch seems like a reasonable solution rather than asking
898 898 users to manually use a different doctest runner when under IPython."""
899 899
900 900 import doctest
901 901 reload(doctest)
902 902 doctest.master=None
903 903
904 904 try:
905 905 doctest.DocTestRunner
906 906 except AttributeError:
907 907 # This is only for python 2.3 compatibility, remove once we move to
908 908 # 2.4 only.
909 909 pass
910 910 else:
911 911 doctest.DocTestRunner.run = dhook_wrap(doctest.DocTestRunner.run)
912 912
913 913 #----------------------------------------------------------------------------
914 914 class HomeDirError(Error):
915 915 pass
916 916
917 917 def get_home_dir():
918 918 """Return the closest possible equivalent to a 'home' directory.
919 919
920 920 We first try $HOME. Absent that, on NT it's $HOMEDRIVE\$HOMEPATH.
921 921
922 922 Currently only Posix and NT are implemented, a HomeDirError exception is
923 923 raised for all other OSes. """
924 924
925 925 isdir = os.path.isdir
926 926 env = os.environ
927 927
928 928 # first, check py2exe distribution root directory for _ipython.
929 929 # This overrides all. Normally does not exist.
930 930
931 931 if hasattr(sys, "frozen"): #Is frozen by py2exe
932 932 if '\\library.zip\\' in IPython.__file__.lower():#libraries compressed to zip-file
933 933 root, rest = IPython.__file__.lower().split('library.zip')
934 934 else:
935 935 root=os.path.join(os.path.split(IPython.__file__)[0],"../../")
936 936 root=os.path.abspath(root).rstrip('\\')
937 937 if isdir(os.path.join(root, '_ipython')):
938 938 os.environ["IPYKITROOT"] = root
939 939 return root
940 940 try:
941 941 homedir = env['HOME']
942 942 if not isdir(homedir):
943 943 # in case a user stuck some string which does NOT resolve to a
944 944 # valid path, it's as good as if we hadn't foud it
945 945 raise KeyError
946 946 return homedir
947 947 except KeyError:
948 948 if os.name == 'posix':
949 949 raise HomeDirError,'undefined $HOME, IPython can not proceed.'
950 950 elif os.name == 'nt':
951 951 # For some strange reason, win9x returns 'nt' for os.name.
952 952 try:
953 953 homedir = os.path.join(env['HOMEDRIVE'],env['HOMEPATH'])
954 954 if not isdir(homedir):
955 955 homedir = os.path.join(env['USERPROFILE'])
956 956 if not isdir(homedir):
957 957 raise HomeDirError
958 958 return homedir
959 959 except KeyError:
960 960 try:
961 961 # Use the registry to get the 'My Documents' folder.
962 962 import _winreg as wreg
963 963 key = wreg.OpenKey(wreg.HKEY_CURRENT_USER,
964 964 "Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders")
965 965 homedir = wreg.QueryValueEx(key,'Personal')[0]
966 966 key.Close()
967 967 if not isdir(homedir):
968 968 e = ('Invalid "Personal" folder registry key '
969 969 'typically "My Documents".\n'
970 970 'Value: %s\n'
971 971 'This is not a valid directory on your system.' %
972 972 homedir)
973 973 raise HomeDirError(e)
974 974 return homedir
975 975 except HomeDirError:
976 976 raise
977 977 except:
978 978 return 'C:\\'
979 979 elif os.name == 'dos':
980 980 # Desperate, may do absurd things in classic MacOS. May work under DOS.
981 981 return 'C:\\'
982 982 else:
983 983 raise HomeDirError,'support for your operating system not implemented.'
984 984
985 985
986 986 def get_ipython_dir():
987 987 """Get the IPython directory for this platform and user.
988 988
989 989 This uses the logic in `get_home_dir` to find the home directory
990 990 and the adds either .ipython or _ipython to the end of the path.
991 991 """
992 992 if os.name == 'posix':
993 993 ipdir_def = '.ipython'
994 994 else:
995 995 ipdir_def = '_ipython'
996 996 home_dir = get_home_dir()
997 997 ipdir = os.path.abspath(os.environ.get('IPYTHONDIR',
998 os.path.join(home_dir,ipdir_def)))
999 return ipdir
998 os.path.join(home_dir, ipdir_def)))
999 return ipdir.decode(sys.getfilesystemencoding())
1000 1000
1001 1001 def get_security_dir():
1002 1002 """Get the IPython security directory.
1003 1003
1004 1004 This directory is the default location for all security related files,
1005 1005 including SSL/TLS certificates and FURL files.
1006 1006
1007 1007 If the directory does not exist, it is created with 0700 permissions.
1008 1008 If it exists, permissions are set to 0700.
1009 1009 """
1010 1010 security_dir = os.path.join(get_ipython_dir(), 'security')
1011 1011 if not os.path.isdir(security_dir):
1012 1012 os.mkdir(security_dir, 0700)
1013 1013 else:
1014 1014 os.chmod(security_dir, 0700)
1015 1015 return security_dir
1016 1016
1017 1017 #****************************************************************************
1018 1018 # strings and text
1019 1019
1020 1020 class LSString(str):
1021 1021 """String derivative with a special access attributes.
1022 1022
1023 1023 These are normal strings, but with the special attributes:
1024 1024
1025 1025 .l (or .list) : value as list (split on newlines).
1026 1026 .n (or .nlstr): original value (the string itself).
1027 1027 .s (or .spstr): value as whitespace-separated string.
1028 1028 .p (or .paths): list of path objects
1029 1029
1030 1030 Any values which require transformations are computed only once and
1031 1031 cached.
1032 1032
1033 1033 Such strings are very useful to efficiently interact with the shell, which
1034 1034 typically only understands whitespace-separated options for commands."""
1035 1035
1036 1036 def get_list(self):
1037 1037 try:
1038 1038 return self.__list
1039 1039 except AttributeError:
1040 1040 self.__list = self.split('\n')
1041 1041 return self.__list
1042 1042
1043 1043 l = list = property(get_list)
1044 1044
1045 1045 def get_spstr(self):
1046 1046 try:
1047 1047 return self.__spstr
1048 1048 except AttributeError:
1049 1049 self.__spstr = self.replace('\n',' ')
1050 1050 return self.__spstr
1051 1051
1052 1052 s = spstr = property(get_spstr)
1053 1053
1054 1054 def get_nlstr(self):
1055 1055 return self
1056 1056
1057 1057 n = nlstr = property(get_nlstr)
1058 1058
1059 1059 def get_paths(self):
1060 1060 try:
1061 1061 return self.__paths
1062 1062 except AttributeError:
1063 1063 self.__paths = [path(p) for p in self.split('\n') if os.path.exists(p)]
1064 1064 return self.__paths
1065 1065
1066 1066 p = paths = property(get_paths)
1067 1067
1068 1068 def print_lsstring(arg):
1069 1069 """ Prettier (non-repr-like) and more informative printer for LSString """
1070 1070 print "LSString (.p, .n, .l, .s available). Value:"
1071 1071 print arg
1072 1072
1073 1073 print_lsstring = result_display.when_type(LSString)(print_lsstring)
1074 1074
1075 1075 #----------------------------------------------------------------------------
1076 1076 class SList(list):
1077 1077 """List derivative with a special access attributes.
1078 1078
1079 1079 These are normal lists, but with the special attributes:
1080 1080
1081 1081 .l (or .list) : value as list (the list itself).
1082 1082 .n (or .nlstr): value as a string, joined on newlines.
1083 1083 .s (or .spstr): value as a string, joined on spaces.
1084 1084 .p (or .paths): list of path objects
1085 1085
1086 1086 Any values which require transformations are computed only once and
1087 1087 cached."""
1088 1088
1089 1089 def get_list(self):
1090 1090 return self
1091 1091
1092 1092 l = list = property(get_list)
1093 1093
1094 1094 def get_spstr(self):
1095 1095 try:
1096 1096 return self.__spstr
1097 1097 except AttributeError:
1098 1098 self.__spstr = ' '.join(self)
1099 1099 return self.__spstr
1100 1100
1101 1101 s = spstr = property(get_spstr)
1102 1102
1103 1103 def get_nlstr(self):
1104 1104 try:
1105 1105 return self.__nlstr
1106 1106 except AttributeError:
1107 1107 self.__nlstr = '\n'.join(self)
1108 1108 return self.__nlstr
1109 1109
1110 1110 n = nlstr = property(get_nlstr)
1111 1111
1112 1112 def get_paths(self):
1113 1113 try:
1114 1114 return self.__paths
1115 1115 except AttributeError:
1116 1116 self.__paths = [path(p) for p in self if os.path.exists(p)]
1117 1117 return self.__paths
1118 1118
1119 1119 p = paths = property(get_paths)
1120 1120
1121 1121 def grep(self, pattern, prune = False, field = None):
1122 1122 """ Return all strings matching 'pattern' (a regex or callable)
1123 1123
1124 1124 This is case-insensitive. If prune is true, return all items
1125 1125 NOT matching the pattern.
1126 1126
1127 1127 If field is specified, the match must occur in the specified
1128 1128 whitespace-separated field.
1129 1129
1130 1130 Examples::
1131 1131
1132 1132 a.grep( lambda x: x.startswith('C') )
1133 1133 a.grep('Cha.*log', prune=1)
1134 1134 a.grep('chm', field=-1)
1135 1135 """
1136 1136
1137 1137 def match_target(s):
1138 1138 if field is None:
1139 1139 return s
1140 1140 parts = s.split()
1141 1141 try:
1142 1142 tgt = parts[field]
1143 1143 return tgt
1144 1144 except IndexError:
1145 1145 return ""
1146 1146
1147 1147 if isinstance(pattern, basestring):
1148 1148 pred = lambda x : re.search(pattern, x, re.IGNORECASE)
1149 1149 else:
1150 1150 pred = pattern
1151 1151 if not prune:
1152 1152 return SList([el for el in self if pred(match_target(el))])
1153 1153 else:
1154 1154 return SList([el for el in self if not pred(match_target(el))])
1155 1155 def fields(self, *fields):
1156 1156 """ Collect whitespace-separated fields from string list
1157 1157
1158 1158 Allows quick awk-like usage of string lists.
1159 1159
1160 1160 Example data (in var a, created by 'a = !ls -l')::
1161 1161 -rwxrwxrwx 1 ville None 18 Dec 14 2006 ChangeLog
1162 1162 drwxrwxrwx+ 6 ville None 0 Oct 24 18:05 IPython
1163 1163
1164 1164 a.fields(0) is ['-rwxrwxrwx', 'drwxrwxrwx+']
1165 1165 a.fields(1,0) is ['1 -rwxrwxrwx', '6 drwxrwxrwx+']
1166 1166 (note the joining by space).
1167 1167 a.fields(-1) is ['ChangeLog', 'IPython']
1168 1168
1169 1169 IndexErrors are ignored.
1170 1170
1171 1171 Without args, fields() just split()'s the strings.
1172 1172 """
1173 1173 if len(fields) == 0:
1174 1174 return [el.split() for el in self]
1175 1175
1176 1176 res = SList()
1177 1177 for el in [f.split() for f in self]:
1178 1178 lineparts = []
1179 1179
1180 1180 for fd in fields:
1181 1181 try:
1182 1182 lineparts.append(el[fd])
1183 1183 except IndexError:
1184 1184 pass
1185 1185 if lineparts:
1186 1186 res.append(" ".join(lineparts))
1187 1187
1188 1188 return res
1189 1189 def sort(self,field= None, nums = False):
1190 1190 """ sort by specified fields (see fields())
1191 1191
1192 1192 Example::
1193 1193 a.sort(1, nums = True)
1194 1194
1195 1195 Sorts a by second field, in numerical order (so that 21 > 3)
1196 1196
1197 1197 """
1198 1198
1199 1199 #decorate, sort, undecorate
1200 1200 if field is not None:
1201 1201 dsu = [[SList([line]).fields(field), line] for line in self]
1202 1202 else:
1203 1203 dsu = [[line, line] for line in self]
1204 1204 if nums:
1205 1205 for i in range(len(dsu)):
1206 1206 numstr = "".join([ch for ch in dsu[i][0] if ch.isdigit()])
1207 1207 try:
1208 1208 n = int(numstr)
1209 1209 except ValueError:
1210 1210 n = 0;
1211 1211 dsu[i][0] = n
1212 1212
1213 1213
1214 1214 dsu.sort()
1215 1215 return SList([t[1] for t in dsu])
1216 1216
1217 1217 def print_slist(arg):
1218 1218 """ Prettier (non-repr-like) and more informative printer for SList """
1219 1219 print "SList (.p, .n, .l, .s, .grep(), .fields(), sort() available):"
1220 1220 if hasattr(arg, 'hideonce') and arg.hideonce:
1221 1221 arg.hideonce = False
1222 1222 return
1223 1223
1224 1224 nlprint(arg)
1225 1225
1226 1226 print_slist = result_display.when_type(SList)(print_slist)
1227 1227
1228 1228
1229 1229
1230 1230 #----------------------------------------------------------------------------
1231 1231 def esc_quotes(strng):
1232 1232 """Return the input string with single and double quotes escaped out"""
1233 1233
1234 1234 return strng.replace('"','\\"').replace("'","\\'")
1235 1235
1236 1236 #----------------------------------------------------------------------------
1237 1237 def make_quoted_expr(s):
1238 1238 """Return string s in appropriate quotes, using raw string if possible.
1239 1239
1240 1240 Effectively this turns string: cd \ao\ao\
1241 1241 to: r"cd \ao\ao\_"[:-1]
1242 1242
1243 1243 Note the use of raw string and padding at the end to allow trailing backslash.
1244 1244
1245 1245 """
1246 1246
1247 1247 tail = ''
1248 1248 tailpadding = ''
1249 1249 raw = ''
1250 1250 if "\\" in s:
1251 1251 raw = 'r'
1252 1252 if s.endswith('\\'):
1253 1253 tail = '[:-1]'
1254 1254 tailpadding = '_'
1255 1255 if '"' not in s:
1256 1256 quote = '"'
1257 1257 elif "'" not in s:
1258 1258 quote = "'"
1259 1259 elif '"""' not in s and not s.endswith('"'):
1260 1260 quote = '"""'
1261 1261 elif "'''" not in s and not s.endswith("'"):
1262 1262 quote = "'''"
1263 1263 else:
1264 1264 # give up, backslash-escaped string will do
1265 1265 return '"%s"' % esc_quotes(s)
1266 1266 res = raw + quote + s + tailpadding + quote + tail
1267 1267 return res
1268 1268
1269 1269
1270 1270 #----------------------------------------------------------------------------
1271 1271 def raw_input_multi(header='', ps1='==> ', ps2='..> ',terminate_str = '.'):
1272 1272 """Take multiple lines of input.
1273 1273
1274 1274 A list with each line of input as a separate element is returned when a
1275 1275 termination string is entered (defaults to a single '.'). Input can also
1276 1276 terminate via EOF (^D in Unix, ^Z-RET in Windows).
1277 1277
1278 1278 Lines of input which end in \\ are joined into single entries (and a
1279 1279 secondary continuation prompt is issued as long as the user terminates
1280 1280 lines with \\). This allows entering very long strings which are still
1281 1281 meant to be treated as single entities.
1282 1282 """
1283 1283
1284 1284 try:
1285 1285 if header:
1286 1286 header += '\n'
1287 1287 lines = [raw_input(header + ps1)]
1288 1288 except EOFError:
1289 1289 return []
1290 1290 terminate = [terminate_str]
1291 1291 try:
1292 1292 while lines[-1:] != terminate:
1293 1293 new_line = raw_input(ps1)
1294 1294 while new_line.endswith('\\'):
1295 1295 new_line = new_line[:-1] + raw_input(ps2)
1296 1296 lines.append(new_line)
1297 1297
1298 1298 return lines[:-1] # don't return the termination command
1299 1299 except EOFError:
1300 1300 print
1301 1301 return lines
1302 1302
1303 1303 #----------------------------------------------------------------------------
1304 1304 def raw_input_ext(prompt='', ps2='... '):
1305 1305 """Similar to raw_input(), but accepts extended lines if input ends with \\."""
1306 1306
1307 1307 line = raw_input(prompt)
1308 1308 while line.endswith('\\'):
1309 1309 line = line[:-1] + raw_input(ps2)
1310 1310 return line
1311 1311
1312 1312 #----------------------------------------------------------------------------
1313 1313 def ask_yes_no(prompt,default=None):
1314 1314 """Asks a question and returns a boolean (y/n) answer.
1315 1315
1316 1316 If default is given (one of 'y','n'), it is used if the user input is
1317 1317 empty. Otherwise the question is repeated until an answer is given.
1318 1318
1319 1319 An EOF is treated as the default answer. If there is no default, an
1320 1320 exception is raised to prevent infinite loops.
1321 1321
1322 1322 Valid answers are: y/yes/n/no (match is not case sensitive)."""
1323 1323
1324 1324 answers = {'y':True,'n':False,'yes':True,'no':False}
1325 1325 ans = None
1326 1326 while ans not in answers.keys():
1327 1327 try:
1328 1328 ans = raw_input(prompt+' ').lower()
1329 1329 if not ans: # response was an empty string
1330 1330 ans = default
1331 1331 except KeyboardInterrupt:
1332 1332 pass
1333 1333 except EOFError:
1334 1334 if default in answers.keys():
1335 1335 ans = default
1336 1336 print
1337 1337 else:
1338 1338 raise
1339 1339
1340 1340 return answers[ans]
1341 1341
1342 1342 #----------------------------------------------------------------------------
1343 1343 def marquee(txt='',width=78,mark='*'):
1344 1344 """Return the input string centered in a 'marquee'."""
1345 1345 if not txt:
1346 1346 return (mark*width)[:width]
1347 1347 nmark = (width-len(txt)-2)/len(mark)/2
1348 1348 if nmark < 0: nmark =0
1349 1349 marks = mark*nmark
1350 1350 return '%s %s %s' % (marks,txt,marks)
1351 1351
1352 1352 #----------------------------------------------------------------------------
1353 1353 class EvalDict:
1354 1354 """
1355 1355 Emulate a dict which evaluates its contents in the caller's frame.
1356 1356
1357 1357 Usage:
1358 1358 >>> number = 19
1359 1359
1360 1360 >>> text = "python"
1361 1361
1362 1362 >>> print "%(text.capitalize())s %(number/9.0).1f rules!" % EvalDict()
1363 1363 Python 2.1 rules!
1364 1364 """
1365 1365
1366 1366 # This version is due to sismex01@hebmex.com on c.l.py, and is basically a
1367 1367 # modified (shorter) version of:
1368 1368 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66018 by
1369 1369 # Skip Montanaro (skip@pobox.com).
1370 1370
1371 1371 def __getitem__(self, name):
1372 1372 frame = sys._getframe(1)
1373 1373 return eval(name, frame.f_globals, frame.f_locals)
1374 1374
1375 1375 EvalString = EvalDict # for backwards compatibility
1376 1376 #----------------------------------------------------------------------------
1377 1377 def qw(words,flat=0,sep=None,maxsplit=-1):
1378 1378 """Similar to Perl's qw() operator, but with some more options.
1379 1379
1380 1380 qw(words,flat=0,sep=' ',maxsplit=-1) -> words.split(sep,maxsplit)
1381 1381
1382 1382 words can also be a list itself, and with flat=1, the output will be
1383 1383 recursively flattened.
1384 1384
1385 1385 Examples:
1386 1386
1387 1387 >>> qw('1 2')
1388 1388 ['1', '2']
1389 1389
1390 1390 >>> qw(['a b','1 2',['m n','p q']])
1391 1391 [['a', 'b'], ['1', '2'], [['m', 'n'], ['p', 'q']]]
1392 1392
1393 1393 >>> qw(['a b','1 2',['m n','p q']],flat=1)
1394 1394 ['a', 'b', '1', '2', 'm', 'n', 'p', 'q']
1395 1395 """
1396 1396
1397 1397 if type(words) in StringTypes:
1398 1398 return [word.strip() for word in words.split(sep,maxsplit)
1399 1399 if word and not word.isspace() ]
1400 1400 if flat:
1401 1401 return flatten(map(qw,words,[1]*len(words)))
1402 1402 return map(qw,words)
1403 1403
1404 1404 #----------------------------------------------------------------------------
1405 1405 def qwflat(words,sep=None,maxsplit=-1):
1406 1406 """Calls qw(words) in flat mode. It's just a convenient shorthand."""
1407 1407 return qw(words,1,sep,maxsplit)
1408 1408
1409 1409 #----------------------------------------------------------------------------
1410 1410 def qw_lol(indata):
1411 1411 """qw_lol('a b') -> [['a','b']],
1412 1412 otherwise it's just a call to qw().
1413 1413
1414 1414 We need this to make sure the modules_some keys *always* end up as a
1415 1415 list of lists."""
1416 1416
1417 1417 if type(indata) in StringTypes:
1418 1418 return [qw(indata)]
1419 1419 else:
1420 1420 return qw(indata)
1421 1421
1422 1422 #-----------------------------------------------------------------------------
1423 1423 def list_strings(arg):
1424 1424 """Always return a list of strings, given a string or list of strings
1425 1425 as input."""
1426 1426
1427 1427 if type(arg) in StringTypes: return [arg]
1428 1428 else: return arg
1429 1429
1430 1430 #----------------------------------------------------------------------------
1431 1431 def grep(pat,list,case=1):
1432 1432 """Simple minded grep-like function.
1433 1433 grep(pat,list) returns occurrences of pat in list, None on failure.
1434 1434
1435 1435 It only does simple string matching, with no support for regexps. Use the
1436 1436 option case=0 for case-insensitive matching."""
1437 1437
1438 1438 # This is pretty crude. At least it should implement copying only references
1439 1439 # to the original data in case it's big. Now it copies the data for output.
1440 1440 out=[]
1441 1441 if case:
1442 1442 for term in list:
1443 1443 if term.find(pat)>-1: out.append(term)
1444 1444 else:
1445 1445 lpat=pat.lower()
1446 1446 for term in list:
1447 1447 if term.lower().find(lpat)>-1: out.append(term)
1448 1448
1449 1449 if len(out): return out
1450 1450 else: return None
1451 1451
1452 1452 #----------------------------------------------------------------------------
1453 1453 def dgrep(pat,*opts):
1454 1454 """Return grep() on dir()+dir(__builtins__).
1455 1455
1456 1456 A very common use of grep() when working interactively."""
1457 1457
1458 1458 return grep(pat,dir(__main__)+dir(__main__.__builtins__),*opts)
1459 1459
1460 1460 #----------------------------------------------------------------------------
1461 1461 def idgrep(pat):
1462 1462 """Case-insensitive dgrep()"""
1463 1463
1464 1464 return dgrep(pat,0)
1465 1465
1466 1466 #----------------------------------------------------------------------------
1467 1467 def igrep(pat,list):
1468 1468 """Synonym for case-insensitive grep."""
1469 1469
1470 1470 return grep(pat,list,case=0)
1471 1471
1472 1472 #----------------------------------------------------------------------------
1473 1473 def indent(str,nspaces=4,ntabs=0):
1474 1474 """Indent a string a given number of spaces or tabstops.
1475 1475
1476 1476 indent(str,nspaces=4,ntabs=0) -> indent str by ntabs+nspaces.
1477 1477 """
1478 1478 if str is None:
1479 1479 return
1480 1480 ind = '\t'*ntabs+' '*nspaces
1481 1481 outstr = '%s%s' % (ind,str.replace(os.linesep,os.linesep+ind))
1482 1482 if outstr.endswith(os.linesep+ind):
1483 1483 return outstr[:-len(ind)]
1484 1484 else:
1485 1485 return outstr
1486 1486
1487 1487 #-----------------------------------------------------------------------------
1488 1488 def native_line_ends(filename,backup=1):
1489 1489 """Convert (in-place) a file to line-ends native to the current OS.
1490 1490
1491 1491 If the optional backup argument is given as false, no backup of the
1492 1492 original file is left. """
1493 1493
1494 1494 backup_suffixes = {'posix':'~','dos':'.bak','nt':'.bak','mac':'.bak'}
1495 1495
1496 1496 bak_filename = filename + backup_suffixes[os.name]
1497 1497
1498 1498 original = open(filename).read()
1499 1499 shutil.copy2(filename,bak_filename)
1500 1500 try:
1501 1501 new = open(filename,'wb')
1502 1502 new.write(os.linesep.join(original.splitlines()))
1503 1503 new.write(os.linesep) # ALWAYS put an eol at the end of the file
1504 1504 new.close()
1505 1505 except:
1506 1506 os.rename(bak_filename,filename)
1507 1507 if not backup:
1508 1508 try:
1509 1509 os.remove(bak_filename)
1510 1510 except:
1511 1511 pass
1512 1512
1513 1513 #----------------------------------------------------------------------------
1514 1514 def get_pager_cmd(pager_cmd = None):
1515 1515 """Return a pager command.
1516 1516
1517 1517 Makes some attempts at finding an OS-correct one."""
1518 1518
1519 1519 if os.name == 'posix':
1520 1520 default_pager_cmd = 'less -r' # -r for color control sequences
1521 1521 elif os.name in ['nt','dos']:
1522 1522 default_pager_cmd = 'type'
1523 1523
1524 1524 if pager_cmd is None:
1525 1525 try:
1526 1526 pager_cmd = os.environ['PAGER']
1527 1527 except:
1528 1528 pager_cmd = default_pager_cmd
1529 1529 return pager_cmd
1530 1530
1531 1531 #-----------------------------------------------------------------------------
1532 1532 def get_pager_start(pager,start):
1533 1533 """Return the string for paging files with an offset.
1534 1534
1535 1535 This is the '+N' argument which less and more (under Unix) accept.
1536 1536 """
1537 1537
1538 1538 if pager in ['less','more']:
1539 1539 if start:
1540 1540 start_string = '+' + str(start)
1541 1541 else:
1542 1542 start_string = ''
1543 1543 else:
1544 1544 start_string = ''
1545 1545 return start_string
1546 1546
1547 1547 #----------------------------------------------------------------------------
1548 1548 # (X)emacs on W32 doesn't like to be bypassed with msvcrt.getch()
1549 1549 if os.name == 'nt' and os.environ.get('TERM','dumb') != 'emacs':
1550 1550 import msvcrt
1551 1551 def page_more():
1552 1552 """ Smart pausing between pages
1553 1553
1554 1554 @return: True if need print more lines, False if quit
1555 1555 """
1556 1556 Term.cout.write('---Return to continue, q to quit--- ')
1557 1557 ans = msvcrt.getch()
1558 1558 if ans in ("q", "Q"):
1559 1559 result = False
1560 1560 else:
1561 1561 result = True
1562 1562 Term.cout.write("\b"*37 + " "*37 + "\b"*37)
1563 1563 return result
1564 1564 else:
1565 1565 def page_more():
1566 1566 ans = raw_input('---Return to continue, q to quit--- ')
1567 1567 if ans.lower().startswith('q'):
1568 1568 return False
1569 1569 else:
1570 1570 return True
1571 1571
1572 1572 esc_re = re.compile(r"(\x1b[^m]+m)")
1573 1573
1574 1574 def page_dumb(strng,start=0,screen_lines=25):
1575 1575 """Very dumb 'pager' in Python, for when nothing else works.
1576 1576
1577 1577 Only moves forward, same interface as page(), except for pager_cmd and
1578 1578 mode."""
1579 1579
1580 1580 out_ln = strng.splitlines()[start:]
1581 1581 screens = chop(out_ln,screen_lines-1)
1582 1582 if len(screens) == 1:
1583 1583 print >>Term.cout, os.linesep.join(screens[0])
1584 1584 else:
1585 1585 last_escape = ""
1586 1586 for scr in screens[0:-1]:
1587 1587 hunk = os.linesep.join(scr)
1588 1588 print >>Term.cout, last_escape + hunk
1589 1589 if not page_more():
1590 1590 return
1591 1591 esc_list = esc_re.findall(hunk)
1592 1592 if len(esc_list) > 0:
1593 1593 last_escape = esc_list[-1]
1594 1594 print >>Term.cout, last_escape + os.linesep.join(screens[-1])
1595 1595
1596 1596 #----------------------------------------------------------------------------
1597 1597 def page(strng,start=0,screen_lines=0,pager_cmd = None):
1598 1598 """Print a string, piping through a pager after a certain length.
1599 1599
1600 1600 The screen_lines parameter specifies the number of *usable* lines of your
1601 1601 terminal screen (total lines minus lines you need to reserve to show other
1602 1602 information).
1603 1603
1604 1604 If you set screen_lines to a number <=0, page() will try to auto-determine
1605 1605 your screen size and will only use up to (screen_size+screen_lines) for
1606 1606 printing, paging after that. That is, if you want auto-detection but need
1607 1607 to reserve the bottom 3 lines of the screen, use screen_lines = -3, and for
1608 1608 auto-detection without any lines reserved simply use screen_lines = 0.
1609 1609
1610 1610 If a string won't fit in the allowed lines, it is sent through the
1611 1611 specified pager command. If none given, look for PAGER in the environment,
1612 1612 and ultimately default to less.
1613 1613
1614 1614 If no system pager works, the string is sent through a 'dumb pager'
1615 1615 written in python, very simplistic.
1616 1616 """
1617 1617
1618 1618 # Some routines may auto-compute start offsets incorrectly and pass a
1619 1619 # negative value. Offset to 0 for robustness.
1620 1620 start = max(0,start)
1621 1621
1622 1622 # first, try the hook
1623 1623 ip = IPython.ipapi.get()
1624 1624 if ip:
1625 1625 try:
1626 1626 ip.IP.hooks.show_in_pager(strng)
1627 1627 return
1628 1628 except IPython.ipapi.TryNext:
1629 1629 pass
1630 1630
1631 1631 # Ugly kludge, but calling curses.initscr() flat out crashes in emacs
1632 1632 TERM = os.environ.get('TERM','dumb')
1633 1633 if TERM in ['dumb','emacs'] and os.name != 'nt':
1634 1634 print strng
1635 1635 return
1636 1636 # chop off the topmost part of the string we don't want to see
1637 1637 str_lines = strng.split(os.linesep)[start:]
1638 1638 str_toprint = os.linesep.join(str_lines)
1639 1639 num_newlines = len(str_lines)
1640 1640 len_str = len(str_toprint)
1641 1641
1642 1642 # Dumb heuristics to guesstimate number of on-screen lines the string
1643 1643 # takes. Very basic, but good enough for docstrings in reasonable
1644 1644 # terminals. If someone later feels like refining it, it's not hard.
1645 1645 numlines = max(num_newlines,int(len_str/80)+1)
1646 1646
1647 1647 if os.name == "nt":
1648 1648 screen_lines_def = get_console_size(defaulty=25)[1]
1649 1649 else:
1650 1650 screen_lines_def = 25 # default value if we can't auto-determine
1651 1651
1652 1652 # auto-determine screen size
1653 1653 if screen_lines <= 0:
1654 1654 if TERM=='xterm':
1655 1655 use_curses = USE_CURSES
1656 1656 else:
1657 1657 # curses causes problems on many terminals other than xterm.
1658 1658 use_curses = False
1659 1659 if use_curses:
1660 1660 # There is a bug in curses, where *sometimes* it fails to properly
1661 1661 # initialize, and then after the endwin() call is made, the
1662 1662 # terminal is left in an unusable state. Rather than trying to
1663 1663 # check everytime for this (by requesting and comparing termios
1664 1664 # flags each time), we just save the initial terminal state and
1665 1665 # unconditionally reset it every time. It's cheaper than making
1666 1666 # the checks.
1667 1667 term_flags = termios.tcgetattr(sys.stdout)
1668 1668 scr = curses.initscr()
1669 1669 screen_lines_real,screen_cols = scr.getmaxyx()
1670 1670 curses.endwin()
1671 1671 # Restore terminal state in case endwin() didn't.
1672 1672 termios.tcsetattr(sys.stdout,termios.TCSANOW,term_flags)
1673 1673 # Now we have what we needed: the screen size in rows/columns
1674 1674 screen_lines += screen_lines_real
1675 1675 #print '***Screen size:',screen_lines_real,'lines x',\
1676 1676 #screen_cols,'columns.' # dbg
1677 1677 else:
1678 1678 screen_lines += screen_lines_def
1679 1679
1680 1680 #print 'numlines',numlines,'screenlines',screen_lines # dbg
1681 1681 if numlines <= screen_lines :
1682 1682 #print '*** normal print' # dbg
1683 1683 print >>Term.cout, str_toprint
1684 1684 else:
1685 1685 # Try to open pager and default to internal one if that fails.
1686 1686 # All failure modes are tagged as 'retval=1', to match the return
1687 1687 # value of a failed system command. If any intermediate attempt
1688 1688 # sets retval to 1, at the end we resort to our own page_dumb() pager.
1689 1689 pager_cmd = get_pager_cmd(pager_cmd)
1690 1690 pager_cmd += ' ' + get_pager_start(pager_cmd,start)
1691 1691 if os.name == 'nt':
1692 1692 if pager_cmd.startswith('type'):
1693 1693 # The default WinXP 'type' command is failing on complex strings.
1694 1694 retval = 1
1695 1695 else:
1696 1696 tmpname = tempfile.mktemp('.txt')
1697 1697 tmpfile = file(tmpname,'wt')
1698 1698 tmpfile.write(strng)
1699 1699 tmpfile.close()
1700 1700 cmd = "%s < %s" % (pager_cmd,tmpname)
1701 1701 if os.system(cmd):
1702 1702 retval = 1
1703 1703 else:
1704 1704 retval = None
1705 1705 os.remove(tmpname)
1706 1706 else:
1707 1707 try:
1708 1708 retval = None
1709 1709 # if I use popen4, things hang. No idea why.
1710 1710 #pager,shell_out = os.popen4(pager_cmd)
1711 1711 pager = os.popen(pager_cmd,'w')
1712 1712 pager.write(strng)
1713 1713 pager.close()
1714 1714 retval = pager.close() # success returns None
1715 1715 except IOError,msg: # broken pipe when user quits
1716 1716 if msg.args == (32,'Broken pipe'):
1717 1717 retval = None
1718 1718 else:
1719 1719 retval = 1
1720 1720 except OSError:
1721 1721 # Other strange problems, sometimes seen in Win2k/cygwin
1722 1722 retval = 1
1723 1723 if retval is not None:
1724 1724 page_dumb(strng,screen_lines=screen_lines)
1725 1725
1726 1726 #----------------------------------------------------------------------------
1727 1727 def page_file(fname,start = 0, pager_cmd = None):
1728 1728 """Page a file, using an optional pager command and starting line.
1729 1729 """
1730 1730
1731 1731 pager_cmd = get_pager_cmd(pager_cmd)
1732 1732 pager_cmd += ' ' + get_pager_start(pager_cmd,start)
1733 1733
1734 1734 try:
1735 1735 if os.environ['TERM'] in ['emacs','dumb']:
1736 1736 raise EnvironmentError
1737 1737 xsys(pager_cmd + ' ' + fname)
1738 1738 except:
1739 1739 try:
1740 1740 if start > 0:
1741 1741 start -= 1
1742 1742 page(open(fname).read(),start)
1743 1743 except:
1744 1744 print 'Unable to show file',`fname`
1745 1745
1746 1746
1747 1747 #----------------------------------------------------------------------------
1748 1748 def snip_print(str,width = 75,print_full = 0,header = ''):
1749 1749 """Print a string snipping the midsection to fit in width.
1750 1750
1751 1751 print_full: mode control:
1752 1752 - 0: only snip long strings
1753 1753 - 1: send to page() directly.
1754 1754 - 2: snip long strings and ask for full length viewing with page()
1755 1755 Return 1 if snipping was necessary, 0 otherwise."""
1756 1756
1757 1757 if print_full == 1:
1758 1758 page(header+str)
1759 1759 return 0
1760 1760
1761 1761 print header,
1762 1762 if len(str) < width:
1763 1763 print str
1764 1764 snip = 0
1765 1765 else:
1766 1766 whalf = int((width -5)/2)
1767 1767 print str[:whalf] + ' <...> ' + str[-whalf:]
1768 1768 snip = 1
1769 1769 if snip and print_full == 2:
1770 1770 if raw_input(header+' Snipped. View (y/n)? [N]').lower() == 'y':
1771 1771 page(str)
1772 1772 return snip
1773 1773
1774 1774 #****************************************************************************
1775 1775 # lists, dicts and structures
1776 1776
1777 1777 def belong(candidates,checklist):
1778 1778 """Check whether a list of items appear in a given list of options.
1779 1779
1780 1780 Returns a list of 1 and 0, one for each candidate given."""
1781 1781
1782 1782 return [x in checklist for x in candidates]
1783 1783
1784 1784 #----------------------------------------------------------------------------
1785 1785 def uniq_stable(elems):
1786 1786 """uniq_stable(elems) -> list
1787 1787
1788 1788 Return from an iterable, a list of all the unique elements in the input,
1789 1789 but maintaining the order in which they first appear.
1790 1790
1791 1791 A naive solution to this problem which just makes a dictionary with the
1792 1792 elements as keys fails to respect the stability condition, since
1793 1793 dictionaries are unsorted by nature.
1794 1794
1795 1795 Note: All elements in the input must be valid dictionary keys for this
1796 1796 routine to work, as it internally uses a dictionary for efficiency
1797 1797 reasons."""
1798 1798
1799 1799 unique = []
1800 1800 unique_dict = {}
1801 1801 for nn in elems:
1802 1802 if nn not in unique_dict:
1803 1803 unique.append(nn)
1804 1804 unique_dict[nn] = None
1805 1805 return unique
1806 1806
1807 1807 #----------------------------------------------------------------------------
1808 1808 class NLprinter:
1809 1809 """Print an arbitrarily nested list, indicating index numbers.
1810 1810
1811 1811 An instance of this class called nlprint is available and callable as a
1812 1812 function.
1813 1813
1814 1814 nlprint(list,indent=' ',sep=': ') -> prints indenting each level by 'indent'
1815 1815 and using 'sep' to separate the index from the value. """
1816 1816
1817 1817 def __init__(self):
1818 1818 self.depth = 0
1819 1819
1820 1820 def __call__(self,lst,pos='',**kw):
1821 1821 """Prints the nested list numbering levels."""
1822 1822 kw.setdefault('indent',' ')
1823 1823 kw.setdefault('sep',': ')
1824 1824 kw.setdefault('start',0)
1825 1825 kw.setdefault('stop',len(lst))
1826 1826 # we need to remove start and stop from kw so they don't propagate
1827 1827 # into a recursive call for a nested list.
1828 1828 start = kw['start']; del kw['start']
1829 1829 stop = kw['stop']; del kw['stop']
1830 1830 if self.depth == 0 and 'header' in kw.keys():
1831 1831 print kw['header']
1832 1832
1833 1833 for idx in range(start,stop):
1834 1834 elem = lst[idx]
1835 1835 if type(elem)==type([]):
1836 1836 self.depth += 1
1837 1837 self.__call__(elem,itpl('$pos$idx,'),**kw)
1838 1838 self.depth -= 1
1839 1839 else:
1840 1840 printpl(kw['indent']*self.depth+'$pos$idx$kw["sep"]$elem')
1841 1841
1842 1842 nlprint = NLprinter()
1843 1843 #----------------------------------------------------------------------------
1844 1844 def all_belong(candidates,checklist):
1845 1845 """Check whether a list of items ALL appear in a given list of options.
1846 1846
1847 1847 Returns a single 1 or 0 value."""
1848 1848
1849 1849 return 1-(0 in [x in checklist for x in candidates])
1850 1850
1851 1851 #----------------------------------------------------------------------------
1852 1852 def sort_compare(lst1,lst2,inplace = 1):
1853 1853 """Sort and compare two lists.
1854 1854
1855 1855 By default it does it in place, thus modifying the lists. Use inplace = 0
1856 1856 to avoid that (at the cost of temporary copy creation)."""
1857 1857 if not inplace:
1858 1858 lst1 = lst1[:]
1859 1859 lst2 = lst2[:]
1860 1860 lst1.sort(); lst2.sort()
1861 1861 return lst1 == lst2
1862 1862
1863 1863 #----------------------------------------------------------------------------
1864 1864 def list2dict(lst):
1865 1865 """Takes a list of (key,value) pairs and turns it into a dict."""
1866 1866
1867 1867 dic = {}
1868 1868 for k,v in lst: dic[k] = v
1869 1869 return dic
1870 1870
1871 1871 #----------------------------------------------------------------------------
1872 1872 def list2dict2(lst,default=''):
1873 1873 """Takes a list and turns it into a dict.
1874 1874 Much slower than list2dict, but more versatile. This version can take
1875 1875 lists with sublists of arbitrary length (including sclars)."""
1876 1876
1877 1877 dic = {}
1878 1878 for elem in lst:
1879 1879 if type(elem) in (types.ListType,types.TupleType):
1880 1880 size = len(elem)
1881 1881 if size == 0:
1882 1882 pass
1883 1883 elif size == 1:
1884 1884 dic[elem] = default
1885 1885 else:
1886 1886 k,v = elem[0], elem[1:]
1887 1887 if len(v) == 1: v = v[0]
1888 1888 dic[k] = v
1889 1889 else:
1890 1890 dic[elem] = default
1891 1891 return dic
1892 1892
1893 1893 #----------------------------------------------------------------------------
1894 1894 def flatten(seq):
1895 1895 """Flatten a list of lists (NOT recursive, only works for 2d lists)."""
1896 1896
1897 1897 return [x for subseq in seq for x in subseq]
1898 1898
1899 1899 #----------------------------------------------------------------------------
1900 1900 def get_slice(seq,start=0,stop=None,step=1):
1901 1901 """Get a slice of a sequence with variable step. Specify start,stop,step."""
1902 1902 if stop == None:
1903 1903 stop = len(seq)
1904 1904 item = lambda i: seq[i]
1905 1905 return map(item,xrange(start,stop,step))
1906 1906
1907 1907 #----------------------------------------------------------------------------
1908 1908 def chop(seq,size):
1909 1909 """Chop a sequence into chunks of the given size."""
1910 1910 chunk = lambda i: seq[i:i+size]
1911 1911 return map(chunk,xrange(0,len(seq),size))
1912 1912
1913 1913 #----------------------------------------------------------------------------
1914 1914 # with is a keyword as of python 2.5, so this function is renamed to withobj
1915 1915 # from its old 'with' name.
1916 1916 def with_obj(object, **args):
1917 1917 """Set multiple attributes for an object, similar to Pascal's with.
1918 1918
1919 1919 Example:
1920 1920 with_obj(jim,
1921 1921 born = 1960,
1922 1922 haircolour = 'Brown',
1923 1923 eyecolour = 'Green')
1924 1924
1925 1925 Credit: Greg Ewing, in
1926 1926 http://mail.python.org/pipermail/python-list/2001-May/040703.html.
1927 1927
1928 1928 NOTE: up until IPython 0.7.2, this was called simply 'with', but 'with'
1929 1929 has become a keyword for Python 2.5, so we had to rename it."""
1930 1930
1931 1931 object.__dict__.update(args)
1932 1932
1933 1933 #----------------------------------------------------------------------------
1934 1934 def setattr_list(obj,alist,nspace = None):
1935 1935 """Set a list of attributes for an object taken from a namespace.
1936 1936
1937 1937 setattr_list(obj,alist,nspace) -> sets in obj all the attributes listed in
1938 1938 alist with their values taken from nspace, which must be a dict (something
1939 1939 like locals() will often do) If nspace isn't given, locals() of the
1940 1940 *caller* is used, so in most cases you can omit it.
1941 1941
1942 1942 Note that alist can be given as a string, which will be automatically
1943 1943 split into a list on whitespace. If given as a list, it must be a list of
1944 1944 *strings* (the variable names themselves), not of variables."""
1945 1945
1946 1946 # this grabs the local variables from the *previous* call frame -- that is
1947 1947 # the locals from the function that called setattr_list().
1948 1948 # - snipped from weave.inline()
1949 1949 if nspace is None:
1950 1950 call_frame = sys._getframe().f_back
1951 1951 nspace = call_frame.f_locals
1952 1952
1953 1953 if type(alist) in StringTypes:
1954 1954 alist = alist.split()
1955 1955 for attr in alist:
1956 1956 val = eval(attr,nspace)
1957 1957 setattr(obj,attr,val)
1958 1958
1959 1959 #----------------------------------------------------------------------------
1960 1960 def getattr_list(obj,alist,*args):
1961 1961 """getattr_list(obj,alist[, default]) -> attribute list.
1962 1962
1963 1963 Get a list of named attributes for an object. When a default argument is
1964 1964 given, it is returned when the attribute doesn't exist; without it, an
1965 1965 exception is raised in that case.
1966 1966
1967 1967 Note that alist can be given as a string, which will be automatically
1968 1968 split into a list on whitespace. If given as a list, it must be a list of
1969 1969 *strings* (the variable names themselves), not of variables."""
1970 1970
1971 1971 if type(alist) in StringTypes:
1972 1972 alist = alist.split()
1973 1973 if args:
1974 1974 if len(args)==1:
1975 1975 default = args[0]
1976 1976 return map(lambda attr: getattr(obj,attr,default),alist)
1977 1977 else:
1978 1978 raise ValueError,'getattr_list() takes only one optional argument'
1979 1979 else:
1980 1980 return map(lambda attr: getattr(obj,attr),alist)
1981 1981
1982 1982 #----------------------------------------------------------------------------
1983 1983 def map_method(method,object_list,*argseq,**kw):
1984 1984 """map_method(method,object_list,*args,**kw) -> list
1985 1985
1986 1986 Return a list of the results of applying the methods to the items of the
1987 1987 argument sequence(s). If more than one sequence is given, the method is
1988 1988 called with an argument list consisting of the corresponding item of each
1989 1989 sequence. All sequences must be of the same length.
1990 1990
1991 1991 Keyword arguments are passed verbatim to all objects called.
1992 1992
1993 1993 This is Python code, so it's not nearly as fast as the builtin map()."""
1994 1994
1995 1995 out_list = []
1996 1996 idx = 0
1997 1997 for object in object_list:
1998 1998 try:
1999 1999 handler = getattr(object, method)
2000 2000 except AttributeError:
2001 2001 out_list.append(None)
2002 2002 else:
2003 2003 if argseq:
2004 2004 args = map(lambda lst:lst[idx],argseq)
2005 2005 #print 'ob',object,'hand',handler,'ar',args # dbg
2006 2006 out_list.append(handler(args,**kw))
2007 2007 else:
2008 2008 out_list.append(handler(**kw))
2009 2009 idx += 1
2010 2010 return out_list
2011 2011
2012 2012 #----------------------------------------------------------------------------
2013 2013 def get_class_members(cls):
2014 2014 ret = dir(cls)
2015 2015 if hasattr(cls,'__bases__'):
2016 2016 for base in cls.__bases__:
2017 2017 ret.extend(get_class_members(base))
2018 2018 return ret
2019 2019
2020 2020 #----------------------------------------------------------------------------
2021 2021 def dir2(obj):
2022 2022 """dir2(obj) -> list of strings
2023 2023
2024 2024 Extended version of the Python builtin dir(), which does a few extra
2025 2025 checks, and supports common objects with unusual internals that confuse
2026 2026 dir(), such as Traits and PyCrust.
2027 2027
2028 2028 This version is guaranteed to return only a list of true strings, whereas
2029 2029 dir() returns anything that objects inject into themselves, even if they
2030 2030 are later not really valid for attribute access (many extension libraries
2031 2031 have such bugs).
2032 2032 """
2033 2033
2034 2034 # Start building the attribute list via dir(), and then complete it
2035 2035 # with a few extra special-purpose calls.
2036 2036 words = dir(obj)
2037 2037
2038 2038 if hasattr(obj,'__class__'):
2039 2039 words.append('__class__')
2040 2040 words.extend(get_class_members(obj.__class__))
2041 2041 #if '__base__' in words: 1/0
2042 2042
2043 2043 # Some libraries (such as traits) may introduce duplicates, we want to
2044 2044 # track and clean this up if it happens
2045 2045 may_have_dupes = False
2046 2046
2047 2047 # this is the 'dir' function for objects with Enthought's traits
2048 2048 if hasattr(obj, 'trait_names'):
2049 2049 try:
2050 2050 words.extend(obj.trait_names())
2051 2051 may_have_dupes = True
2052 2052 except TypeError:
2053 2053 # This will happen if `obj` is a class and not an instance.
2054 2054 pass
2055 2055
2056 2056 # Support for PyCrust-style _getAttributeNames magic method.
2057 2057 if hasattr(obj, '_getAttributeNames'):
2058 2058 try:
2059 2059 words.extend(obj._getAttributeNames())
2060 2060 may_have_dupes = True
2061 2061 except TypeError:
2062 2062 # `obj` is a class and not an instance. Ignore
2063 2063 # this error.
2064 2064 pass
2065 2065
2066 2066 if may_have_dupes:
2067 2067 # eliminate possible duplicates, as some traits may also
2068 2068 # appear as normal attributes in the dir() call.
2069 2069 words = list(set(words))
2070 2070 words.sort()
2071 2071
2072 2072 # filter out non-string attributes which may be stuffed by dir() calls
2073 2073 # and poor coding in third-party modules
2074 2074 return [w for w in words if isinstance(w, basestring)]
2075 2075
2076 2076 #----------------------------------------------------------------------------
2077 2077 def import_fail_info(mod_name,fns=None):
2078 2078 """Inform load failure for a module."""
2079 2079
2080 2080 if fns == None:
2081 2081 warn("Loading of %s failed.\n" % (mod_name,))
2082 2082 else:
2083 2083 warn("Loading of %s from %s failed.\n" % (fns,mod_name))
2084 2084
2085 2085 #----------------------------------------------------------------------------
2086 2086 # Proposed popitem() extension, written as a method
2087 2087
2088 2088
2089 2089 class NotGiven: pass
2090 2090
2091 2091 def popkey(dct,key,default=NotGiven):
2092 2092 """Return dct[key] and delete dct[key].
2093 2093
2094 2094 If default is given, return it if dct[key] doesn't exist, otherwise raise
2095 2095 KeyError. """
2096 2096
2097 2097 try:
2098 2098 val = dct[key]
2099 2099 except KeyError:
2100 2100 if default is NotGiven:
2101 2101 raise
2102 2102 else:
2103 2103 return default
2104 2104 else:
2105 2105 del dct[key]
2106 2106 return val
2107 2107
2108 2108 def wrap_deprecated(func, suggest = '<nothing>'):
2109 2109 def newFunc(*args, **kwargs):
2110 2110 warnings.warn("Call to deprecated function %s, use %s instead" %
2111 2111 ( func.__name__, suggest),
2112 2112 category=DeprecationWarning,
2113 2113 stacklevel = 2)
2114 2114 return func(*args, **kwargs)
2115 2115 return newFunc
2116 2116
2117 2117
2118 2118 def _num_cpus_unix():
2119 2119 """Return the number of active CPUs on a Unix system."""
2120 2120 return os.sysconf("SC_NPROCESSORS_ONLN")
2121 2121
2122 2122
2123 2123 def _num_cpus_darwin():
2124 2124 """Return the number of active CPUs on a Darwin system."""
2125 2125 p = subprocess.Popen(['sysctl','-n','hw.ncpu'],stdout=subprocess.PIPE)
2126 2126 return p.stdout.read()
2127 2127
2128 2128
2129 2129 def _num_cpus_windows():
2130 2130 """Return the number of active CPUs on a Windows system."""
2131 2131 return os.environ.get("NUMBER_OF_PROCESSORS")
2132 2132
2133 2133
2134 2134 def num_cpus():
2135 2135 """Return the effective number of CPUs in the system as an integer.
2136 2136
2137 2137 This cross-platform function makes an attempt at finding the total number of
2138 2138 available CPUs in the system, as returned by various underlying system and
2139 2139 python calls.
2140 2140
2141 2141 If it can't find a sensible answer, it returns 1 (though an error *may* make
2142 2142 it return a large positive number that's actually incorrect).
2143 2143 """
2144 2144
2145 2145 # Many thanks to the Parallel Python project (http://www.parallelpython.com)
2146 2146 # for the names of the keys we needed to look up for this function. This
2147 2147 # code was inspired by their equivalent function.
2148 2148
2149 2149 ncpufuncs = {'Linux':_num_cpus_unix,
2150 2150 'Darwin':_num_cpus_darwin,
2151 2151 'Windows':_num_cpus_windows,
2152 2152 # On Vista, python < 2.5.2 has a bug and returns 'Microsoft'
2153 2153 # See http://bugs.python.org/issue1082 for details.
2154 2154 'Microsoft':_num_cpus_windows,
2155 2155 }
2156 2156
2157 2157 ncpufunc = ncpufuncs.get(platform.system(),
2158 2158 # default to unix version (Solaris, AIX, etc)
2159 2159 _num_cpus_unix)
2160 2160
2161 2161 try:
2162 2162 ncpus = max(1,int(ncpufunc()))
2163 2163 except:
2164 2164 ncpus = 1
2165 2165 return ncpus
2166 2166
2167 2167 #*************************** end of file <genutils.py> **********************
@@ -1,783 +1,778 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 IPython -- An enhanced Interactive Python
4 4
5 5 Requires Python 2.1 or better.
6 6
7 7 This file contains the main make_IPython() starter function.
8 8
9 9 $Id: ipmaker.py 2930 2008-01-11 07:03:11Z vivainio $"""
10 10
11 11 #*****************************************************************************
12 12 # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu>
13 13 #
14 14 # Distributed under the terms of the BSD License. The full license is in
15 15 # the file COPYING, distributed as part of this software.
16 16 #*****************************************************************************
17 17
18 18 from IPython import Release
19 19 __author__ = '%s <%s>' % Release.authors['Fernando']
20 20 __license__ = Release.license
21 21 __version__ = Release.version
22 22
23 23 try:
24 24 credits._Printer__data = """
25 25 Python: %s
26 26
27 27 IPython: Fernando Perez, Janko Hauser, Nathan Gray, and many users.
28 28 See http://ipython.scipy.org for more information.""" \
29 29 % credits._Printer__data
30 30
31 31 copyright._Printer__data += """
32 32
33 33 Copyright (c) 2001-2004 Fernando Perez, Janko Hauser, Nathan Gray.
34 34 All Rights Reserved."""
35 35 except NameError:
36 36 # Can happen if ipython was started with 'python -S', so that site.py is
37 37 # not loaded
38 38 pass
39 39
40 40 #****************************************************************************
41 41 # Required modules
42 42
43 43 # From the standard library
44 44 import __main__
45 45 import __builtin__
46 46 import os
47 47 import re
48 48 import sys
49 49 import types
50 50 from pprint import pprint,pformat
51 51
52 52 # Our own
53 53 from IPython import DPyGetOpt
54 54 from IPython.ipstruct import Struct
55 55 from IPython.OutputTrap import OutputTrap
56 56 from IPython.ConfigLoader import ConfigLoader
57 57 from IPython.iplib import InteractiveShell
58 58 from IPython.usage import cmd_line_usage,interactive_usage
59 59 from IPython.genutils import *
60 60
61 61 def force_import(modname):
62 62 if modname in sys.modules:
63 63 print "reload",modname
64 64 reload(sys.modules[modname])
65 65 else:
66 66 __import__(modname)
67 67
68 68
69 69 #-----------------------------------------------------------------------------
70 70 def make_IPython(argv=None,user_ns=None,user_global_ns=None,debug=1,
71 71 rc_override=None,shell_class=InteractiveShell,
72 72 embedded=False,**kw):
73 73 """This is a dump of IPython into a single function.
74 74
75 75 Later it will have to be broken up in a sensible manner.
76 76
77 77 Arguments:
78 78
79 79 - argv: a list similar to sys.argv[1:]. It should NOT contain the desired
80 80 script name, b/c DPyGetOpt strips the first argument only for the real
81 81 sys.argv.
82 82
83 83 - user_ns: a dict to be used as the user's namespace."""
84 84
85 85 #----------------------------------------------------------------------
86 86 # Defaults and initialization
87 87
88 88 # For developer debugging, deactivates crash handler and uses pdb.
89 89 DEVDEBUG = False
90 90
91 91 if argv is None:
92 92 argv = sys.argv
93 93
94 94 # __IP is the main global that lives throughout and represents the whole
95 95 # application. If the user redefines it, all bets are off as to what
96 96 # happens.
97 97
98 98 # __IP is the name of he global which the caller will have accessible as
99 99 # __IP.name. We set its name via the first parameter passed to
100 100 # InteractiveShell:
101 101
102 102 IP = shell_class('__IP',user_ns=user_ns,user_global_ns=user_global_ns,
103 103 embedded=embedded,**kw)
104 104
105 105 # Put 'help' in the user namespace
106 106 try:
107 107 from site import _Helper
108 108 IP.user_ns['help'] = _Helper()
109 109 except ImportError:
110 110 warn('help() not available - check site.py')
111 111 IP.user_config_ns = {}
112 112
113 113
114 114 if DEVDEBUG:
115 115 # For developer debugging only (global flag)
116 116 from IPython import ultraTB
117 117 sys.excepthook = ultraTB.VerboseTB(call_pdb=1)
118 118
119 119 IP.BANNER_PARTS = ['Python %s\n'
120 120 'Type "copyright", "credits" or "license" '
121 121 'for more information.\n'
122 122 % (sys.version.split('\n')[0],),
123 123 "IPython %s -- An enhanced Interactive Python."
124 124 % (__version__,),
125 125 """\
126 126 ? -> Introduction and overview of IPython's features.
127 127 %quickref -> Quick reference.
128 128 help -> Python's own help system.
129 129 object? -> Details about 'object'. ?object also works, ?? prints more.
130 130 """ ]
131 131
132 132 IP.usage = interactive_usage
133 133
134 # Platform-dependent suffix and directory names. We use _ipython instead
135 # of .ipython under win32 b/c there's software that breaks with .named
136 # directories on that platform.
134 # Platform-dependent suffix.
137 135 if os.name == 'posix':
138 136 rc_suffix = ''
139 ipdir_def = '.ipython'
140 137 else:
141 138 rc_suffix = '.ini'
142 ipdir_def = '_ipython'
143 139
144 140 # default directory for configuration
145 ipythondir_def = os.path.abspath(os.environ.get('IPYTHONDIR',
146 os.path.join(IP.home_dir,ipdir_def)))
147
141 ipythondir_def = get_ipython_dir()
142
148 143 sys.path.insert(0, '') # add . to sys.path. Fix from Prabhu Ramachandran
149 144
150 145 # we need the directory where IPython itself is installed
151 146 import IPython
152 147 IPython_dir = os.path.dirname(IPython.__file__)
153 148 del IPython
154 149
155 150 #-------------------------------------------------------------------------
156 151 # Command line handling
157 152
158 153 # Valid command line options (uses DPyGetOpt syntax, like Perl's
159 154 # GetOpt::Long)
160 155
161 156 # Any key not listed here gets deleted even if in the file (like session
162 157 # or profile). That's deliberate, to maintain the rc namespace clean.
163 158
164 159 # Each set of options appears twice: under _conv only the names are
165 160 # listed, indicating which type they must be converted to when reading the
166 161 # ipythonrc file. And under DPyGetOpt they are listed with the regular
167 162 # DPyGetOpt syntax (=s,=i,:f,etc).
168 163
169 164 # Make sure there's a space before each end of line (they get auto-joined!)
170 165 cmdline_opts = ('autocall=i autoindent! automagic! banner! cache_size|cs=i '
171 166 'c=s classic|cl color_info! colors=s confirm_exit! '
172 167 'debug! deep_reload! editor=s log|l messages! nosep '
173 168 'object_info_string_level=i pdb! '
174 169 'pprint! prompt_in1|pi1=s prompt_in2|pi2=s prompt_out|po=s '
175 170 'pydb! '
176 171 'pylab_import_all! '
177 172 'quick screen_length|sl=i prompts_pad_left=i '
178 173 'logfile|lf=s logplay|lp=s profile|p=s '
179 174 'readline! readline_merge_completions! '
180 175 'readline_omit__names! '
181 176 'rcfile=s separate_in|si=s separate_out|so=s '
182 177 'separate_out2|so2=s xmode=s wildcards_case_sensitive! '
183 178 'magic_docstrings system_verbose! '
184 179 'multi_line_specials! '
185 180 'term_title! wxversion=s '
186 181 'autoedit_syntax!')
187 182
188 183 # Options that can *only* appear at the cmd line (not in rcfiles).
189 184
190 185 cmdline_only = ('help interact|i ipythondir=s Version upgrade '
191 186 'gthread! qthread! q4thread! wthread! tkthread! pylab! tk! '
192 187 # 'twisted!' # disabled for now.
193 188 )
194 189
195 190 # Build the actual name list to be used by DPyGetOpt
196 191 opts_names = qw(cmdline_opts) + qw(cmdline_only)
197 192
198 193 # Set sensible command line defaults.
199 194 # This should have everything from cmdline_opts and cmdline_only
200 195 opts_def = Struct(autocall = 1,
201 196 autoedit_syntax = 0,
202 197 autoindent = 0,
203 198 automagic = 1,
204 199 autoexec = [],
205 200 banner = 1,
206 201 c = '',
207 202 cache_size = 1000,
208 203 classic = 0,
209 204 color_info = 0,
210 205 colors = 'NoColor',
211 206 confirm_exit = 1,
212 207 debug = 0,
213 208 deep_reload = 0,
214 209 editor = '0',
215 210 gthread = 0,
216 211 help = 0,
217 212 interact = 0,
218 213 ipythondir = ipythondir_def,
219 214 log = 0,
220 215 logfile = '',
221 216 logplay = '',
222 217 messages = 1,
223 218 multi_line_specials = 1,
224 219 nosep = 0,
225 220 object_info_string_level = 0,
226 221 pdb = 0,
227 222 pprint = 0,
228 223 profile = '',
229 224 prompt_in1 = 'In [\\#]: ',
230 225 prompt_in2 = ' .\\D.: ',
231 226 prompt_out = 'Out[\\#]: ',
232 227 prompts_pad_left = 1,
233 228 pydb = 0,
234 229 pylab = 0,
235 230 pylab_import_all = 1,
236 231 q4thread = 0,
237 232 qthread = 0,
238 233 quick = 0,
239 234 quiet = 0,
240 235 rcfile = 'ipythonrc' + rc_suffix,
241 236 readline = 1,
242 237 readline_merge_completions = 1,
243 238 readline_omit__names = 0,
244 239 screen_length = 0,
245 240 separate_in = '\n',
246 241 separate_out = '\n',
247 242 separate_out2 = '',
248 243 system_header = 'IPython system call: ',
249 244 system_verbose = 0,
250 245 term_title = 1,
251 246 tk = 0,
252 247 #twisted= 0, # disabled for now
253 248 upgrade = 0,
254 249 Version = 0,
255 250 wildcards_case_sensitive = 1,
256 251 wthread = 0,
257 252 wxversion = '0',
258 253 xmode = 'Context',
259 254 magic_docstrings = 0, # undocumented, for doc generation
260 255 )
261 256
262 257 # Things that will *only* appear in rcfiles (not at the command line).
263 258 # Make sure there's a space before each end of line (they get auto-joined!)
264 259 rcfile_opts = { qwflat: 'include import_mod import_all execfile ',
265 260 qw_lol: 'import_some ',
266 261 # for things with embedded whitespace:
267 262 list_strings:'execute alias readline_parse_and_bind ',
268 263 # Regular strings need no conversion:
269 264 None:'readline_remove_delims ',
270 265 }
271 266 # Default values for these
272 267 rc_def = Struct(include = [],
273 268 import_mod = [],
274 269 import_all = [],
275 270 import_some = [[]],
276 271 execute = [],
277 272 execfile = [],
278 273 alias = [],
279 274 readline_parse_and_bind = [],
280 275 readline_remove_delims = '',
281 276 )
282 277
283 278 # Build the type conversion dictionary from the above tables:
284 279 typeconv = rcfile_opts.copy()
285 280 typeconv.update(optstr2types(cmdline_opts))
286 281
287 282 # FIXME: the None key appears in both, put that back together by hand. Ugly!
288 283 typeconv[None] += ' ' + rcfile_opts[None]
289 284
290 285 # Remove quotes at ends of all strings (used to protect spaces)
291 286 typeconv[unquote_ends] = typeconv[None]
292 287 del typeconv[None]
293 288
294 289 # Build the list we'll use to make all config decisions with defaults:
295 290 opts_all = opts_def.copy()
296 291 opts_all.update(rc_def)
297 292
298 293 # Build conflict resolver for recursive loading of config files:
299 294 # - preserve means the outermost file maintains the value, it is not
300 295 # overwritten if an included file has the same key.
301 296 # - add_flip applies + to the two values, so it better make sense to add
302 297 # those types of keys. But it flips them first so that things loaded
303 298 # deeper in the inclusion chain have lower precedence.
304 299 conflict = {'preserve': ' '.join([ typeconv[int],
305 300 typeconv[unquote_ends] ]),
306 301 'add_flip': ' '.join([ typeconv[qwflat],
307 302 typeconv[qw_lol],
308 303 typeconv[list_strings] ])
309 304 }
310 305
311 306 # Now actually process the command line
312 307 getopt = DPyGetOpt.DPyGetOpt()
313 308 getopt.setIgnoreCase(0)
314 309
315 310 getopt.parseConfiguration(opts_names)
316 311
317 312 try:
318 313 getopt.processArguments(argv)
319 314 except DPyGetOpt.ArgumentError, exc:
320 315 print cmd_line_usage
321 316 warn('\nError in Arguments: "%s"' % exc)
322 317 sys.exit(1)
323 318
324 319 # convert the options dict to a struct for much lighter syntax later
325 320 opts = Struct(getopt.optionValues)
326 321 args = getopt.freeValues
327 322
328 323 # this is the struct (which has default values at this point) with which
329 324 # we make all decisions:
330 325 opts_all.update(opts)
331 326
332 327 # Options that force an immediate exit
333 328 if opts_all.help:
334 329 page(cmd_line_usage)
335 330 sys.exit()
336 331
337 332 if opts_all.Version:
338 333 print __version__
339 334 sys.exit()
340 335
341 336 if opts_all.magic_docstrings:
342 337 IP.magic_magic('-latex')
343 338 sys.exit()
344 339
345 340 # add personal ipythondir to sys.path so that users can put things in
346 341 # there for customization
347 342 sys.path.append(os.path.abspath(opts_all.ipythondir))
348 343
349 344 # Create user config directory if it doesn't exist. This must be done
350 345 # *after* getting the cmd line options.
351 346 if not os.path.isdir(opts_all.ipythondir):
352 347 IP.user_setup(opts_all.ipythondir,rc_suffix,'install')
353 348
354 349 # upgrade user config files while preserving a copy of the originals
355 350 if opts_all.upgrade:
356 351 IP.user_setup(opts_all.ipythondir,rc_suffix,'upgrade')
357 352
358 353 # check mutually exclusive options in the *original* command line
359 354 mutex_opts(opts,[qw('log logfile'),qw('rcfile profile'),
360 355 qw('classic profile'),qw('classic rcfile')])
361 356
362 357 #---------------------------------------------------------------------------
363 358 # Log replay
364 359
365 360 # if -logplay, we need to 'become' the other session. That basically means
366 361 # replacing the current command line environment with that of the old
367 362 # session and moving on.
368 363
369 364 # this is needed so that later we know we're in session reload mode, as
370 365 # opts_all will get overwritten:
371 366 load_logplay = 0
372 367
373 368 if opts_all.logplay:
374 369 load_logplay = opts_all.logplay
375 370 opts_debug_save = opts_all.debug
376 371 try:
377 372 logplay = open(opts_all.logplay)
378 373 except IOError:
379 374 if opts_all.debug: IP.InteractiveTB()
380 375 warn('Could not open logplay file '+`opts_all.logplay`)
381 376 # restore state as if nothing had happened and move on, but make
382 377 # sure that later we don't try to actually load the session file
383 378 logplay = None
384 379 load_logplay = 0
385 380 del opts_all.logplay
386 381 else:
387 382 try:
388 383 logplay.readline()
389 384 logplay.readline();
390 385 # this reloads that session's command line
391 386 cmd = logplay.readline()[6:]
392 387 exec cmd
393 388 # restore the true debug flag given so that the process of
394 389 # session loading itself can be monitored.
395 390 opts.debug = opts_debug_save
396 391 # save the logplay flag so later we don't overwrite the log
397 392 opts.logplay = load_logplay
398 393 # now we must update our own structure with defaults
399 394 opts_all.update(opts)
400 395 # now load args
401 396 cmd = logplay.readline()[6:]
402 397 exec cmd
403 398 logplay.close()
404 399 except:
405 400 logplay.close()
406 401 if opts_all.debug: IP.InteractiveTB()
407 402 warn("Logplay file lacking full configuration information.\n"
408 403 "I'll try to read it, but some things may not work.")
409 404
410 405 #-------------------------------------------------------------------------
411 406 # set up output traps: catch all output from files, being run, modules
412 407 # loaded, etc. Then give it to the user in a clean form at the end.
413 408
414 409 msg_out = 'Output messages. '
415 410 msg_err = 'Error messages. '
416 411 msg_sep = '\n'
417 412 msg = Struct(config = OutputTrap('Configuration Loader',msg_out,
418 413 msg_err,msg_sep,debug,
419 414 quiet_out=1),
420 415 user_exec = OutputTrap('User File Execution',msg_out,
421 416 msg_err,msg_sep,debug),
422 417 logplay = OutputTrap('Log Loader',msg_out,
423 418 msg_err,msg_sep,debug),
424 419 summary = ''
425 420 )
426 421
427 422 #-------------------------------------------------------------------------
428 423 # Process user ipythonrc-type configuration files
429 424
430 425 # turn on output trapping and log to msg.config
431 426 # remember that with debug on, trapping is actually disabled
432 427 msg.config.trap_all()
433 428
434 429 # look for rcfile in current or default directory
435 430 try:
436 431 opts_all.rcfile = filefind(opts_all.rcfile,opts_all.ipythondir)
437 432 except IOError:
438 433 if opts_all.debug: IP.InteractiveTB()
439 434 warn('Configuration file %s not found. Ignoring request.'
440 435 % (opts_all.rcfile) )
441 436
442 437 # 'profiles' are a shorthand notation for config filenames
443 438 profile_handled_by_legacy = False
444 439 if opts_all.profile:
445 440
446 441 try:
447 442 opts_all.rcfile = filefind('ipythonrc-' + opts_all.profile
448 443 + rc_suffix,
449 444 opts_all.ipythondir)
450 445 profile_handled_by_legacy = True
451 446 except IOError:
452 447 if opts_all.debug: IP.InteractiveTB()
453 448 opts.profile = '' # remove profile from options if invalid
454 449 # We won't warn anymore, primary method is ipy_profile_PROFNAME
455 450 # which does trigger a warning.
456 451
457 452 # load the config file
458 453 rcfiledata = None
459 454 if opts_all.quick:
460 455 print 'Launching IPython in quick mode. No config file read.'
461 456 elif opts_all.rcfile:
462 457 try:
463 458 cfg_loader = ConfigLoader(conflict)
464 459 rcfiledata = cfg_loader.load(opts_all.rcfile,typeconv,
465 460 'include',opts_all.ipythondir,
466 461 purge = 1,
467 462 unique = conflict['preserve'])
468 463 except:
469 464 IP.InteractiveTB()
470 465 warn('Problems loading configuration file '+
471 466 `opts_all.rcfile`+
472 467 '\nStarting with default -bare bones- configuration.')
473 468 else:
474 469 warn('No valid configuration file found in either currrent directory\n'+
475 470 'or in the IPython config. directory: '+`opts_all.ipythondir`+
476 471 '\nProceeding with internal defaults.')
477 472
478 473 #------------------------------------------------------------------------
479 474 # Set exception handlers in mode requested by user.
480 475 otrap = OutputTrap(trap_out=1) # trap messages from magic_xmode
481 476 IP.magic_xmode(opts_all.xmode)
482 477 otrap.release_out()
483 478
484 479 #------------------------------------------------------------------------
485 480 # Execute user config
486 481
487 482 # Create a valid config structure with the right precedence order:
488 483 # defaults < rcfile < command line. This needs to be in the instance, so
489 484 # that method calls below that rely on it find it.
490 485 IP.rc = rc_def.copy()
491 486
492 487 # Work with a local alias inside this routine to avoid unnecessary
493 488 # attribute lookups.
494 489 IP_rc = IP.rc
495 490
496 491 IP_rc.update(opts_def)
497 492 if rcfiledata:
498 493 # now we can update
499 494 IP_rc.update(rcfiledata)
500 495 IP_rc.update(opts)
501 496 IP_rc.update(rc_override)
502 497
503 498 # Store the original cmd line for reference:
504 499 IP_rc.opts = opts
505 500 IP_rc.args = args
506 501
507 502 # create a *runtime* Struct like rc for holding parameters which may be
508 503 # created and/or modified by runtime user extensions.
509 504 IP.runtime_rc = Struct()
510 505
511 506 # from this point on, all config should be handled through IP_rc,
512 507 # opts* shouldn't be used anymore.
513 508
514 509
515 510 # update IP_rc with some special things that need manual
516 511 # tweaks. Basically options which affect other options. I guess this
517 512 # should just be written so that options are fully orthogonal and we
518 513 # wouldn't worry about this stuff!
519 514
520 515 if IP_rc.classic:
521 516 IP_rc.quick = 1
522 517 IP_rc.cache_size = 0
523 518 IP_rc.pprint = 0
524 519 IP_rc.prompt_in1 = '>>> '
525 520 IP_rc.prompt_in2 = '... '
526 521 IP_rc.prompt_out = ''
527 522 IP_rc.separate_in = IP_rc.separate_out = IP_rc.separate_out2 = '0'
528 523 IP_rc.colors = 'NoColor'
529 524 IP_rc.xmode = 'Plain'
530 525
531 526 IP.pre_config_initialization()
532 527 # configure readline
533 528
534 529 # update exception handlers with rc file status
535 530 otrap.trap_out() # I don't want these messages ever.
536 531 IP.magic_xmode(IP_rc.xmode)
537 532 otrap.release_out()
538 533
539 534 # activate logging if requested and not reloading a log
540 535 if IP_rc.logplay:
541 536 IP.magic_logstart(IP_rc.logplay + ' append')
542 537 elif IP_rc.logfile:
543 538 IP.magic_logstart(IP_rc.logfile)
544 539 elif IP_rc.log:
545 540 IP.magic_logstart()
546 541
547 542 # find user editor so that it we don't have to look it up constantly
548 543 if IP_rc.editor.strip()=='0':
549 544 try:
550 545 ed = os.environ['EDITOR']
551 546 except KeyError:
552 547 if os.name == 'posix':
553 548 ed = 'vi' # the only one guaranteed to be there!
554 549 else:
555 550 ed = 'notepad' # same in Windows!
556 551 IP_rc.editor = ed
557 552
558 553 # Keep track of whether this is an embedded instance or not (useful for
559 554 # post-mortems).
560 555 IP_rc.embedded = IP.embedded
561 556
562 557 # Recursive reload
563 558 try:
564 559 from IPython import deep_reload
565 560 if IP_rc.deep_reload:
566 561 __builtin__.reload = deep_reload.reload
567 562 else:
568 563 __builtin__.dreload = deep_reload.reload
569 564 del deep_reload
570 565 except ImportError:
571 566 pass
572 567
573 568 # Save the current state of our namespace so that the interactive shell
574 569 # can later know which variables have been created by us from config files
575 570 # and loading. This way, loading a file (in any way) is treated just like
576 571 # defining things on the command line, and %who works as expected.
577 572
578 573 # DON'T do anything that affects the namespace beyond this point!
579 574 IP.internal_ns.update(__main__.__dict__)
580 575
581 576 #IP.internal_ns.update(locals()) # so our stuff doesn't show up in %who
582 577
583 578 # Now run through the different sections of the users's config
584 579 if IP_rc.debug:
585 580 print 'Trying to execute the following configuration structure:'
586 581 print '(Things listed first are deeper in the inclusion tree and get'
587 582 print 'loaded first).\n'
588 583 pprint(IP_rc.__dict__)
589 584
590 585 for mod in IP_rc.import_mod:
591 586 try:
592 587 exec 'import '+mod in IP.user_ns
593 588 except :
594 589 IP.InteractiveTB()
595 590 import_fail_info(mod)
596 591
597 592 for mod_fn in IP_rc.import_some:
598 593 if not mod_fn == []:
599 594 mod,fn = mod_fn[0],','.join(mod_fn[1:])
600 595 try:
601 596 exec 'from '+mod+' import '+fn in IP.user_ns
602 597 except :
603 598 IP.InteractiveTB()
604 599 import_fail_info(mod,fn)
605 600
606 601 for mod in IP_rc.import_all:
607 602 try:
608 603 exec 'from '+mod+' import *' in IP.user_ns
609 604 except :
610 605 IP.InteractiveTB()
611 606 import_fail_info(mod)
612 607
613 608 for code in IP_rc.execute:
614 609 try:
615 610 exec code in IP.user_ns
616 611 except:
617 612 IP.InteractiveTB()
618 613 warn('Failure executing code: ' + `code`)
619 614
620 615 # Execute the files the user wants in ipythonrc
621 616 for file in IP_rc.execfile:
622 617 try:
623 618 file = filefind(file,sys.path+[IPython_dir])
624 619 except IOError:
625 620 warn(itpl('File $file not found. Skipping it.'))
626 621 else:
627 622 IP.safe_execfile(os.path.expanduser(file),IP.user_ns)
628 623
629 624 # finally, try importing ipy_*_conf for final configuration
630 625 try:
631 626 import ipy_system_conf
632 627 except ImportError:
633 628 if opts_all.debug: IP.InteractiveTB()
634 629 warn("Could not import 'ipy_system_conf'")
635 630 except:
636 631 IP.InteractiveTB()
637 632 import_fail_info('ipy_system_conf')
638 633
639 634 # only import prof module if ipythonrc-PROF was not found
640 635 if opts_all.profile and not profile_handled_by_legacy:
641 636 profmodname = 'ipy_profile_' + opts_all.profile
642 637 try:
643 638
644 639 force_import(profmodname)
645 640 except:
646 641 IP.InteractiveTB()
647 642 print "Error importing",profmodname,"- perhaps you should run %upgrade?"
648 643 import_fail_info(profmodname)
649 644 else:
650 645 opts.profile = opts_all.profile
651 646 else:
652 647 force_import('ipy_profile_none')
653 648 try:
654 649
655 650 force_import('ipy_user_conf')
656 651
657 652 except:
658 653 conf = opts_all.ipythondir + "/ipy_user_conf.py"
659 654 IP.InteractiveTB()
660 655 if not os.path.isfile(conf):
661 656 warn(conf + ' does not exist, please run %upgrade!')
662 657
663 658 import_fail_info("ipy_user_conf")
664 659
665 660 # Define the history file for saving commands in between sessions
666 661 try:
667 662 histfname = 'history-%s' % opts.profile
668 663 except AttributeError:
669 664 histfname = 'history'
670 665 IP.histfile = os.path.join(opts_all.ipythondir,histfname)
671 666
672 667 # finally, push the argv to options again to ensure highest priority
673 668 IP_rc.update(opts)
674 669
675 670 # release stdout and stderr and save config log into a global summary
676 671 msg.config.release_all()
677 672 if IP_rc.messages:
678 673 msg.summary += msg.config.summary_all()
679 674
680 675 #------------------------------------------------------------------------
681 676 # Setup interactive session
682 677
683 678 # Now we should be fully configured. We can then execute files or load
684 679 # things only needed for interactive use. Then we'll open the shell.
685 680
686 681 # Take a snapshot of the user namespace before opening the shell. That way
687 682 # we'll be able to identify which things were interactively defined and
688 683 # which were defined through config files.
689 684 IP.user_config_ns.update(IP.user_ns)
690 685
691 686 # Force reading a file as if it were a session log. Slower but safer.
692 687 if load_logplay:
693 688 print 'Replaying log...'
694 689 try:
695 690 if IP_rc.debug:
696 691 logplay_quiet = 0
697 692 else:
698 693 logplay_quiet = 1
699 694
700 695 msg.logplay.trap_all()
701 696 IP.safe_execfile(load_logplay,IP.user_ns,
702 697 islog = 1, quiet = logplay_quiet)
703 698 msg.logplay.release_all()
704 699 if IP_rc.messages:
705 700 msg.summary += msg.logplay.summary_all()
706 701 except:
707 702 warn('Problems replaying logfile %s.' % load_logplay)
708 703 IP.InteractiveTB()
709 704
710 705 # Load remaining files in command line
711 706 msg.user_exec.trap_all()
712 707
713 708 # Do NOT execute files named in the command line as scripts to be loaded
714 709 # by embedded instances. Doing so has the potential for an infinite
715 710 # recursion if there are exceptions thrown in the process.
716 711
717 712 # XXX FIXME: the execution of user files should be moved out to after
718 713 # ipython is fully initialized, just as if they were run via %run at the
719 714 # ipython prompt. This would also give them the benefit of ipython's
720 715 # nice tracebacks.
721 716
722 717 if (not embedded and IP_rc.args and
723 718 not IP_rc.args[0].lower().endswith('.ipy')):
724 719 name_save = IP.user_ns['__name__']
725 720 IP.user_ns['__name__'] = '__main__'
726 721 # Set our own excepthook in case the user code tries to call it
727 722 # directly. This prevents triggering the IPython crash handler.
728 723 old_excepthook,sys.excepthook = sys.excepthook, IP.excepthook
729 724
730 725 save_argv = sys.argv[1:] # save it for later restoring
731 726
732 727 sys.argv = args
733 728
734 729 try:
735 730 IP.safe_execfile(args[0], IP.user_ns)
736 731 finally:
737 732 # Reset our crash handler in place
738 733 sys.excepthook = old_excepthook
739 734 sys.argv[:] = save_argv
740 735 IP.user_ns['__name__'] = name_save
741 736
742 737 msg.user_exec.release_all()
743 738
744 739 if IP_rc.messages:
745 740 msg.summary += msg.user_exec.summary_all()
746 741
747 742 # since we can't specify a null string on the cmd line, 0 is the equivalent:
748 743 if IP_rc.nosep:
749 744 IP_rc.separate_in = IP_rc.separate_out = IP_rc.separate_out2 = '0'
750 745 if IP_rc.separate_in == '0': IP_rc.separate_in = ''
751 746 if IP_rc.separate_out == '0': IP_rc.separate_out = ''
752 747 if IP_rc.separate_out2 == '0': IP_rc.separate_out2 = ''
753 748 IP_rc.separate_in = IP_rc.separate_in.replace('\\n','\n')
754 749 IP_rc.separate_out = IP_rc.separate_out.replace('\\n','\n')
755 750 IP_rc.separate_out2 = IP_rc.separate_out2.replace('\\n','\n')
756 751
757 752 # Determine how many lines at the bottom of the screen are needed for
758 753 # showing prompts, so we can know wheter long strings are to be printed or
759 754 # paged:
760 755 num_lines_bot = IP_rc.separate_in.count('\n')+1
761 756 IP_rc.screen_length = IP_rc.screen_length - num_lines_bot
762 757
763 758 # configure startup banner
764 759 if IP_rc.c: # regular python doesn't print the banner with -c
765 760 IP_rc.banner = 0
766 761 if IP_rc.banner:
767 762 BANN_P = IP.BANNER_PARTS
768 763 else:
769 764 BANN_P = []
770 765
771 766 if IP_rc.profile: BANN_P.append('IPython profile: %s\n' % IP_rc.profile)
772 767
773 768 # add message log (possibly empty)
774 769 if msg.summary: BANN_P.append(msg.summary)
775 770 # Final banner is a string
776 771 IP.BANNER = '\n'.join(BANN_P)
777 772
778 773 # Finalize the IPython instance. This assumes the rc structure is fully
779 774 # in place.
780 775 IP.post_config_initialization()
781 776
782 777 return IP
783 778 #************************ end of file <ipmaker.py> **************************
@@ -1,157 +1,204 b''
1 1 # encoding: utf-8
2 2
3 3 """Tests for genutils.py"""
4 4
5 5 __docformat__ = "restructuredtext en"
6 6
7 7 #-----------------------------------------------------------------------------
8 8 # Copyright (C) 2008 The IPython Development Team
9 9 #
10 10 # Distributed under the terms of the BSD License. The full license is in
11 11 # the file COPYING, distributed as part of this software.
12 12 #-----------------------------------------------------------------------------
13 13
14 14 #-----------------------------------------------------------------------------
15 15 # Imports
16 16 #-----------------------------------------------------------------------------
17 17
18 18 from IPython import genutils
19 19
20 20 import os, sys, IPython
21 21 env = os.environ
22 22
23 23 from os.path import join, abspath
24 24
25 25 def test_get_home_dir_1():
26 26 """Testcase to see if we can call get_home_dir without Exceptions."""
27 27 home_dir = genutils.get_home_dir()
28 28
29 29 def test_get_home_dir_2():
30 30 """Testcase for py2exe logic, un-compressed lib
31 31 """
32 32 sys.frozen=True
33 33 oldstuff=IPython.__file__
34 34
35 35 #fake filename for IPython.__init__
36 36 IPython.__file__=abspath(join(".", "home_test_dir/Lib/IPython/__init__.py"))
37 37
38 38 home_dir = genutils.get_home_dir()
39 39 assert home_dir==abspath(join(".", "home_test_dir"))
40 40 IPython.__file__=oldstuff
41 41 del sys.frozen
42 42
43 43 def test_get_home_dir_3():
44 44 """Testcase for py2exe logic, compressed lib
45 45 """
46 46
47 47 sys.frozen=True
48 48 oldstuff=IPython.__file__
49 49
50 50 #fake filename for IPython.__init__
51 51 IPython.__file__=abspath(join(".", "home_test_dir/Library.zip/IPython/__init__.py"))
52 52
53 53 home_dir = genutils.get_home_dir()
54 54 assert home_dir==abspath(join(".", "home_test_dir")).lower()
55 55
56 56 del sys.frozen
57 57 IPython.__file__=oldstuff
58 58
59 59
60 60 def test_get_home_dir_4():
61 61 """Testcase $HOME is set, then use its value as home directory."""
62 62 oldstuff=env["HOME"]
63 63
64 64 env["HOME"]=join(".","home_test_dir")
65 65 home_dir = genutils.get_home_dir()
66 66 assert home_dir==env["HOME"]
67 67
68 68 env["HOME"]=oldstuff
69 69
70 70 def test_get_home_dir_5():
71 71 """Testcase $HOME is not set, os=='posix'.
72 72 This should fail with HomeDirError"""
73 73 oldstuff=env["HOME"],os.name
74 74
75 75 os.name='posix'
76 76 del os.environ["HOME"]
77 77 try:
78 78 genutils.get_home_dir()
79 79 assert False
80 80 except genutils.HomeDirError:
81 81 pass
82 82 finally:
83 83 env["HOME"],os.name=oldstuff
84 84
85 85 def test_get_home_dir_6():
86 86 """Testcase $HOME is not set, os=='nt'
87 87 env['HOMEDRIVE'],env['HOMEPATH'] points to path."""
88 88
89 89 oldstuff=env["HOME"],os.name,env['HOMEDRIVE'],env['HOMEPATH']
90 90
91 91 os.name='nt'
92 92 del os.environ["HOME"]
93 93 env['HOMEDRIVE'],env['HOMEPATH']=os.path.abspath("."),"home_test_dir"
94 94
95 95 home_dir = genutils.get_home_dir()
96 96 assert home_dir==abspath(join(".", "home_test_dir"))
97 97
98 98 env["HOME"],os.name,env['HOMEDRIVE'],env['HOMEPATH']=oldstuff
99 99
100 100 def test_get_home_dir_8():
101 101 """Testcase $HOME is not set, os=='nt'
102 102 env['HOMEDRIVE'],env['HOMEPATH'] do not point to path.
103 103 env['USERPROFILE'] points to path
104 104 """
105 105 oldstuff=(env["HOME"],os.name,env['HOMEDRIVE'],env['HOMEPATH'])
106 106
107 107 os.name='nt'
108 108 del os.environ["HOME"]
109 109 env['HOMEDRIVE'],env['HOMEPATH']=os.path.abspath("."),"DOES NOT EXIST"
110 110 env["USERPROFILE"]=abspath(join(".","home_test_dir"))
111 111
112 112 home_dir = genutils.get_home_dir()
113 113 assert home_dir==abspath(join(".", "home_test_dir"))
114 114
115 115 (env["HOME"],os.name,env['HOMEDRIVE'],env['HOMEPATH'])=oldstuff
116 116
117 117 def test_get_home_dir_9():
118 118 """Testcase $HOME is not set, os=='nt'
119 119 env['HOMEDRIVE'],env['HOMEPATH'], env['USERPROFILE'] missing
120 120 """
121 121 import _winreg as wreg
122 122 oldstuff = (env["HOME"],os.name,env['HOMEDRIVE'],
123 123 env['HOMEPATH'],env["USERPROFILE"],
124 124 wreg.OpenKey, wreg.QueryValueEx,
125 125 )
126 126 os.name='nt'
127 127 del env["HOME"],env['HOMEDRIVE']
128 128
129 129 #Stub windows registry functions
130 130 def OpenKey(x,y):
131 131 class key:
132 132 def Close(self):
133 133 pass
134 134 return key()
135 135 def QueryValueEx(x,y):
136 136 return [abspath(join(".", "home_test_dir"))]
137 137
138 138 wreg.OpenKey=OpenKey
139 139 wreg.QueryValueEx=QueryValueEx
140 140
141 141
142 142 home_dir = genutils.get_home_dir()
143 143 assert home_dir==abspath(join(".", "home_test_dir"))
144 144
145 145 (env["HOME"],os.name,env['HOMEDRIVE'],
146 146 env['HOMEPATH'],env["USERPROFILE"],
147 147 wreg.OpenKey, wreg.QueryValueEx,) = oldstuff
148 148
149 149
150 def test_get_ipython_dir():
150 def test_get_ipython_dir_1():
151 151 """Testcase to see if we can call get_ipython_dir without Exceptions."""
152 152 ipdir = genutils.get_ipython_dir()
153 153
154 def test_get_security_dir():
155 """Testcase to see if we can call get_security_dir without Exceptions."""
156 sdir = genutils.get_security_dir()
154 def test_get_ipython_dir_2():
155 """Testcase to see if we can call get_ipython_dir without Exceptions."""
156 oldstuff = (env['IPYTHONDIR'],)
157
158 env['IPYTHONDIR']="someplace/.ipython"
159 ipdir = genutils.get_ipython_dir()
160 assert ipdir == os.path.abspath("someplace/.ipython")
161
162 (env['IPYTHONDIR'],)=oldstuff
163
164 class test_get_ipython_dir_3:
165 @classmethod
166 def setup_class(cls):
167 cls.oldstuff = (env['IPYTHONDIR'], os.name, genutils.get_home_dir)
168 del env['IPYTHONDIR']
169 genutils.get_home_dir=lambda : "someplace"
170
171 @classmethod
172 def teardown_class(cls):
173 (env['IPYTHONDIR'], os.name, genutils.get_home_dir)=cls.oldstuff
174
175 def test_get_ipython_dir_a(self):
176 """Testcase to see if we can call get_ipython_dir without Exceptions."""
177
178 os.name="posix"
179 ipdir = genutils.get_ipython_dir()
180 assert ipdir == os.path.abspath(os.path.join("someplace", ".ipython"))
181
182 def test_get_ipython_dir_b(self):
183 """Testcase to see if we can call get_ipython_dir without Exceptions."""
184
185 os.name="nt"
186 ipdir = genutils.get_ipython_dir()
187 assert ipdir == os.path.abspath(os.path.join("someplace", "_ipython"))
188
189 class test_get_security_dir:
190 @classmethod
191 def setup_class(cls):
192 cls.oldstuff = (env['IPYTHONDIR'], os.name, genutils.get_home_dir)
193 del env['IPYTHONDIR']
194 genutils.get_home_dir=lambda : "someplace"
195
196 @classmethod
197 def teardown_class(cls):
198 (env['IPYTHONDIR'], os.name, genutils.get_home_dir)=cls.oldstuff
199
200
201 def test_get_security_dir():
202 """Testcase to see if we can call get_security_dir without Exceptions."""
203 sdir = genutils.get_security_dir()
157 204 No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now