14710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"""Utilities needed to emulate Python's interactive interpreter. 24710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 34710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm""" 44710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 54710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Inspired by similar code by Jeff Epler and Fredrik Lundh. 64710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 74710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 84710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport sys 94710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport traceback 104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfrom codeop import CommandCompiler, compile_command 114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm__all__ = ["InteractiveInterpreter", "InteractiveConsole", "interact", 134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "compile_command"] 144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef softspace(file, newvalue): 164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm oldvalue = 0 174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm oldvalue = file.softspace 194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except AttributeError: 204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pass 214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm file.softspace = newvalue 234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except (AttributeError, TypeError): 244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # "attribute-less object" or "read-only attributes" 254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pass 264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return oldvalue 274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass InteractiveInterpreter: 294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Base class for InteractiveConsole. 304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm This class deals with parsing and interpreter state (the user's 324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm namespace); it doesn't deal with input buffering or prompting or 334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm input file naming (the filename is always passed in explicitly). 344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __init__(self, locals=None): 384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Constructor. 394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm The optional 'locals' argument specifies the dictionary in 414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm which code will be executed; it defaults to a newly created 424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dictionary with key "__name__" set to "__console__" and key 434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "__doc__" set to None. 444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if locals is None: 474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm locals = {"__name__": "__console__", "__doc__": None} 484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.locals = locals 494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.compile = CommandCompiler() 504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def runsource(self, source, filename="<input>", symbol="single"): 524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Compile and run some source in the interpreter. 534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Arguments are as for compile_command(). 554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm One several things can happen: 574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1) The input is incorrect; compile_command() raised an 594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm exception (SyntaxError or OverflowError). A syntax traceback 604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm will be printed by calling the showsyntaxerror() method. 614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2) The input is incomplete, and more input is required; 634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm compile_command() returned None. Nothing happens. 644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3) The input is complete; compile_command() returned a code 664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm object. The code is executed by calling self.runcode() (which 674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm also handles run-time exceptions, except for SystemExit). 684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm The return value is True in case 2, False in the other cases (unless 704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm an exception is raised). The return value can be used to 714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm decide whether to use sys.ps1 or sys.ps2 to prompt the next 724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm line. 734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm code = self.compile(source, filename, symbol) 774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except (OverflowError, SyntaxError, ValueError): 784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Case 1 794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.showsyntaxerror(filename) 804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return False 814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if code is None: 834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Case 2 844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return True 854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Case 3 874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.runcode(code) 884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return False 894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def runcode(self, code): 914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Execute a code object. 924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm When an exception occurs, self.showtraceback() is called to 944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm display a traceback. All exceptions are caught except 954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm SystemExit, which is reraised. 964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm A note about KeyboardInterrupt: this exception may occur 984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm elsewhere in this code, and may not always be caught. The 994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm caller should be prepared to deal with it. 1004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 1024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 1034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm exec code in self.locals 1044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except SystemExit: 1054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise 1064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except: 1074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.showtraceback() 1084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 1094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if softspace(sys.stdout, 0): 1104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print 1114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def showsyntaxerror(self, filename=None): 1134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Display the syntax error that just occurred. 1144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm This doesn't display a stack trace because there isn't one. 1164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm If a filename is given, it is stuffed in the exception instead 1184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm of what was there before (because Python's parser always uses 1194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "<string>" when reading from a string). 1204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm The output is written by self.write(), below. 1224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 1244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm type, value, sys.last_traceback = sys.exc_info() 1254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sys.last_type = type 1264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sys.last_value = value 1274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if filename and type is SyntaxError: 1284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Work hard to stuff the correct filename in the exception 1294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 1304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm msg, (dummy_filename, lineno, offset, line) = value 1314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except: 1324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Not the format we expect; leave it alone 1334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pass 1344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 1354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Stuff in the right filename 1364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm value = SyntaxError(msg, (filename, lineno, offset, line)) 1374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sys.last_value = value 1384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm list = traceback.format_exception_only(type, value) 1394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm map(self.write, list) 1404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def showtraceback(self): 1424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Display the exception that just occurred. 1434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm We remove the first stack item because it is our own code. 1454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm The output is written by self.write(), below. 1474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 1494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 1504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm type, value, tb = sys.exc_info() 1514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sys.last_type = type 1524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sys.last_value = value 1534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sys.last_traceback = tb 1544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm tblist = traceback.extract_tb(tb) 1554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm del tblist[:1] 1564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm list = traceback.format_list(tblist) 1574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if list: 1584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm list.insert(0, "Traceback (most recent call last):\n") 1594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm list[len(list):] = traceback.format_exception_only(type, value) 1604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm finally: 1614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm tblist = tb = None 1624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm map(self.write, list) 1634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def write(self, data): 1654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Write a string. 1664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm The base implementation writes to sys.stderr; a subclass may 1684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm replace this with a different implementation. 1694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 1714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sys.stderr.write(data) 1724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass InteractiveConsole(InteractiveInterpreter): 1754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Closely emulate the behavior of the interactive Python interpreter. 1764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm This class builds on InteractiveInterpreter and adds prompting 1784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm using the familiar sys.ps1 and sys.ps2, and input buffering. 1794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 1814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __init__(self, locals=None, filename="<console>"): 1834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Constructor. 1844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm The optional locals argument will be passed to the 1864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm InteractiveInterpreter base class. 1874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm The optional filename argument should specify the (file)name 1894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm of the input stream; it will show up in tracebacks. 1904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 1924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm InteractiveInterpreter.__init__(self, locals) 1934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.filename = filename 1944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.resetbuffer() 1954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def resetbuffer(self): 1974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Reset the input buffer.""" 1984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.buffer = [] 1994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def interact(self, banner=None): 2014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Closely emulate the interactive Python console. 2024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm The optional banner argument specify the banner to print 2044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm before the first interaction; by default it prints a banner 2054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm similar to the one printed by the real Python interpreter, 2064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm followed by the current class name in parentheses (so as not 2074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm to confuse this with the real interpreter -- since it's so 2084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm close!). 2094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 2114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 2124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sys.ps1 2134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except AttributeError: 2144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sys.ps1 = ">>> " 2154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 2164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sys.ps2 2174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except AttributeError: 2184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sys.ps2 = "... " 2194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm cprt = 'Type "help", "copyright", "credits" or "license" for more information.' 2204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if banner is None: 2214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.write("Python %s on %s\n%s\n(%s)\n" % 2224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (sys.version, sys.platform, cprt, 2234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.__class__.__name__)) 2244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 2254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.write("%s\n" % str(banner)) 2264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm more = 0 2274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm while 1: 2284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 2294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if more: 2304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm prompt = sys.ps2 2314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 2324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm prompt = sys.ps1 2334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 2344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm line = self.raw_input(prompt) 2354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Can be None if sys.stdin was redefined 2364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm encoding = getattr(sys.stdin, "encoding", None) 2374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if encoding and not isinstance(line, unicode): 2384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm line = line.decode(encoding) 2394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except EOFError: 2404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.write("\n") 2414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm break 2424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 2434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm more = self.push(line) 2444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except KeyboardInterrupt: 2454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.write("\nKeyboardInterrupt\n") 2464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.resetbuffer() 2474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm more = 0 2484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def push(self, line): 2504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Push a line to the interpreter. 2514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm The line should not have a trailing newline; it may have 2534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm internal newlines. The line is appended to a buffer and the 2544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm interpreter's runsource() method is called with the 2554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm concatenated contents of the buffer as source. If this 2564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm indicates that the command was executed or invalid, the buffer 2574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm is reset; otherwise, the command is incomplete, and the buffer 2584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm is left as it was after the line was appended. The return 2594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm value is 1 if more input is required, 0 if the line was dealt 2604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm with in some way (this is the same as runsource()). 2614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 2634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.buffer.append(line) 2644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm source = "\n".join(self.buffer) 2654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm more = self.runsource(source, self.filename) 2664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not more: 2674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.resetbuffer() 2684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return more 2694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def raw_input(self, prompt=""): 2714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Write a prompt and read a line. 2724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm The returned line does not include the trailing newline. 2744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm When the user enters the EOF key sequence, EOFError is raised. 2754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm The base implementation uses the built-in function 2774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raw_input(); a subclass may replace this with a different 2784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm implementation. 2794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 2814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return raw_input(prompt) 2824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef interact(banner=None, readfunc=None, local=None): 2854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Closely emulate the interactive Python interpreter. 2864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm This is a backwards compatible interface to the InteractiveConsole 2884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm class. When readfunc is not specified, it attempts to import the 2894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm readline module to enable GNU readline if it is available. 2904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Arguments (all optional, all default to None): 2924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm banner -- passed to InteractiveConsole.interact() 2944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm readfunc -- if not None, replaces InteractiveConsole.raw_input() 2954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm local -- passed to InteractiveInterpreter.__init__() 2964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 2984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm console = InteractiveConsole(local) 2994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if readfunc is not None: 3004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm console.raw_input = readfunc 3014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 3024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 3034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm import readline 3044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except ImportError: 3054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pass 3064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm console.interact(banner) 3074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmif __name__ == "__main__": 3104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm interact() 311