python-2.5.2/win32/Lib/code.py
changeset 0 ae805ac0140d
equal deleted inserted replaced
-1:000000000000 0:ae805ac0140d
       
     1 """Utilities needed to emulate Python's interactive interpreter.
       
     2 
       
     3 """
       
     4 
       
     5 # Inspired by similar code by Jeff Epler and Fredrik Lundh.
       
     6 
       
     7 
       
     8 import sys
       
     9 import traceback
       
    10 from codeop import CommandCompiler, compile_command
       
    11 
       
    12 __all__ = ["InteractiveInterpreter", "InteractiveConsole", "interact",
       
    13            "compile_command"]
       
    14 
       
    15 def softspace(file, newvalue):
       
    16     oldvalue = 0
       
    17     try:
       
    18         oldvalue = file.softspace
       
    19     except AttributeError:
       
    20         pass
       
    21     try:
       
    22         file.softspace = newvalue
       
    23     except (AttributeError, TypeError):
       
    24         # "attribute-less object" or "read-only attributes"
       
    25         pass
       
    26     return oldvalue
       
    27 
       
    28 class InteractiveInterpreter:
       
    29     """Base class for InteractiveConsole.
       
    30 
       
    31     This class deals with parsing and interpreter state (the user's
       
    32     namespace); it doesn't deal with input buffering or prompting or
       
    33     input file naming (the filename is always passed in explicitly).
       
    34 
       
    35     """
       
    36 
       
    37     def __init__(self, locals=None):
       
    38         """Constructor.
       
    39 
       
    40         The optional 'locals' argument specifies the dictionary in
       
    41         which code will be executed; it defaults to a newly created
       
    42         dictionary with key "__name__" set to "__console__" and key
       
    43         "__doc__" set to None.
       
    44 
       
    45         """
       
    46         if locals is None:
       
    47             locals = {"__name__": "__console__", "__doc__": None}
       
    48         self.locals = locals
       
    49         self.compile = CommandCompiler()
       
    50 
       
    51     def runsource(self, source, filename="<input>", symbol="single"):
       
    52         """Compile and run some source in the interpreter.
       
    53 
       
    54         Arguments are as for compile_command().
       
    55 
       
    56         One several things can happen:
       
    57 
       
    58         1) The input is incorrect; compile_command() raised an
       
    59         exception (SyntaxError or OverflowError).  A syntax traceback
       
    60         will be printed by calling the showsyntaxerror() method.
       
    61 
       
    62         2) The input is incomplete, and more input is required;
       
    63         compile_command() returned None.  Nothing happens.
       
    64 
       
    65         3) The input is complete; compile_command() returned a code
       
    66         object.  The code is executed by calling self.runcode() (which
       
    67         also handles run-time exceptions, except for SystemExit).
       
    68 
       
    69         The return value is True in case 2, False in the other cases (unless
       
    70         an exception is raised).  The return value can be used to
       
    71         decide whether to use sys.ps1 or sys.ps2 to prompt the next
       
    72         line.
       
    73 
       
    74         """
       
    75         try:
       
    76             code = self.compile(source, filename, symbol)
       
    77         except (OverflowError, SyntaxError, ValueError):
       
    78             # Case 1
       
    79             self.showsyntaxerror(filename)
       
    80             return False
       
    81 
       
    82         if code is None:
       
    83             # Case 2
       
    84             return True
       
    85 
       
    86         # Case 3
       
    87         self.runcode(code)
       
    88         return False
       
    89 
       
    90     def runcode(self, code):
       
    91         """Execute a code object.
       
    92 
       
    93         When an exception occurs, self.showtraceback() is called to
       
    94         display a traceback.  All exceptions are caught except
       
    95         SystemExit, which is reraised.
       
    96 
       
    97         A note about KeyboardInterrupt: this exception may occur
       
    98         elsewhere in this code, and may not always be caught.  The
       
    99         caller should be prepared to deal with it.
       
   100 
       
   101         """
       
   102         try:
       
   103             exec code in self.locals
       
   104         except SystemExit:
       
   105             raise
       
   106         except:
       
   107             self.showtraceback()
       
   108         else:
       
   109             if softspace(sys.stdout, 0):
       
   110                 print
       
   111 
       
   112     def showsyntaxerror(self, filename=None):
       
   113         """Display the syntax error that just occurred.
       
   114 
       
   115         This doesn't display a stack trace because there isn't one.
       
   116 
       
   117         If a filename is given, it is stuffed in the exception instead
       
   118         of what was there before (because Python's parser always uses
       
   119         "<string>" when reading from a string).
       
   120 
       
   121         The output is written by self.write(), below.
       
   122 
       
   123         """
       
   124         type, value, sys.last_traceback = sys.exc_info()
       
   125         sys.last_type = type
       
   126         sys.last_value = value
       
   127         if filename and type is SyntaxError:
       
   128             # Work hard to stuff the correct filename in the exception
       
   129             try:
       
   130                 msg, (dummy_filename, lineno, offset, line) = value
       
   131             except:
       
   132                 # Not the format we expect; leave it alone
       
   133                 pass
       
   134             else:
       
   135                 # Stuff in the right filename
       
   136                 value = SyntaxError(msg, (filename, lineno, offset, line))
       
   137                 sys.last_value = value
       
   138         list = traceback.format_exception_only(type, value)
       
   139         map(self.write, list)
       
   140 
       
   141     def showtraceback(self):
       
   142         """Display the exception that just occurred.
       
   143 
       
   144         We remove the first stack item because it is our own code.
       
   145 
       
   146         The output is written by self.write(), below.
       
   147 
       
   148         """
       
   149         try:
       
   150             type, value, tb = sys.exc_info()
       
   151             sys.last_type = type
       
   152             sys.last_value = value
       
   153             sys.last_traceback = tb
       
   154             tblist = traceback.extract_tb(tb)
       
   155             del tblist[:1]
       
   156             list = traceback.format_list(tblist)
       
   157             if list:
       
   158                 list.insert(0, "Traceback (most recent call last):\n")
       
   159             list[len(list):] = traceback.format_exception_only(type, value)
       
   160         finally:
       
   161             tblist = tb = None
       
   162         map(self.write, list)
       
   163 
       
   164     def write(self, data):
       
   165         """Write a string.
       
   166 
       
   167         The base implementation writes to sys.stderr; a subclass may
       
   168         replace this with a different implementation.
       
   169 
       
   170         """
       
   171         sys.stderr.write(data)
       
   172 
       
   173 
       
   174 class InteractiveConsole(InteractiveInterpreter):
       
   175     """Closely emulate the behavior of the interactive Python interpreter.
       
   176 
       
   177     This class builds on InteractiveInterpreter and adds prompting
       
   178     using the familiar sys.ps1 and sys.ps2, and input buffering.
       
   179 
       
   180     """
       
   181 
       
   182     def __init__(self, locals=None, filename="<console>"):
       
   183         """Constructor.
       
   184 
       
   185         The optional locals argument will be passed to the
       
   186         InteractiveInterpreter base class.
       
   187 
       
   188         The optional filename argument should specify the (file)name
       
   189         of the input stream; it will show up in tracebacks.
       
   190 
       
   191         """
       
   192         InteractiveInterpreter.__init__(self, locals)
       
   193         self.filename = filename
       
   194         self.resetbuffer()
       
   195 
       
   196     def resetbuffer(self):
       
   197         """Reset the input buffer."""
       
   198         self.buffer = []
       
   199 
       
   200     def interact(self, banner=None):
       
   201         """Closely emulate the interactive Python console.
       
   202 
       
   203         The optional banner argument specify the banner to print
       
   204         before the first interaction; by default it prints a banner
       
   205         similar to the one printed by the real Python interpreter,
       
   206         followed by the current class name in parentheses (so as not
       
   207         to confuse this with the real interpreter -- since it's so
       
   208         close!).
       
   209 
       
   210         """
       
   211         try:
       
   212             sys.ps1
       
   213         except AttributeError:
       
   214             sys.ps1 = ">>> "
       
   215         try:
       
   216             sys.ps2
       
   217         except AttributeError:
       
   218             sys.ps2 = "... "
       
   219         cprt = 'Type "help", "copyright", "credits" or "license" for more information.'
       
   220         if banner is None:
       
   221             self.write("Python %s on %s\n%s\n(%s)\n" %
       
   222                        (sys.version, sys.platform, cprt,
       
   223                         self.__class__.__name__))
       
   224         else:
       
   225             self.write("%s\n" % str(banner))
       
   226         more = 0
       
   227         while 1:
       
   228             try:
       
   229                 if more:
       
   230                     prompt = sys.ps2
       
   231                 else:
       
   232                     prompt = sys.ps1
       
   233                 try:
       
   234                     line = self.raw_input(prompt)
       
   235                 except EOFError:
       
   236                     self.write("\n")
       
   237                     break
       
   238                 else:
       
   239                     more = self.push(line)
       
   240             except KeyboardInterrupt:
       
   241                 self.write("\nKeyboardInterrupt\n")
       
   242                 self.resetbuffer()
       
   243                 more = 0
       
   244 
       
   245     def push(self, line):
       
   246         """Push a line to the interpreter.
       
   247 
       
   248         The line should not have a trailing newline; it may have
       
   249         internal newlines.  The line is appended to a buffer and the
       
   250         interpreter's runsource() method is called with the
       
   251         concatenated contents of the buffer as source.  If this
       
   252         indicates that the command was executed or invalid, the buffer
       
   253         is reset; otherwise, the command is incomplete, and the buffer
       
   254         is left as it was after the line was appended.  The return
       
   255         value is 1 if more input is required, 0 if the line was dealt
       
   256         with in some way (this is the same as runsource()).
       
   257 
       
   258         """
       
   259         self.buffer.append(line)
       
   260         source = "\n".join(self.buffer)
       
   261         more = self.runsource(source, self.filename)
       
   262         if not more:
       
   263             self.resetbuffer()
       
   264         return more
       
   265 
       
   266     def raw_input(self, prompt=""):
       
   267         """Write a prompt and read a line.
       
   268 
       
   269         The returned line does not include the trailing newline.
       
   270         When the user enters the EOF key sequence, EOFError is raised.
       
   271 
       
   272         The base implementation uses the built-in function
       
   273         raw_input(); a subclass may replace this with a different
       
   274         implementation.
       
   275 
       
   276         """
       
   277         return raw_input(prompt)
       
   278 
       
   279 
       
   280 def interact(banner=None, readfunc=None, local=None):
       
   281     """Closely emulate the interactive Python interpreter.
       
   282 
       
   283     This is a backwards compatible interface to the InteractiveConsole
       
   284     class.  When readfunc is not specified, it attempts to import the
       
   285     readline module to enable GNU readline if it is available.
       
   286 
       
   287     Arguments (all optional, all default to None):
       
   288 
       
   289     banner -- passed to InteractiveConsole.interact()
       
   290     readfunc -- if not None, replaces InteractiveConsole.raw_input()
       
   291     local -- passed to InteractiveInterpreter.__init__()
       
   292 
       
   293     """
       
   294     console = InteractiveConsole(local)
       
   295     if readfunc is not None:
       
   296         console.raw_input = readfunc
       
   297     else:
       
   298         try:
       
   299             import readline
       
   300         except ImportError:
       
   301             pass
       
   302     console.interact(banner)
       
   303 
       
   304 
       
   305 if __name__ == '__main__':
       
   306     import pdb
       
   307     pdb.run("interact()\n")