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