a
    
aAK                     @   s   d dl mZmZmZmZ d dlZd dlZd dlZd dlZd dl	Z	d dl
Z
d dl
mZ d dlmZmZmZmZmZmZ d dlmZ dZe Zg Ze ZG dd deZG dd	 d	ejZdddZdd Z dd Z!dddZ"dd Z#dd Z$dd Z%dS )    )absolute_importdivisionprint_functionunicode_literalsN)adapter)compatfmtjsonlog	messagingsockets)
componentsc                   @   sP   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd ZdS )
Connectionaw  A debug server that is connected to the adapter.

    Servers that are not participating in a debug session are managed directly by the
    corresponding Connection instance.

    Servers that are participating in a debug session are managed by that sessions's
    Server component instance, but Connection object remains, and takes over again
    once the session ends.
    c           
         s  ddl m} d _d  _d  _tj|t }t	|  _
 j
  zL    j
d}|dt }|dt _|dtdd	 _ jd
krd  _t   j
_|_tjtjtj}d}t||d}z j
dd|i W n& tjy   tjd dd Y n0 tn  jr0W d    W d S t fddtD rVttd t tdk}t!  t"#  W d    n1 s0    Y  W n0 t$y   td  j
%  t&  Y d S 0 |' j}	|	d u rt(d  n4z|	j)*  W d S  t$y   td  Y n0 |r*d S t(d  zB j
dddi  j
dd ji  j
d  j
d W n( t$y   td   j
%  Y n0 d S )!Nr   )sessionsFZpydevdSystemInfoZprocesspidppidT)Zoptional z
if 'debugpy' not in sys.modules:
    sys.path.insert(0, {debugpy_dir!r})
    try:
        import debugpy
    finally:
        del sys.path[0]
)debugpy_dirZevaluateZ
expressionz"Failed to inject debugpy into {0}:warninglevelc                 3   s   | ]}|j  j kV  qd S N)r   .0connselfr   6lib/python3.9/site-packages/debugpy/adapter/servers.py	<genexpr>r       z&Connection.__init__.<locals>.<genexpr>z({0} is already connected to this adapterz,Failed to accept incoming server connection:z2No active debug session for parent process of {0}.z*Failed to notify parent session about {0}:z(No clients to wait for - unblocking {0}.
initializeZ	adapterIDdebugpyZattachZsubProcessIdZconfigurationDone
disconnectz&Failed to unblock orphaned subprocess:)+debugpy.adapterr   disconnectedserverr   r   ZJsonIOStreamZfrom_socketstrZJsonMessageChannelchannelstartauthenticaterequestr	   objectintr   nameospathdirnamer!   __file__r   MessageHandlingErrorr
   swallow_exception_lockany_connectionsKeyErrorlenappend_connections_changedset	Exceptionclosedont_wait_for_first_connectiongetinfoclientZnotify_of_subprocess)
r   Zsockr   streamr@   Zprocess_infor   Zinject_debugpyZis_first_serverZparent_sessionr   r   r   __init__*   sz    


,




zConnection.__init__c                 C   s   dt | jd u rdnd| j S )NServerz[?]z	[pid={0}])r   r   r   r   r   r   __str__   s    zConnection.__str__c                 C   sL   t d u rtj d u rd S | jddt i}|d tj krH| j  tdd S )NZpydevdAuthorizeZdebugServerAccessTokenZclientAccessTokenz6Mismatched "clientAccessToken"; server not authorized.)access_tokenr   r'   r*   r=   RuntimeError)r   Zauthr   r   r   r)      s    
zConnection.authenticatec                 C   s   | dd S Nz=Requests from the debug server to the client are not allowed.Z
isnt_validr   r*   r   r   r   r*      s    zConnection.requestc                 C   s   d S r   r   r   eventr   r   r   rL      s    zConnection.eventc                 C   s   | j   d S r   r'   r=   rK   r   r   r   terminated_event   s    zConnection.terminated_eventc                 C   s^   t F d| _| jd ur"| j  n| tv r<t|  t  W d    n1 sP0    Y  d S NT)r4   r$   r%   r"   r6   remover:   r;   r   r   r   r   r"      s    

