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 8import sys 9import traceback 10 11 12 13 14 15 16 17 18#START --------------------------- from codeop import CommandCompiler, compile_command 19#START --------------------------- from codeop import CommandCompiler, compile_command 20#START --------------------------- from codeop import CommandCompiler, compile_command 21#START --------------------------- from codeop import CommandCompiler, compile_command 22#START --------------------------- from codeop import CommandCompiler, compile_command 23r"""Utilities to compile possibly incomplete Python source code. 24 25This module provides two interfaces, broadly similar to the builtin 26function compile(), which take program text, a filename and a 'mode' 27and: 28 29- Return code object if the command is complete and valid 30- Return None if the command is incomplete 31- Raise SyntaxError, ValueError or OverflowError if the command is a 32 syntax error (OverflowError and ValueError can be produced by 33 malformed literals). 34 35Approach: 36 37First, check if the source consists entirely of blank lines and 38comments; if so, replace it with 'pass', because the built-in 39parser doesn't always do the right thing for these. 40 41Compile three times: as is, with \n, and with \n\n appended. If it 42compiles as is, it's complete. If it compiles with one \n appended, 43we expect more. If it doesn't compile either way, we compare the 44error we get when compiling with \n or \n\n appended. If the errors 45are the same, the code is broken. But if the errors are different, we 46expect more. Not intuitive; not even guaranteed to hold in future 47releases; but this matches the compiler's behavior from Python 1.4 48through 2.2, at least. 49 50Caveat: 51 52It is possible (but not likely) that the parser stops parsing with a 53successful outcome before reaching the end of the source; in this 54case, trailing symbols may be ignored instead of causing an error. 55For example, a backslash followed by two newlines may be followed by 56arbitrary garbage. This will be fixed once the API for the parser is 57better. 58 59The two interfaces are: 60 61compile_command(source, filename, symbol): 62 63 Compiles a single command in the manner described above. 64 65CommandCompiler(): 66 67 Instances of this class have __call__ methods identical in 68 signature to compile_command; the difference is that if the 69 instance compiles program text containing a __future__ statement, 70 the instance 'remembers' and compiles all subsequent program texts 71 with the statement in force. 72 73The module also provides another class: 74 75Compile(): 76 77 Instances of this class act like the built-in function compile, 78 but with 'memory' in the sense described above. 79""" 80 81import __future__ 82 83_features = [getattr(__future__, fname) 84 for fname in __future__.all_feature_names] 85 86__all__ = ["compile_command", "Compile", "CommandCompiler"] 87 88PyCF_DONT_IMPLY_DEDENT = 0x200 # Matches pythonrun.h 89 90def _maybe_compile(compiler, source, filename, symbol): 91 # Check for source consisting of only blank lines and comments 92 for line in source.split("\n"): 93 line = line.strip() 94 if line and line[0] != '#': 95 break # Leave it alone 96 else: 97 if symbol != "eval": 98 source = "pass" # Replace it with a 'pass' statement 99 100 err = err1 = err2 = None 101 code = code1 = code2 = None 102 103 try: 104 code = compiler(source, filename, symbol) 105 except SyntaxError: 106 pass 107 108 try: 109 code1 = compiler(source + "\n", filename, symbol) 110 except SyntaxError as err1: 111 pass 112 113 try: 114 code2 = compiler(source + "\n\n", filename, symbol) 115 except SyntaxError as err2: 116 pass 117 118 if code: 119 return code 120 if not code1 and repr(err1) == repr(err2): 121 raise SyntaxError(err1) 122 123def _compile(source, filename, symbol): 124 return compile(source, filename, symbol, PyCF_DONT_IMPLY_DEDENT) 125 126def compile_command(source, filename="<input>", symbol="single"): 127 r"""Compile a command and determine whether it is incomplete. 128 129 Arguments: 130 131 source -- the source string; may contain \n characters 132 filename -- optional filename from which source was read; default 133 "<input>" 134 symbol -- optional grammar start symbol; "single" (default) or "eval" 135 136 Return value / exceptions raised: 137 138 - Return a code object if the command is complete and valid 139 - Return None if the command is incomplete 140 - Raise SyntaxError, ValueError or OverflowError if the command is a 141 syntax error (OverflowError and ValueError can be produced by 142 malformed literals). 143 """ 144 return _maybe_compile(_compile, source, filename, symbol) 145 146class Compile: 147 """Instances of this class behave much like the built-in compile 148 function, but if one is used to compile text containing a future 149 statement, it "remembers" and compiles all subsequent program texts 150 with the statement in force.""" 151 def __init__(self): 152 self.flags = PyCF_DONT_IMPLY_DEDENT 153 154 def __call__(self, source, filename, symbol): 155 codeob = compile(source, filename, symbol, self.flags, 1) 156 for feature in _features: 157 if codeob.co_flags & feature.compiler_flag: 158 self.flags |= feature.compiler_flag 159 return codeob 160 161class CommandCompiler: 162 """Instances of this class have __call__ methods identical in 163 signature to compile_command; the difference is that if the 164 instance compiles program text containing a __future__ statement, 165 the instance 'remembers' and compiles all subsequent program texts 166 with the statement in force.""" 167 168 def __init__(self,): 169 self.compiler = Compile() 170 171 def __call__(self, source, filename="<input>", symbol="single"): 172 r"""Compile a command and determine whether it is incomplete. 173 174 Arguments: 175 176 source -- the source string; may contain \n characters 177 filename -- optional filename from which source was read; 178 default "<input>" 179 symbol -- optional grammar start symbol; "single" (default) or 180 "eval" 181 182 Return value / exceptions raised: 183 184 - Return a code object if the command is complete and valid 185 - Return None if the command is incomplete 186 - Raise SyntaxError, ValueError or OverflowError if the command is a 187 syntax error (OverflowError and ValueError can be produced by 188 malformed literals). 189 """ 190 return _maybe_compile(self.compiler, source, filename, symbol) 191 192#END --------------------------- from codeop import CommandCompiler, compile_command 193#END --------------------------- from codeop import CommandCompiler, compile_command 194#END --------------------------- from codeop import CommandCompiler, compile_command 195#END --------------------------- from codeop import CommandCompiler, compile_command 196#END --------------------------- from codeop import CommandCompiler, compile_command 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214__all__ = ["InteractiveInterpreter", "InteractiveConsole", "interact", 215 "compile_command"] 216 217def softspace(file, newvalue): 218 oldvalue = 0 219 try: 220 oldvalue = file.softspace 221 except AttributeError: 222 pass 223 try: 224 file.softspace = newvalue 225 except (AttributeError, TypeError): 226 # "attribute-less object" or "read-only attributes" 227 pass 228 return oldvalue 229 230class InteractiveInterpreter: 231 """Base class for InteractiveConsole. 232 233 This class deals with parsing and interpreter state (the user's 234 namespace); it doesn't deal with input buffering or prompting or 235 input file naming (the filename is always passed in explicitly). 236 237 """ 238 239 def __init__(self, locals=None): 240 """Constructor. 241 242 The optional 'locals' argument specifies the dictionary in 243 which code will be executed; it defaults to a newly created 244 dictionary with key "__name__" set to "__console__" and key 245 "__doc__" set to None. 246 247 """ 248 if locals is None: 249 locals = {"__name__": "__console__", "__doc__": None} 250 self.locals = locals 251 self.compile = CommandCompiler() 252 253 def runsource(self, source, filename="<input>", symbol="single"): 254 """Compile and run some source in the interpreter. 255 256 Arguments are as for compile_command(). 257 258 One several things can happen: 259 260 1) The input is incorrect; compile_command() raised an 261 exception (SyntaxError or OverflowError). A syntax traceback 262 will be printed by calling the showsyntaxerror() method. 263 264 2) The input is incomplete, and more input is required; 265 compile_command() returned None. Nothing happens. 266 267 3) The input is complete; compile_command() returned a code 268 object. The code is executed by calling self.runcode() (which 269 also handles run-time exceptions, except for SystemExit). 270 271 The return value is True in case 2, False in the other cases (unless 272 an exception is raised). The return value can be used to 273 decide whether to use sys.ps1 or sys.ps2 to prompt the next 274 line. 275 276 """ 277 try: 278 code = self.compile(source, filename, symbol) 279 except (OverflowError, SyntaxError, ValueError): 280 # Case 1 281 self.showsyntaxerror(filename) 282 return False 283 284 if code is None: 285 # Case 2 286 return True 287 288 # Case 3 289 self.runcode(code) 290 return False 291 292 def runcode(self, code): 293 """Execute a code object. 294 295 When an exception occurs, self.showtraceback() is called to 296 display a traceback. All exceptions are caught except 297 SystemExit, which is reraised. 298 299 A note about KeyboardInterrupt: this exception may occur 300 elsewhere in this code, and may not always be caught. The 301 caller should be prepared to deal with it. 302 303 """ 304 try: 305 exec code in self.locals 306 except SystemExit: 307 raise 308 except: 309 self.showtraceback() 310 else: 311 if softspace(sys.stdout, 0): 312 sys.stdout.write('\n') 313 314 def showsyntaxerror(self, filename=None): 315 """Display the syntax error that just occurred. 316 317 This doesn't display a stack trace because there isn't one. 318 319 If a filename is given, it is stuffed in the exception instead 320 of what was there before (because Python's parser always uses 321 "<string>" when reading from a string). 322 323 The output is written by self.write(), below. 324 325 """ 326 type, value, sys.last_traceback = sys.exc_info() 327 sys.last_type = type 328 sys.last_value = value 329 if filename and type is SyntaxError: 330 # Work hard to stuff the correct filename in the exception 331 try: 332 msg, (dummy_filename, lineno, offset, line) = value 333 except: 334 # Not the format we expect; leave it alone 335 pass 336 else: 337 # Stuff in the right filename 338 value = SyntaxError(msg, (filename, lineno, offset, line)) 339 sys.last_value = value 340 list = traceback.format_exception_only(type, value) 341 map(self.write, list) 342 343 def showtraceback(self): 344 """Display the exception that just occurred. 345 346 We remove the first stack item because it is our own code. 347 348 The output is written by self.write(), below. 349 350 """ 351 try: 352 type, value, tb = sys.exc_info() 353 sys.last_type = type 354 sys.last_value = value 355 sys.last_traceback = tb 356 tblist = traceback.extract_tb(tb) 357 del tblist[:1] 358 list = traceback.format_list(tblist) 359 if list: 360 list.insert(0, "Traceback (most recent call last):\n") 361 list[len(list):] = traceback.format_exception_only(type, value) 362 finally: 363 tblist = tb = None 364 map(self.write, list) 365 366 def write(self, data): 367 """Write a string. 368 369 The base implementation writes to sys.stderr; a subclass may 370 replace this with a different implementation. 371 372 """ 373 sys.stderr.write(data) 374 375 376class InteractiveConsole(InteractiveInterpreter): 377 """Closely emulate the behavior of the interactive Python interpreter. 378 379 This class builds on InteractiveInterpreter and adds prompting 380 using the familiar sys.ps1 and sys.ps2, and input buffering. 381 382 """ 383 384 def __init__(self, locals=None, filename="<console>"): 385 """Constructor. 386 387 The optional locals argument will be passed to the 388 InteractiveInterpreter base class. 389 390 The optional filename argument should specify the (file)name 391 of the input stream; it will show up in tracebacks. 392 393 """ 394 InteractiveInterpreter.__init__(self, locals) 395 self.filename = filename 396 self.resetbuffer() 397 398 def resetbuffer(self): 399 """Reset the input buffer.""" 400 self.buffer = [] 401 402 def interact(self, banner=None): 403 """Closely emulate the interactive Python console. 404 405 The optional banner argument specify the banner to print 406 before the first interaction; by default it prints a banner 407 similar to the one printed by the real Python interpreter, 408 followed by the current class name in parentheses (so as not 409 to confuse this with the real interpreter -- since it's so 410 close!). 411 412 """ 413 try: 414 sys.ps1 #@UndefinedVariable 415 except AttributeError: 416 sys.ps1 = ">>> " 417 try: 418 sys.ps2 #@UndefinedVariable 419 except AttributeError: 420 sys.ps2 = "... " 421 cprt = 'Type "help", "copyright", "credits" or "license" for more information.' 422 if banner is None: 423 self.write("Python %s on %s\n%s\n(%s)\n" % 424 (sys.version, sys.platform, cprt, 425 self.__class__.__name__)) 426 else: 427 self.write("%s\n" % str(banner)) 428 more = 0 429 while 1: 430 try: 431 if more: 432 prompt = sys.ps2 #@UndefinedVariable 433 else: 434 prompt = sys.ps1 #@UndefinedVariable 435 try: 436 line = self.raw_input(prompt) 437 # Can be None if sys.stdin was redefined 438 encoding = getattr(sys.stdin, "encoding", None) 439 if encoding and not isinstance(line, unicode): 440 line = line.decode(encoding) 441 except EOFError: 442 self.write("\n") 443 break 444 else: 445 more = self.push(line) 446 except KeyboardInterrupt: 447 self.write("\nKeyboardInterrupt\n") 448 self.resetbuffer() 449 more = 0 450 451 def push(self, line): 452 """Push a line to the interpreter. 453 454 The line should not have a trailing newline; it may have 455 internal newlines. The line is appended to a buffer and the 456 interpreter's runsource() method is called with the 457 concatenated contents of the buffer as source. If this 458 indicates that the command was executed or invalid, the buffer 459 is reset; otherwise, the command is incomplete, and the buffer 460 is left as it was after the line was appended. The return 461 value is 1 if more input is required, 0 if the line was dealt 462 with in some way (this is the same as runsource()). 463 464 """ 465 self.buffer.append(line) 466 source = "\n".join(self.buffer) 467 more = self.runsource(source, self.filename) 468 if not more: 469 self.resetbuffer() 470 return more 471 472 def raw_input(self, prompt=""): 473 """Write a prompt and read a line. 474 475 The returned line does not include the trailing newline. 476 When the user enters the EOF key sequence, EOFError is raised. 477 478 The base implementation uses the built-in function 479 raw_input(); a subclass may replace this with a different 480 implementation. 481 482 """ 483 return raw_input(prompt) 484 485 486def interact(banner=None, readfunc=None, local=None): 487 """Closely emulate the interactive Python interpreter. 488 489 This is a backwards compatible interface to the InteractiveConsole 490 class. When readfunc is not specified, it attempts to import the 491 readline module to enable GNU readline if it is available. 492 493 Arguments (all optional, all default to None): 494 495 banner -- passed to InteractiveConsole.interact() 496 readfunc -- if not None, replaces InteractiveConsole.raw_input() 497 local -- passed to InteractiveInterpreter.__init__() 498 499 """ 500 console = InteractiveConsole(local) 501 if readfunc is not None: 502 console.raw_input = readfunc 503 else: 504 try: 505 import readline 506 except ImportError: 507 pass 508 console.interact(banner) 509 510 511if __name__ == '__main__': 512 import pdb 513 pdb.run("interact()\n") 514