blob: 13cec62976bd3d81f7117770c1abbe172cd7f90e [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
Serhiy Storchaka39e70a42013-01-25 15:30:58 +020019from idlelib import PyShell
20from idlelib import IOBinding
Chui Tey5d2af632002-05-26 13:36:41 +000021
Kurt B. Kaiser5afa1df2002-10-10 08:25:24 +000022import __main__
23
Kurt B. Kaiser24d7e0c2003-06-05 23:51:29 +000024LOCALHOST = '127.0.0.1'
25
Terry Jan Reedy95a3f112013-06-28 23:50:12 -040026import warnings
Kurt B. Kaiser49a5fe12004-07-04 01:25:56 +000027
Terry Jan Reedy95a3f112013-06-28 23:50:12 -040028def idle_showwarning_subproc(
29 message, category, filename, lineno, file=None, line=None):
30 """Show Idle-format warning after replacing warnings.showwarning.
Andrew Svetlova2251aa2012-03-13 18:36:13 -070031
Terry Jan Reedy95a3f112013-06-28 23:50:12 -040032 The only difference is the formatter called.
33 """
34 if file is None:
35 file = sys.stderr
36 try:
37 file.write(PyShell.idle_formatwarning(
38 message, category, filename, lineno, line))
39 except IOError:
40 pass # the file (probably stderr) is invalid - this warning gets lost.
41
42_warnings_showwarning = None
43
44def capture_warnings(capture):
45 "Replace warning.showwarning with idle_showwarning_subproc, or reverse."
46
47 global _warnings_showwarning
48 if capture:
49 if _warnings_showwarning is None:
50 _warnings_showwarning = warnings.showwarning
51 warnings.showwarning = idle_showwarning_subproc
52 else:
53 if _warnings_showwarning is not None:
54 warnings.showwarning = _warnings_showwarning
55 _warnings_showwarning = None
56
57capture_warnings(True)
Andrew Svetlov753445a2012-03-26 21:56:44 +030058tcl = tkinter.Tcl()
59
Andrew Svetlov753445a2012-03-26 21:56:44 +030060def handle_tk_events(tcl=tcl):
Andrew Svetlova2251aa2012-03-13 18:36:13 -070061 """Process any tk events that are ready to be dispatched if tkinter
62 has been imported, a tcl interpreter has been created and tk has been
63 loaded."""
Andrew Svetlov753445a2012-03-26 21:56:44 +030064 tcl.eval("update")
Andrew Svetlova2251aa2012-03-13 18:36:13 -070065
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +000066# Thread shared globals: Establish a queue between a subthread (which handles
67# the socket) and the main thread (which runs user code), plus global
Guido van Rossum8ce8a782007-11-01 19:42:39 +000068# completion, exit and interruptable (the main thread) flags:
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +000069
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +000070exit_now = False
71quitting = False
Guido van Rossum8ce8a782007-11-01 19:42:39 +000072interruptable = False
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +000073
Kurt B. Kaiser62df0442003-05-28 01:47:46 +000074def main(del_exitfunc=False):
Kurt B. Kaiserb4179362002-07-26 00:06:42 +000075 """Start the Python execution server in a subprocess
76
Kurt B. Kaiser5afa1df2002-10-10 08:25:24 +000077 In the Python subprocess, RPCServer is instantiated with handlerclass
78 MyHandler, which inherits register/unregister methods from RPCHandler via
79 the mix-in class SocketIO.
Kurt B. Kaiserb4179362002-07-26 00:06:42 +000080
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +000081 When the RPCServer 'server' is instantiated, the TCPServer initialization
Kurt B. Kaiser5afa1df2002-10-10 08:25:24 +000082 creates an instance of run.MyHandler and calls its handle() method.
83 handle() instantiates a run.Executive object, passing it a reference to the
84 MyHandler object. That reference is saved as attribute rpchandler of the
85 Executive instance. The Executive methods have access to the reference and
86 can pass it on to entities that they command
87 (e.g. RemoteDebugger.Debugger.start_debugger()). The latter, in turn, can
88 call MyHandler(SocketIO) register/unregister methods via the reference to
89 register and unregister themselves.
Kurt B. Kaiserb4179362002-07-26 00:06:42 +000090
91 """
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +000092 global exit_now
93 global quitting
Kurt B. Kaiser62df0442003-05-28 01:47:46 +000094 global no_exitfunc
95 no_exitfunc = del_exitfunc
Kurt B. Kaiseraf3eb872004-01-21 18:54:30 +000096 #time.sleep(15) # test subprocess not responding
Kurt B. Kaisere67842a2009-04-04 20:13:23 +000097 try:
98 assert(len(sys.argv) > 1)
99 port = int(sys.argv[-1])
100 except:
Kurt B. Kaiser8fc98c32009-04-04 20:20:29 +0000101 print("IDLE Subprocess: no IP port passed in sys.argv.",
102 file=sys.__stderr__)
Kurt B. Kaisere67842a2009-04-04 20:13:23 +0000103 return
Terry Jan Reedy95a3f112013-06-28 23:50:12 -0400104
105 capture_warnings(True)
Chui Tey5d2af632002-05-26 13:36:41 +0000106 sys.argv[:] = [""]
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +0000107 sockthread = threading.Thread(target=manage_socket,
108 name='SockThread',
Kurt B. Kaiser24d7e0c2003-06-05 23:51:29 +0000109 args=((LOCALHOST, port),))
Benjamin Peterson71088cc2008-09-19 21:49:37 +0000110 sockthread.daemon = True
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +0000111 sockthread.start()
112 while 1:
113 try:
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000114 if exit_now:
115 try:
Kurt B. Kaiser62df0442003-05-28 01:47:46 +0000116 exit()
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000117 except KeyboardInterrupt:
118 # exiting but got an extra KBI? Try again!
119 continue
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000120 try:
Kurt B. Kaiser20345fb2005-05-05 23:29:54 +0000121 seq, request = rpc.request_queue.get(block=True, timeout=0.05)
Alexandre Vassalottif260e442008-05-11 19:59:59 +0000122 except queue.Empty:
Andrew Svetlova2251aa2012-03-13 18:36:13 -0700123 handle_tk_events()
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000124 continue
125 method, args, kwargs = request
126 ret = method(*args, **kwargs)
127 rpc.response_queue.put((seq, ret))
Kurt B. Kaiseraa6b8562003-05-14 18:15:40 +0000128 except KeyboardInterrupt:
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000129 if quitting:
130 exit_now = True
Kurt B. Kaiseraa6b8562003-05-14 18:15:40 +0000131 continue
Kurt B. Kaisera2792be2003-05-17 21:04:10 +0000132 except SystemExit:
Terry Jan Reedy95a3f112013-06-28 23:50:12 -0400133 capture_warnings(False)
Kurt B. Kaisera2792be2003-05-17 21:04:10 +0000134 raise
Kurt B. Kaiser9ec454e2003-05-12 02:33:47 +0000135 except:
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000136 type, value, tb = sys.exc_info()
Kurt B. Kaisera2792be2003-05-17 21:04:10 +0000137 try:
138 print_exception()
139 rpc.response_queue.put((seq, None))
140 except:
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000141 # Link didn't work, print same exception to __stderr__
142 traceback.print_exception(type, value, tb, file=sys.__stderr__)
Kurt B. Kaiser62df0442003-05-28 01:47:46 +0000143 exit()
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000144 else:
145 continue
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +0000146
147def manage_socket(address):
Kurt B. Kaiseraf3eb872004-01-21 18:54:30 +0000148 for i in range(3):
Kurt B. Kaiserb4179362002-07-26 00:06:42 +0000149 time.sleep(i)
150 try:
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000151 server = MyRPCServer(address, MyHandler)
Kurt B. Kaiserb4179362002-07-26 00:06:42 +0000152 break
Andrew Svetlov0832af62012-12-18 23:10:48 +0200153 except OSError as err:
154 print("IDLE Subprocess: OSError: " + err.args[1] +
Georg Brandl6464d472007-10-22 16:16:13 +0000155 ", retrying....", file=sys.__stderr__)
Amaury Forgeot d'Arcefae8c42008-11-21 23:08:09 +0000156 socket_error = err
Kurt B. Kaiserb4179362002-07-26 00:06:42 +0000157 else:
Amaury Forgeot d'Arcefae8c42008-11-21 23:08:09 +0000158 print("IDLE Subprocess: Connection to "
159 "IDLE GUI failed, exiting.", file=sys.__stderr__)
160 show_socket_error(socket_error, address)
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000161 global exit_now
162 exit_now = True
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000163 return
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +0000164 server.handle_request() # A single request only
165
Kurt B. Kaiseraf3eb872004-01-21 18:54:30 +0000166def show_socket_error(err, address):
Georg Brandl14fc4272008-05-17 18:39:55 +0000167 import tkinter
168 import tkinter.messagebox as tkMessageBox
169 root = tkinter.Tk()
Kurt B. Kaiseraf3eb872004-01-21 18:54:30 +0000170 root.withdraw()
Georg Brandl6464d472007-10-22 16:16:13 +0000171 if err.args[0] == 61: # connection refused
Kurt B. Kaiseraf3eb872004-01-21 18:54:30 +0000172 msg = "IDLE's subprocess can't connect to %s:%d. This may be due "\
173 "to your personal firewall configuration. It is safe to "\
174 "allow this internal connection because no data is visible on "\
175 "external ports." % address
176 tkMessageBox.showerror("IDLE Subprocess Error", msg, parent=root)
177 else:
Georg Brandl6464d472007-10-22 16:16:13 +0000178 tkMessageBox.showerror("IDLE Subprocess Error",
179 "Socket Error: %s" % err.args[1])
Kurt B. Kaiseraf3eb872004-01-21 18:54:30 +0000180 root.destroy()
181
Kurt B. Kaiser9ec454e2003-05-12 02:33:47 +0000182def print_exception():
Kurt B. Kaisere9802a32004-01-02 04:04:04 +0000183 import linecache
184 linecache.checkcache()
Kurt B. Kaiser9ec454e2003-05-12 02:33:47 +0000185 flush_stdout()
186 efile = sys.stderr
Kurt B. Kaiser924f6162003-11-19 04:52:32 +0000187 typ, val, tb = excinfo = sys.exc_info()
188 sys.last_type, sys.last_value, sys.last_traceback = excinfo
Serhiy Storchaka78470b42013-01-09 12:21:57 +0200189 seen = set()
190
191 def print_exc(typ, exc, tb):
192 seen.add(exc)
193 context = exc.__context__
194 cause = exc.__cause__
195 if cause is not None and cause not in seen:
196 print_exc(type(cause), cause, cause.__traceback__)
197 print("\nThe above exception was the direct cause "
198 "of the following exception:\n", file=efile)
Serhiy Storchaka71317492013-01-09 12:24:48 +0200199 elif (context is not None and
200 not exc.__suppress_context__ and
201 context not in seen):
Serhiy Storchaka78470b42013-01-09 12:21:57 +0200202 print_exc(type(context), context, context.__traceback__)
203 print("\nDuring handling of the above exception, "
204 "another exception occurred:\n", file=efile)
205 if tb:
206 tbe = traceback.extract_tb(tb)
207 print('Traceback (most recent call last):', file=efile)
208 exclude = ("run.py", "rpc.py", "threading.py", "queue.py",
209 "RemoteDebugger.py", "bdb.py")
210 cleanup_traceback(tbe, exclude)
211 traceback.print_list(tbe, file=efile)
212 lines = traceback.format_exception_only(typ, exc)
213 for line in lines:
214 print(line, end='', file=efile)
215
216 print_exc(typ, val, tb)
Kurt B. Kaiser9ec454e2003-05-12 02:33:47 +0000217
218def cleanup_traceback(tb, exclude):
219 "Remove excluded traces from beginning/end of tb; get cached lines"
220 orig_tb = tb[:]
221 while tb:
222 for rpcfile in exclude:
223 if tb[0][0].count(rpcfile):
224 break # found an exclude, break for: and delete tb[0]
225 else:
226 break # no excludes, have left RPC code, break while:
227 del tb[0]
228 while tb:
229 for rpcfile in exclude:
230 if tb[-1][0].count(rpcfile):
231 break
232 else:
233 break
234 del tb[-1]
235 if len(tb) == 0:
236 # exception was in IDLE internals, don't prune!
237 tb[:] = orig_tb[:]
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000238 print("** IDLE Internal Exception: ", file=sys.stderr)
Kurt B. Kaiser9ec454e2003-05-12 02:33:47 +0000239 rpchandler = rpc.objecttable['exec'].rpchandler
240 for i in range(len(tb)):
241 fn, ln, nm, line = tb[i]
242 if nm == '?':
243 nm = "-toplevel-"
244 if not line and fn.startswith("<pyshell#"):
245 line = rpchandler.remotecall('linecache', 'getline',
246 (fn, ln), {})
247 tb[i] = fn, ln, nm, line
248
249def flush_stdout():
Guido van Rossum79139b22007-02-09 23:20:19 +0000250 """XXX How to do this now?"""
Kurt B. Kaiser9ec454e2003-05-12 02:33:47 +0000251
Kurt B. Kaiser62df0442003-05-28 01:47:46 +0000252def exit():
Guido van Rossumc76a2502007-08-09 14:26:58 +0000253 """Exit subprocess, possibly after first clearing exit functions.
Kurt B. Kaiser62df0442003-05-28 01:47:46 +0000254
255 If config-main.cfg/.def 'General' 'delete-exitfunc' is True, then any
Guido van Rossumc76a2502007-08-09 14:26:58 +0000256 functions registered with atexit will be removed before exiting.
257 (VPython support)
Kurt B. Kaiser62df0442003-05-28 01:47:46 +0000258
259 """
260 if no_exitfunc:
Guido van Rossumc76a2502007-08-09 14:26:58 +0000261 import atexit
262 atexit._clear()
Terry Jan Reedy95a3f112013-06-28 23:50:12 -0400263 capture_warnings(False)
Kurt B. Kaiser62df0442003-05-28 01:47:46 +0000264 sys.exit(0)
Chui Tey5d2af632002-05-26 13:36:41 +0000265
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000266class MyRPCServer(rpc.RPCServer):
267
268 def handle_error(self, request, client_address):
269 """Override RPCServer method for IDLE
270
271 Interrupt the MainThread and exit server if link is dropped.
272
273 """
Kurt B. Kaisere9535112004-11-19 15:46:49 +0000274 global quitting
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000275 try:
276 raise
277 except SystemExit:
278 raise
279 except EOFError:
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000280 global exit_now
281 exit_now = True
Kurt B. Kaiser93e8e542003-06-13 22:03:43 +0000282 thread.interrupt_main()
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000283 except:
284 erf = sys.__stderr__
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000285 print('\n' + '-'*40, file=erf)
286 print('Unhandled server exception!', file=erf)
Amaury Forgeot d'Arcbed17102008-11-29 01:48:47 +0000287 print('Thread: %s' % threading.current_thread().name, file=erf)
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000288 print('Client Address: ', client_address, file=erf)
289 print('Request: ', repr(request), file=erf)
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000290 traceback.print_exc(file=erf)
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000291 print('\n*** Unrecoverable, server exiting!', file=erf)
292 print('-'*40, file=erf)
Kurt B. Kaisere9535112004-11-19 15:46:49 +0000293 quitting = True
294 thread.interrupt_main()
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000295
Chui Tey5d2af632002-05-26 13:36:41 +0000296class MyHandler(rpc.RPCHandler):
297
298 def handle(self):
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +0000299 """Override base method"""
Chui Tey5d2af632002-05-26 13:36:41 +0000300 executive = Executive(self)
301 self.register("exec", executive)
Serhiy Storchaka39e70a42013-01-25 15:30:58 +0200302 self.console = self.get_remote_proxy("console")
303 sys.stdin = PyShell.PseudoInputFile(self.console, "stdin",
304 IOBinding.encoding)
305 sys.stdout = PyShell.PseudoOutputFile(self.console, "stdout",
306 IOBinding.encoding)
307 sys.stderr = PyShell.PseudoOutputFile(self.console, "stderr",
308 IOBinding.encoding)
309
Andrew Svetlovcd49d532012-03-25 11:43:02 +0300310 sys.displayhook = rpc.displayhook
Kurt B. Kaiserf609a342007-12-28 03:57:56 +0000311 # page help() text to shell.
312 import pydoc # import must be done here to capture i/o binding
313 pydoc.pager = pydoc.plainpager
Benjamin Peterson0d4931e2013-05-11 22:24:28 -0500314
315 # Keep a reference to stdin so that it won't try to exit IDLE if
316 # sys.stdin gets changed from within IDLE's shell. See issue17838.
317 self._keep_stdin = sys.stdin
318
Kurt B. Kaiser9f366092003-06-02 01:50:19 +0000319 self.interp = self.get_remote_proxy("interp")
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000320 rpc.RPCHandler.getresponse(self, myseq=None, wait=0.05)
321
322 def exithook(self):
323 "override SocketIO method - wait for MainThread to shut us down"
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000324 time.sleep(10)
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000325
326 def EOFhook(self):
327 "Override SocketIO method - terminate wait on callback and exit thread"
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000328 global quitting
329 quitting = True
Kurt B. Kaiser93e8e542003-06-13 22:03:43 +0000330 thread.interrupt_main()
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000331
332 def decode_interrupthook(self):
333 "interrupt awakened thread"
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000334 global quitting
335 quitting = True
Kurt B. Kaiser93e8e542003-06-13 22:03:43 +0000336 thread.interrupt_main()
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +0000337
Chui Tey5d2af632002-05-26 13:36:41 +0000338
Kurt B. Kaiserdcba6622004-12-21 22:10:32 +0000339class Executive(object):
Chui Tey5d2af632002-05-26 13:36:41 +0000340
341 def __init__(self, rpchandler):
Kurt B. Kaiserffd3a422002-06-26 02:32:09 +0000342 self.rpchandler = rpchandler
Kurt B. Kaiseradc63842002-08-25 14:08:07 +0000343 self.locals = __main__.__dict__
Kurt B. Kaiser5afa1df2002-10-10 08:25:24 +0000344 self.calltip = CallTips.CallTips()
Kurt B. Kaiserb1754452005-11-18 22:05:48 +0000345 self.autocomplete = AutoComplete.AutoComplete()
Chui Tey5d2af632002-05-26 13:36:41 +0000346
347 def runcode(self, code):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000348 global interruptable
Kurt B. Kaiser86bc4642003-02-27 23:04:17 +0000349 try:
Kurt B. Kaiser9f366092003-06-02 01:50:19 +0000350 self.usr_exc_info = None
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000351 interruptable = True
352 try:
353 exec(code, self.locals)
354 finally:
355 interruptable = False
Roger Serwyf4675212013-06-11 22:25:14 -0500356 except SystemExit:
357 # Scripts that raise SystemExit should just
358 # return to the interactive prompt
359 pass
Kurt B. Kaiser86bc4642003-02-27 23:04:17 +0000360 except:
Kurt B. Kaiser9f366092003-06-02 01:50:19 +0000361 self.usr_exc_info = sys.exc_info()
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000362 if quitting:
Kurt B. Kaiser62df0442003-05-28 01:47:46 +0000363 exit()
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000364 # even print a user code SystemExit exception, continue
365 print_exception()
Kurt B. Kaiser9f366092003-06-02 01:50:19 +0000366 jit = self.rpchandler.console.getvar("<<toggle-jit-stack-viewer>>")
367 if jit:
368 self.rpchandler.interp.open_remote_stack_viewer()
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +0000369 else:
Kurt B. Kaiser9ec454e2003-05-12 02:33:47 +0000370 flush_stdout()
Chui Tey5d2af632002-05-26 13:36:41 +0000371
Kurt B. Kaiser003091c2003-02-17 18:57:16 +0000372 def interrupt_the_server(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000373 if interruptable:
374 thread.interrupt_main()
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +0000375
Kurt B. Kaiser0e3a5772002-06-16 03:32:24 +0000376 def start_the_debugger(self, gui_adap_oid):
Kurt B. Kaiserffd3a422002-06-26 02:32:09 +0000377 return RemoteDebugger.start_debugger(self.rpchandler, gui_adap_oid)
378
379 def stop_the_debugger(self, idb_adap_oid):
380 "Unregister the Idb Adapter. Link objects and Idb then subject to GC"
381 self.rpchandler.unregister(idb_adap_oid)
Chui Tey5d2af632002-05-26 13:36:41 +0000382
Kurt B. Kaiser5afa1df2002-10-10 08:25:24 +0000383 def get_the_calltip(self, name):
384 return self.calltip.fetch_tip(name)
385
Kurt B. Kaiserb1754452005-11-18 22:05:48 +0000386 def get_the_completion_list(self, what, mode):
387 return self.autocomplete.fetch_completions(what, mode)
388
Chui Tey5d2af632002-05-26 13:36:41 +0000389 def stackviewer(self, flist_oid=None):
Kurt B. Kaiser9f366092003-06-02 01:50:19 +0000390 if self.usr_exc_info:
391 typ, val, tb = self.usr_exc_info
392 else:
Chui Tey5d2af632002-05-26 13:36:41 +0000393 return None
394 flist = None
395 if flist_oid is not None:
Kurt B. Kaiserffd3a422002-06-26 02:32:09 +0000396 flist = self.rpchandler.get_remote_proxy(flist_oid)
Chui Tey5d2af632002-05-26 13:36:41 +0000397 while tb and tb.tb_frame.f_globals["__name__"] in ["rpc", "run"]:
398 tb = tb.tb_next
Kurt B. Kaiser9f366092003-06-02 01:50:19 +0000399 sys.last_type = typ
400 sys.last_value = val
Chui Tey5d2af632002-05-26 13:36:41 +0000401 item = StackViewer.StackTreeItem(flist, tb)
402 return RemoteObjectBrowser.remote_object_tree_item(item)
Terry Jan Reedy95a3f112013-06-28 23:50:12 -0400403
404capture_warnings(False) # Make sure turned off; see issue 18081