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