""" idlelib.runSimplified, pyshell.ModifiedInterpreter spawns a subprocess withf'''{sys.executable} -c "__import__('idlelib.run').run.main()"''''.run' is needed because __import__ returns idlelib, not idlelib.run."""import ioimport linecacheimport queueimport sysimport timeimport tracebackimport _thread as threadimport threadingimport warningsfrom idlelib import autocomplete # AutoComplete, fetch_encodingsfrom idlelib import calltip # Calltipfrom idlelib import debugger_r # start_debuggerfrom idlelib import debugobj_r # remote_object_tree_itemfrom idlelib import iomenu # encodingfrom idlelib import rpc # multiple objectsfrom idlelib import stackviewer # StackTreeItemimport __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 = FalseLOCALHOST = '127.0.0.1'def idle_formatwarning(message, category, filename, lineno, line=None):"""Format warnings the IDLE way."""s = "\nWarning (from warnings module):\n"s += ' File \"%s\", line %s\n' % (filename, lineno)if line is None:line = linecache.getline(filename, lineno)line = line.strip()if line:s += " %s\n" % lines += "%s: %s\n" % (category.__name__, message)return sdef 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.stderrtry:file.write(idle_formatwarning(message, category, filename, lineno, line))except OSError:pass # the file (probably stderr) is invalid - this warning gets lost._warnings_showwarning = Nonedef capture_warnings(capture):"Replace warning.showwarning with idle_showwarning_subproc, or reverse."global _warnings_showwarningif capture:if _warnings_showwarning is None:_warnings_showwarning = warnings.showwarningwarnings.showwarning = idle_showwarning_subprocelse:if _warnings_showwarning is not None:warnings.showwarning = _warnings_showwarning_warnings_showwarning = Nonecapture_warnings(True)tcl = tkinter.Tcl()def handle_tk_events(tcl=tcl):"""Process any tk events that are ready to be dispatched if tkinterhas been imported, a tcl interpreter has been created and tk has beenloaded."""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 interruptable (the main thread) flags:exit_now = Falsequitting = Falseinterruptable = Falsedef main(del_exitfunc=False):"""Start the Python execution server in a subprocessIn the Python subprocess, RPCServer is instantiated with handlerclassMyHandler, which inherits register/unregister methods from RPCHandler viathe mix-in class SocketIO.When the RPCServer 'server' is instantiated, the TCPServer initializationcreates an instance of run.MyHandler and calls its handle() method.handle() instantiates a run.Executive object, passing it a reference to theMyHandler object. That reference is saved as attribute rpchandler of theExecutive instance. The Executive methods have access to the reference andcan pass it on to entities that they command(e.g. debugger_r.Debugger.start_debugger()). The latter, in turn, cancall MyHandler(SocketIO) register/unregister methods via the reference toregister and unregister themselves."""global exit_nowglobal quittingglobal no_exitfuncno_exitfunc = del_exitfunc#time.sleep(15) # test subprocess not respondingtry:assert(len(sys.argv) > 1)port = int(sys.argv[-1])except:print("IDLE Subprocess: no IP port passed in sys.argv.",file=sys.__stderr__)returncapture_warnings(True)sys.argv[:] = [""]sockthread = threading.Thread(target=manage_socket,name='SockThread',args=((LOCALHOST, port),))sockthread.daemon = Truesockthread.start()while 1:try:if exit_now:try:exit()except KeyboardInterrupt:# exiting but got an extra KBI? Try again!continuetry: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) = requestret = method(*args, **kwargs)rpc.response_queue.put((seq, ret))else:handle_tk_events()except KeyboardInterrupt:if quitting:exit_now = Truecontinueexcept SystemExit:capture_warnings(False)raiseexcept: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:continuedef manage_socket(address):for i in range(3):time.sleep(i)try:server = MyRPCServer(address, MyHandler)breakexcept OSError as err:print("IDLE Subprocess: OSError: " + err.args[1] +", retrying....", file=sys.__stderr__)socket_error = errelse:print("IDLE Subprocess: Connection to ""IDLE GUI failed, exiting.", file=sys.__stderr__)show_socket_error(socket_error, address)global exit_nowexit_now = Truereturnserver.handle_request() # A single request onlydef show_socket_error(err, address):"Display socket error from manage_socket."import tkinterfrom tkinter.messagebox import showerrorroot = 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 print_exception():import linecachelinecache.checkcache()flush_stdout()efile = sys.stderrtyp, val, tb = excinfo = sys.exc_info()sys.last_type, sys.last_value, sys.last_traceback = excinfoseen = 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 andnot exc.__suppress_context__ andid(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 = traceback.format_exception_only(typ, exc)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):breakelse:breakdel 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'].rpchandlerfor 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, linedef 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 anyfunctions registered with atexit will be removed before exiting.(VPython support)"""if no_exitfunc:import atexitatexit._clear()capture_warnings(False)sys.exit(0)def fix_scaling(root):"""Scale fonts on HiDPI displays."""import tkinter.fontscaling = 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)class MyRPCServer(rpc.RPCServer):def handle_error(self, request, client_address):"""Override RPCServer method for IDLEInterrupt the MainThread and exit server if link is dropped."""global quittingtry:raiseexcept SystemExit:raiseexcept EOFError:global exit_nowexit_now = Truethread.interrupt_main()except:erf = sys.__stderr__print('\n' + '-'*40, file=erf)print('Unhandled server exception!', file=erf)print('Thread: %s' % threading.current_thread().name, file=erf)print('Client Address: ', client_address, file=erf)print('Request: ', repr(request), file=erf)traceback.print_exc(file=erf)print('\n*** Unrecoverable, server exiting!', file=erf)print('-'*40, file=erf)quitting = Truethread.interrupt_main()# Pseudofiles for shell-remote communication (also used in pyshell)class PseudoFile(io.TextIOBase):def __init__(self, shell, tags, encoding=None):self.shell = shellself.tags = tagsself._encoding = encoding@propertydef encoding(self):return self._encoding@propertydef name(self):return '<%s>' % self.tagsdef isatty(self):return Trueclass PseudoOutputFile(PseudoFile):def writable(self):return Truedef write(self, s):if self.closed:raise ValueError("write to closed file")if type(s) is not str:if not isinstance(s, str):raise TypeError('must be str, not ' + type(s).__name__)# See issue #19481s = str.__str__(s)return self.shell.write(s, self.tags)class PseudoInputFile(PseudoFile):def __init__(self, shell, tags, encoding=None):PseudoFile.__init__(self, shell, tags, encoding)self._line_buffer = ''def readable(self):return Truedef read(self, size=-1):if self.closed:raise ValueError("read from closed file")if size is None:size = -1elif not isinstance(size, int):raise TypeError('must be int, not ' + type(size).__name__)result = self._line_bufferself._line_buffer = ''if size < 0:while True:line = self.shell.readline()if not line: breakresult += lineelse:while len(result) < size:line = self.shell.readline()if not line: breakresult += lineself._line_buffer = result[size:]result = result[:size]return resultdef readline(self, size=-1):if self.closed:raise ValueError("read from closed file")if size is None:size = -1elif 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 + 1self._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 = PseudoInputFile(self.console, "stdin",iomenu.encoding)sys.stdout = PseudoOutputFile(self.console, "stdout",iomenu.encoding)sys.stderr = PseudoOutputFile(self.console, "stderr",iomenu.encoding)sys.displayhook = rpc.displayhook# page help() text to shell.import pydoc # import must be done here to capture i/o bindingpydoc.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.stdinself.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 quittingquitting = Truethread.interrupt_main()def decode_interrupthook(self):"interrupt awakened thread"global quittingquitting = Truethread.interrupt_main()class Executive(object):def __init__(self, rpchandler):self.rpchandler = rpchandlerself.locals = __main__.__dict__self.calltip = calltip.Calltip()self.autocomplete = autocomplete.AutoComplete()def runcode(self, code):global interruptabletry:self.usr_exc_info = Noneinterruptable = Truetry:exec(code, self.locals)finally:interruptable = Falseexcept 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.usr_exc_info = sys.exc_info()if quitting:exit()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 interruptable: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.usr_exc_info:typ, val, tb = self.usr_exc_infoelse:return Noneflist = Noneif 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_nextsys.last_type = typsys.last_value = valitem = stackviewer.StackTreeItem(flist, tb)return debugobj_r.remote_object_tree_item(item)if __name__ == '__main__':from unittest import mainmain('idlelib.idle_test.test_run', verbosity=2)capture_warnings(False) # Make sure turned off; see bpo-18081.
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。