183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport sys 283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport io 383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport linecache 483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport time 583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport socket 683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport traceback 783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport thread 883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport threading 983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport Queue 1083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 1183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfrom idlelib import CallTips 1283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfrom idlelib import AutoComplete 1383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 1483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfrom idlelib import RemoteDebugger 1583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfrom idlelib import RemoteObjectBrowser 1683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfrom idlelib import StackViewer 1783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfrom idlelib import rpc 1883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfrom idlelib import PyShell 1983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfrom idlelib import IOBinding 2083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 2183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport __main__ 2283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 2383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew HsiehLOCALHOST = '127.0.0.1' 2483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 2583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehtry: 2683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh import warnings 2783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehexcept ImportError: 2883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh pass 2983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehelse: 3083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def idle_formatwarning_subproc(message, category, filename, lineno, 3183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh line=None): 3283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh """Format warnings the IDLE way""" 3383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh s = "\nWarning (from warnings module):\n" 3483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh s += ' File \"%s\", line %s\n' % (filename, lineno) 3583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if line is None: 3683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh line = linecache.getline(filename, lineno) 3783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh line = line.strip() 3883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if line: 3983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh s += " %s\n" % line 4083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh s += "%s: %s\n" % (category.__name__, message) 4183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return s 4283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh warnings.formatwarning = idle_formatwarning_subproc 4383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 4483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# Thread shared globals: Establish a queue between a subthread (which handles 4583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# the socket) and the main thread (which runs user code), plus global 4683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# completion, exit and interruptable (the main thread) flags: 4783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 4883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehexit_now = False 4983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehquitting = False 5083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehinterruptable = False 5183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 5283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef main(del_exitfunc=False): 5383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh """Start the Python execution server in a subprocess 5483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 5583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh In the Python subprocess, RPCServer is instantiated with handlerclass 5683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh MyHandler, which inherits register/unregister methods from RPCHandler via 5783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh the mix-in class SocketIO. 5883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 5983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh When the RPCServer 'server' is instantiated, the TCPServer initialization 6083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh creates an instance of run.MyHandler and calls its handle() method. 6183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh handle() instantiates a run.Executive object, passing it a reference to the 6283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh MyHandler object. That reference is saved as attribute rpchandler of the 6383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh Executive instance. The Executive methods have access to the reference and 6483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh can pass it on to entities that they command 6583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh (e.g. RemoteDebugger.Debugger.start_debugger()). The latter, in turn, can 6683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh call MyHandler(SocketIO) register/unregister methods via the reference to 6783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh register and unregister themselves. 6883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 6983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh """ 7083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh global exit_now 7183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh global quitting 7283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh global no_exitfunc 7383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh no_exitfunc = del_exitfunc 7483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh #time.sleep(15) # test subprocess not responding 7583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh try: 7683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh assert(len(sys.argv) > 1) 7783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh port = int(sys.argv[-1]) 7883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh except: 7983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh print>>sys.stderr, "IDLE Subprocess: no IP port passed in sys.argv." 8083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return 8183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh sys.argv[:] = [""] 8283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh sockthread = threading.Thread(target=manage_socket, 8383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh name='SockThread', 8483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh args=((LOCALHOST, port),)) 8583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh sockthread.setDaemon(True) 8683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh sockthread.start() 8783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh while 1: 8883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh try: 8983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if exit_now: 9083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh try: 9183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh exit() 9283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh except KeyboardInterrupt: 9383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # exiting but got an extra KBI? Try again! 9483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh continue 9583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh try: 9683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh seq, request = rpc.request_queue.get(block=True, timeout=0.05) 9783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh except Queue.Empty: 9883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh continue 9983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh method, args, kwargs = request 10083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh ret = method(*args, **kwargs) 10183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh rpc.response_queue.put((seq, ret)) 10283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh except KeyboardInterrupt: 10383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if quitting: 10483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh exit_now = True 10583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh continue 10683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh except SystemExit: 10783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh raise 10883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh except: 10983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh type, value, tb = sys.exc_info() 11083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh try: 11183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh print_exception() 11283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh rpc.response_queue.put((seq, None)) 11383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh except: 11483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # Link didn't work, print same exception to __stderr__ 11583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh traceback.print_exception(type, value, tb, file=sys.__stderr__) 11683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh exit() 11783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh else: 11883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh continue 11983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 12083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef manage_socket(address): 12183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh for i in range(3): 12283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh time.sleep(i) 12383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh try: 12483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh server = MyRPCServer(address, MyHandler) 12583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh break 12683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh except socket.error, err: 12783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh print>>sys.__stderr__,"IDLE Subprocess: socket error: "\ 12883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh + err.args[1] + ", retrying...." 12983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh else: 13083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh print>>sys.__stderr__, "IDLE Subprocess: Connection to "\ 13183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh "IDLE GUI failed, exiting." 13283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh show_socket_error(err, address) 13383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh global exit_now 13483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh exit_now = True 13583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return 13683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh server.handle_request() # A single request only 13783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 13883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef show_socket_error(err, address): 13983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh import Tkinter 14083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh import tkMessageBox 14183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh root = Tkinter.Tk() 14283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh root.withdraw() 14383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if err.args[0] == 61: # connection refused 14483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh msg = "IDLE's subprocess can't connect to %s:%d. This may be due "\ 14583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh "to your personal firewall configuration. It is safe to "\ 14683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh "allow this internal connection because no data is visible on "\ 14783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh "external ports." % address 14883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh tkMessageBox.showerror("IDLE Subprocess Error", msg, parent=root) 14983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh else: 15083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh tkMessageBox.showerror("IDLE Subprocess Error", 15183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh "Socket Error: %s" % err.args[1]) 15283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh root.destroy() 15383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 15483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef print_exception(): 15583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh import linecache 15683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh linecache.checkcache() 15783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh flush_stdout() 15883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh efile = sys.stderr 15983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh typ, val, tb = excinfo = sys.exc_info() 16083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh sys.last_type, sys.last_value, sys.last_traceback = excinfo 16183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh tbe = traceback.extract_tb(tb) 16283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh print>>efile, '\nTraceback (most recent call last):' 16383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh exclude = ("run.py", "rpc.py", "threading.py", "Queue.py", 16483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh "RemoteDebugger.py", "bdb.py") 16583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh cleanup_traceback(tbe, exclude) 16683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh traceback.print_list(tbe, file=efile) 16783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh lines = traceback.format_exception_only(typ, val) 16883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh for line in lines: 16983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh print>>efile, line, 17083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 17183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef cleanup_traceback(tb, exclude): 17283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh "Remove excluded traces from beginning/end of tb; get cached lines" 17383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh orig_tb = tb[:] 17483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh while tb: 17583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh for rpcfile in exclude: 17683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if tb[0][0].count(rpcfile): 17783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh break # found an exclude, break for: and delete tb[0] 17883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh else: 17983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh break # no excludes, have left RPC code, break while: 18083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh del tb[0] 18183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh while tb: 18283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh for rpcfile in exclude: 18383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if tb[-1][0].count(rpcfile): 18483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh break 18583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh else: 18683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh break 18783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh del tb[-1] 18883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if len(tb) == 0: 18983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # exception was in IDLE internals, don't prune! 19083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh tb[:] = orig_tb[:] 19183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh print>>sys.stderr, "** IDLE Internal Exception: " 19283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh rpchandler = rpc.objecttable['exec'].rpchandler 19383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh for i in range(len(tb)): 19483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh fn, ln, nm, line = tb[i] 19583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if nm == '?': 19683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh nm = "-toplevel-" 19783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if not line and fn.startswith("<pyshell#"): 19883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh line = rpchandler.remotecall('linecache', 'getline', 19983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh (fn, ln), {}) 20083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh tb[i] = fn, ln, nm, line 20183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 20283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef flush_stdout(): 20383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh try: 20483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if sys.stdout.softspace: 20583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh sys.stdout.softspace = 0 20683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh sys.stdout.write("\n") 20783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh except (AttributeError, EOFError): 20883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh pass 20983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 21083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef exit(): 21183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh """Exit subprocess, possibly after first deleting sys.exitfunc 21283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 21383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh If config-main.cfg/.def 'General' 'delete-exitfunc' is True, then any 21483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh sys.exitfunc will be removed before exiting. (VPython support) 21583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 21683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh """ 21783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if no_exitfunc: 21883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh try: 21983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh del sys.exitfunc 22083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh except AttributeError: 22183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh pass 22283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh sys.exit(0) 22383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 22483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass MyRPCServer(rpc.RPCServer): 22583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 22683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def handle_error(self, request, client_address): 22783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh """Override RPCServer method for IDLE 22883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 22983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh Interrupt the MainThread and exit server if link is dropped. 23083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 23183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh """ 23283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh global quitting 23383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh try: 23483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh raise 23583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh except SystemExit: 23683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh raise 23783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh except EOFError: 23883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh global exit_now 23983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh exit_now = True 24083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh thread.interrupt_main() 24183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh except: 24283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh erf = sys.__stderr__ 24383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh print>>erf, '\n' + '-'*40 24483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh print>>erf, 'Unhandled server exception!' 24583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh print>>erf, 'Thread: %s' % threading.currentThread().getName() 24683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh print>>erf, 'Client Address: ', client_address 24783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh print>>erf, 'Request: ', repr(request) 24883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh traceback.print_exc(file=erf) 24983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh print>>erf, '\n*** Unrecoverable, server exiting!' 25083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh print>>erf, '-'*40 25183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh quitting = True 25283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh thread.interrupt_main() 25383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 25483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass MyHandler(rpc.RPCHandler): 25583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 25683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def handle(self): 25783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh """Override base method""" 25883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh executive = Executive(self) 25983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.register("exec", executive) 26083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.console = self.get_remote_proxy("console") 26183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh sys.stdin = PyShell.PseudoInputFile(self.console, "stdin", 26283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh IOBinding.encoding) 26383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh sys.stdout = PyShell.PseudoOutputFile(self.console, "stdout", 26483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh IOBinding.encoding) 26583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh sys.stderr = PyShell.PseudoOutputFile(self.console, "stderr", 26683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh IOBinding.encoding) 26783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 26883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # Keep a reference to stdin so that it won't try to exit IDLE if 26983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # sys.stdin gets changed from within IDLE's shell. See issue17838. 27083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self._keep_stdin = sys.stdin 27183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 27283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.interp = self.get_remote_proxy("interp") 27383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh rpc.RPCHandler.getresponse(self, myseq=None, wait=0.05) 27483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 27583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def exithook(self): 27683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh "override SocketIO method - wait for MainThread to shut us down" 27783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh time.sleep(10) 27883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 27983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def EOFhook(self): 28083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh "Override SocketIO method - terminate wait on callback and exit thread" 28183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh global quitting 28283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh quitting = True 28383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh thread.interrupt_main() 28483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 28583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def decode_interrupthook(self): 28683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh "interrupt awakened thread" 28783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh global quitting 28883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh quitting = True 28983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh thread.interrupt_main() 29083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 29183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 29283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass Executive(object): 29383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 29483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def __init__(self, rpchandler): 29583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.rpchandler = rpchandler 29683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.locals = __main__.__dict__ 29783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.calltip = CallTips.CallTips() 29883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.autocomplete = AutoComplete.AutoComplete() 29983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 30083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def runcode(self, code): 30183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh global interruptable 30283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh try: 30383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.usr_exc_info = None 30483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh interruptable = True 30583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh try: 30683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh exec code in self.locals 30783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh finally: 30883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh interruptable = False 30983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh except SystemExit: 31083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # Scripts that raise SystemExit should just 31183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh # return to the interactive prompt 31283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh pass 31383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh except: 31483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.usr_exc_info = sys.exc_info() 31583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if quitting: 31683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh exit() 31783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh print_exception() 31883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh jit = self.rpchandler.console.getvar("<<toggle-jit-stack-viewer>>") 31983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if jit: 32083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.rpchandler.interp.open_remote_stack_viewer() 32183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh else: 32283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh flush_stdout() 32383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 32483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def interrupt_the_server(self): 32583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if interruptable: 32683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh thread.interrupt_main() 32783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 32883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def start_the_debugger(self, gui_adap_oid): 32983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return RemoteDebugger.start_debugger(self.rpchandler, gui_adap_oid) 33083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 33183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def stop_the_debugger(self, idb_adap_oid): 33283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh "Unregister the Idb Adapter. Link objects and Idb then subject to GC" 33383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh self.rpchandler.unregister(idb_adap_oid) 33483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 33583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def get_the_calltip(self, name): 33683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return self.calltip.fetch_tip(name) 33783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 33883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def get_the_completion_list(self, what, mode): 33983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return self.autocomplete.fetch_completions(what, mode) 34083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh 34183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh def stackviewer(self, flist_oid=None): 34283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if self.usr_exc_info: 34383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh typ, val, tb = self.usr_exc_info 34483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh else: 34583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return None 34683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh flist = None 34783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh if flist_oid is not None: 34883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh flist = self.rpchandler.get_remote_proxy(flist_oid) 34983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh while tb and tb.tb_frame.f_globals["__name__"] in ["rpc", "run"]: 35083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh tb = tb.tb_next 35183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh sys.last_type = typ 35283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh sys.last_value = val 35383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh item = StackViewer.StackTreeItem(flist, tb) 35483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh return RemoteObjectBrowser.remote_object_tree_item(item) 355