o
    Zh@                     @   s   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mZ d dlZd dlZd dlZd dlmZ d dlmZ dd ZG dd	 d	ZG d
d dejZde
e dee dee fddZG dd dZdd ZdS )    N)Path)ListUnionSequenceOptionalAnyTupleSet)Producer)	_sys_pathc              	   C   s~   g }|  dD ].}|d}z
t|d | }W n ty&   || Y qw |||d d  g|  q|s=td|S )NZtx*   z6MISSING test execution (tx) nodes: please specify --tx)getvaluefindint
ValueErrorappendextendpytest
UsageError)configZ	xspeclistZxspecinum r   I/var/www/html/lang_env/lib/python3.10/site-packages/xdist/workermanage.pyparse_spec_config   s   
r   c                   @   sp   e Zd ZdZg dZddddZdd	 Zd
d Zdd Zdd Z	dd Z
dee fddZdd ZdddZdS )NodeManager
   )z.*z*.pycz*.pyoz*~Npyexecnetcachereturnc                 C   s   || _ | j jd| _| j d| _| jd u rt j| _t	 | _
|d u r*|  }g | _|D ]"}t|tjs<t|}|jsE|jsE||_| j
| | j| q/|  | _|  | _t | _d S )Nnodemanager
testrunuid)r   tracegetZ	getoptionr!   uuiduuid4hexexecnetGroupgroup
_getxspecsspecs
isinstanceXSpecchdirpopenZallocate_idr   _getrsyncdirsroots_getrsyncoptionsrsyncoptionsset_rsynced_specs)selfr   r+   Zdefaultchdirspecr   r   r   __init__&   s&   




zNodeManager.__init__c                 C   s0   | j r| j D ]}| j||fi | j qdS dS )z1Rsync the set of roots to the node's gateway cwd.N)r1   rsyncr3   )r6   gatewayrootr   r   r   rsync_roots;   s
   
zNodeManager.rsync_rootsc                    s6   j jjj jd d  fddjD S )N)r   r+   zsetting up nodesc                    s   g | ]} | qS r   )
setup_node).0r7   puteventr6   r   r   
<listcomp>D   s    z+NodeManager.setup_nodes.<locals>.<listcomp>)r   hookZpytest_xdist_setupnodesr+   r"   )r6   r@   r   r?   r   setup_nodesA   s   
zNodeManager.setup_nodesc                 C   sV   | j |}| jjj|d | | t| || j|}||_|  | 	d|  |S )N)r:   zstarted node %r)
r)   Zmakegatewayr   rB   Zpytest_xdist_newgatewayr<   WorkerControllernodesetupr"   )r6   r7   r@   ZgwrE   r   r   r   r=   F   s   
zNodeManager.setup_nodec                 C   s   | j | j d S N)r)   	terminateEXIT_TIMEOUTr6   r   r   r   teardown_nodesP      zNodeManager.teardown_nodesc                 C   s   dd t | jD S )Nc                 S   s   g | ]}t |qS r   )r'   r-   r>   xr   r   r   rA   T   s    z*NodeManager._getxspecs.<locals>.<listcomp>)r   r   rJ   r   r   r   r*   S   s   zNodeManager._getxspecsc                 C   s   | j D ]
}|jr|jr nqg S dd l}dd l}dd }||j}||j}| j}||g}||jj7 }|	d}	|	r?|
|	 g }
|D ]}t| }| sW|d|||
vr`|
| qC|
S )Nr   c                 S   s*   |  d}tj|dkrtj| S |S )zRReturn the directory path if p is a package or the path to the .py file otherwise.coz__init__.py)rstripospathbasenamedirname)pstrippedr   r   r   get_dir_   s   
z*NodeManager._getrsyncdirs.<locals>.get_dirZ	rsyncdirszrsyncdir doesn't exist: )r+   r/   r.   r   _pytest__file__r   optionZrsyncdirgetinir   r   resolveexistsr   r   )r6   r7   r   rX   rW   Z
pytestpathZ	pytestdirr   
candidatesZ
rsyncrootsr1   r;   r   r   r   r0   V   s2   





zNodeManager._getrsyncdirsc                 C   sR   t | j}|dd | jjjD 7 }|dd | jdD 7 }|t| jjdddS )z#Get options to be passed for rsync.c                 S      g | ]}t |qS r   strr>   rR   r   r   r   rA   {       z0NodeManager._getrsyncoptions.<locals>.<listcomp>c                 S   r_   r   r`   rb   r   r   r   rA   |   rc   rsyncignoreverboser   )ignoresre   )listDEFAULT_IGNORESr   rZ   rd   r[   getattr)r6   rf   r   r   r   r2   x   s   
zNodeManager._getrsyncoptionsFc                    s   t ||d}|jjr!js!|dtjt 	  dS f| j
v r*dS  fdd}|j||d | j
f | jjj|gd |  | jjj|gd dS )z'Perform rsync to remote hosts for node.)re   rf   zA
                import sys ; sys.path.insert(0, %r)
            Nc                      s    r
 d d S d S )NZrsyncrootreadyr   r   notifysourcer7   r   r   finished   s   z#NodeManager.rsync.<locals>.finished)rm   )rl   Zgateways)	HostRSyncr7   r/   r.   remote_execrQ   rR   rT   ra   Z	waitcloser5   add_target_hostaddr   rB   Zpytest_xdist_rsyncstartsendZpytest_xdist_rsyncfinish)r6   r:   rl   rk   re   rf   r9   rm   r   rj   r   r9      s$   zNodeManager.rsync)Nr   )r   N)NFN)__name__