zConnection.disconnectc                 C   sP   t 8 | jdurttd| | t|| | _W d   n1 sB0    Y  dS )zAttaches this server to the specified Session as a Server component.

        Raises ValueError if the server already belongs to some session.
        NzAttaching {0} to {1})r4   r%   
ValueErrorr
   r@   rD   )r   sessionr   r   r   attach_to_session   s
    
zConnection.attach_to_sessionN)__name__
__module____qualname____doc__rC   rE   r)   r*   rL   rN   r"   rS   r   r   r   r   r      s   
 
r   c                       s   e Zd ZdZejjZG dd dejZ fddZe	dd Z
e	dd	 Zd
d Zedd Zedd Zedd Zedd Zedd Zedd Zedd Zdd Z fddZ  ZS )rD   z1Handles the debug server side of a debug session.c                   @   sL   e Zd Zddddddddddddddddddddddddddg g g dZdS )zServer.CapabilitiesF)ZsupportsCompletionsRequestZsupportsConditionalBreakpointsZ supportsConfigurationDoneRequestZsupportsDataBreakpointsZ supportsDelayedStackTraceLoadingZsupportsDisassembleRequestZsupportsEvaluateForHoversZsupportsExceptionInfoRequestZsupportsExceptionOptionsZsupportsFunctionBreakpointsZsupportsGotoTargetsRequestZ!supportsHitConditionalBreakpointsZsupportsLoadedSourcesRequestZsupportsLogPointsZsupportsModulesRequestZsupportsReadMemoryRequestZsupportsRestartFrameZsupportsRestartRequestZsupportsSetExpressionZsupportsSetVariableZsupportsStepBackZsupportsStepInTargetsRequestZsupportsTerminateDebuggeeZsupportsTerminateRequestZsupportsTerminateThreadsRequestZsupportsValueFormattingOptionsZexceptionBreakpointFiltersZadditionalModuleColumnsZsupportedChecksumAlgorithmsN)rT   rU   rV   Z
PROPERTIESr   r   r   r   Capabilities   s<   rX   c                    s   |j d u sJ | |j rJ tt| j||jd || _| jjd u sJJ | jjrx| jjj| jkrxt	
d| jjj| j | j| j_| |_ W d    n1 s0    Y  d S )N)r'   z6Launcher reported PID={0}, but server reported PID={1})r%   superrD   rC   r'   
connectionrR   r   launcherr
   r@   )r   rR   rZ   	__class__r   r   rC     s    

zServer.__init__c                 C   s   | j jS )z>Process ID of the debuggee process, as reported by the server.)rZ   r   r   r   r   r   r     s    z
Server.pidc                 C   s   | j jS )zEParent process ID of the debuggee process, as reported by the server.)rZ   r   r   r   r   r   r     s    zServer.ppidc                 C   s@   | dsJ | j  | j|}|  | | |j| _d S )Nr    )	Z
is_requestrZ   r)   r'   Z	propagateZwait_for_responserX   ZresponseZcapabilitiesrJ   r   r   r   r      s
    
zServer.initializec                 C   s   | dd S rH   rI   rJ   r   r   r   r*   '  s    zServer.requestc                 C   s   | j | d S r   )rA   propagate_after_startrK   r   r   r   rL   3  s    zServer.eventc                 C   s   d S r   r   rK   r   r   r   initialized_event7  s    zServer.initialized_eventc                 C   s   | j s| j| d S r   r[   rA   r^   rK   r   r   r   process_event<  s    zServer.process_eventc                 C   s   | j jdvr| j | d S )N)ZvisualstudioZvsformac)rA   Z	client_idr^   rK   r   r   r   continued_eventB  s    zServer.continued_eventc                 C   s   | j s| j| d S r   r`   rK   r   r   r   exited_eventZ  s    zServer.exited_eventc                 C   s   | j   d S r   rM   rK   r   r   r   rN   `  s    zServer.terminated_eventc                 C   sX   t @ d| _| j| j_t| j | j_| jj_d | j_W d    n1 sJ0    Y  d S )NF)	r4   Zis_connectedrZ   r'   handlersr&   r-   rB   r%   r   r   r   r   detach_from_sessione  s
    
