B „ fl/ã@sôdZddlZddlmZdZdadZiZiZiZ iZ dd„Z dd „Z Gd d „d ƒZ Gd d „d ƒZdd„ZGdd„dƒZGdd„dƒZGdd„dƒZGdd„dƒZGdd„dƒZdd„Zdd„Zdd„Zd d!„Zed"krðdd#lmZed$d%d&d'�dS)(aÎSupport for remote Python debugging. Some ASCII art to describe the structure: IN PYTHON SUBPROCESS # IN IDLE PROCESS # # oid='gui_adapter' +----------+ # +------------+ +-----+ | GUIProxy |--remote#call-->| GUIAdapter |--calls-->| GUI | +-----+--calls-->+----------+ # +------------+ +-----+ | Idb | # / +-----+<-calls--+------------+ # +----------+<--calls-/ | IdbAdapter |<--remote#call--| IdbProxy | +------------+ # +----------+ oid='idb_adapter' # The purpose of the Proxy and Adapter classes is to translate certain arguments and return values that cannot be transported through the RPC barrier, in particular frame and traceback objects. éN)ÚdebuggerÚ idb_adapterZ gui_adaptercCst|ƒ}|t|<|S)N)ÚidÚ frametable)ÚframeÚfid©rú7/opt/alt/python37/lib64/python3.7/idlelib/debugger_r.pyÚ wrap_frame(sr cCsN|dkr dS|d}t|tjƒs$t‚t|ƒ}|t|<|d|d|f}|SdS)z0replace info[2], a traceback instance, by its IDNéré)Ú isinstanceÚtypesÚ TracebackTypeÚAssertionErrorrÚtracebacktable)ÚinfoÚ tracebackZ traceback_idÚ modified_inforrr Ú wrap_info-src@seZdZdd„Zddd„ZdS)ÚGUIProxycCs||_||_dS)N)ÚconnÚoid)ÚselfrÚ gui_adap_oidrrr Ú__init__;szGUIProxy.__init__NcCs&|j |jd|t|ƒt|ƒfi¡dS)NÚ interaction)rÚ remotecallrr r)rÚmessagerrrrr r?s zGUIProxy.interaction)N)Ú__name__Ú __module__Ú __qualname__rrrrrr r9src@s¬eZdZdd„Zdd„Zdd„Zdd„Zd d „Zd d „Zd d„Z dd„Z dd„Z dd„Z dd„Z dd„Zdd„Zdd„Zdd„Zdd „Zd!d"„Zd#d$„Zd%d&„Zd'd(„Zd)S)*Ú IdbAdaptercCs ||_dS)N)Úidb)rr#rrr rHszIdbAdapter.__init__cCs|j ¡dS)N)r#Úset_step)rrrr r$MszIdbAdapter.set_stepcCs|j ¡dS)N)r#Úset_quit)rrrr r%PszIdbAdapter.set_quitcCs|j ¡dS)N)r#Ú set_continue)rrrr r&SszIdbAdapter.set_continuecCst|}|j |¡dS)N)rr#Úset_next)rrrrrr r'VszIdbAdapter.set_nextcCst|}|j |¡dS)N)rr#Ú set_return)rrrrrr r(ZszIdbAdapter.set_returncCsFt|}|dkrd}nt|}|j ||¡\}}dd„|Dƒ}||fS)NcSsg|]\}}t|ƒ|f‘qSr)r )Ú.0Zframe2Úkrrr ú esz(IdbAdapter.get_stack..)rrr#Ú get_stack)rrÚtbidrÚtbÚstackÚirrr r,^szIdbAdapter.get_stackcCsddl}|j ||j¡dS)Nr)Ú__main__r#ÚrunÚ__dict__)rÚcmdr1rrr r2hszIdbAdapter.runcCs|j ||¡}|S)N)r#Ú set_break)rÚfilenameÚlinenoÚmsgrrr r5lszIdbAdapter.set_breakcCs|j ||¡}|S)N)r#Ú clear_break)rr6r7r8rrr r9pszIdbAdapter.clear_breakcCs|j |¡}|S)N)r#Úclear_all_file_breaks)rr6r8rrr r:ts z IdbAdapter.clear_all_file_breakscCst|}t||ƒS)N)rÚgetattr)rrÚnamerrrr Ú frame_attrzszIdbAdapter.frame_attrcCs"t|}|j}t|ƒ}|t|<|S)N)rÚ f_globalsrÚ dicttable)rrrÚdictÚdidrrr Ú frame_globals~s zIdbAdapter.frame_globalscCs"t|}|j}t|ƒ}|t|<|S)N)rÚf_localsrr?)rrrr@rArrr Ú frame_locals…s zIdbAdapter.frame_localscCs"t|}|j}t|ƒ}|t|<|S)N)rÚf_coderÚ codetable)rrrÚcodeÚcidrrr Ú frame_codeŒs zIdbAdapter.frame_codecCst|}|jS)N)rFÚco_name)rrHrGrrr Ú code_name•szIdbAdapter.code_namecCst|}|jS)N)rFÚ co_filename)rrHrGrrr Ú code_filename™szIdbAdapter.code_filenamecCs tdƒ‚dS)Nz"dict_keys not public or pickleable)ÚNotImplementedError)rrArrr Ú dict_keysŸszIdbAdapter.dict_keyscCst|}t| ¡ƒS)N)r?ÚlistÚkeys)rrAr@rrr Údict_keys_list¦szIdbAdapter.dict_keys_listcCst|}||}t|ƒ}|S)N)r?Úrepr)rrAÚkeyr@Úvaluerrr Ú dict_itemªszIdbAdapter.dict_itemN)rr r!rr$r%r&r'r(r,r2r5r9r:r=rBrDrIrKrMrOrRrVrrrr r"Fs(  r"cCs,t||ƒ}t |¡}t|ƒ}| t|¡tS)a|Start the debugger and its RPC link in the Python subprocess Start the subprocess side of the split debugger and set up that side of the RPC link by instantiating the GUIProxy, Idb debugger, and IdbAdapter objects and linking them together. Register the IdbAdapter with the RPCServer to handle RPC requests from the split debugger GUI via the IdbProxy. )rrZIdbr"ÚregisterÚ idb_adap_oid)Z rpchandlerrZ gui_proxyr#Zidb_adaprrr Ústart_debugger³s   rYc@s<eZdZdd„Zdd„Zdd„Zdd„Zd d „Zd d „Zd S)Ú FrameProxycCs||_||_d|_i|_dS)Nr)Ú_connÚ_fidÚ_oidÚ _dictcache)rrrrrr rËszFrameProxy.__init__cCsb|dd…dkrt|ƒ‚|dkr(| ¡S|dkr8| ¡S|dkrH| ¡S|j |jd|j|fi¡S)Nr Ú_rEr>rCr=)ÚAttributeErrorÚ _get_f_codeÚ_get_f_globalsÚ _get_f_localsr[rr]r\)rr<rrr Ú __getattr__Ñs zFrameProxy.__getattr__cCs(|j |jd|jfi¡}t|j|j|ƒS)NrI)r[rr]r\Ú CodeProxy)rrHrrr raÝszFrameProxy._get_f_codecCs"|j |jd|jfi¡}| |¡S)NrB)r[rr]r\Ú_get_dict_proxy)rrArrr rbás  zFrameProxy._get_f_globalscCs"|j |jd|jfi¡}| |¡S)NrD)r[rr]r\rf)rrArrr rcæs  zFrameProxy._get_f_localscCs2||jkr|j|St|j|j|ƒ}||j|<|S)N)r^Ú DictProxyr[r])rrAZdprrr rfës    zFrameProxy._get_dict_proxyN) rr r!rrdrarbrcrfrrrr rZÉs  rZc@seZdZdd„Zdd„ZdS)recCs||_||_||_dS)N)r[r]Ú_cid)rrrrHrrr rõszCodeProxy.__init__cCsD|dkr |j |jd|jfi¡S|dkr@|j |jd|jfi¡SdS)NrJrKrLrM)r[rr]rh)rr<rrr rdús    zCodeProxy.__getattr__N)rr r!rrdrrrr reósrec@s,eZdZdd„Zdd„Zdd„Zdd„Zd S) rgcCs||_||_||_dS)N)r[r]Ú_did)rrrrArrr rszDictProxy.__init__cCs|j |jd|jfi¡S)NrR)r[rr]ri)rrrr rQs zDictProxy.keyscCs|j |jd|j|fi¡S)NrV)r[rr]ri)rrTrrr Ú __getitem__s zDictProxy.__getitem__cCs t|ƒ‚dS)N)r`)rr<rrr rdszDictProxy.__getattr__N)rr r!rrQrjrdrrrr rgs rgc@seZdZdd„Zdd„ZdS)Ú GUIAdaptercCs||_||_dS)N)rÚgui)rrrlrrr rszGUIAdapter.__init__cCs t|j|ƒ}|j |||¡dS)N)rZrrlr)rrrrrrrr r!s zGUIAdapter.interactionN)rr r!rrrrrr rksrkc@sleZdZdd„Zdd„Zdd„Zdd„Zd d „Zd d „Zd d„Z dd„Z dd„Z dd„Z dd„Z dd„ZdS)ÚIdbProxycCs||_||_||_dS)N)rrÚshell)rrrnrrrr r)szIdbProxy.__init__cOs|j |j|||¡}|S)N)rrr)rZ methodnameÚargsÚkwargsrUrrr Úcall.sz IdbProxy.callcCs$|j |jd|fi¡}||jj_dS)Nr2)rZ asyncqueuerrnZinterpZ active_seq)rr4ÚlocalsÚseqrrr r24sz IdbProxy.runcs.ˆ d|j|¡\}}‡fdd„|Dƒ}||fS)Nr,cs g|]\}}tˆj|ƒ|f‘qSr)rZr)r)rr*)rrr r+<sz&IdbProxy.get_stack..)rqr\)rrr-r/r0r)rr r,9szIdbProxy.get_stackcCs| d¡dS)Nr&)rq)rrrr r&?szIdbProxy.set_continuecCs| d¡dS)Nr$)rq)rrrr r$BszIdbProxy.set_stepcCs| d|j¡dS)Nr')rqr\)rrrrr r'EszIdbProxy.set_nextcCs| d|j¡dS)Nr()rqr\)rrrrr r(HszIdbProxy.set_returncCs| d¡dS)Nr%)rq)rrrr r%KszIdbProxy.set_quitcCs| d||¡}|S)Nr5)rq)rr6r7r8rrr r5NszIdbProxy.set_breakcCs| d||¡}|S)Nr9)rq)rr6r7r8rrr r9RszIdbProxy.clear_breakcCs| d|¡}|S)Nr:)rq)rr6r8rrr r:Vs zIdbProxy.clear_all_file_breaksN)rr r!rrqr2r,r&r$r'r(r%r5r9r:rrrr rm'srmcCsD| ddtfi¡at||tƒ}t ||¡}t||ƒ}| t|¡|S)a]Start the subprocess debugger, initialize the debugger GUI and RPC link Request the RPCServer start the Python subprocess debugger and link. Set up the Idle side of the split debugger by instantiating the IdbProxy, debugger GUI, and debugger GUIAdapter objects and linking them together. Register the GUIAdapter with the RPCClient to handle debugger GUI interaction requests coming from the subprocess debugger via the GUIProxy. The IdbAdapter will pass execution and environment requests coming from the Idle debugger GUI to the subprocess debugger via the IdbProxy. ÚexecÚstart_the_debugger)rrrXrmrZDebuggerrkrW)ÚrpccltZpyshellZ idb_proxyrlZgui_adaprrr Ústart_remote_debuggerZs     rwcCst|ƒ| t¡dS)a]Shut down subprocess debugger and Idle side of debugger RPC link Request that the RPCServer shut down the subprocess debugger and link. Unregister the GUIAdapter, which will cause a GC on the Idle process debugger and RPC link objects. (The second reference to the debugger GUI is deleted in pyshell.close_remote_debugger().) N)Úclose_subprocess_debuggerZ unregisterr)rvrrr Úclose_remote_debuggerrs rycCs| ddtfi¡dS)NrtZstop_the_debugger)rrX)rvrrr rx~srxcCs&| ddtfi¡}|tks"tdƒ‚dS)Nrtruz Idb restarted with different oid)rrrXr)rvZidb_adap_oid_retrrr Úrestart_subprocess_debugger�s rzr1)Úmainzidlelib.idle_test.test_debuggerr F)Ú verbosityÚexit)Ú__doc__rZidlelibrZ debuggingrXrrr?rFrr rrr"rYrZrergrkrmrwryrxrzrZunittestr{rrrr Ús4   m* 3