__module____qualname__rI   rh   r8   r<   rC   r=   rK   r*   r   r   r0   r2   r9   r   r   r   r   r   "   s    
"r   c                	       st   e Zd ZdZeedf Zdddedeee  de	ddf fd	d
Z
dedefddZd fdd	Zdd Z  ZS )rn   z%RSyncer that filters out common fileszos.PathLike[str]N)rf   	sourcedirrf   kwargsr   c                   s:   |d u rg }dd |D | _ t jddt|i| d S )Nc              	   S   s"   g | ]}t tt|qS r   )recompilefnmatch	translaterQ   fspathrM   r   r   r   rA      s   " z&HostRSync.__init__.<locals>.<listcomp>rv   r   )_ignoressuperr8   r   )r6   rv   rf   rw   	__class__r   r   r8      s   zHostRSync.__init__rR   c                 C   s8   t |}| jD ]}||js|t|r dS qdS )NFT)r   r}   matchnamera   )r6   rR   Zcrer   r   r   filter   s   
zHostRSync.filterc                    s&   t j| j}t j|||dd d S )NT)Zfinishedcallbackdelete)rQ   rR   rS   
_sourcedirr~   Z
add_target)r6   r:   rm   
remotepathr   r   r   rp      s   zHostRSync.add_target_hostc                 C   sJ   | j dkr#tj| jd | }|jj}t|j d| d|  d S d S )Nr   /:z <= )Z_verboserQ   rR   rS   r   r7   r.   print)r6   r:   Zmodified_rel_pathrR   r   r   r   r   _report_send_file   s
   
zHostRSync._report_send_filerG   )rs   rt   ru   __doc__r   ra   PathLiker   r   objectr8   boolr   rp   r   __classcell__r   r   r   r   rn      s     
rn   r1   argsr   c           
   
   C   s   d}g }|D ]b}| |}t|d }z| }W n ty$   d}Y nw |s-|| q| D ](}z||}	W n tyC   d }	Y nw |	sJ||krW|jd t|	 |d<  n	q/td| d||	| q|S )Nz::r   Fr   zarg z not relative to an rsync root)
splitr   r]   OSErrorr   relative_tor   r   ra   join)
r1   r   Z	splitcoderesultargpartsr|   r]   r;   rN   r   r   r   make_reltoroot   s4   

r   c                   @   s   e Zd ZdZG dd dZdd Zdd Ze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d Zdd ZdS )rD   c                   @   s    e Zd Zejdddd ZdS )zWorkerController.RemoteHookT)Ztrylastc                 C   s   t jS rG   )xdistremoterJ   r   r   r   pytest_xdist_getremotemodule   s   z8WorkerController.RemoteHook.pytest_xdist_getremotemoduleN)rs   rt   ru   r   Zhookimplr   r   r   r   r   
RemoteHook   s    
r   c                 C   sn   |j |   || _|| _|| _|| _|jt|j	|j
tjd| _d| _d| _td|j |jjd| _d S )N)ZworkeridZworkercountr!   ZmainargvFz
workerctl-)enabled)Zpluginmanagerregisterr   r    r@   r:   r   idlenr+   r!   sysargvworkerinput_down_shutdown_sentr
   rZ   debuglog)r6   r    r:   r   r@   r   r   r   r8      s   zWorkerController.__init__c                 C   s   d| j j d| jj dS )N< >)r   rs   r:   r   rJ   r   r   r   __repr__   s   zWorkerController.__repr__c                 C   s   | j p| jS rG   )r   r   rJ   r   r   r   shutting_down   s   zWorkerController.shutting_downc                 C   s  |  d | jj}t| jdrdd | jjjpdD }i }n
