Removed the Requirement to Install Python and NodeJS (Now Bundled with Borealis)
This commit is contained in:
653
Dependencies/Python/Lib/idlelib/run.py
vendored
Normal file
653
Dependencies/Python/Lib/idlelib/run.py
vendored
Normal file
@ -0,0 +1,653 @@
|
||||
""" idlelib.run
|
||||
|
||||
Simplified, pyshell.ModifiedInterpreter spawns a subprocess with
|
||||
f'''{sys.executable} -c "__import__('idlelib.run').run.main()"'''
|
||||
'.run' is needed because __import__ returns idlelib, not idlelib.run.
|
||||
"""
|
||||
import contextlib
|
||||
import functools
|
||||
import io
|
||||
import linecache
|
||||
import queue
|
||||
import sys
|
||||
import textwrap
|
||||
import time
|
||||
import traceback
|
||||
import _thread as thread
|
||||
import threading
|
||||
import warnings
|
||||
|
||||
import idlelib # testing
|
||||
from idlelib import autocomplete # AutoComplete, fetch_encodings
|
||||
from idlelib import calltip # Calltip
|
||||
from idlelib import debugger_r # start_debugger
|
||||
from idlelib import debugobj_r # remote_object_tree_item
|
||||
from idlelib import iomenu # encoding
|
||||
from idlelib import rpc # multiple objects
|
||||
from idlelib import stackviewer # StackTreeItem
|
||||
import __main__
|
||||
|
||||
import tkinter # Use tcl and, if startup fails, messagebox.
|
||||
if not hasattr(sys.modules['idlelib.run'], 'firstrun'):
|
||||
# Undo modifications of tkinter by idlelib imports; see bpo-25507.
|
||||
for mod in ('simpledialog', 'messagebox', 'font',
|
||||
'dialog', 'filedialog', 'commondialog',
|
||||
'ttk'):
|
||||
delattr(tkinter, mod)
|
||||
del sys.modules['tkinter.' + mod]
|
||||
# Avoid AttributeError if run again; see bpo-37038.
|
||||
sys.modules['idlelib.run'].firstrun = False
|
||||
|
||||
LOCALHOST = '127.0.0.1'
|
||||
|
||||
try:
|
||||
eof = 'Ctrl-D (end-of-file)'
|
||||
exit.eof = eof
|
||||
quit.eof = eof
|
||||
except NameError: # In case subprocess started with -S (maybe in future).
|
||||
pass
|
||||
|
||||
|
||||
def idle_formatwarning(message, category, filename, lineno, line=None):
|
||||
"""Format warnings the IDLE way."""
|
||||
|
||||
s = "\nWarning (from warnings module):\n"
|
||||
s += f' File \"{filename}\", line {lineno}\n'
|
||||
if line is None:
|
||||
line = linecache.getline(filename, lineno)
|
||||
line = line.strip()
|
||||
if line:
|
||||
s += " %s\n" % line
|
||||
s += f"{category.__name__}: {message}\n"
|
||||
return s
|
||||
|
||||
def idle_showwarning_subproc(
|
||||
message, category, filename, lineno, file=None, line=None):
|
||||
"""Show Idle-format warning after replacing warnings.showwarning.
|
||||
|
||||
The only difference is the formatter called.
|
||||
"""
|
||||
if file is None:
|
||||
file = sys.stderr
|
||||
try:
|
||||
file.write(idle_formatwarning(
|
||||
message, category, filename, lineno, line))
|
||||
except OSError:
|
||||
pass # the file (probably stderr) is invalid - this warning gets lost.
|
||||
|
||||
_warnings_showwarning = None
|
||||
|
||||
def capture_warnings(capture):
|
||||
"Replace warning.showwarning with idle_showwarning_subproc, or reverse."
|
||||
|
||||
global _warnings_showwarning
|
||||
if capture:
|
||||
if _warnings_showwarning is None:
|
||||
_warnings_showwarning = warnings.showwarning
|
||||
warnings.showwarning = idle_showwarning_subproc
|
||||
else:
|
||||
if _warnings_showwarning is not None:
|
||||
warnings.showwarning = _warnings_showwarning
|
||||
_warnings_showwarning = None
|
||||
|
||||
capture_warnings(True)
|
||||
|
||||
if idlelib.testing:
|
||||
# gh-121008: When testing IDLE, don't create a Tk object to avoid side
|
||||
# effects such as installing a PyOS_InputHook hook.
|
||||
def handle_tk_events():
|
||||
pass
|
||||
else:
|
||||
tcl = tkinter.Tcl()
|
||||
|
||||
def handle_tk_events(tcl=tcl):
|
||||
"""Process any tk events that are ready to be dispatched if tkinter
|
||||
has been imported, a tcl interpreter has been created and tk has been
|
||||
loaded."""
|
||||
tcl.eval("update")
|
||||
|
||||
# Thread shared globals: Establish a queue between a subthread (which handles
|
||||
# the socket) and the main thread (which runs user code), plus global
|
||||
# completion, exit and interruptible (the main thread) flags:
|
||||
|
||||
exit_now = False
|
||||
quitting = False
|
||||
interruptible = False
|
||||
|
||||
def main(del_exitfunc=False):
|
||||
"""Start the Python execution server in a subprocess
|
||||
|
||||
In the Python subprocess, RPCServer is instantiated with handlerclass
|
||||
MyHandler, which inherits register/unregister methods from RPCHandler via
|
||||
the mix-in class SocketIO.
|
||||
|
||||
When the RPCServer 'server' is instantiated, the TCPServer initialization
|
||||
creates an instance of run.MyHandler and calls its handle() method.
|
||||
handle() instantiates a run.Executive object, passing it a reference to the
|
||||
MyHandler object. That reference is saved as attribute rpchandler of the
|
||||
Executive instance. The Executive methods have access to the reference and
|
||||
can pass it on to entities that they command
|
||||
(e.g. debugger_r.Debugger.start_debugger()). The latter, in turn, can
|
||||
call MyHandler(SocketIO) register/unregister methods via the reference to
|
||||
register and unregister themselves.
|
||||
|
||||
"""
|
||||
global exit_now
|
||||
global quitting
|
||||
global no_exitfunc
|
||||
no_exitfunc = del_exitfunc
|
||||
#time.sleep(15) # test subprocess not responding
|
||||
try:
|
||||
assert(len(sys.argv) > 1)
|
||||
port = int(sys.argv[-1])
|
||||
except:
|
||||
print("IDLE Subprocess: no IP port passed in sys.argv.",
|
||||
file=sys.__stderr__)
|
||||
return
|
||||
|
||||
capture_warnings(True)
|
||||
sys.argv[:] = [""]
|
||||
threading.Thread(target=manage_socket,
|
||||
name='SockThread',
|
||||
args=((LOCALHOST, port),),
|
||||
daemon=True,
|
||||
).start()
|
||||
|
||||
while True:
|
||||
try:
|
||||
if exit_now:
|
||||
try:
|
||||
exit()
|
||||
except KeyboardInterrupt:
|
||||
# exiting but got an extra KBI? Try again!
|
||||
continue
|
||||
try:
|
||||
request = rpc.request_queue.get(block=True, timeout=0.05)
|
||||
except queue.Empty:
|
||||
request = None
|
||||
# Issue 32207: calling handle_tk_events here adds spurious
|
||||
# queue.Empty traceback to event handling exceptions.
|
||||
if request:
|
||||
seq, (method, args, kwargs) = request
|
||||
ret = method(*args, **kwargs)
|
||||
rpc.response_queue.put((seq, ret))
|
||||
else:
|
||||
handle_tk_events()
|
||||
except KeyboardInterrupt:
|
||||
if quitting:
|
||||
exit_now = True
|
||||
continue
|
||||
except SystemExit:
|
||||
capture_warnings(False)
|
||||
raise
|
||||
except:
|
||||
type, value, tb = sys.exc_info()
|
||||
try:
|
||||
print_exception()
|
||||
rpc.response_queue.put((seq, None))
|
||||
except:
|
||||
# Link didn't work, print same exception to __stderr__
|
||||
traceback.print_exception(type, value, tb, file=sys.__stderr__)
|
||||
exit()
|
||||
else:
|
||||
continue
|
||||
|
||||
def manage_socket(address):
|
||||
for i in range(3):
|
||||
time.sleep(i)
|
||||
try:
|
||||
server = MyRPCServer(address, MyHandler)
|
||||
break
|
||||
except OSError as err:
|
||||
print("IDLE Subprocess: OSError: " + err.args[1] +
|
||||
", retrying....", file=sys.__stderr__)
|
||||
socket_error = err
|
||||
else:
|
||||
print("IDLE Subprocess: Connection to "
|
||||
"IDLE GUI failed, exiting.", file=sys.__stderr__)
|
||||
show_socket_error(socket_error, address)
|
||||
global exit_now
|
||||
exit_now = True
|
||||
return
|
||||
server.handle_request() # A single request only
|
||||
|
||||
def show_socket_error(err, address):
|
||||
"Display socket error from manage_socket."
|
||||
import tkinter
|
||||
from tkinter.messagebox import showerror
|
||||
root = tkinter.Tk()
|
||||
fix_scaling(root)
|
||||
root.withdraw()
|
||||
showerror(
|
||||
"Subprocess Connection Error",
|
||||
f"IDLE's subprocess can't connect to {address[0]}:{address[1]}.\n"
|
||||
f"Fatal OSError #{err.errno}: {err.strerror}.\n"
|
||||
"See the 'Startup failure' section of the IDLE doc, online at\n"
|
||||
"https://docs.python.org/3/library/idle.html#startup-failure",
|
||||
parent=root)
|
||||
root.destroy()
|
||||
|
||||
|
||||
def get_message_lines(typ, exc, tb):
|
||||
"Return line composing the exception message."
|
||||
if typ in (AttributeError, NameError):
|
||||
# 3.10+ hints are not directly accessible from python (#44026).
|
||||
err = io.StringIO()
|
||||
with contextlib.redirect_stderr(err):
|
||||
sys.__excepthook__(typ, exc, tb)
|
||||
return [err.getvalue().split("\n")[-2] + "\n"]
|
||||
else:
|
||||
return traceback.format_exception_only(typ, exc)
|
||||
|
||||
|
||||
def print_exception():
|
||||
import linecache
|
||||
linecache.checkcache()
|
||||
flush_stdout()
|
||||
efile = sys.stderr
|
||||
typ, val, tb = excinfo = sys.exc_info()
|
||||
sys.last_type, sys.last_value, sys.last_traceback = excinfo
|
||||
sys.last_exc = val
|
||||
seen = set()
|
||||
|
||||
def print_exc(typ, exc, tb):
|
||||
seen.add(id(exc))
|
||||
context = exc.__context__
|
||||
cause = exc.__cause__
|
||||
if cause is not None and id(cause) not in seen:
|
||||
print_exc(type(cause), cause, cause.__traceback__)
|
||||
print("\nThe above exception was the direct cause "
|
||||
"of the following exception:\n", file=efile)
|
||||
elif (context is not None and
|
||||
not exc.__suppress_context__ and
|
||||
id(context) not in seen):
|
||||
print_exc(type(context), context, context.__traceback__)
|
||||
print("\nDuring handling of the above exception, "
|
||||
"another exception occurred:\n", file=efile)
|
||||
if tb:
|
||||
tbe = traceback.extract_tb(tb)
|
||||
print('Traceback (most recent call last):', file=efile)
|
||||
exclude = ("run.py", "rpc.py", "threading.py", "queue.py",
|
||||
"debugger_r.py", "bdb.py")
|
||||
cleanup_traceback(tbe, exclude)
|
||||
traceback.print_list(tbe, file=efile)
|
||||
lines = get_message_lines(typ, exc, tb)
|
||||
for line in lines:
|
||||
print(line, end='', file=efile)
|
||||
|
||||
print_exc(typ, val, tb)
|
||||
|
||||
def cleanup_traceback(tb, exclude):
|
||||
"Remove excluded traces from beginning/end of tb; get cached lines"
|
||||
orig_tb = tb[:]
|
||||
while tb:
|
||||
for rpcfile in exclude:
|
||||
if tb[0][0].count(rpcfile):
|
||||
break # found an exclude, break for: and delete tb[0]
|
||||
else:
|
||||
break # no excludes, have left RPC code, break while:
|
||||
del tb[0]
|
||||
while tb:
|
||||
for rpcfile in exclude:
|
||||
if tb[-1][0].count(rpcfile):
|
||||
break
|
||||
else:
|
||||
break
|
||||
del tb[-1]
|
||||
if len(tb) == 0:
|
||||
# exception was in IDLE internals, don't prune!
|
||||
tb[:] = orig_tb[:]
|
||||
print("** IDLE Internal Exception: ", file=sys.stderr)
|
||||
rpchandler = rpc.objecttable['exec'].rpchandler
|
||||
for i in range(len(tb)):
|
||||
fn, ln, nm, line = tb[i]
|
||||
if nm == '?':
|
||||
nm = "-toplevel-"
|
||||
if not line and fn.startswith("<pyshell#"):
|
||||
line = rpchandler.remotecall('linecache', 'getline',
|
||||
(fn, ln), {})
|
||||
tb[i] = fn, ln, nm, line
|
||||
|
||||
def flush_stdout():
|
||||
"""XXX How to do this now?"""
|
||||
|
||||
def exit():
|
||||
"""Exit subprocess, possibly after first clearing exit functions.
|
||||
|
||||
If config-main.cfg/.def 'General' 'delete-exitfunc' is True, then any
|
||||
functions registered with atexit will be removed before exiting.
|
||||
(VPython support)
|
||||
|
||||
"""
|
||||
if no_exitfunc:
|
||||
import atexit
|
||||
atexit._clear()
|
||||
capture_warnings(False)
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
def fix_scaling(root):
|
||||
"""Scale fonts on HiDPI displays."""
|
||||
import tkinter.font
|
||||
scaling = float(root.tk.call('tk', 'scaling'))
|
||||
if scaling > 1.4:
|
||||
for name in tkinter.font.names(root):
|
||||
font = tkinter.font.Font(root=root, name=name, exists=True)
|
||||
size = int(font['size'])
|
||||
if size < 0:
|
||||
font['size'] = round(-0.75*size)
|
||||
|
||||
|
||||
def fixdoc(fun, text):
|
||||
tem = (fun.__doc__ + '\n\n') if fun.__doc__ is not None else ''
|
||||
fun.__doc__ = tem + textwrap.fill(textwrap.dedent(text))
|
||||
|
||||
RECURSIONLIMIT_DELTA = 30
|
||||
|
||||
def install_recursionlimit_wrappers():
|
||||
"""Install wrappers to always add 30 to the recursion limit."""
|
||||
# see: bpo-26806
|
||||
|
||||
@functools.wraps(sys.setrecursionlimit)
|
||||
def setrecursionlimit(*args, **kwargs):
|
||||
# mimic the original sys.setrecursionlimit()'s input handling
|
||||
if kwargs:
|
||||
raise TypeError(
|
||||
"setrecursionlimit() takes no keyword arguments")
|
||||
try:
|
||||
limit, = args
|
||||
except ValueError:
|
||||
raise TypeError(f"setrecursionlimit() takes exactly one "
|
||||
f"argument ({len(args)} given)")
|
||||
if not limit > 0:
|
||||
raise ValueError(
|
||||
"recursion limit must be greater or equal than 1")
|
||||
|
||||
return setrecursionlimit.__wrapped__(limit + RECURSIONLIMIT_DELTA)
|
||||
|
||||
fixdoc(setrecursionlimit, f"""\
|
||||
This IDLE wrapper adds {RECURSIONLIMIT_DELTA} to prevent possible
|
||||
uninterruptible loops.""")
|
||||
|
||||
@functools.wraps(sys.getrecursionlimit)
|
||||
def getrecursionlimit():
|
||||
return getrecursionlimit.__wrapped__() - RECURSIONLIMIT_DELTA
|
||||
|
||||
fixdoc(getrecursionlimit, f"""\
|
||||
This IDLE wrapper subtracts {RECURSIONLIMIT_DELTA} to compensate
|
||||
for the {RECURSIONLIMIT_DELTA} IDLE adds when setting the limit.""")
|
||||
|
||||
# add the delta to the default recursion limit, to compensate
|
||||
sys.setrecursionlimit(sys.getrecursionlimit() + RECURSIONLIMIT_DELTA)
|
||||
|
||||
sys.setrecursionlimit = setrecursionlimit
|
||||
sys.getrecursionlimit = getrecursionlimit
|
||||
|
||||
|
||||
def uninstall_recursionlimit_wrappers():
|
||||
"""Uninstall the recursion limit wrappers from the sys module.
|
||||
|
||||
IDLE only uses this for tests. Users can import run and call
|
||||
this to remove the wrapping.
|
||||
"""
|
||||
if (
|
||||
getattr(sys.setrecursionlimit, '__wrapped__', None) and
|
||||
getattr(sys.getrecursionlimit, '__wrapped__', None)
|
||||
):
|
||||
sys.setrecursionlimit = sys.setrecursionlimit.__wrapped__
|
||||
sys.getrecursionlimit = sys.getrecursionlimit.__wrapped__
|
||||
sys.setrecursionlimit(sys.getrecursionlimit() - RECURSIONLIMIT_DELTA)
|
||||
|
||||
|
||||
class MyRPCServer(rpc.RPCServer):
|
||||
|
||||
def handle_error(self, request, client_address):
|
||||
"""Override RPCServer method for IDLE
|
||||
|
||||
Interrupt the MainThread and exit server if link is dropped.
|
||||
|
||||
"""
|
||||
global quitting
|
||||
try:
|
||||
raise
|
||||
except SystemExit:
|
||||
raise
|
||||
except EOFError:
|
||||
global exit_now
|
||||
exit_now = True
|
||||
thread.interrupt_main()
|
||||
except:
|
||||
erf = sys.__stderr__
|
||||
print(textwrap.dedent(f"""
|
||||
{'-'*40}
|
||||
Unhandled exception in user code execution server!'
|
||||
Thread: {threading.current_thread().name}
|
||||
IDLE Client Address: {client_address}
|
||||
Request: {request!r}
|
||||
"""), file=erf)
|
||||
traceback.print_exc(limit=-20, file=erf)
|
||||
print(textwrap.dedent(f"""
|
||||
*** Unrecoverable, server exiting!
|
||||
|
||||
Users should never see this message; it is likely transient.
|
||||
If this recurs, report this with a copy of the message
|
||||
and an explanation of how to make it repeat.
|
||||
{'-'*40}"""), file=erf)
|
||||
quitting = True
|
||||
thread.interrupt_main()
|
||||
|
||||
|
||||
# Pseudofiles for shell-remote communication (also used in pyshell)
|
||||
|
||||
class StdioFile(io.TextIOBase):
|
||||
|
||||
def __init__(self, shell, tags, encoding='utf-8', errors='strict'):
|
||||
self.shell = shell
|
||||
# GH-78889: accessing unpickleable attributes freezes Shell.
|
||||
# IDLE only needs methods; allow 'width' for possible use.
|
||||
self.shell._RPCProxy__attributes = {'width': 1}
|
||||
self.tags = tags
|
||||
self._encoding = encoding
|
||||
self._errors = errors
|
||||
|
||||
@property
|
||||
def encoding(self):
|
||||
return self._encoding
|
||||
|
||||
@property
|
||||
def errors(self):
|
||||
return self._errors
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return '<%s>' % self.tags
|
||||
|
||||
def isatty(self):
|
||||
return True
|
||||
|
||||
|
||||
class StdOutputFile(StdioFile):
|
||||
|
||||
def writable(self):
|
||||
return True
|
||||
|
||||
def write(self, s):
|
||||
if self.closed:
|
||||
raise ValueError("write to closed file")
|
||||
s = str.encode(s, self.encoding, self.errors).decode(self.encoding, self.errors)
|
||||
return self.shell.write(s, self.tags)
|
||||
|
||||
|
||||
class StdInputFile(StdioFile):
|
||||
_line_buffer = ''
|
||||
|
||||
def readable(self):
|
||||
return True
|
||||
|
||||
def read(self, size=-1):
|
||||
if self.closed:
|
||||
raise ValueError("read from closed file")
|
||||
if size is None:
|
||||
size = -1
|
||||
elif not isinstance(size, int):
|
||||
raise TypeError('must be int, not ' + type(size).__name__)
|
||||
result = self._line_buffer
|
||||
self._line_buffer = ''
|
||||
if size < 0:
|
||||
while line := self.shell.readline():
|
||||
result += line
|
||||
else:
|
||||
while len(result) < size:
|
||||
line = self.shell.readline()
|
||||
if not line: break
|
||||
result += line
|
||||
self._line_buffer = result[size:]
|
||||
result = result[:size]
|
||||
return result
|
||||
|
||||
def readline(self, size=-1):
|
||||
if self.closed:
|
||||
raise ValueError("read from closed file")
|
||||
if size is None:
|
||||
size = -1
|
||||
elif not isinstance(size, int):
|
||||
raise TypeError('must be int, not ' + type(size).__name__)
|
||||
line = self._line_buffer or self.shell.readline()
|
||||
if size < 0:
|
||||
size = len(line)
|
||||
eol = line.find('\n', 0, size)
|
||||
if eol >= 0:
|
||||
size = eol + 1
|
||||
self._line_buffer = line[size:]
|
||||
return line[:size]
|
||||
|
||||
def close(self):
|
||||
self.shell.close()
|
||||
|
||||
|
||||
class MyHandler(rpc.RPCHandler):
|
||||
|
||||
def handle(self):
|
||||
"""Override base method"""
|
||||
executive = Executive(self)
|
||||
self.register("exec", executive)
|
||||
self.console = self.get_remote_proxy("console")
|
||||
sys.stdin = StdInputFile(self.console, "stdin",
|
||||
iomenu.encoding, iomenu.errors)
|
||||
sys.stdout = StdOutputFile(self.console, "stdout",
|
||||
iomenu.encoding, iomenu.errors)
|
||||
sys.stderr = StdOutputFile(self.console, "stderr",
|
||||
iomenu.encoding, "backslashreplace")
|
||||
|
||||
sys.displayhook = rpc.displayhook
|
||||
# page help() text to shell.
|
||||
import pydoc # import must be done here to capture i/o binding
|
||||
pydoc.pager = pydoc.plainpager
|
||||
|
||||
# Keep a reference to stdin so that it won't try to exit IDLE if
|
||||
# sys.stdin gets changed from within IDLE's shell. See issue17838.
|
||||
self._keep_stdin = sys.stdin
|
||||
|
||||
install_recursionlimit_wrappers()
|
||||
|
||||
self.interp = self.get_remote_proxy("interp")
|
||||
rpc.RPCHandler.getresponse(self, myseq=None, wait=0.05)
|
||||
|
||||
def exithook(self):
|
||||
"override SocketIO method - wait for MainThread to shut us down"
|
||||
time.sleep(10)
|
||||
|
||||
def EOFhook(self):
|
||||
"Override SocketIO method - terminate wait on callback and exit thread"
|
||||
global quitting
|
||||
quitting = True
|
||||
thread.interrupt_main()
|
||||
|
||||
def decode_interrupthook(self):
|
||||
"interrupt awakened thread"
|
||||
global quitting
|
||||
quitting = True
|
||||
thread.interrupt_main()
|
||||
|
||||
|
||||
class Executive:
|
||||
|
||||
def __init__(self, rpchandler):
|
||||
self.rpchandler = rpchandler
|
||||
if idlelib.testing is False:
|
||||
self.locals = __main__.__dict__
|
||||
self.calltip = calltip.Calltip()
|
||||
self.autocomplete = autocomplete.AutoComplete()
|
||||
else:
|
||||
self.locals = {}
|
||||
|
||||
def runcode(self, code):
|
||||
global interruptible
|
||||
try:
|
||||
self.user_exc_info = None
|
||||
interruptible = True
|
||||
try:
|
||||
exec(code, self.locals)
|
||||
finally:
|
||||
interruptible = False
|
||||
except SystemExit as e:
|
||||
if e.args: # SystemExit called with an argument.
|
||||
ob = e.args[0]
|
||||
if not isinstance(ob, (type(None), int)):
|
||||
print('SystemExit: ' + str(ob), file=sys.stderr)
|
||||
# Return to the interactive prompt.
|
||||
except:
|
||||
self.user_exc_info = sys.exc_info() # For testing, hook, viewer.
|
||||
if quitting:
|
||||
exit()
|
||||
if sys.excepthook is sys.__excepthook__:
|
||||
print_exception()
|
||||
else:
|
||||
try:
|
||||
sys.excepthook(*self.user_exc_info)
|
||||
except:
|
||||
self.user_exc_info = sys.exc_info() # For testing.
|
||||
print_exception()
|
||||
jit = self.rpchandler.console.getvar("<<toggle-jit-stack-viewer>>")
|
||||
if jit:
|
||||
self.rpchandler.interp.open_remote_stack_viewer()
|
||||
else:
|
||||
flush_stdout()
|
||||
|
||||
def interrupt_the_server(self):
|
||||
if interruptible:
|
||||
thread.interrupt_main()
|
||||
|
||||
def start_the_debugger(self, gui_adap_oid):
|
||||
return debugger_r.start_debugger(self.rpchandler, gui_adap_oid)
|
||||
|
||||
def stop_the_debugger(self, idb_adap_oid):
|
||||
"Unregister the Idb Adapter. Link objects and Idb then subject to GC"
|
||||
self.rpchandler.unregister(idb_adap_oid)
|
||||
|
||||
def get_the_calltip(self, name):
|
||||
return self.calltip.fetch_tip(name)
|
||||
|
||||
def get_the_completion_list(self, what, mode):
|
||||
return self.autocomplete.fetch_completions(what, mode)
|
||||
|
||||
def stackviewer(self, flist_oid=None):
|
||||
if self.user_exc_info:
|
||||
_, exc, tb = self.user_exc_info
|
||||
else:
|
||||
return None
|
||||
flist = None
|
||||
if flist_oid is not None:
|
||||
flist = self.rpchandler.get_remote_proxy(flist_oid)
|
||||
while tb and tb.tb_frame.f_globals["__name__"] in ["rpc", "run"]:
|
||||
tb = tb.tb_next
|
||||
exc.__traceback__ = tb
|
||||
item = stackviewer.StackTreeItem(exc, flist)
|
||||
return debugobj_r.remote_object_tree_item(item)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from unittest import main
|
||||
main('idlelib.idle_test.test_run', verbosity=2)
|
||||
|
||||
capture_warnings(False) # Make sure turned off; see bpo-18081.
|
Reference in New Issue
Block a user