blob: 9ede2ff48eca51e1b303346f3fc7a1fe6abe5d57 [file] [log] [blame]
Chui Tey5d2af632002-05-26 13:36:41 +00001import sys
Kurt B. Kaiserb4179362002-07-26 00:06:42 +00002import time
3import socket
Kurt B. Kaiserd694c1f2002-07-28 03:35:31 +00004import __main__
Chui Tey5d2af632002-05-26 13:36:41 +00005import rpc
6
7def main():
Kurt B. Kaiserb4179362002-07-26 00:06:42 +00008 """Start the Python execution server in a subprocess
9
10 In Idle, RPCServer is instantiated with handlerclass MyHandler, which
11 inherits register/unregister methods from RPCHandler via the mix-in class
12 SocketIO.
13
14 When the RPCServer is instantiated, the TCPServer initialization creates an
15 instance of run.MyHandler and calls its handle() method. handle()
16 instantiates a run.Executive, passing it a reference to the MyHandler
17 object. That reference is saved as an attribute of the Executive instance.
18 The Executive methods have access to the reference and can pass it on to
19 entities that they command (e.g. RemoteDebugger.Debugger.start_debugger()).
20 The latter, in turn, can call MyHandler(SocketIO) register/unregister
21 methods via the reference to register and unregister themselves.
22
23 """
Chui Tey5d2af632002-05-26 13:36:41 +000024 port = 8833
25 if sys.argv[1:]:
26 port = int(sys.argv[1])
27 sys.argv[:] = [""]
28 addr = ("localhost", port)
Kurt B. Kaiser8dcdb772002-08-05 03:52:10 +000029 for i in range(6):
Kurt B. Kaiserb4179362002-07-26 00:06:42 +000030 time.sleep(i)
31 try:
32 svr = rpc.RPCServer(addr, MyHandler)
33 break
34 except socket.error, err:
Kurt B. Kaiser8dcdb772002-08-05 03:52:10 +000035 if i < 3:
Kurt B. Kaiserb4179362002-07-26 00:06:42 +000036 print>>sys.__stderr__, ".. ",
37 else:
38 print>>sys.__stderr__,"\nPython subprocess socket error: "\
39 + err[1] + ", retrying...."
40 else:
41 print>>sys.__stderr__, "\nConnection to Idle failed, exiting."
42 sys.exit()
Chui Tey5d2af632002-05-26 13:36:41 +000043 svr.handle_request() # A single request only
44
45class MyHandler(rpc.RPCHandler):
46
47 def handle(self):
48 executive = Executive(self)
49 self.register("exec", executive)
50 sys.stdin = self.get_remote_proxy("stdin")
51 sys.stdout = self.get_remote_proxy("stdout")
52 sys.stderr = self.get_remote_proxy("stderr")
53 rpc.RPCHandler.handle(self)
54
55class Executive:
56
57 def __init__(self, rpchandler):
Kurt B. Kaiserffd3a422002-06-26 02:32:09 +000058 self.rpchandler = rpchandler
Kurt B. Kaiserd694c1f2002-07-28 03:35:31 +000059 self.base_env_keys = __main__.__dict__.keys()
Chui Tey5d2af632002-05-26 13:36:41 +000060
61 def runcode(self, code):
Kurt B. Kaiserd694c1f2002-07-28 03:35:31 +000062 exec code in __main__.__dict__
63
64 def clear_the_environment(self):
65 global __main__
66 env = __main__.__dict__
67 for key in env.keys():
68 if key not in self.base_env_keys:
69 del env[key]
70 env['__doc__'] = None
Chui Tey5d2af632002-05-26 13:36:41 +000071
Kurt B. Kaiser0e3a5772002-06-16 03:32:24 +000072 def start_the_debugger(self, gui_adap_oid):
Chui Tey5d2af632002-05-26 13:36:41 +000073 import RemoteDebugger
Kurt B. Kaiserffd3a422002-06-26 02:32:09 +000074 return RemoteDebugger.start_debugger(self.rpchandler, gui_adap_oid)
75
76 def stop_the_debugger(self, idb_adap_oid):
77 "Unregister the Idb Adapter. Link objects and Idb then subject to GC"
78 self.rpchandler.unregister(idb_adap_oid)
Chui Tey5d2af632002-05-26 13:36:41 +000079
80 def stackviewer(self, flist_oid=None):
81 if not hasattr(sys, "last_traceback"):
82 return None
83 flist = None
84 if flist_oid is not None:
Kurt B. Kaiserffd3a422002-06-26 02:32:09 +000085 flist = self.rpchandler.get_remote_proxy(flist_oid)
Chui Tey5d2af632002-05-26 13:36:41 +000086 import RemoteObjectBrowser
87 import StackViewer
88 tb = sys.last_traceback
89 while tb and tb.tb_frame.f_globals["__name__"] in ["rpc", "run"]:
90 tb = tb.tb_next
91 item = StackViewer.StackTreeItem(flist, tb)
92 return RemoteObjectBrowser.remote_object_tree_item(item)