blob: dbf046bc5d36993ff4c37037143bf6d209185f4b [file] [log] [blame]
Chui Tey5d2af632002-05-26 13:36:41 +00001import sys
Martin v. Löwis9ae3f7a2012-07-09 20:46:11 +02002import io
Kurt B. Kaiser49a5fe12004-07-04 01:25:56 +00003import linecache
Kurt B. Kaiserb4179362002-07-26 00:06:42 +00004import time
5import socket
Kurt B. Kaiser86bc4642003-02-27 23:04:17 +00006import traceback
Georg Brandl2067bfd2008-05-25 13:05:15 +00007import _thread as thread
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +00008import threading
Alexandre Vassalottif260e442008-05-11 19:59:59 +00009import queue
Andrew Svetlov753445a2012-03-26 21:56:44 +030010import tkinter
Kurt B. Kaiser5afa1df2002-10-10 08:25:24 +000011
Kurt B. Kaiser2d7f6a02007-08-22 23:01:33 +000012from idlelib import CallTips
13from idlelib import AutoComplete
Kurt B. Kaiserb1754452005-11-18 22:05:48 +000014
Kurt B. Kaiser2d7f6a02007-08-22 23:01:33 +000015from idlelib import RemoteDebugger
16from idlelib import RemoteObjectBrowser
17from idlelib import StackViewer
18from idlelib import rpc
Chui Tey5d2af632002-05-26 13:36:41 +000019
Kurt B. Kaiser5afa1df2002-10-10 08:25:24 +000020import __main__
21
Kurt B. Kaiser24d7e0c2003-06-05 23:51:29 +000022LOCALHOST = '127.0.0.1'
23
Kurt B. Kaiser49a5fe12004-07-04 01:25:56 +000024try:
25 import warnings
26except ImportError:
27 pass
28else:
Benjamin Peterson206e3072008-10-19 14:07:49 +000029 def idle_formatwarning_subproc(message, category, filename, lineno,
Guilherme Polo1fff0082009-08-14 15:05:30 +000030 line=None):
Kurt B. Kaiser49a5fe12004-07-04 01:25:56 +000031 """Format warnings the IDLE way"""
32 s = "\nWarning (from warnings module):\n"
33 s += ' File \"%s\", line %s\n' % (filename, lineno)
Guilherme Polo1fff0082009-08-14 15:05:30 +000034 if line is None:
35 line = linecache.getline(filename, lineno)
36 line = line.strip()
Kurt B. Kaiser49a5fe12004-07-04 01:25:56 +000037 if line:
38 s += " %s\n" % line
39 s += "%s: %s\n" % (category.__name__, message)
40 return s
41 warnings.formatwarning = idle_formatwarning_subproc
42
Andrew Svetlova2251aa2012-03-13 18:36:13 -070043
Andrew Svetlov753445a2012-03-26 21:56:44 +030044tcl = tkinter.Tcl()
45
46
47def handle_tk_events(tcl=tcl):
Andrew Svetlova2251aa2012-03-13 18:36:13 -070048 """Process any tk events that are ready to be dispatched if tkinter
49 has been imported, a tcl interpreter has been created and tk has been
50 loaded."""
Andrew Svetlov753445a2012-03-26 21:56:44 +030051 tcl.eval("update")
Andrew Svetlova2251aa2012-03-13 18:36:13 -070052
53
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +000054# Thread shared globals: Establish a queue between a subthread (which handles
55# the socket) and the main thread (which runs user code), plus global
Guido van Rossum8ce8a782007-11-01 19:42:39 +000056# completion, exit and interruptable (the main thread) flags:
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +000057
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +000058exit_now = False
59quitting = False
Guido van Rossum8ce8a782007-11-01 19:42:39 +000060interruptable = False
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +000061
Kurt B. Kaiser62df0442003-05-28 01:47:46 +000062def main(del_exitfunc=False):
Kurt B. Kaiserb4179362002-07-26 00:06:42 +000063 """Start the Python execution server in a subprocess
64
Kurt B. Kaiser5afa1df2002-10-10 08:25:24 +000065 In the Python subprocess, RPCServer is instantiated with handlerclass
66 MyHandler, which inherits register/unregister methods from RPCHandler via
67 the mix-in class SocketIO.
Kurt B. Kaiserb4179362002-07-26 00:06:42 +000068
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +000069 When the RPCServer 'server' is instantiated, the TCPServer initialization
Kurt B. Kaiser5afa1df2002-10-10 08:25:24 +000070 creates an instance of run.MyHandler and calls its handle() method.
71 handle() instantiates a run.Executive object, passing it a reference to the
72 MyHandler object. That reference is saved as attribute rpchandler of the
73 Executive instance. The Executive methods have access to the reference and
74 can pass it on to entities that they command
75 (e.g. RemoteDebugger.Debugger.start_debugger()). The latter, in turn, can
76 call MyHandler(SocketIO) register/unregister methods via the reference to
77 register and unregister themselves.
Kurt B. Kaiserb4179362002-07-26 00:06:42 +000078
79 """
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +000080 global exit_now
81 global quitting
Kurt B. Kaiser62df0442003-05-28 01:47:46 +000082 global no_exitfunc
83 no_exitfunc = del_exitfunc
Kurt B. Kaiseraf3eb872004-01-21 18:54:30 +000084 #time.sleep(15) # test subprocess not responding
Kurt B. Kaisere67842a2009-04-04 20:13:23 +000085 try:
86 assert(len(sys.argv) > 1)
87 port = int(sys.argv[-1])
88 except:
Kurt B. Kaiser8fc98c32009-04-04 20:20:29 +000089 print("IDLE Subprocess: no IP port passed in sys.argv.",
90 file=sys.__stderr__)
Kurt B. Kaisere67842a2009-04-04 20:13:23 +000091 return
Chui Tey5d2af632002-05-26 13:36:41 +000092 sys.argv[:] = [""]
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +000093 sockthread = threading.Thread(target=manage_socket,
94 name='SockThread',
Kurt B. Kaiser24d7e0c2003-06-05 23:51:29 +000095 args=((LOCALHOST, port),))
Benjamin Peterson71088cc2008-09-19 21:49:37 +000096 sockthread.daemon = True
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +000097 sockthread.start()
98 while 1:
99 try:
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000100 if exit_now:
101 try:
Kurt B. Kaiser62df0442003-05-28 01:47:46 +0000102 exit()
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000103 except KeyboardInterrupt:
104 # exiting but got an extra KBI? Try again!
105 continue
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000106 try:
Kurt B. Kaiser20345fb2005-05-05 23:29:54 +0000107 seq, request = rpc.request_queue.get(block=True, timeout=0.05)
Alexandre Vassalottif260e442008-05-11 19:59:59 +0000108 except queue.Empty:
Andrew Svetlova2251aa2012-03-13 18:36:13 -0700109 handle_tk_events()
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000110 continue
111 method, args, kwargs = request
112 ret = method(*args, **kwargs)
113 rpc.response_queue.put((seq, ret))
Kurt B. Kaiseraa6b8562003-05-14 18:15:40 +0000114 except KeyboardInterrupt:
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000115 if quitting:
116 exit_now = True
Kurt B. Kaiseraa6b8562003-05-14 18:15:40 +0000117 continue
Kurt B. Kaisera2792be2003-05-17 21:04:10 +0000118 except SystemExit:
119 raise
Kurt B. Kaiser9ec454e2003-05-12 02:33:47 +0000120 except:
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000121 type, value, tb = sys.exc_info()
Kurt B. Kaisera2792be2003-05-17 21:04:10 +0000122 try:
123 print_exception()
124 rpc.response_queue.put((seq, None))
125 except:
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000126 # Link didn't work, print same exception to __stderr__
127 traceback.print_exception(type, value, tb, file=sys.__stderr__)
Kurt B. Kaiser62df0442003-05-28 01:47:46 +0000128 exit()
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000129 else:
130 continue
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +0000131
132def manage_socket(address):
Kurt B. Kaiseraf3eb872004-01-21 18:54:30 +0000133 for i in range(3):
Kurt B. Kaiserb4179362002-07-26 00:06:42 +0000134 time.sleep(i)
135 try:
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000136 server = MyRPCServer(address, MyHandler)
Kurt B. Kaiserb4179362002-07-26 00:06:42 +0000137 break
Guido van Rossumb940e112007-01-10 16:19:56 +0000138 except socket.error as err:
Georg Brandl6464d472007-10-22 16:16:13 +0000139 print("IDLE Subprocess: socket error: " + err.args[1] +
140 ", retrying....", file=sys.__stderr__)
Amaury Forgeot d'Arcefae8c42008-11-21 23:08:09 +0000141 socket_error = err
Kurt B. Kaiserb4179362002-07-26 00:06:42 +0000142 else:
Amaury Forgeot d'Arcefae8c42008-11-21 23:08:09 +0000143 print("IDLE Subprocess: Connection to "
144 "IDLE GUI failed, exiting.", file=sys.__stderr__)
145 show_socket_error(socket_error, address)
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000146 global exit_now
147 exit_now = True
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000148 return
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +0000149 server.handle_request() # A single request only
150
Kurt B. Kaiseraf3eb872004-01-21 18:54:30 +0000151def show_socket_error(err, address):
Georg Brandl14fc4272008-05-17 18:39:55 +0000152 import tkinter
153 import tkinter.messagebox as tkMessageBox
154 root = tkinter.Tk()
Kurt B. Kaiseraf3eb872004-01-21 18:54:30 +0000155 root.withdraw()
Georg Brandl6464d472007-10-22 16:16:13 +0000156 if err.args[0] == 61: # connection refused
Kurt B. Kaiseraf3eb872004-01-21 18:54:30 +0000157 msg = "IDLE's subprocess can't connect to %s:%d. This may be due "\
158 "to your personal firewall configuration. It is safe to "\
159 "allow this internal connection because no data is visible on "\
160 "external ports." % address
161 tkMessageBox.showerror("IDLE Subprocess Error", msg, parent=root)
162 else:
Georg Brandl6464d472007-10-22 16:16:13 +0000163 tkMessageBox.showerror("IDLE Subprocess Error",
164 "Socket Error: %s" % err.args[1])
Kurt B. Kaiseraf3eb872004-01-21 18:54:30 +0000165 root.destroy()
166
Kurt B. Kaiser9ec454e2003-05-12 02:33:47 +0000167def print_exception():
Kurt B. Kaisere9802a32004-01-02 04:04:04 +0000168 import linecache
169 linecache.checkcache()
Kurt B. Kaiser9ec454e2003-05-12 02:33:47 +0000170 flush_stdout()
171 efile = sys.stderr
Kurt B. Kaiser924f6162003-11-19 04:52:32 +0000172 typ, val, tb = excinfo = sys.exc_info()
173 sys.last_type, sys.last_value, sys.last_traceback = excinfo
Serhiy Storchaka78470b42013-01-09 12:21:57 +0200174 seen = set()
175
176 def print_exc(typ, exc, tb):
177 seen.add(exc)
178 context = exc.__context__
179 cause = exc.__cause__
180 if cause is not None and cause not in seen:
181 print_exc(type(cause), cause, cause.__traceback__)
182 print("\nThe above exception was the direct cause "
183 "of the following exception:\n", file=efile)
Serhiy Storchaka71317492013-01-09 12:24:48 +0200184 elif (context is not None and
185 not exc.__suppress_context__ and
186 context not in seen):
Serhiy Storchaka78470b42013-01-09 12:21:57 +0200187 print_exc(type(context), context, context.__traceback__)
188 print("\nDuring handling of the above exception, "
189 "another exception occurred:\n", file=efile)
190 if tb:
191 tbe = traceback.extract_tb(tb)
192 print('Traceback (most recent call last):', file=efile)
193 exclude = ("run.py", "rpc.py", "threading.py", "queue.py",
194 "RemoteDebugger.py", "bdb.py")
195 cleanup_traceback(tbe, exclude)
196 traceback.print_list(tbe, file=efile)
197 lines = traceback.format_exception_only(typ, exc)
198 for line in lines:
199 print(line, end='', file=efile)
200
201 print_exc(typ, val, tb)
Kurt B. Kaiser9ec454e2003-05-12 02:33:47 +0000202
203def cleanup_traceback(tb, exclude):
204 "Remove excluded traces from beginning/end of tb; get cached lines"
205 orig_tb = tb[:]
206 while tb:
207 for rpcfile in exclude:
208 if tb[0][0].count(rpcfile):
209 break # found an exclude, break for: and delete tb[0]
210 else:
211 break # no excludes, have left RPC code, break while:
212 del tb[0]
213 while tb:
214 for rpcfile in exclude:
215 if tb[-1][0].count(rpcfile):
216 break
217 else:
218 break
219 del tb[-1]
220 if len(tb) == 0:
221 # exception was in IDLE internals, don't prune!
222 tb[:] = orig_tb[:]
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000223 print("** IDLE Internal Exception: ", file=sys.stderr)
Kurt B. Kaiser9ec454e2003-05-12 02:33:47 +0000224 rpchandler = rpc.objecttable['exec'].rpchandler
225 for i in range(len(tb)):
226 fn, ln, nm, line = tb[i]
227 if nm == '?':
228 nm = "-toplevel-"
229 if not line and fn.startswith("<pyshell#"):
230 line = rpchandler.remotecall('linecache', 'getline',
231 (fn, ln), {})
232 tb[i] = fn, ln, nm, line
233
234def flush_stdout():
Guido van Rossum79139b22007-02-09 23:20:19 +0000235 """XXX How to do this now?"""
Kurt B. Kaiser9ec454e2003-05-12 02:33:47 +0000236
Kurt B. Kaiser62df0442003-05-28 01:47:46 +0000237def exit():
Guido van Rossumc76a2502007-08-09 14:26:58 +0000238 """Exit subprocess, possibly after first clearing exit functions.
Kurt B. Kaiser62df0442003-05-28 01:47:46 +0000239
240 If config-main.cfg/.def 'General' 'delete-exitfunc' is True, then any
Guido van Rossumc76a2502007-08-09 14:26:58 +0000241 functions registered with atexit will be removed before exiting.
242 (VPython support)
Kurt B. Kaiser62df0442003-05-28 01:47:46 +0000243
244 """
245 if no_exitfunc:
Guido van Rossumc76a2502007-08-09 14:26:58 +0000246 import atexit
247 atexit._clear()
Kurt B. Kaiser62df0442003-05-28 01:47:46 +0000248 sys.exit(0)
Chui Tey5d2af632002-05-26 13:36:41 +0000249
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000250class MyRPCServer(rpc.RPCServer):
251
252 def handle_error(self, request, client_address):
253 """Override RPCServer method for IDLE
254
255 Interrupt the MainThread and exit server if link is dropped.
256
257 """
Kurt B. Kaisere9535112004-11-19 15:46:49 +0000258 global quitting
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000259 try:
260 raise
261 except SystemExit:
262 raise
263 except EOFError:
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000264 global exit_now
265 exit_now = True
Kurt B. Kaiser93e8e542003-06-13 22:03:43 +0000266 thread.interrupt_main()
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000267 except:
268 erf = sys.__stderr__
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000269 print('\n' + '-'*40, file=erf)
270 print('Unhandled server exception!', file=erf)
Amaury Forgeot d'Arcbed17102008-11-29 01:48:47 +0000271 print('Thread: %s' % threading.current_thread().name, file=erf)
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000272 print('Client Address: ', client_address, file=erf)
273 print('Request: ', repr(request), file=erf)
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000274 traceback.print_exc(file=erf)
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000275 print('\n*** Unrecoverable, server exiting!', file=erf)
276 print('-'*40, file=erf)
Kurt B. Kaisere9535112004-11-19 15:46:49 +0000277 quitting = True
278 thread.interrupt_main()
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000279
Martin v. Löwis9ae3f7a2012-07-09 20:46:11 +0200280class _RPCFile(io.TextIOBase):
Martin v. Löwis1d0f6dd2012-07-09 20:52:40 +0200281 """Wrapper class for the RPC proxy to typecheck arguments
Martin v. Löwisc2761652012-07-11 08:48:34 +0200282 that may not support pickling. The base class is there only
283 to support type tests; all implementations come from the remote
284 object."""
Martin v. Löwis9ae3f7a2012-07-09 20:46:11 +0200285
286 def __init__(self, rpc):
287 super.__setattr__(self, 'rpc', rpc)
288
Martin v. Löwisc2761652012-07-11 08:48:34 +0200289 def __getattribute__(self, name):
Martin v. Löwis67097fd2012-07-11 09:17:15 +0200290 # When accessing the 'rpc' attribute, or 'write', use ours
Martin v. Löwisc882b7c2012-07-25 10:47:20 +0200291 if name in ('rpc', 'write', 'writelines'):
Martin v. Löwisc2761652012-07-11 08:48:34 +0200292 return io.TextIOBase.__getattribute__(self, name)
293 # Else only look into the remote object only
Martin v. Löwis9ae3f7a2012-07-09 20:46:11 +0200294 return getattr(self.rpc, name)
295
296 def __setattr__(self, name, value):
297 return setattr(self.rpc, name, value)
298
Martin v. Löwisc882b7c2012-07-25 10:47:20 +0200299 @staticmethod
300 def _ensure_string(func):
301 def f(self, s):
302 if not isinstance(s, str):
303 raise TypeError('must be str, not ' + type(s).__name__)
304 return func(self, s)
305 return f
306
307class _RPCOutputFile(_RPCFile):
308 @_RPCFile._ensure_string
Martin v. Löwis9ae3f7a2012-07-09 20:46:11 +0200309 def write(self, s):
310 if not isinstance(s, str):
311 raise TypeError('must be str, not ' + type(s).__name__)
312 return self.rpc.write(s)
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000313
Martin v. Löwisc882b7c2012-07-25 10:47:20 +0200314class _RPCInputFile(_RPCFile):
315 @_RPCFile._ensure_string
316 def write(self, s):
317 raise io.UnsupportedOperation("not writable")
318 writelines = write
319
Chui Tey5d2af632002-05-26 13:36:41 +0000320class MyHandler(rpc.RPCHandler):
321
322 def handle(self):
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +0000323 """Override base method"""
Chui Tey5d2af632002-05-26 13:36:41 +0000324 executive = Executive(self)
325 self.register("exec", executive)
Martin v. Löwisc882b7c2012-07-25 10:47:20 +0200326 self.console = self.get_remote_proxy("stdin")
327 sys.stdin = _RPCInputFile(self.console)
328 sys.stdout = _RPCOutputFile(self.get_remote_proxy("stdout"))
329 sys.stderr = _RPCOutputFile(self.get_remote_proxy("stderr"))
Andrew Svetlovcd49d532012-03-25 11:43:02 +0300330 sys.displayhook = rpc.displayhook
Kurt B. Kaiserf609a342007-12-28 03:57:56 +0000331 # page help() text to shell.
332 import pydoc # import must be done here to capture i/o binding
333 pydoc.pager = pydoc.plainpager
Kurt B. Kaiser2d7f6a02007-08-22 23:01:33 +0000334 from idlelib import IOBinding
Martin v. Löwisbcc651a2003-06-22 07:52:56 +0000335 sys.stdin.encoding = sys.stdout.encoding = \
336 sys.stderr.encoding = IOBinding.encoding
Kurt B. Kaiser9f366092003-06-02 01:50:19 +0000337 self.interp = self.get_remote_proxy("interp")
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000338 rpc.RPCHandler.getresponse(self, myseq=None, wait=0.05)
339
340 def exithook(self):
341 "override SocketIO method - wait for MainThread to shut us down"
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000342 time.sleep(10)
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000343
344 def EOFhook(self):
345 "Override SocketIO method - terminate wait on callback and exit thread"
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000346 global quitting
347 quitting = True
Kurt B. Kaiser93e8e542003-06-13 22:03:43 +0000348 thread.interrupt_main()
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000349
350 def decode_interrupthook(self):
351 "interrupt awakened thread"
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000352 global quitting
353 quitting = True
Kurt B. Kaiser93e8e542003-06-13 22:03:43 +0000354 thread.interrupt_main()
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +0000355
Chui Tey5d2af632002-05-26 13:36:41 +0000356
Kurt B. Kaiserdcba6622004-12-21 22:10:32 +0000357class Executive(object):
Chui Tey5d2af632002-05-26 13:36:41 +0000358
359 def __init__(self, rpchandler):
Kurt B. Kaiserffd3a422002-06-26 02:32:09 +0000360 self.rpchandler = rpchandler
Kurt B. Kaiseradc63842002-08-25 14:08:07 +0000361 self.locals = __main__.__dict__
Kurt B. Kaiser5afa1df2002-10-10 08:25:24 +0000362 self.calltip = CallTips.CallTips()
Kurt B. Kaiserb1754452005-11-18 22:05:48 +0000363 self.autocomplete = AutoComplete.AutoComplete()
Chui Tey5d2af632002-05-26 13:36:41 +0000364
365 def runcode(self, code):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000366 global interruptable
Kurt B. Kaiser86bc4642003-02-27 23:04:17 +0000367 try:
Kurt B. Kaiser9f366092003-06-02 01:50:19 +0000368 self.usr_exc_info = None
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000369 interruptable = True
370 try:
371 exec(code, self.locals)
372 finally:
373 interruptable = False
Kurt B. Kaiser86bc4642003-02-27 23:04:17 +0000374 except:
Kurt B. Kaiser9f366092003-06-02 01:50:19 +0000375 self.usr_exc_info = sys.exc_info()
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000376 if quitting:
Kurt B. Kaiser62df0442003-05-28 01:47:46 +0000377 exit()
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000378 # even print a user code SystemExit exception, continue
379 print_exception()
Kurt B. Kaiser9f366092003-06-02 01:50:19 +0000380 jit = self.rpchandler.console.getvar("<<toggle-jit-stack-viewer>>")
381 if jit:
382 self.rpchandler.interp.open_remote_stack_viewer()
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +0000383 else:
Kurt B. Kaiser9ec454e2003-05-12 02:33:47 +0000384 flush_stdout()
Chui Tey5d2af632002-05-26 13:36:41 +0000385
Kurt B. Kaiser003091c2003-02-17 18:57:16 +0000386 def interrupt_the_server(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000387 if interruptable:
388 thread.interrupt_main()
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +0000389
Kurt B. Kaiser0e3a5772002-06-16 03:32:24 +0000390 def start_the_debugger(self, gui_adap_oid):
Kurt B. Kaiserffd3a422002-06-26 02:32:09 +0000391 return RemoteDebugger.start_debugger(self.rpchandler, gui_adap_oid)
392
393 def stop_the_debugger(self, idb_adap_oid):
394 "Unregister the Idb Adapter. Link objects and Idb then subject to GC"
395 self.rpchandler.unregister(idb_adap_oid)
Chui Tey5d2af632002-05-26 13:36:41 +0000396
Kurt B. Kaiser5afa1df2002-10-10 08:25:24 +0000397 def get_the_calltip(self, name):
398 return self.calltip.fetch_tip(name)
399
Kurt B. Kaiserb1754452005-11-18 22:05:48 +0000400 def get_the_completion_list(self, what, mode):
401 return self.autocomplete.fetch_completions(what, mode)
402
Chui Tey5d2af632002-05-26 13:36:41 +0000403 def stackviewer(self, flist_oid=None):
Kurt B. Kaiser9f366092003-06-02 01:50:19 +0000404 if self.usr_exc_info:
405 typ, val, tb = self.usr_exc_info
406 else:
Chui Tey5d2af632002-05-26 13:36:41 +0000407 return None
408 flist = None
409 if flist_oid is not None:
Kurt B. Kaiserffd3a422002-06-26 02:32:09 +0000410 flist = self.rpchandler.get_remote_proxy(flist_oid)
Chui Tey5d2af632002-05-26 13:36:41 +0000411 while tb and tb.tb_frame.f_globals["__name__"] in ["rpc", "run"]:
412 tb = tb.tb_next
Kurt B. Kaiser9f366092003-06-02 01:50:19 +0000413 sys.last_type = typ
414 sys.last_value = val
Chui Tey5d2af632002-05-26 13:36:41 +0000415 item = StackViewer.StackTreeItem(flist, tb)
416 return RemoteObjectBrowser.remote_object_tree_item(item)