\d/ZdZddlZddlZddlmZdZdadZiZiZ iZ iZ dZ dZ Gdd ZGd d Zd ZGd dZGddZGddZGddZGddZdZdZdZdZedkrddlmZeddd dSdS)!aSupport 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_adapter gui_adapterc8t|}|t|<|SN)id frametable)framefids #..\python\lib\idlelib\debugger_r.py wrap_framer (s U))CJsO Jc|dS|d}t|tjsJt|}|t|<|d|d|f}|S)z0replace info[2], a traceback instance, by its IDNr) isinstancetypes TracebackTypertracebacktable)info traceback traceback_id modified_infos r wrap_infor-s] |tG )U%899999)}} '0|$a$q'<8 rceZdZdZddZdS)GUIProxyc"||_||_dSr)connoid)selfr gui_adap_oids r __init__zGUIProxy.__init__;s rNc |j|jd|t|t |fidS)N interaction)r remotecallrr r)r messager rs r r$zGUIProxy.interaction?sI TX}%z%'8'8)D//J ! ! ! ! !rr__name__ __module__ __qualname__r"r$rr rr9s7   !!!!!!rrceZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZdZdZdZdZdZdZdS) IdbAdapterc||_dSr)idb)r r/s r r"zIdbAdapter.__init__Hs rc8|jdSr)r/set_stepr s r r1zIdbAdapter.set_stepM rc8|jdSr)r/set_quitr2s r r5zIdbAdapter.set_quitPr3rc8|jdSr)r/ set_continuer2s r r7zIdbAdapter.set_continueSs rcTt|}|j|dSr)r r/set_nextr r r s r r9zIdbAdapter.set_nextVs'3 %     rcTt|}|j|dSr)r r/ set_returnr:s r r<zIdbAdapter.set_returnZs'3 E"""""rct|}|d}n t|}|j||\}}d|D}||fS)Nc6g|]\}}t||fSr+)r ).0frame2ks r z(IdbAdapter.get_stack..es)@@@YVQ*V$$a(@@@r)r rr/ get_stack)r r tbidr tbstackis r rCzIdbAdapter.get_stack^sX3 <BB%B8%%eR00q@@%@@@axrcNddl}|j||jdS)Nr)__main__r/run__dict__)r cmdrIs r rJzIdbAdapter.runhs*  S(+,,,,,rc<|j||}|Sr)r/ set_breakr filenamelinenomsgs r rNzIdbAdapter.set_breaklsh  622 rc<|j||}|Sr)r/ clear_breakrOs r rTzIdbAdapter.clear_breakpsh""8V44 rc:|j|}|Sr)r/clear_all_file_breaksr rPrRs r rVz IdbAdapter.clear_all_file_breakstsh,,X66 rc<t|}t||Sr)r getattr)r r namer s r frame_attrzIdbAdapter.frame_attrzs3ud###rc`t|}|j}t|}|t|<|Sr)r f_globalsr dicttabler r r dictdids r frame_globalszIdbAdapter.frame_globals~s+3hh # rc`t|}|j}t|}|t|<|Sr)r f_localsrr^r_s r frame_localszIdbAdapter.frame_localss+3~hh # rc`t|}|j}t|}|t|<|Sr)r f_coder codetable)r r r codecids r frame_codezIdbAdapter.frame_codes+3|hh # rc*t|}|jSr)rhco_namer rjris r code_namezIdbAdapter.code_names~|rc*t|}|jSr)rh co_filenamerns r code_filenamezIdbAdapter.code_filenames~rc td)Nz"dict_keys not public or pickleable)NotImplementedErrorr ras r dict_keyszIdbAdapter.dict_keyss!"FGGGrc^t|}t|Sr)r^listkeys)r rar`s r dict_keys_listzIdbAdapter.dict_keys_lists!~DIIKK   rcXt|}||}tj|}|Sr)r^reprlibrepr)r rakeyr`values r dict_itemzIdbAdapter.dict_items(~S  U## rN)r(r)r*r"r1r5r7r9r<rCrJrNrTrVr[rbrerkrorrrvrzrr+rr r-r-FsC    !!!###--- $$$   HHH!!!rr-ct||}tj|}t|}|t |t S)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. )rrIdbr-register idb_adap_oid) rpchandlerr! gui_proxyr/idb_adaps r start_debuggerrsI\22I ,y ! !C#H h/// rc2eZdZdZdZdZdZdZdZdS) FrameProxyc>||_||_d|_i|_dS)Nr)_conn_fid_oid _dictcache)r rr s r r"zFrameProxy.__init__s"  ! rc*|dddkrt||dkr|S|dkr|S|dkr|S|j|jd|j|fiS)Nr_rgr]rdr[)AttributeError _get_f_code_get_f_globals _get_f_localsrr%rrr rZs r __getattr__zFrameProxy.__getattr__s 8s?? && & 8  ##%% % ;  &&(( ( :  %%'' 'z$$TY &*i%6<< .<s.EEEVS!*TY,,a0EEErrr)r r rDrFrGs` r rCzIdbProxy.get_stack9s@99[%*d;;qEEEEuEEEaxrc0|ddS)Nr7rr2s r r7zIdbProxy.set_continue?s .!!!!!rc0|ddS)Nr1rr2s r r1zIdbProxy.set_stepB *rc<|d|jdS)Nr9rr r s r r9zIdbProxy.set_nextEs *ej)))))rc<|d|jdS)Nr<rrs r r<zIdbProxy.set_returnHs , +++++rc0|ddS)Nr5rr2s r r5zIdbProxy.set_quitKrrc4|d||}|S)NrNrrOs r rNzIdbProxy.set_breakNsii Xv66 rc4|d||}|S)NrTrrOs r rTzIdbProxy.clear_breakRsii x88 rc2|d|}|S)NrVrrWs r rVzIdbProxy.clear_all_file_breaksVsii/:: rN)r(r)r*r"rrJrCr7r1r9r<r5rNrTrVr+rr rr's  +++  """***,,,rrc|ddtfiat||t}t j||}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. execstart_the_debugger)r%r!rrrDebuggerrr)rpccltpyshell idb_proxyrgui_adaps r start_remote_debuggerrZsp $$V-A$0?B88L,77I  GY / /C&#&&H OOL(+++ JrcXt||tdS)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_debugger unregisterr!rs r close_remote_debuggerrrs,f%%% l#####rcB|ddtfidS)Nrstop_the_debugger)r%rrs r rr~s% f1L?BGGGGGrcl|ddtfi}|tks JddS)Nrrz Idb restarted with different oid)r%r!r)ridb_adap_oid_rets r restart_subprocess_debuggerrsD((1E*6">> | + + +-O + + + + +rrI)mainz!idlelib.idle_test.test_debugger_rrF) verbosityexit)__doc__r|ridlelibr debuggingrr!r r^rhrr rrr-rrrrrrrrrrr(unittestrr+rr rs1*           ! ! ! ! ! ! ! !hhhhhhhhZ,''''''''T ; ; ; ; ; ; ; ; ########0 < < < < < < < <11111111f0 $ $ $HHHPPP  zD ,FFFFFFr