home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / pyos2bin.zip / Lib / code.py < prev    next >
Text File  |  1997-10-07  |  3KB  |  105 lines

  1. # XXX This is broken with class exceptions
  2.  
  3. """Utilities dealing with code objects."""
  4.  
  5. def compile_command(source, filename="<input>", symbol="single"):
  6.     r"""Compile a command and determine whether it is incomplete.
  7.  
  8.     Arguments:
  9.  
  10.     source -- the source string; may contain \n characters
  11.     filename -- optional filename from which source was read; default "<input>"
  12.     symbol -- optional grammar start symbol; "single" (default) or "eval"
  13.  
  14.     Return value / exception raised:
  15.  
  16.     - Return a code object if the command is complete and valid
  17.     - Return None if the command is incomplete
  18.     - Raise SyntaxError if the command is a syntax error
  19.  
  20.     Approach:
  21.     
  22.     Compile three times: as is, with \n, and with \n\n appended.  If
  23.     it compiles as is, it's complete.  If it compiles with one \n
  24.     appended, we expect more.  If it doesn't compile either way, we
  25.     compare the error we get when compiling with \n or \n\n appended.
  26.     If the errors are the same, the code is broken.  But if the errors
  27.     are different, we expect more.  Not intuitive; not even guaranteed
  28.     to hold in future releases; but this matches the compiler's
  29.     behavior in Python 1.4 and 1.5.
  30.  
  31.     """
  32.  
  33.     err = err1 = err2 = None
  34.     code = code1 = code2 = None
  35.  
  36.     try:
  37.     code = compile(source, filename, symbol)
  38.     except SyntaxError, err:
  39.     pass
  40.  
  41.     try:
  42.     code1 = compile(source + "\n", filename, symbol)
  43.     except SyntaxError, err1:
  44.     pass
  45.  
  46.     try:
  47.     code2 = compile(source + "\n\n", filename, symbol)
  48.     except SyntaxError, err2:
  49.     pass
  50.  
  51.     if code:
  52.     return code
  53.     if not code1 and err1 == err2:
  54.     raise SyntaxError, err1
  55.  
  56.  
  57. def interact(banner=None, readfunc=raw_input, local=None):
  58.     # Due to Jeff Epler, with changes by Guido:
  59.     """Closely emulate the interactive Python console."""
  60.     try: import readline # Enable GNU readline if available
  61.     except: pass
  62.     local = local or {}
  63.     import sys, string, traceback
  64.     sys.ps1 = '>>> '
  65.     sys.ps2 = '... '
  66.     if banner:
  67.     print banner
  68.     else:
  69.     print "Python Interactive Console", sys.version
  70.     print sys.copyright
  71.     buf = []
  72.     while 1:
  73.     if buf: prompt = sys.ps2
  74.     else: prompt = sys.ps1
  75.     try: line = readfunc(prompt)
  76.     except KeyboardInterrupt:
  77.         print "\nKeyboardInterrupt"
  78.         buf = []
  79.         continue
  80.     except EOFError: break
  81.     buf.append(line)
  82.     try: x = compile_command(string.join(buf, "\n"))
  83.     except SyntaxError:
  84.         traceback.print_exc(0)
  85.         buf = []
  86.         continue
  87.     if x == None: continue
  88.     else:
  89.         try: exec x in local
  90.         except:
  91.         exc_type, exc_value, exc_traceback = \
  92.             sys.exc_type, sys.exc_value, \
  93.             sys.exc_traceback
  94.         l = len(traceback.extract_tb(sys.exc_traceback))
  95.         try: 1/0
  96.         except:
  97.             m = len(traceback.extract_tb(
  98.                 sys.exc_traceback))
  99.         traceback.print_exception(exc_type,
  100.             exc_value, exc_traceback, l-m)
  101.         buf = []
  102.         
  103. if __name__ == '__main__':
  104.     interact()
  105.