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