PyXR

c:\python24\lib \ code.py



0001 """Utilities needed to emulate Python's interactive interpreter.
0002 
0003 """
0004 
0005 # Inspired by similar code by Jeff Epler and Fredrik Lundh.
0006 
0007 
0008 import sys
0009 import traceback
0010 from codeop import CommandCompiler, compile_command
0011 
0012 __all__ = ["InteractiveInterpreter", "InteractiveConsole", "interact",
0013            "compile_command"]
0014 
0015 def softspace(file, newvalue):
0016     oldvalue = 0
0017     try:
0018         oldvalue = file.softspace
0019     except AttributeError:
0020         pass
0021     try:
0022         file.softspace = newvalue
0023     except (AttributeError, TypeError):
0024         # "attribute-less object" or "read-only attributes"
0025         pass
0026     return oldvalue
0027 
0028 class InteractiveInterpreter:
0029     """Base class for InteractiveConsole.
0030 
0031     This class deals with parsing and interpreter state (the user's
0032     namespace); it doesn't deal with input buffering or prompting or
0033     input file naming (the filename is always passed in explicitly).
0034 
0035     """
0036 
0037     def __init__(self, locals=None):
0038         """Constructor.
0039 
0040         The optional 'locals' argument specifies the dictionary in
0041         which code will be executed; it defaults to a newly created
0042         dictionary with key "__name__" set to "__console__" and key
0043         "__doc__" set to None.
0044 
0045         """
0046         if locals is None:
0047             locals = {"__name__": "__console__", "__doc__": None}
0048         self.locals = locals
0049         self.compile = CommandCompiler()
0050 
0051     def runsource(self, source, filename="<input>", symbol="single"):
0052         """Compile and run some source in the interpreter.
0053 
0054         Arguments are as for compile_command().
0055 
0056         One several things can happen:
0057 
0058         1) The input is incorrect; compile_command() raised an
0059         exception (SyntaxError or OverflowError).  A syntax traceback
0060         will be printed by calling the showsyntaxerror() method.
0061 
0062         2) The input is incomplete, and more input is required;
0063         compile_command() returned None.  Nothing happens.
0064 
0065         3) The input is complete; compile_command() returned a code
0066         object.  The code is executed by calling self.runcode() (which
0067         also handles run-time exceptions, except for SystemExit).
0068 
0069         The return value is True in case 2, False in the other cases (unless
0070         an exception is raised).  The return value can be used to
0071         decide whether to use sys.ps1 or sys.ps2 to prompt the next
0072         line.
0073 
0074         """
0075         try:
0076             code = self.compile(source, filename, symbol)
0077         except (OverflowError, SyntaxError, ValueError):
0078             # Case 1
0079             self.showsyntaxerror(filename)
0080             return False
0081 
0082         if code is None:
0083             # Case 2
0084             return True
0085 
0086         # Case 3
0087         self.runcode(code)
0088         return False
0089 
0090     def runcode(self, code):
0091         """Execute a code object.
0092 
0093         When an exception occurs, self.showtraceback() is called to
0094         display a traceback.  All exceptions are caught except
0095         SystemExit, which is reraised.
0096 
0097         A note about KeyboardInterrupt: this exception may occur
0098         elsewhere in this code, and may not always be caught.  The
0099         caller should be prepared to deal with it.
0100 
0101         """
0102         try:
0103             exec code in self.locals
0104         except SystemExit:
0105             raise
0106         except:
0107             self.showtraceback()
0108         else:
0109             if softspace(sys.stdout, 0):
0110                 print
0111 
0112     def showsyntaxerror(self, filename=None):
0113         """Display the syntax error that just occurred.
0114 
0115         This doesn't display a stack trace because there isn't one.
0116 
0117         If a filename is given, it is stuffed in the exception instead
0118         of what was there before (because Python's parser always uses
0119         "<string>" when reading from a string).
0120 
0121         The output is written by self.write(), below.
0122 
0123         """
0124         type, value, sys.last_traceback = sys.exc_info()
0125         sys.last_type = type
0126         sys.last_value = value
0127         if filename and type is SyntaxError:
0128             # Work hard to stuff the correct filename in the exception
0129             try:
0130                 msg, (dummy_filename, lineno, offset, line) = value
0131             except:
0132                 # Not the format we expect; leave it alone
0133                 pass
0134             else:
0135                 # Stuff in the right filename
0136                 value = SyntaxError(msg, (filename, lineno, offset, line))
0137                 sys.last_value = value
0138         list = traceback.format_exception_only(type, value)
0139         map(self.write, list)
0140 
0141     def showtraceback(self):
0142         """Display the exception that just occurred.
0143 
0144         We remove the first stack item because it is our own code.
0145 
0146         The output is written by self.write(), below.
0147 
0148         """
0149         try:
0150             type, value, tb = sys.exc_info()
0151             sys.last_type = type
0152             sys.last_value = value
0153             sys.last_traceback = tb
0154             tblist = traceback.extract_tb(tb)
0155             del tblist[:1]
0156             list = traceback.format_list(tblist)
0157             if list:
0158                 list.insert(0, "Traceback (most recent call last):\n")
0159             list[len(list):] = traceback.format_exception_only(type, value)
0160         finally:
0161             tblist = tb = None
0162         map(self.write, list)
0163 
0164     def write(self, data):
0165         """Write a string.
0166 
0167         The base implementation writes to sys.stderr; a subclass may
0168         replace this with a different implementation.
0169 
0170         """
0171         sys.stderr.write(data)
0172 
0173 
0174 class InteractiveConsole(InteractiveInterpreter):
0175     """Closely emulate the behavior of the interactive Python interpreter.
0176 
0177     This class builds on InteractiveInterpreter and adds prompting
0178     using the familiar sys.ps1 and sys.ps2, and input buffering.
0179 
0180     """
0181 
0182     def __init__(self, locals=None, filename="<console>"):
0183         """Constructor.
0184 
0185         The optional locals argument will be passed to the
0186         InteractiveInterpreter base class.
0187 
0188         The optional filename argument should specify the (file)name
0189         of the input stream; it will show up in tracebacks.
0190 
0191         """
0192         InteractiveInterpreter.__init__(self, locals)
0193         self.filename = filename
0194         self.resetbuffer()
0195 
0196     def resetbuffer(self):
0197         """Reset the input buffer."""
0198         self.buffer = []
0199 
0200     def interact(self, banner=None):
0201         """Closely emulate the interactive Python console.
0202 
0203         The optional banner argument specify the banner to print
0204         before the first interaction; by default it prints a banner
0205         similar to the one printed by the real Python interpreter,
0206         followed by the current class name in parentheses (so as not
0207         to confuse this with the real interpreter -- since it's so
0208         close!).
0209 
0210         """
0211         try:
0212             sys.ps1
0213         except AttributeError:
0214             sys.ps1 = ">>> "
0215         try:
0216             sys.ps2
0217         except AttributeError:
0218             sys.ps2 = "... "
0219         cprt = 'Type "help", "copyright", "credits" or "license" for more information.'
0220         if banner is None:
0221             self.write("Python %s on %s\n%s\n(%s)\n" %
0222                        (sys.version, sys.platform, cprt,
0223                         self.__class__.__name__))
0224         else:
0225             self.write("%s\n" % str(banner))
0226         more = 0
0227         while 1:
0228             try:
0229                 if more:
0230                     prompt = sys.ps2
0231                 else:
0232                     prompt = sys.ps1
0233                 try:
0234                     line = self.raw_input(prompt)
0235                 except EOFError:
0236                     self.write("\n")
0237                     break
0238                 else:
0239                     more = self.push(line)
0240             except KeyboardInterrupt:
0241                 self.write("\nKeyboardInterrupt\n")
0242                 self.resetbuffer()
0243                 more = 0
0244 
0245     def push(self, line):
0246         """Push a line to the interpreter.
0247 
0248         The line should not have a trailing newline; it may have
0249         internal newlines.  The line is appended to a buffer and the
0250         interpreter's runsource() method is called with the
0251         concatenated contents of the buffer as source.  If this
0252         indicates that the command was executed or invalid, the buffer
0253         is reset; otherwise, the command is incomplete, and the buffer
0254         is left as it was after the line was appended.  The return
0255         value is 1 if more input is required, 0 if the line was dealt
0256         with in some way (this is the same as runsource()).
0257 
0258         """
0259         self.buffer.append(line)
0260         source = "\n".join(self.buffer)
0261         more = self.runsource(source, self.filename)
0262         if not more:
0263             self.resetbuffer()
0264         return more
0265 
0266     def raw_input(self, prompt=""):
0267         """Write a prompt and read a line.
0268 
0269         The returned line does not include the trailing newline.
0270         When the user enters the EOF key sequence, EOFError is raised.
0271 
0272         The base implementation uses the built-in function
0273         raw_input(); a subclass may replace this with a different
0274         implementation.
0275 
0276         """
0277         return raw_input(prompt)
0278 
0279 
0280 def interact(banner=None, readfunc=None, local=None):
0281     """Closely emulate the interactive Python interpreter.
0282 
0283     This is a backwards compatible interface to the InteractiveConsole
0284     class.  When readfunc is not specified, it attempts to import the
0285     readline module to enable GNU readline if it is available.
0286 
0287     Arguments (all optional, all default to None):
0288 
0289     banner -- passed to InteractiveConsole.interact()
0290     readfunc -- if not None, replaces InteractiveConsole.raw_input()
0291     local -- passed to InteractiveInterpreter.__init__()
0292 
0293     """
0294     console = InteractiveConsole(local)
0295     if readfunc is not None:
0296         console.raw_input = readfunc
0297     else:
0298         try:
0299             import readline
0300         except ImportError:
0301             pass
0302     console.interact(banner)
0303 
0304 
0305 if __name__ == '__main__':
0306     import pdb
0307     pdb.run("interact()\n")
0308 

Generated by PyXR 0.9.4
SourceForge.net Logo