zServer.detach_from_sessionc                    sJ   t $ t| j t  W d    n1 s.0    Y  tt|   d S r   )	r4   r6   rP   rZ   r:   r;   rY   rD   r"   r   r\   r   r   r"   l  s    &zServer.disconnect)rT   rU   rV   rW   r   	ComponentZmessage_handlerrX   rC   propertyr   r   r    r*   rL   r_   ra   rb   rc   rN   re   r"   __classcell__r   r   r\   r   rD      s2   !








rD   	127.0.0.1c                 C   s   t dt| |at S )NrD   )r   server   listenergetsockname)hostportr   r   r   rj   s  s    rj   c                   C   s0   zt   W n ty*   tjdd Y n0 d S )Nr   r   )rk   r=   r<   r
   r3   r   r   r   r   stop_servingy  s    ro   c                   C   s0   t  ttW  d    S 1 s"0    Y  d S r   )r4   listr6   r   r   r   r   connections  s    rq   c                    s   fdddk_ r8tjdd}d|_|  dkrLtd|  tT t	   fdd	t
D }t|d
}|d
usj r|W  d
   S W d
   n1 s0    Y  t  qLd
S )zWaits until there is a server with the specified PID connected to this adapter,
    and returns the corresponding Connection.

    If there is more than one server connection already available, returns the oldest
    one.
    c                      s@   t   d_t t  W d    n1 s20    Y  d S rO   )timesleep	timed_outr4   r:   r;   r   )timeoutwait_for_timeoutr   r   rv     s    
z-wait_for_connection.<locals>.wait_for_timeoutr   z%servers.wait_for_connection() timeouttargetr-   Tz/{0} waiting for connection from debug server...c                 3   s   | ]} |r|V  qd S r   r   r   )	predicater   r   r     r   z&wait_for_connection.<locals>.<genexpr>N)rt   	threadingThreaddaemonr(   r
   r@   r4   r:   clearr6   nextwait)rR   ry   ru   threadZconnsr   r   )ry   ru   rv   r   wait_for_connection  s"    

0r   c                   C   sR   t   t0 t   tts.W d   dS W d   q 1 sB0    Y  q dS )zBlocks until all debug servers disconnect from the adapter.

    If there are no server connections, waits until at least one is established first,
    before waiting for it to disconnect.
    N)r:   r   r4   r}   r8   r6   r   r   r   r   wait_until_disconnected  s
    r   c                   C   s0   t  t  W d   n1 s"0    Y  dS )zlUnblocks any pending wait_until_disconnected() call that is waiting on the
    first server to connect.
    N)r4   r:   r;   r   r   r   r   r>     s    r>   c              
      s  t  \}}tjttjt	j
d|d t| g}tjd urN|dtjg7 }||7 }|dtg7 }td| ztj|dtjtjtjd W nB ty } z*td ttd	|W Y d }~n
d }~0 0  fd
d}tj|tdd}d|_|  d S )Nz	--connect:z--adapter-access-tokenz--pidz/Spawning attach-to-PID debugger injector: {0!r}r   )bufsizestdinstdoutstderrz7Failed to inject debug server into process with PID={0}z<Failed to inject debug server into process with PID={0}: {1}c                     s4    j  } | sq$td|   q td d S )NzInjector[PID={0}] output:
{1}zInjector[PID={0}] exited.)r   readliner
   r@   rstrip)lineZinjectorr   r   r   capture_output  s
    
zinject.<locals>.capture_outputzInjector[PID={0}] outputrw   T)rk   rl   sys
executabler   filenamer.   r/   r0   r!   r1   r&   r   rF   r
   r@   
subprocessPopenPIPEZSTDOUTr<   r3   r   r2   r   rz   r{   r|   r(   )r   Zdebugpy_argsrm   rn   Zcmdlineexcr   r   r   r   r   inject  sD    

	
r   )ri   r   )N)&Z
__future__r   r   r   r   r.   r   r   rz   rr   r!   r   Zdebugpy.commonr   r   r	   r
   r   r   r#   r   rF   RLockr4   r6   ZEventr:   r+   r   rf   rD   rj   ro   rq   r   r   r>   r   r   r   r   r   <module>   s0     > 

"