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