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