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