blob: afa9744a346c92bd0c071259b930af3772a429e9 [file] [log] [blame]
Terry Jan Reedy6cf0e132016-07-15 02:43:03 -04001import io
Kurt B. Kaiser49a5fe12004-07-04 01:25:56 +00002import linecache
Terry Jan Reedy6cf0e132016-07-15 02:43:03 -04003import queue
4import sys
Terry Jan Reedy6cf0e132016-07-15 02:43:03 -04005import time
6import traceback
Terry Jan Reedybfbaa6b2016-08-31 00:50:55 -04007import _thread as thread
8import threading
9import warnings
Kurt B. Kaiser5afa1df2002-10-10 08:25:24 +000010
Terry Jan Reedybfbaa6b2016-08-31 00:50:55 -040011import tkinter # Tcl, deletions, messagebox if startup fails
Kurt B. Kaiserb1754452005-11-18 22:05:48 +000012
Terry Jan Reedybfbaa6b2016-08-31 00:50:55 -040013from idlelib import autocomplete # AutoComplete, fetch_encodings
14from idlelib import calltips # CallTips
15from idlelib import debugger_r # start_debugger
16from idlelib import debugobj_r # remote_object_tree_item
17from idlelib import iomenu # encoding
18from idlelib import rpc # multiple objects
19from idlelib import stackviewer # StackTreeItem
Kurt B. Kaiser5afa1df2002-10-10 08:25:24 +000020import __main__
21
Terry Jan Reedyff1d5ab2016-07-16 18:26:32 -040022for mod in ('simpledialog', 'messagebox', 'font',
23 'dialog', 'filedialog', 'commondialog',
Terry Jan Reedy41bc0672016-07-16 18:27:11 -040024 'ttk'):
Terry Jan Reedyff1d5ab2016-07-16 18:26:32 -040025 delattr(tkinter, mod)
26 del sys.modules['tkinter.' + mod]
27
Kurt B. Kaiser24d7e0c2003-06-05 23:51:29 +000028LOCALHOST = '127.0.0.1'
29
Kurt B. Kaiser49a5fe12004-07-04 01:25:56 +000030
Terry Jan Reedy6cf0e132016-07-15 02:43:03 -040031def idle_formatwarning(message, category, filename, lineno, line=None):
32 """Format warnings the IDLE way."""
33
34 s = "\nWarning (from warnings module):\n"
35 s += ' File \"%s\", line %s\n' % (filename, lineno)
36 if line is None:
37 line = linecache.getline(filename, lineno)
38 line = line.strip()
39 if line:
40 s += " %s\n" % line
41 s += "%s: %s\n" % (category.__name__, message)
42 return s
43
Terry Jan Reedy95a3f112013-06-28 23:50:12 -040044def idle_showwarning_subproc(
45 message, category, filename, lineno, file=None, line=None):
46 """Show Idle-format warning after replacing warnings.showwarning.
Andrew Svetlova2251aa2012-03-13 18:36:13 -070047
Terry Jan Reedy95a3f112013-06-28 23:50:12 -040048 The only difference is the formatter called.
49 """
50 if file is None:
51 file = sys.stderr
52 try:
Terry Jan Reedy6cf0e132016-07-15 02:43:03 -040053 file.write(idle_formatwarning(
Terry Jan Reedy95a3f112013-06-28 23:50:12 -040054 message, category, filename, lineno, line))
55 except IOError:
56 pass # the file (probably stderr) is invalid - this warning gets lost.
57
58_warnings_showwarning = None
59
60def capture_warnings(capture):
61 "Replace warning.showwarning with idle_showwarning_subproc, or reverse."
62
63 global _warnings_showwarning
64 if capture:
65 if _warnings_showwarning is None:
66 _warnings_showwarning = warnings.showwarning
67 warnings.showwarning = idle_showwarning_subproc
68 else:
69 if _warnings_showwarning is not None:
70 warnings.showwarning = _warnings_showwarning
71 _warnings_showwarning = None
72
73capture_warnings(True)
Andrew Svetlov753445a2012-03-26 21:56:44 +030074tcl = tkinter.Tcl()
75
Andrew Svetlov753445a2012-03-26 21:56:44 +030076def handle_tk_events(tcl=tcl):
Andrew Svetlova2251aa2012-03-13 18:36:13 -070077 """Process any tk events that are ready to be dispatched if tkinter
78 has been imported, a tcl interpreter has been created and tk has been
79 loaded."""
Andrew Svetlov753445a2012-03-26 21:56:44 +030080 tcl.eval("update")
Andrew Svetlova2251aa2012-03-13 18:36:13 -070081
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +000082# Thread shared globals: Establish a queue between a subthread (which handles
83# the socket) and the main thread (which runs user code), plus global
Guido van Rossum8ce8a782007-11-01 19:42:39 +000084# completion, exit and interruptable (the main thread) flags:
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +000085
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +000086exit_now = False
87quitting = False
Guido van Rossum8ce8a782007-11-01 19:42:39 +000088interruptable = False
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +000089
Kurt B. Kaiser62df0442003-05-28 01:47:46 +000090def main(del_exitfunc=False):
Kurt B. Kaiserb4179362002-07-26 00:06:42 +000091 """Start the Python execution server in a subprocess
92
Kurt B. Kaiser5afa1df2002-10-10 08:25:24 +000093 In the Python subprocess, RPCServer is instantiated with handlerclass
94 MyHandler, which inherits register/unregister methods from RPCHandler via
95 the mix-in class SocketIO.
Kurt B. Kaiserb4179362002-07-26 00:06:42 +000096
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +000097 When the RPCServer 'server' is instantiated, the TCPServer initialization
Kurt B. Kaiser5afa1df2002-10-10 08:25:24 +000098 creates an instance of run.MyHandler and calls its handle() method.
99 handle() instantiates a run.Executive object, passing it a reference to the
100 MyHandler object. That reference is saved as attribute rpchandler of the
101 Executive instance. The Executive methods have access to the reference and
102 can pass it on to entities that they command
Terry Jan Reedy6fa5bdc2016-05-28 13:22:31 -0400103 (e.g. debugger_r.Debugger.start_debugger()). The latter, in turn, can
Kurt B. Kaiser5afa1df2002-10-10 08:25:24 +0000104 call MyHandler(SocketIO) register/unregister methods via the reference to
105 register and unregister themselves.
Kurt B. Kaiserb4179362002-07-26 00:06:42 +0000106
107 """
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000108 global exit_now
109 global quitting
Kurt B. Kaiser62df0442003-05-28 01:47:46 +0000110 global no_exitfunc
111 no_exitfunc = del_exitfunc
Kurt B. Kaiseraf3eb872004-01-21 18:54:30 +0000112 #time.sleep(15) # test subprocess not responding
Kurt B. Kaisere67842a2009-04-04 20:13:23 +0000113 try:
114 assert(len(sys.argv) > 1)
115 port = int(sys.argv[-1])
116 except:
Kurt B. Kaiser8fc98c32009-04-04 20:20:29 +0000117 print("IDLE Subprocess: no IP port passed in sys.argv.",
118 file=sys.__stderr__)
Kurt B. Kaisere67842a2009-04-04 20:13:23 +0000119 return
Terry Jan Reedy95a3f112013-06-28 23:50:12 -0400120
121 capture_warnings(True)
Chui Tey5d2af632002-05-26 13:36:41 +0000122 sys.argv[:] = [""]
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +0000123 sockthread = threading.Thread(target=manage_socket,
124 name='SockThread',
Kurt B. Kaiser24d7e0c2003-06-05 23:51:29 +0000125 args=((LOCALHOST, port),))
Benjamin Peterson71088cc2008-09-19 21:49:37 +0000126 sockthread.daemon = True
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +0000127 sockthread.start()
128 while 1:
129 try:
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000130 if exit_now:
131 try:
Kurt B. Kaiser62df0442003-05-28 01:47:46 +0000132 exit()
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000133 except KeyboardInterrupt:
134 # exiting but got an extra KBI? Try again!
135 continue
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000136 try:
Kurt B. Kaiser20345fb2005-05-05 23:29:54 +0000137 seq, request = rpc.request_queue.get(block=True, timeout=0.05)
Alexandre Vassalottif260e442008-05-11 19:59:59 +0000138 except queue.Empty:
Andrew Svetlova2251aa2012-03-13 18:36:13 -0700139 handle_tk_events()
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000140 continue
141 method, args, kwargs = request
142 ret = method(*args, **kwargs)
143 rpc.response_queue.put((seq, ret))
Kurt B. Kaiseraa6b8562003-05-14 18:15:40 +0000144 except KeyboardInterrupt:
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000145 if quitting:
146 exit_now = True
Kurt B. Kaiseraa6b8562003-05-14 18:15:40 +0000147 continue
Kurt B. Kaisera2792be2003-05-17 21:04:10 +0000148 except SystemExit:
Terry Jan Reedy95a3f112013-06-28 23:50:12 -0400149 capture_warnings(False)
Kurt B. Kaisera2792be2003-05-17 21:04:10 +0000150 raise
Kurt B. Kaiser9ec454e2003-05-12 02:33:47 +0000151 except:
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000152 type, value, tb = sys.exc_info()
Kurt B. Kaisera2792be2003-05-17 21:04:10 +0000153 try:
154 print_exception()
155 rpc.response_queue.put((seq, None))
156 except:
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000157 # Link didn't work, print same exception to __stderr__
158 traceback.print_exception(type, value, tb, file=sys.__stderr__)
Kurt B. Kaiser62df0442003-05-28 01:47:46 +0000159 exit()
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000160 else:
161 continue
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +0000162
163def manage_socket(address):
Kurt B. Kaiseraf3eb872004-01-21 18:54:30 +0000164 for i in range(3):
Kurt B. Kaiserb4179362002-07-26 00:06:42 +0000165 time.sleep(i)
166 try:
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000167 server = MyRPCServer(address, MyHandler)
Kurt B. Kaiserb4179362002-07-26 00:06:42 +0000168 break
Andrew Svetlov0832af62012-12-18 23:10:48 +0200169 except OSError as err:
170 print("IDLE Subprocess: OSError: " + err.args[1] +
Georg Brandl6464d472007-10-22 16:16:13 +0000171 ", retrying....", file=sys.__stderr__)
Amaury Forgeot d'Arcefae8c42008-11-21 23:08:09 +0000172 socket_error = err
Kurt B. Kaiserb4179362002-07-26 00:06:42 +0000173 else:
Amaury Forgeot d'Arcefae8c42008-11-21 23:08:09 +0000174 print("IDLE Subprocess: Connection to "
175 "IDLE GUI failed, exiting.", file=sys.__stderr__)
176 show_socket_error(socket_error, address)
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000177 global exit_now
178 exit_now = True
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000179 return
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +0000180 server.handle_request() # A single request only
181
Kurt B. Kaiseraf3eb872004-01-21 18:54:30 +0000182def show_socket_error(err, address):
Georg Brandl14fc4272008-05-17 18:39:55 +0000183 import tkinter
184 import tkinter.messagebox as tkMessageBox
185 root = tkinter.Tk()
Kurt B. Kaiseraf3eb872004-01-21 18:54:30 +0000186 root.withdraw()
Georg Brandl6464d472007-10-22 16:16:13 +0000187 if err.args[0] == 61: # connection refused
Kurt B. Kaiseraf3eb872004-01-21 18:54:30 +0000188 msg = "IDLE's subprocess can't connect to %s:%d. This may be due "\
189 "to your personal firewall configuration. It is safe to "\
190 "allow this internal connection because no data is visible on "\
191 "external ports." % address
192 tkMessageBox.showerror("IDLE Subprocess Error", msg, parent=root)
193 else:
Georg Brandl6464d472007-10-22 16:16:13 +0000194 tkMessageBox.showerror("IDLE Subprocess Error",
Terry Jan Reedy3be2e542015-09-25 22:22:55 -0400195 "Socket Error: %s" % err.args[1], parent=root)
Kurt B. Kaiseraf3eb872004-01-21 18:54:30 +0000196 root.destroy()
197
Kurt B. Kaiser9ec454e2003-05-12 02:33:47 +0000198def print_exception():
Kurt B. Kaisere9802a32004-01-02 04:04:04 +0000199 import linecache
200 linecache.checkcache()
Kurt B. Kaiser9ec454e2003-05-12 02:33:47 +0000201 flush_stdout()
202 efile = sys.stderr
Kurt B. Kaiser924f6162003-11-19 04:52:32 +0000203 typ, val, tb = excinfo = sys.exc_info()
204 sys.last_type, sys.last_value, sys.last_traceback = excinfo
Serhiy Storchaka78470b42013-01-09 12:21:57 +0200205 seen = set()
206
207 def print_exc(typ, exc, tb):
208 seen.add(exc)
209 context = exc.__context__
210 cause = exc.__cause__
211 if cause is not None and cause not in seen:
212 print_exc(type(cause), cause, cause.__traceback__)
213 print("\nThe above exception was the direct cause "
214 "of the following exception:\n", file=efile)
Serhiy Storchaka71317492013-01-09 12:24:48 +0200215 elif (context is not None and
216 not exc.__suppress_context__ and
217 context not in seen):
Serhiy Storchaka78470b42013-01-09 12:21:57 +0200218 print_exc(type(context), context, context.__traceback__)
219 print("\nDuring handling of the above exception, "
220 "another exception occurred:\n", file=efile)
221 if tb:
222 tbe = traceback.extract_tb(tb)
223 print('Traceback (most recent call last):', file=efile)
224 exclude = ("run.py", "rpc.py", "threading.py", "queue.py",
Terry Jan Reedy6fa5bdc2016-05-28 13:22:31 -0400225 "debugger_r.py", "bdb.py")
Serhiy Storchaka78470b42013-01-09 12:21:57 +0200226 cleanup_traceback(tbe, exclude)
227 traceback.print_list(tbe, file=efile)
228 lines = traceback.format_exception_only(typ, exc)
229 for line in lines:
230 print(line, end='', file=efile)
231
232 print_exc(typ, val, tb)
Kurt B. Kaiser9ec454e2003-05-12 02:33:47 +0000233
234def cleanup_traceback(tb, exclude):
235 "Remove excluded traces from beginning/end of tb; get cached lines"
236 orig_tb = tb[:]
237 while tb:
238 for rpcfile in exclude:
239 if tb[0][0].count(rpcfile):
240 break # found an exclude, break for: and delete tb[0]
241 else:
242 break # no excludes, have left RPC code, break while:
243 del tb[0]
244 while tb:
245 for rpcfile in exclude:
246 if tb[-1][0].count(rpcfile):
247 break
248 else:
249 break
250 del tb[-1]
251 if len(tb) == 0:
252 # exception was in IDLE internals, don't prune!
253 tb[:] = orig_tb[:]
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000254 print("** IDLE Internal Exception: ", file=sys.stderr)
Kurt B. Kaiser9ec454e2003-05-12 02:33:47 +0000255 rpchandler = rpc.objecttable['exec'].rpchandler
256 for i in range(len(tb)):
257 fn, ln, nm, line = tb[i]
258 if nm == '?':
259 nm = "-toplevel-"
260 if not line and fn.startswith("<pyshell#"):
261 line = rpchandler.remotecall('linecache', 'getline',
262 (fn, ln), {})
263 tb[i] = fn, ln, nm, line
264
265def flush_stdout():
Guido van Rossum79139b22007-02-09 23:20:19 +0000266 """XXX How to do this now?"""
Kurt B. Kaiser9ec454e2003-05-12 02:33:47 +0000267
Kurt B. Kaiser62df0442003-05-28 01:47:46 +0000268def exit():
Guido van Rossumc76a2502007-08-09 14:26:58 +0000269 """Exit subprocess, possibly after first clearing exit functions.
Kurt B. Kaiser62df0442003-05-28 01:47:46 +0000270
271 If config-main.cfg/.def 'General' 'delete-exitfunc' is True, then any
Guido van Rossumc76a2502007-08-09 14:26:58 +0000272 functions registered with atexit will be removed before exiting.
273 (VPython support)
Kurt B. Kaiser62df0442003-05-28 01:47:46 +0000274
275 """
276 if no_exitfunc:
Guido van Rossumc76a2502007-08-09 14:26:58 +0000277 import atexit
278 atexit._clear()
Terry Jan Reedy95a3f112013-06-28 23:50:12 -0400279 capture_warnings(False)
Kurt B. Kaiser62df0442003-05-28 01:47:46 +0000280 sys.exit(0)
Chui Tey5d2af632002-05-26 13:36:41 +0000281
Terry Jan Reedybfbaa6b2016-08-31 00:50:55 -0400282
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000283class MyRPCServer(rpc.RPCServer):
284
285 def handle_error(self, request, client_address):
286 """Override RPCServer method for IDLE
287
288 Interrupt the MainThread and exit server if link is dropped.
289
290 """
Kurt B. Kaisere9535112004-11-19 15:46:49 +0000291 global quitting
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000292 try:
293 raise
294 except SystemExit:
295 raise
296 except EOFError:
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000297 global exit_now
298 exit_now = True
Kurt B. Kaiser93e8e542003-06-13 22:03:43 +0000299 thread.interrupt_main()
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000300 except:
301 erf = sys.__stderr__
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000302 print('\n' + '-'*40, file=erf)
303 print('Unhandled server exception!', file=erf)
Amaury Forgeot d'Arcbed17102008-11-29 01:48:47 +0000304 print('Thread: %s' % threading.current_thread().name, file=erf)
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000305 print('Client Address: ', client_address, file=erf)
306 print('Request: ', repr(request), file=erf)
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000307 traceback.print_exc(file=erf)
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000308 print('\n*** Unrecoverable, server exiting!', file=erf)
309 print('-'*40, file=erf)
Kurt B. Kaisere9535112004-11-19 15:46:49 +0000310 quitting = True
311 thread.interrupt_main()
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000312
Terry Jan Reedy6cf0e132016-07-15 02:43:03 -0400313
314# Pseudofiles for shell-remote communication (also used in pyshell)
315
316class PseudoFile(io.TextIOBase):
317
318 def __init__(self, shell, tags, encoding=None):
319 self.shell = shell
320 self.tags = tags
321 self._encoding = encoding
322
323 @property
324 def encoding(self):
325 return self._encoding
326
327 @property
328 def name(self):
329 return '<%s>' % self.tags
330
331 def isatty(self):
332 return True
333
334
335class PseudoOutputFile(PseudoFile):
336
337 def writable(self):
338 return True
339
340 def write(self, s):
341 if self.closed:
342 raise ValueError("write to closed file")
343 if type(s) is not str:
344 if not isinstance(s, str):
345 raise TypeError('must be str, not ' + type(s).__name__)
346 # See issue #19481
347 s = str.__str__(s)
348 return self.shell.write(s, self.tags)
349
350
351class PseudoInputFile(PseudoFile):
352
353 def __init__(self, shell, tags, encoding=None):
354 PseudoFile.__init__(self, shell, tags, encoding)
355 self._line_buffer = ''
356
357 def readable(self):
358 return True
359
360 def read(self, size=-1):
361 if self.closed:
362 raise ValueError("read from closed file")
363 if size is None:
364 size = -1
365 elif not isinstance(size, int):
366 raise TypeError('must be int, not ' + type(size).__name__)
367 result = self._line_buffer
368 self._line_buffer = ''
369 if size < 0:
370 while True:
371 line = self.shell.readline()
372 if not line: break
373 result += line
374 else:
375 while len(result) < size:
376 line = self.shell.readline()
377 if not line: break
378 result += line
379 self._line_buffer = result[size:]
380 result = result[:size]
381 return result
382
383 def readline(self, size=-1):
384 if self.closed:
385 raise ValueError("read from closed file")
386 if size is None:
387 size = -1
388 elif not isinstance(size, int):
389 raise TypeError('must be int, not ' + type(size).__name__)
390 line = self._line_buffer or self.shell.readline()
391 if size < 0:
392 size = len(line)
393 eol = line.find('\n', 0, size)
394 if eol >= 0:
395 size = eol + 1
396 self._line_buffer = line[size:]
397 return line[:size]
398
399 def close(self):
400 self.shell.close()
401
402
Chui Tey5d2af632002-05-26 13:36:41 +0000403class MyHandler(rpc.RPCHandler):
404
405 def handle(self):
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +0000406 """Override base method"""
Chui Tey5d2af632002-05-26 13:36:41 +0000407 executive = Executive(self)
408 self.register("exec", executive)
Serhiy Storchaka39e70a42013-01-25 15:30:58 +0200409 self.console = self.get_remote_proxy("console")
Terry Jan Reedy6cf0e132016-07-15 02:43:03 -0400410 sys.stdin = PseudoInputFile(self.console, "stdin",
Terry Jan Reedy6fa5bdc2016-05-28 13:22:31 -0400411 iomenu.encoding)
Terry Jan Reedy6cf0e132016-07-15 02:43:03 -0400412 sys.stdout = PseudoOutputFile(self.console, "stdout",
Terry Jan Reedy6fa5bdc2016-05-28 13:22:31 -0400413 iomenu.encoding)
Terry Jan Reedy6cf0e132016-07-15 02:43:03 -0400414 sys.stderr = PseudoOutputFile(self.console, "stderr",
Terry Jan Reedy6fa5bdc2016-05-28 13:22:31 -0400415 iomenu.encoding)
Serhiy Storchaka39e70a42013-01-25 15:30:58 +0200416
Andrew Svetlovcd49d532012-03-25 11:43:02 +0300417 sys.displayhook = rpc.displayhook
Kurt B. Kaiserf609a342007-12-28 03:57:56 +0000418 # page help() text to shell.
419 import pydoc # import must be done here to capture i/o binding
420 pydoc.pager = pydoc.plainpager
Benjamin Peterson0d4931e2013-05-11 22:24:28 -0500421
422 # Keep a reference to stdin so that it won't try to exit IDLE if
423 # sys.stdin gets changed from within IDLE's shell. See issue17838.
424 self._keep_stdin = sys.stdin
425
Kurt B. Kaiser9f366092003-06-02 01:50:19 +0000426 self.interp = self.get_remote_proxy("interp")
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000427 rpc.RPCHandler.getresponse(self, myseq=None, wait=0.05)
428
429 def exithook(self):
430 "override SocketIO method - wait for MainThread to shut us down"
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000431 time.sleep(10)
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000432
433 def EOFhook(self):
434 "Override SocketIO method - terminate wait on callback and exit thread"
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000435 global quitting
436 quitting = True
Kurt B. Kaiser93e8e542003-06-13 22:03:43 +0000437 thread.interrupt_main()
Kurt B. Kaisera00050f2003-05-08 20:26:55 +0000438
439 def decode_interrupthook(self):
440 "interrupt awakened thread"
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000441 global quitting
442 quitting = True
Kurt B. Kaiser93e8e542003-06-13 22:03:43 +0000443 thread.interrupt_main()
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +0000444
Chui Tey5d2af632002-05-26 13:36:41 +0000445
Kurt B. Kaiserdcba6622004-12-21 22:10:32 +0000446class Executive(object):
Chui Tey5d2af632002-05-26 13:36:41 +0000447
448 def __init__(self, rpchandler):
Kurt B. Kaiserffd3a422002-06-26 02:32:09 +0000449 self.rpchandler = rpchandler
Kurt B. Kaiseradc63842002-08-25 14:08:07 +0000450 self.locals = __main__.__dict__
Terry Jan Reedy6fa5bdc2016-05-28 13:22:31 -0400451 self.calltip = calltips.CallTips()
452 self.autocomplete = autocomplete.AutoComplete()
Chui Tey5d2af632002-05-26 13:36:41 +0000453
454 def runcode(self, code):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000455 global interruptable
Kurt B. Kaiser86bc4642003-02-27 23:04:17 +0000456 try:
Kurt B. Kaiser9f366092003-06-02 01:50:19 +0000457 self.usr_exc_info = None
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000458 interruptable = True
459 try:
460 exec(code, self.locals)
461 finally:
462 interruptable = False
Roger Serwyf4675212013-06-11 22:25:14 -0500463 except SystemExit:
464 # Scripts that raise SystemExit should just
465 # return to the interactive prompt
466 pass
Kurt B. Kaiser86bc4642003-02-27 23:04:17 +0000467 except:
Kurt B. Kaiser9f366092003-06-02 01:50:19 +0000468 self.usr_exc_info = sys.exc_info()
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000469 if quitting:
Kurt B. Kaiser62df0442003-05-28 01:47:46 +0000470 exit()
Kurt B. Kaiser67fd0ea2003-05-24 20:59:15 +0000471 # even print a user code SystemExit exception, continue
472 print_exception()
Kurt B. Kaiser9f366092003-06-02 01:50:19 +0000473 jit = self.rpchandler.console.getvar("<<toggle-jit-stack-viewer>>")
474 if jit:
475 self.rpchandler.interp.open_remote_stack_viewer()
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +0000476 else:
Kurt B. Kaiser9ec454e2003-05-12 02:33:47 +0000477 flush_stdout()
Chui Tey5d2af632002-05-26 13:36:41 +0000478
Kurt B. Kaiser003091c2003-02-17 18:57:16 +0000479 def interrupt_the_server(self):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000480 if interruptable:
481 thread.interrupt_main()
Kurt B. Kaiser11c53e22003-03-22 19:40:19 +0000482
Kurt B. Kaiser0e3a5772002-06-16 03:32:24 +0000483 def start_the_debugger(self, gui_adap_oid):
Terry Jan Reedy6fa5bdc2016-05-28 13:22:31 -0400484 return debugger_r.start_debugger(self.rpchandler, gui_adap_oid)
Kurt B. Kaiserffd3a422002-06-26 02:32:09 +0000485
486 def stop_the_debugger(self, idb_adap_oid):
487 "Unregister the Idb Adapter. Link objects and Idb then subject to GC"
488 self.rpchandler.unregister(idb_adap_oid)
Chui Tey5d2af632002-05-26 13:36:41 +0000489
Kurt B. Kaiser5afa1df2002-10-10 08:25:24 +0000490 def get_the_calltip(self, name):
491 return self.calltip.fetch_tip(name)
492
Kurt B. Kaiserb1754452005-11-18 22:05:48 +0000493 def get_the_completion_list(self, what, mode):
494 return self.autocomplete.fetch_completions(what, mode)
495
Chui Tey5d2af632002-05-26 13:36:41 +0000496 def stackviewer(self, flist_oid=None):
Kurt B. Kaiser9f366092003-06-02 01:50:19 +0000497 if self.usr_exc_info:
498 typ, val, tb = self.usr_exc_info
499 else:
Chui Tey5d2af632002-05-26 13:36:41 +0000500 return None
501 flist = None
502 if flist_oid is not None:
Kurt B. Kaiserffd3a422002-06-26 02:32:09 +0000503 flist = self.rpchandler.get_remote_proxy(flist_oid)
Chui Tey5d2af632002-05-26 13:36:41 +0000504 while tb and tb.tb_frame.f_globals["__name__"] in ["rpc", "run"]:
505 tb = tb.tb_next
Kurt B. Kaiser9f366092003-06-02 01:50:19 +0000506 sys.last_type = typ
507 sys.last_value = val
Terry Jan Reedy6fa5bdc2016-05-28 13:22:31 -0400508 item = stackviewer.StackTreeItem(flist, tb)
509 return debugobj_r.remote_object_tree_item(item)
Terry Jan Reedy95a3f112013-06-28 23:50:12 -0400510
511capture_warnings(False) # Make sure turned off; see issue 18081