| jj}t| jj}|j	r.|j
r5t| jj|}|j	rRd| jj }t| jdrR| jj }t|| |d< | jjj| d	 | jj }| j|| _| jjj	rntnd }| j| j|||f | jr| jj| j| jd
 d S d S )Nzsetting up worker sessioninvocation_paramsc                 S   r_   r   r`   rM   r   r   r   rA     rc   z*WorkerController.setup.<locals>.<listcomp>r   zpopen-%s_tmp_path_factorybasetemprE   )Z	endmarker)r   r:   r7   hasattrr   r   r   varsrZ   r/   r.   r   r    r1   r   r   Zgetbasetempra   rB   Zpytest_configure_noder   ro   channelr   rr   r   r@   Zsetcallbackprocess_from_remoteENDMARK)r6   r7   r   Zoption_dictr   r   Zremote_moduleZchange_sys_pathr   r   r   rF     s,   
zWorkerController.setupc                 C   sV   t | dr| j s| d| j | j  t | dr)| d| j | j  d S d S )Nr   closingr:   Zexiting)r   r   isclosedr   closer:   exitrJ   r   r   r   ensure_teardown  s   



z WorkerController.ensure_teardownc                 C      | j d|d d S )NZruntestsindicessendcommandr6   r   r   r   r   send_runtest_some)  rL   z"WorkerController.send_runtest_somec                 C   s   |  d d S )NZruntests_allr   rJ   r   r   r   send_runtest_all,  s   z!WorkerController.send_runtest_allc                 C   r   )NZstealr   r   r   r   r   r   
send_steal/  rL   zWorkerController.send_stealc                 C   s6   | j sz| d W n	 ty   Y nw d| _d S d S )NshutdownT)r   r   r   r   rJ   r   r   r   r   2  s   
zWorkerController.shutdownc                 K   s,   |  d| d| d | j||f dS )z4send a named parametrized command to the other side.zsending command (**)N)r   r   rr   )r6   r   rw   r   r   r   r   :  s   zWorkerController.sendcommandc                 K   s*   |  d| d| d | ||f d S )Nzqueuing r   r   )r   r@   )r6   	eventnamerw   r   r   r   notify_inproc?  s   zWorkerController.notify_inprocc           
      C   s  z=|| j kr&| j }| js#|rt|trd}| jd| |d d| _W dS |\}}|dv r=| d| d| d	 W dS |d
krO| j|fd| i| W dS |dkra| j|fd| i| W dS |dkrwd| _|d | _| jd| d W dS |dv r| j|fd| i| W dS |dv r|	dd}| j
jj| j
|d d}|dur||_| j|| |d W dS |dkr| j|| |d d W dS |dkr| j|fd| i| W dS |dkr| j|fd| i| W dS |dkr| j||d |d |d |d d W dS |d krt|d! }| j|||d" |d# d$ W dS |d%kr8t|d! }| j|||d" |d |d& d' W dS td(|  tyG       d)d*lm} | }	td+|	 | j
|	 |   | jd| |	d Y dS ),a
  this gets called for each object we receive from
        the other side and if the channel closes.

        Note that channel callbacks run in the receiver
        thread of execnet gateways - we need to
        avoid raising exceptions or doing heavy work.
        zNot properly terminatedZ	errordown)rE   errorTN)Zcollectionstartz	ignoring (r   ZworkerreadyrE   Zinternal_errorZworkerfinishedworkeroutputr   )ZlogstartZ	logfinish)Z
testreportZcollectreportZteardownreport
item_indexdata)r   r   )rE   repZcollectionfinishids)rE   r   Zruntest_protocol_completeZunscheduledZ
logwarningmessagecodenodeid)r   r   r   Z
fslocationZwarning_capturedZwarning_message_datawhenitem)warning_messager   r   Zwarning_recordedlocation)r   r   r   r   zunknown event: r   )ExceptionInfoz!!!!!!!!!!!!!!!!!!!!)r   r   Z_getremoteerrorr   r,   EOFErrorr   r   r   popr   rB   Zpytest_report_from_serializabler   unserialize_warning_messager   KeyboardInterruptZ_pytest._coder   Zfrom_currentr   Znotify_exceptionr   )
r6   Z	eventcallerrr   rw   r   r   r   r   excinfor   r   r   r   C  s   






z$WorkerController.process_from_remoteN)rs   rt   ru   r   r   r8   r   propertyr   rF   r   r   r   r   r   r   r   r   r   r   r   r   rD      s     
rD   c           
      C   s  dd l }dd l}| d rK|| d }t|| d }d }| d d ur4z|| d  }W n	 ty3   Y nw |d u rJdj| d | d | d d}t|}n| d }| d rb|| d }t|| d	 }nd }||d
}|jjD ]}	|	d
v rtqm| |	 ||	< qm|jdi |S )Nr   Zmessage_moduleZmessage_class_nameZmessage_argsz{mod}.{cls}: {msg}Zmessage_str)modclsmsgZcategory_moduleZcategory_class_name)r   categoryr   )	warnings	importlibimport_moduleri   	TypeErrorformatWarningWarningMessage_WARNING_DETAILS)
r   r   r   r   r   r   message_textr   rw   	attr_namer   r   r   r     s>   
r   )rz   rQ   rx   r   r$   pathlibr   typingr   r   r   r   r   r   r	   r   r'   Zxdist.remoter   r
   Zxdist.pluginr   r   r   ZRSyncrn   ra   r   rD   r   r   r   r   r   <module>   s(    $ "$ 9