blob: 595e7bc3aa1109d1f8bb280bfc2b3edea93ca159 [file] [log] [blame]
Chui Tey5d2af632002-05-26 13:36:41 +00001import sys
Kurt B. Kaiser49a5fe12004-07-04 01:25:56 +00002import linecache
Kurt B. Kaiserb4179362002-07-26 00:06:42 +00003import time
Kurt B. Kaiser86bc4642003-02-27 23:04:17 +00004import traceback
Georg Brandl2067bfd2008-05-25 13:05:15 +00005import _thread as thread
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +00006import threading
Alexandre Vassalottif260e442008-05-11 19:59:59 +00007import queue
Andrew Svetlov753445a2012-03-26 21:56:44 +03008import tkinter
Kurt B. Kaiser5afa1df2002-10-10 08:25:24 +00009
Kurt B. Kaiser2d7f6a02007-08-22 23:01:33 +000010from idlelib import CallTips
11from idlelib import AutoComplete
Kurt B. Kaiserb1754452005-11-18 22:05:48 +000012
Kurt B. Kaiser2d7f6a02007-08-22 23:01:33 +000013from idlelib import RemoteDebugger
14from idlelib import RemoteObjectBrowser
15from idlelib import StackViewer
16from idlelib import rpc
Serhiy Storchaka39e70a42013-01-25 15:30:58 +020017from idlelib import PyShell
18from idlelib import IOBinding
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
Terry Jan Reedy95a3f112013-06-28 23:50:12 -040024import warnings
Kurt B. Kaiser49a5fe12004-07-04 01:25:56 +000025
Terry Jan Reedy95a3f112013-06-28 23:50:12 -040026def idle_showwarning_subproc(
27 message, category, filename, lineno, file=None, line=None):
28 """Show Idle-format warning after replacing warnings.showwarning.
Andrew Svetlova2251aa2012-03-13 18:36:13 -070029
Terry Jan Reedy95a3f112013-06-28 23:50:12 -040030 The only difference is the formatter called.
31 """
32 if file is None:
33 file = sys.stderr
34 try:
35 file.write(PyShell.idle_formatwarning(
36 message, category, filename, lineno, line))
37 except IOError:
38 pass # the file (probably stderr) is invalid - this warning gets lost.
39
40_warnings_showwarning = None
41
42def capture_warnings(capture):
43 "Replace warning.showwarning with idle_showwarning_subproc, or reverse."
44
45 global _warnings_showwarning
46 if capture:
47 if _warnings_showwarning is None:
48 _warnings_showwarning = warnings.showwarning
49 warnings.showwarning = idle_showwarning_subproc
50 else:
51 if _warnings_showwarning is not None:
52 warnings.showwarning = _warnings_showwarning
53 _warnings_showwarning = None
54
55capture_warnings(True)
Andrew Svetlov753445a2012-03-26 21:56:44 +030056tcl = tkinter.Tcl()
57
Andrew Svetlov753445a2012-03-26 21:56:44 +030058def handle_tk_events(tcl=tcl):
Andrew Svetlova2251aa2012-03-13 18:36:13 -070059 """Process any tk events that are ready to be dispatched if tkinter
60 has been imported, a tcl interpreter has been created and tk has been
61 loaded."""
Andrew Svetlov753445a2012-03-26 21:56:44 +030062 tcl.eval("update")
Andrew Svetlova2251aa2012-03-13 18:36:13 -070063
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +000064# Thread shared globals: Establish a queue between a subthread (which handles
65# the socket) and the main thread (which runs user code), plus global
Guido van Rossum8ce8a782007-11-01 19:42:39 +000066# completion, exit and interruptable (the main thread) flags:
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +000067
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +000068exit_now = False
69quitting = False
Guido van Rossum8ce8a782007-11-01 19:42:39 +000070interruptable = False
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +000071
Kurt B. Kaiser62df0442003-05-28 01:47:46 +000072def main(del_exitfunc=False):
Kurt B. Kaiserb4179362002-07-26 00:06:42 +000073 """Start the Python execution server in a subprocess
74
Kurt B. Kaiser5afa1df2002-10-10 08:25:24 +000075 In the Python subprocess, RPCServer is instantiated with handlerclass
76 MyHandler, which inherits register/unregister methods from RPCHandler via
77 the mix-in class SocketIO.
Kurt B. Kaiserb4179362002-07-26 00:06:42 +000078
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +000079 When the RPCServer 'server' is instantiated, the TCPServer initialization
Kurt B. Kaiser5afa1df2002-10-10 08:25:24 +000080 creates an instance of run.MyHandler and calls its handle() method.
81 handle() instantiates a run.Executive object, passing it a reference to the
82 MyHandler object. That reference is saved as attribute rpchandler of the
83 Executive instance. The Executive methods have access to the reference and
84 can pass it on to entities that they command
85 (e.g. RemoteDebugger.Debugger.start_debugger()). The latter, in turn, can
86 call MyHandler(SocketIO) register/unregister methods via the reference to
87 register and unregister themselves.
Kurt B. Kaiserb4179362002-07-26 00:06:42 +000088
89 """
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +000090 global exit_now
91 global quitting
Kurt B. Kaiser62df0442003-05-28 01:47:46 +000092 global no_exitfunc
93 no_exitfunc = del_exitfunc
Kurt B. Kaiseraf3eb872004-01-21 18:54:30 +000094 #time.sleep(15) # test subprocess not responding
Kurt B. Kaisere67842a2009-04-04 20:13:23 +000095 try:
96 assert(len(sys.argv) > 1)
97 port = int(sys.argv[-1])
98 except:
Kurt B. Kaiser8fc98c32009-04-04 20:20:29 +000099 print("IDLE Subprocess: no IP port passed in sys.argv.",
100 file=sys.__stderr__)
Kurt B. Kaisere67842a2009-04-04 20:13:23 +0000101 return
Terry Jan Reedy95a3f112013-06-28 23:50:12 -0400102
103 capture_warnings(True)
Chui Tey5d2af632002-05-26 13:36:41 +0000104 sys.argv[:] = [""]
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +0000105 sockthread = threading.Thread(target=manage_socket,
106 name='SockThread',
Kurt B. Kaiser24d7e0c2003-06-05 23:51:29 +0000107 args=((LOCALHOST, port),))
Benjamin Peterson71088cc2008-09-19 21:49:37 +0000108 sockthread.daemon = True
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +0000109 sockthread.start()
110 while 1:
111 try:
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000112 if exit_now:
113 try:
Kurt B. Kaiser62df0442003-05-28 01:47:46 +0000114 exit()
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000115 except KeyboardInterrupt:
116 # exiting but got an extra KBI? Try again!
117 continue
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000118 try:
Kurt B. Kaiser20345fb2005-05-05 23:29:54 +0000119 seq, request = rpc.request_queue.get(block=True, timeout=0.05)
Alexandre Vassalottif260e442008-05-11 19:59:59 +0000120 except queue.Empty:
Andrew Svetlova2251aa2012-03-13 18:36:13 -0700121 handle_tk_events()
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000122 continue
123 method, args, kwargs = request
124 ret = method(*args, **kwargs)
125 rpc.response_queue.put((seq, ret))
Kurt B. Kaiseraa6b8562003-05-14 18:15:40 +0000126 except KeyboardInterrupt:
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000127 if quitting:
128 exit_now = True
Kurt B. Kaiseraa6b8562003-05-14 18:15:40 +0000129 continue
Kurt B. Kaisera2792be2003-05-17 21:04:10 +0000130 except SystemExit:
Terry Jan Reedy95a3f112013-06-28 23:50:12 -0400131 capture_warnings(False)
Kurt B. Kaisera2792be2003-05-17 21:04:10 +0000132 raise
Kurt B. Kaiser9ec454e2003-05-12 02:33:47 +0000133 except:
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000134 type, value, tb = sys.exc_info()
Kurt B. Kaisera2792be2003-05-17 21:04:10 +0000135 try:
136 print_exception()
137 rpc.response_queue.put((seq, None))
138 except:
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000139 # Link didn't work, print same exception to __stderr__
140 traceback.print_exception(type, value, tb, file=sys.__stderr__)
Kurt B. Kaiser62df0442003-05-28 01:47:46 +0000141 exit()
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000142 else:
143 continue
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +0000144
145def manage_socket(address):
Kurt B. Kaiseraf3eb872004-01-21 18:54:30 +0000146 for i in range(3):
Kurt B. Kaiserb4179362002-07-26 00:06:42 +0000147 time.sleep(i)
148 try:
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000149 server = MyRPCServer(address, MyHandler)
Kurt B. Kaiserb4179362002-07-26 00:06:42 +0000150 break
Andrew Svetlov0832af62012-12-18 23:10:48 +0200151 except OSError as err:
152 print("IDLE Subprocess: OSError: " + err.args[1] +
Georg Brandl6464d472007-10-22 16:16:13 +0000153 ", retrying....", file=sys.__stderr__)
Amaury Forgeot d'Arcefae8c42008-11-21 23:08:09 +0000154 socket_error = err
Kurt B. Kaiserb4179362002-07-26 00:06:42 +0000155 else:
Amaury Forgeot d'Arcefae8c42008-11-21 23:08:09 +0000156 print("IDLE Subprocess: Connection to "
157 "IDLE GUI failed, exiting.", file=sys.__stderr__)
158 show_socket_error(socket_error, address)
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000159 global exit_now
160 exit_now = True
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000161 return
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +0000162 server.handle_request() # A single request only
163
Kurt B. Kaiseraf3eb872004-01-21 18:54:30 +0000164def show_socket_error(err, address):
Georg Brandl14fc4272008-05-17 18:39:55 +0000165 import tkinter
166 import tkinter.messagebox as tkMessageBox
167 root = tkinter.Tk()
Kurt B. Kaiseraf3eb872004-01-21 18:54:30 +0000168 root.withdraw()
Georg Brandl6464d472007-10-22 16:16:13 +0000169 if err.args[0] == 61: # connection refused
Kurt B. Kaiseraf3eb872004-01-21 18:54:30 +0000170 msg = "IDLE's subprocess can't connect to %s:%d. This may be due "\
171 "to your personal firewall configuration. It is safe to "\
172 "allow this internal connection because no data is visible on "\
173 "external ports." % address
174 tkMessageBox.showerror("IDLE Subprocess Error", msg, parent=root)
175 else:
Georg Brandl6464d472007-10-22 16:16:13 +0000176 tkMessageBox.showerror("IDLE Subprocess Error",
Terry Jan Reedy3be2e542015-09-25 22:22:55 -0400177 "Socket Error: %s" % err.args[1], parent=root)
Kurt B. Kaiseraf3eb872004-01-21 18:54:30 +0000178 root.destroy()
179
Kurt B. Kaiser9ec454e2003-05-12 02:33:47 +0000180def print_exception():
Kurt B. Kaisere9802a32004-01-02 04:04:04 +0000181 import linecache
182 linecache.checkcache()
Kurt B. Kaiser9ec454e2003-05-12 02:33:47 +0000183 flush_stdout()
184 efile = sys.stderr
Kurt B. Kaiser924f6162003-11-19 04:52:32 +0000185 typ, val, tb = excinfo = sys.exc_info()
186 sys.last_type, sys.last_value, sys.last_traceback = excinfo
Serhiy Storchaka78470b42013-01-09 12:21:57 +0200187 seen = set()
188
189 def print_exc(typ, exc, tb):
190 seen.add(exc)
191 context = exc.__context__
192 cause = exc.__cause__
193 if cause is not None and cause not in seen:
194 print_exc(type(cause), cause, cause.__traceback__)
195 print("\nThe above exception was the direct cause "
196 "of the following exception:\n", file=efile)
Serhiy Storchaka71317492013-01-09 12:24:48 +0200197 elif (context is not None and
198 not exc.__suppress_context__ and
199 context not in seen):
Serhiy Storchaka78470b42013-01-09 12:21:57 +0200200 print_exc(type(context), context, context.__traceback__)
201 print("\nDuring handling of the above exception, "
202 "another exception occurred:\n", file=efile)
203 if tb:
204 tbe = traceback.extract_tb(tb)
205 print('Traceback (most recent call last):', file=efile)
206 exclude = ("run.py", "rpc.py", "threading.py", "queue.py",
207 "RemoteDebugger.py", "bdb.py")
208 cleanup_traceback(tbe, exclude)
209 traceback.print_list(tbe, file=efile)
210 lines = traceback.format_exception_only(typ, exc)
211 for line in lines:
212 print(line, end='', file=efile)
213
214 print_exc(typ, val, tb)
Kurt B. Kaiser9ec454e2003-05-12 02:33:47 +0000215
216def cleanup_traceback(tb, exclude):
217 "Remove excluded traces from beginning/end of tb; get cached lines"
218 orig_tb = tb[:]
219 while tb:
220 for rpcfile in exclude:
221 if tb[0][0].count(rpcfile):
222 break # found an exclude, break for: and delete tb[0]
223 else:
224 break # no excludes, have left RPC code, break while:
225 del tb[0]
226 while tb:
227 for rpcfile in exclude:
228 if tb[-1][0].count(rpcfile):
229 break
230 else:
231 break
232 del tb[-1]
233 if len(tb) == 0:
234 # exception was in IDLE internals, don't prune!
235 tb[:] = orig_tb[:]
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000236 print("** IDLE Internal Exception: ", file=sys.stderr)
Kurt B. Kaiser9ec454e2003-05-12 02:33:47 +0000237 rpchandler = rpc.objecttable['exec'].rpchandler
238 for i in range(len(tb)):
239 fn, ln, nm, line = tb[i]
240 if nm == '?':
241 nm = "-toplevel-"
242 if not line and fn.startswith("<pyshell#"):
243 line = rpchandler.remotecall('linecache', 'getline',
244 (fn, ln), {})
245 tb[i] = fn, ln, nm, line
246
247def flush_stdout():
Guido van Rossum79139b22007-02-09 23:20:19 +0000248 """XXX How to do this now?"""
Kurt B. Kaiser9ec454e2003-05-12 02:33:47 +0000249
Kurt B. Kaiser62df0442003-05-28 01:47:46 +0000250def exit():
Guido van Rossumc76a2502007-08-09 14:26:58 +0000251 """Exit subprocess, possibly after first clearing exit functions.
Kurt B. Kaiser62df0442003-05-28 01:47:46 +0000252
253 If config-main.cfg/.def 'General' 'delete-exitfunc' is True, then any
Guido van Rossumc76a2502007-08-09 14:26:58 +0000254 functions registered with atexit will be removed before exiting.
255 (VPython support)
Kurt B. Kaiser62df0442003-05-28 01:47:46 +0000256
257 """
258 if no_exitfunc:
Guido van Rossumc76a2502007-08-09 14:26:58 +0000259 import atexit
260 atexit._clear()
Terry Jan Reedy95a3f112013-06-28 23:50:12 -0400261 capture_warnings(False)
Kurt B. Kaiser62df0442003-05-28 01:47:46 +0000262 sys.exit(0)
Chui Tey5d2af632002-05-26 13:36:41 +0000263
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000264class MyRPCServer(rpc.RPCServer):
265
266 def handle_error(self, request, client_address):
267 """Override RPCServer method for IDLE
268
269 Interrupt the MainThread and exit server if link is dropped.
270
271 """
Kurt B. Kaisere9535112004-11-19 15:46:49 +0000272 global quitting
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000273 try:
274 raise
275 except SystemExit:
276 raise
277 except EOFError:
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000278 global exit_now
279 exit_now = True
Kurt B. Kaiser93e8e542003-06-13 22:03:43 +0000280 thread.interrupt_main()
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000281 except:
282 erf = sys.__stderr__
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000283 print('\n' + '-'*40, file=erf)
284 print('Unhandled server exception!', file=erf)
Amaury Forgeot d'Arcbed17102008-11-29 01:48:47 +0000285 print('Thread: %s' % threading.current_thread().name, file=erf)
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000286 print('Client Address: ', client_address, file=erf)
287 print('Request: ', repr(request), file=erf)
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000288 traceback.print_exc(file=erf)
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000289 print('\n*** Unrecoverable, server exiting!', file=erf)
290 print('-'*40, file=erf)
Kurt B. Kaisere9535112004-11-19 15:46:49 +0000291 quitting = True
292 thread.interrupt_main()
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000293
Chui Tey5d2af632002-05-26 13:36:41 +0000294class MyHandler(rpc.RPCHandler):
295
296 def handle(self):
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +0000297 """Override base method"""
Chui Tey5d2af632002-05-26 13:36:41 +0000298 executive = Executive(self)
299 self.register("exec", executive)
Serhiy Storchaka39e70a42013-01-25 15:30:58 +0200300 self.console = self.get_remote_proxy("console")
301 sys.stdin = PyShell.PseudoInputFile(self.console, "stdin",
302 IOBinding.encoding)
303 sys.stdout = PyShell.PseudoOutputFile(self.console, "stdout",
304 IOBinding.encoding)
305 sys.stderr = PyShell.PseudoOutputFile(self.console, "stderr",
306 IOBinding.encoding)
307
Andrew Svetlovcd49d532012-03-25 11:43:02 +0300308 sys.displayhook = rpc.displayhook
Kurt B. Kaiserf609a342007-12-28 03:57:56 +0000309 # page help() text to shell.
310 import pydoc # import must be done here to capture i/o binding
311 pydoc.pager = pydoc.plainpager
Benjamin Peterson0d4931e2013-05-11 22:24:28 -0500312
313 # Keep a reference to stdin so that it won't try to exit IDLE if
314 # sys.stdin gets changed from within IDLE's shell. See issue17838.
315 self._keep_stdin = sys.stdin
316
Kurt B. Kaiser9f366092003-06-02 01:50:19 +0000317 self.interp = self.get_remote_proxy("interp")
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000318 rpc.RPCHandler.getresponse(self, myseq=None, wait=0.05)
319
320 def exithook(self):
321 "override SocketIO method - wait for MainThread to shut us down"
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000322 time.sleep(10)
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000323
324 def EOFhook(self):
325 "Override SocketIO method - terminate wait on callback and exit thread"
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000326 global quitting
327 quitting = True
Kurt B. Kaiser93e8e542003-06-13 22:03:43 +0000328 thread.interrupt_main()
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000329
330 def decode_interrupthook(self):
331 "interrupt awakened thread"
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000332 global quitting
333 quitting = True
Kurt B. Kaiser93e8e542003-06-13 22:03:43 +0000334 thread.interrupt_main()
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +0000335
Chui Tey5d2af632002-05-26 13:36:41 +0000336
Kurt B. Kaiserdcba6622004-12-21 22:10:32 +0000337class Executive(object):
Chui Tey5d2af632002-05-26 13:36:41 +0000338
339 def __init__(self, rpchandler):
Kurt B. Kaiserffd3a422002-06-26 02:32:09 +0000340 self.rpchandler = rpchandler
Kurt B. Kaiseradc63842002-08-25 14:08:07 +0000341 self.locals = __main__.__dict__
Kurt B. Kaiser5afa1df2002-10-10 08:25:24 +0000342 self.calltip = CallTips.CallTips()
Kurt B. Kaiserb1754452005-11-18 22:05:48 +0000343 self.autocomplete = AutoComplete.AutoComplete()
Chui Tey5d2af632002-05-26 13:36:41 +0000344
345 def runcode(self, code):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000346 global interruptable
Kurt B. Kaiser86bc4642003-02-27 23:04:17 +0000347 try:
Kurt B. Kaiser9f366092003-06-02 01:50:19 +0000348 self.usr_exc_info = None
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000349 interruptable = True
350 try:
351 exec(code, self.locals)
352 finally:
353 interruptable = False
Roger Serwyf4675212013-06-11 22:25:14 -0500354 except SystemExit:
355 # Scripts that raise SystemExit should just
356 # return to the interactive prompt
357 pass
Kurt B. Kaiser86bc4642003-02-27 23:04:17 +0000358 except:
Kurt B. Kaiser9f366092003-06-02 01:50:19 +0000359 self.usr_exc_info = sys.exc_info()
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000360 if quitting:
Kurt B. Kaiser62df0442003-05-28 01:47:46 +0000361 exit()
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000362 # even print a user code SystemExit exception, continue
363 print_exception()
Kurt B. Kaiser9f366092003-06-02 01:50:19 +0000364 jit = self.rpchandler.console.getvar("<<toggle-jit-stack-viewer>>")
365 if jit:
366 self.rpchandler.interp.open_remote_stack_viewer()
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +0000367 else:
Kurt B. Kaiser9ec454e2003-05-12 02:33:47 +0000368 flush_stdout()
Chui Tey5d2af632002-05-26 13:36:41 +0000369
Kurt B. Kaiser003091c2003-02-17 18:57:16 +0000370 def interrupt_the_server(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000371 if interruptable:
372 thread.interrupt_main()
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +0000373
Kurt B. Kaiser0e3a5772002-06-16 03:32:24 +0000374 def start_the_debugger(self, gui_adap_oid):
Kurt B. Kaiserffd3a422002-06-26 02:32:09 +0000375 return RemoteDebugger.start_debugger(self.rpchandler, gui_adap_oid)
376
377 def stop_the_debugger(self, idb_adap_oid):
378 "Unregister the Idb Adapter. Link objects and Idb then subject to GC"
379 self.rpchandler.unregister(idb_adap_oid)
Chui Tey5d2af632002-05-26 13:36:41 +0000380
Kurt B. Kaiser5afa1df2002-10-10 08:25:24 +0000381 def get_the_calltip(self, name):
382 return self.calltip.fetch_tip(name)
383
Kurt B. Kaiserb1754452005-11-18 22:05:48 +0000384 def get_the_completion_list(self, what, mode):
385 return self.autocomplete.fetch_completions(what, mode)
386
Chui Tey5d2af632002-05-26 13:36:41 +0000387 def stackviewer(self, flist_oid=None):
Kurt B. Kaiser9f366092003-06-02 01:50:19 +0000388 if self.usr_exc_info:
389 typ, val, tb = self.usr_exc_info
390 else:
Chui Tey5d2af632002-05-26 13:36:41 +0000391 return None
392 flist = None
393 if flist_oid is not None:
Kurt B. Kaiserffd3a422002-06-26 02:32:09 +0000394 flist = self.rpchandler.get_remote_proxy(flist_oid)
Chui Tey5d2af632002-05-26 13:36:41 +0000395 while tb and tb.tb_frame.f_globals["__name__"] in ["rpc", "run"]:
396 tb = tb.tb_next
Kurt B. Kaiser9f366092003-06-02 01:50:19 +0000397 sys.last_type = typ
398 sys.last_value = val
Chui Tey5d2af632002-05-26 13:36:41 +0000399 item = StackViewer.StackTreeItem(flist, tb)
400 return RemoteObjectBrowser.remote_object_tree_item(item)
Terry Jan Reedy95a3f112013-06-28 23:50:12 -0400401
402capture_warnings(False) # Make sure turned off; see issue 18081