a
    4ñ»j¢I  ã                   @  s>  d dl mZ d dlmZ d dlZd dlZd dlZd dlmZ d dl	Z	d dl
Z
d dlmZ d dlmZ d dlmZ d dlm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Zd d
lmZ d dlmZ dddœdd„ZG dd„ dƒZG dd„ dejƒZddddœdd„ZG dd„ dejƒZ G dd„ dƒZ!dddœd d!„Z"dS )"é    )Úannotations)ÚSequenceN)ÚPath)ÚAny)ÚCallable)ÚLiteral)ÚUnion)Ú	_sys_path)ÚProducer)Ú
WorkerInfoúpytest.Configz	list[str])ÚconfigÚreturnc              	   C  s‚   g }|   d¡}|D ]\}| d¡}zt|d |… ƒ}W n tyP   | |¡ Y q0 | ||d d … g| ¡ q|s~t d¡‚|S )NÚtxÚ*é   z6MISSING test execution (tx) nodes: please specify --tx)ÚgetvalueÚfindÚintÚ
ValueErrorÚappendÚextendÚpytestÚ
UsageError)r   Z	xspeclistr   ZxspecÚiÚnum© r   ú8E:\soccer\ml_env\Lib\site-packages\xdist/workermanage.pyÚparse_tx_spec_config   s    

ÿr   c                   @  sÀ   e Zd ZdZg d¢Zd0ddddd	œd
d„Zdddœdd„Zdddœdd„Zddddœdd„Zddœdd„Z	ddœdd„Z
ddœd d!„Zd"dœd#d$„Zd%dœd&d'„Zd1dd)d*d+d,dd-œd.d/„ZdS )2ÚNodeManageré
   )z.*z*.pycz*.pyoz*~NÚpyexecnetcacher   z$Sequence[execnet.XSpec | str] | NoneÚstrÚNone)r   ÚspecsÚdefaultchdirr   c                 C  s$  || _ | j j d¡| _| j  d¡| _| jd u r:t ¡ j| _tj	dd�| _
|  ¡ D ]2}t|dd ƒd u rvt d|› d�¡‚| j
 |¡ qP|d u r”|  ¡ }g | _|D ]d}t|tjƒs¸t |¡}t|dd ƒdkrØt d	|› �¡}|jsê|jsê||_| j
 |¡ | j |¡ qž|  ¡ | _|  ¡ | _tƒ | _d S )
NÚnodemanagerÚ
testrunuidÚmain_thread_only)Ú	execmodelÚidzProxy gateway z must include an idr)   úexecmodel=main_thread_only//)r   ÚtraceÚgetÚ	getoptionr'   ÚuuidÚuuid4ÚhexÚexecnetÚGroupÚgroupÚ_getpxspecsÚgetattrr   r   ÚmakegatewayÚ_gettxspecsr$   Ú
isinstanceÚXSpecÚchdirÚpopenZallocate_idr   Ú_getrsyncdirsÚrootsÚ_getrsyncoptionsÚrsyncoptionsÚsetÚ_rsynced_specs)Úselfr   r$   r%   Z
proxy_specÚspecr   r   r   Ú__init__0   s6    

ÿ


zNodeManager.__init__úexecnet.Gateway)Úgatewayr   c                 C  s,   | j r(| j D ]}| j||fi | j¤Ž qdS )z1Rsync the set of roots to the node's gateway cwd.N)r>   Úrsyncr@   )rC   rG   Úrootr   r   r   Úrsync_rootsU   s    
zNodeManager.rsync_rootsú,Callable[[tuple[str, dict[str, Any]]], None]zlist[WorkerController])Úputeventr   c                   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)Ú.0rD   ©rL   rC   r   r   Ú
<listcomp>a   ó    z+NodeManager.setup_nodes.<locals>.<listcomp>)r   ÚhookZpytest_xdist_setupnodesr$   r,   )rC   rL   r   rO   r   Úsetup_nodes[   s    
zNodeManager.setup_nodeszexecnet.XSpecÚWorkerController)rD   rL   r   c                 C  sv   t |dd ƒdkr t d|› �¡}| j |¡}| jjj|d� |  |¡ t	| || j|ƒ}||_
| ¡  |  d| ¡ |S )Nr)   r(   r+   )rG   zstarted node %r)r6   r2   r:   r4   r7   r   rR   Zpytest_xdist_newgatewayrJ   rT   ÚnodeÚsetupr,   )rC   rD   rL   ZgwrU   r   r   r   rM   c   s    
zNodeManager.setup_node©r   c                 C  s   | j  | j¡ d S ©N)r4   Ú	terminateÚEXIT_TIMEOUT©rC   r   r   r   Úteardown_nodest   s    zNodeManager.teardown_nodeszlist[execnet.XSpec]c                 C  s   dd„ t | jƒD ƒS )Nc                 S  s   g | ]}t  |¡‘qS r   ©r2   r:   ©rN   Úxr   r   r   rP   x   rQ   z+NodeManager._gettxspecs.<locals>.<listcomp>)r   r   r[   r   r   r   r8   w   s    zNodeManager._gettxspecsc                 C  s   dd„ | j  d¡D ƒS )Nc                 S  s   g | ]}t  |¡‘qS r   r]   r^   r   r   r   rP   {   rQ   z+NodeManager._getpxspecs.<locals>.<listcomp>Zpx)r   r.   r[   r   r   r   r5   z   s    zNodeManager._getpxspecsz
list[Path]c                 C  sÎ   | j D ]}|jr|jr q qg S dd l}dd l}dddœdd„}||jƒ}||jƒ}| j}||g}||jj7 }| 	d¡}	|	r†| 
|	¡ g }
|D ]:}t|ƒ ¡ }| ¡ s¶| d|›�¡‚||
vrŽ|
 |¡ qŽ|
S )Nr   r"   )Úpr   c                 S  s.   |   d¡}tj |¡dkr&tj | ¡S |S dS )zRReturn the directory path if p is a package or the path to the .py file otherwise.Úcoz__init__.pyN)ÚrstripÚosÚpathÚbasenameÚdirname)r`   Ústrippedr   r   r   Úget_dir†   s    
z*NodeManager._getrsyncdirs.<locals>.get_dirZ	rsyncdirszrsyncdir doesn't exist: )r$   r<   r;   Ú_pytestr   Ú__file__r   ÚoptionZrsyncdirÚgetinir   r   ÚresolveÚexistsr   r   )rC   rD   ri   r   rh   Z
pytestpathZ	pytestdirr   Ú
candidatesZ
rsyncrootsr>   rI   Ú	root_pathr   r   r   r=   }   s.    




zNodeManager._getrsyncdirsúdict[str, Any]c                 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  s   g | ]}t |ƒ‘qS r   ©r"   ©rN   rd   r   r   r   rP   ¢   rQ   z0NodeManager._getrsyncoptions.<locals>.<listcomp>c                 S  s   g | ]}t |ƒ‘qS r   rr   rs   r   r   r   rP   £   rQ   ÚrsyncignoreÚverboser   ©Úignoresru   )ÚlistÚDEFAULT_IGNORESr   rk   rt   rl   r6   )rC   rw   r   r   r   r?   Ÿ   s    
þzNodeManager._getrsyncoptionsFzstr | os.PathLike[str]zBCallable[[str, execnet.XSpec, str | os.PathLike[str]], Any] | Noner   zSequence[str] | None)rG   ÚsourceÚnotifyru   rw   r   c                   sÀ   t ˆ|dk|d�}|j‰ˆjrFˆjsF| dtj tˆƒ¡ ¡ 	¡  dS ˆˆf| j
v rXdS ddœ‡ ‡‡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.r   )ru   rw   zA
                import sys ; sys.path.insert(0, %r)
            Nr#   rW   c                     s   ˆ rˆ dˆˆƒ d S )NZrsyncrootreadyr   r   ©r{   rz   rD   r   r   ÚfinishedÇ   s    z#NodeManager.rsync.<locals>.finished)r}   )rz   Zgateways)Ú	HostRSyncrD   r<   r;   Úremote_execrc   rd   rf   r"   Z	waitcloserB   Úadd_target_hostÚaddr   rR   Zpytest_xdist_rsyncstartÚsendZpytest_xdist_rsyncfinish)rC   rG   rz   r{   ru   rw   rH   r}   r   r|   r   rH   ª   s"    ýÿzNodeManager.rsync)Nr!   )NFN)Ú__name__Ú
__module__Ú__qualname__rZ   ry   rE   rJ   rS   rM   r\   r8   r5   r=   r?   rH   r   r   r   r   r   ,   s"     ü%"   ør   c                      sz   e Zd ZdZeedf Zdddœdddd	d
œ‡ fdd„Zdddœdd„Zdddd	dœ‡ fdd„Z	ddd	dœdd„Z
‡  ZS )r~   z&RSyncer that filters out common files.zos.PathLike[str]NTrv   ÚPathLikezSequence[PathLike] | NoneÚboolr#   )Ú	sourcedirrw   ru   r   c                  s4   |d u rg }dd„ |D ƒ| _ tƒ jt|ƒ|d� d S )Nc              	   S  s"   g | ]}t  t t |¡¡¡‘qS r   )ÚreÚcompileÚfnmatchÚ	translaterc   Úfspathr^   r   r   r   rP   à   rQ   z&HostRSync.__init__.<locals>.<listcomp>)rˆ   ru   )Ú_ignoresÚsuperrE   r   )rC   rˆ   rw   ru   ©Ú	__class__r   r   rE   ×   s    zHostRSync.__init__)rd   r   c                 C  s8   t |ƒ}| jD ]$}| |j¡s,| t|ƒ¡r dS qdS )NFT)r   rŽ   ÚmatchÚnamer"   )rC   rd   Zcrer   r   r   Úfilterã   s
    
zHostRSync.filterrF   zCallable[[], None] | None)rG   r}   r   c                   s&   t j | j¡}tƒ j|||dd� d S )NT)ZfinishedcallbackÚdelete)rc   rd   re   Ú
_sourcedirr�   Z
add_target)rC   rG   r}   Ú
remotepathr�   r   r   r€   ë   s    zHostRSync.add_target_hostr"   )rG   Úmodified_rel_pathr   c                 C  sF   | j dkrBtj | j¡d | }|jj}t|j› d|› d|› �ƒ d S )Nr   ú/ú:z <= )Z_verboserc   rd   re   r–   rD   r;   Úprint)rC   rG   r˜   rd   r—   r   r   r   Ú_report_send_fileó   s    
zHostRSync._report_send_file)N)rƒ   r„   r…   Ú__doc__r   r"   r†   rE   r”   r€   rœ   Ú__classcell__r   r   r�   r   r~   Ò   s   û ýr~   zSequence[Path])r>   Úargsr   c           
   
   C  sÖ   d}g }|D ]Ä}|  |¡}t|d ƒ}z| ¡ }W n tyH   d}Y n0 |sZ| |¡ q| D ]P}z| |¡}	W n ty†   d }	Y n0 |	s”||kr^|jd t|	ƒ |d<  qÀq^td|› d�ƒ‚| | 	|¡¡ q|S )Nz::r   Fr™   zarg z not relative to an rsync root)
Úsplitr   rn   ÚOSErrorr   Úrelative_tor   r“   r"   Újoin)
r>   rŸ   Z	splitcodeÚresultÚargÚpartsr�   rn   rI   r_   r   r   r   Úmake_reltorootþ   s.    



r§   c                   @  s   e Zd ZdZdS )ÚMarkeréÿÿÿÿN)rƒ   r„   r…   ÚENDr   r   r   r   r¨     s   r¨   c                   @  sæ   e Zd ZU ded< G dd„ dƒZddddd	d
œdd„Zddœdd„Zeddœdd„ƒZd	dœdd„Z	d	dœdd„Z
dd	dœdd„Zd	dœdd„Zdd	dœdd„Zd	dœd d!„Zdd"d	d#œd$d%„Zdd"d	d&œd'd(„Zd)d	d*œd+d,„Zd-S ).rT   r   Z
workerinfoc                   @  s&   e Zd Zejdd�ddœdd„ƒZdS )zWorkerController.RemoteHookT)Ztrylastr   rW   c                 C  s   t jS rX   )ÚxdistÚremoter[   r   r   r   Úpytest_xdist_getremotemodule$  s    z8WorkerController.RemoteHook.pytest_xdist_getremotemoduleN)rƒ   r„   r…   r   Zhookimplr­   r   r   r   r   Ú
RemoteHook#  s   
r®   r   rF   r   rK   r#   )r&   rG   r   rL   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&   rL   rG   r   r*   Úlenr$   r'   ÚsysÚargvÚworkerinputÚ_downÚ_shutdown_sentr
   rk   ÚdebugÚlog)rC   r&   rG   r   rL   r   r   r   rE   (  s    üzWorkerController.__init__r"   rW   c                 C  s   d| j j› d| jj› d�S )Nú<ú ú>)r‘   rƒ   rG   r*   r[   r   r   r   Ú__repr__>  s    zWorkerController.__repr__r‡   c                 C  s   | j p
| jS rX   )rµ   r¶   r[   r   r   r   Úshutting_downA  s    zWorkerController.shutting_downc                 C  sü   |   d¡ | j ¡  | jj}dd„ | jjjp.dD ƒ}i }|jrD|jrRt	| j
j|ƒ}|jrŒd| jj }t| jdƒrŒ| jj ¡ }t|| ƒ|d< | jjj| d� | jj ¡ }| j |¡| _| jjjrÄtnd }| j | j|||f¡ | jrø| jj| jtjd	� d S )
Nzsetting up worker sessionc                 S  s   g | ]}t |ƒ‘qS r   rr   r^   r   r   r   rP   M  rQ   z*WorkerController.setup.<locals>.<listcomp>r   zpopen-%sÚ_tmp_path_factoryÚbasetemp©rU   )Z	endmarker)r¸   rG   Z_rinforD   r   Zinvocation_paramsrŸ   r<   r;   r§   r&   r>   r*   Úhasattrr¾   Zgetbasetempr"   rR   Zpytest_configure_noder­   r   Úchannelr	   r‚   r´   rL   ZsetcallbackÚprocess_from_remoter¨   rª   )rC   rD   rŸ   Úoption_dictr“   r¿   Zremote_moduleZchange_sys_pathr   r   r   rV   E  s&    

zWorkerController.setupc                 C  sR   t | dƒr,| j ¡ s,|  d| j¡ | j ¡  t | dƒrN|  d| j¡ | j ¡  d S )NrÂ   ÚclosingrG   Zexiting)rÁ   rÂ   Úisclosedr¸   ÚcloserG   Úexitr[   r   r   r   Úensure_teardownc  s    



z WorkerController.ensure_teardownzSequence[int])Úindicesr   c                 C  s   | j d|d� d S )NZruntests©rÊ   ©Úsendcommand©rC   rÊ   r   r   r   Úsend_runtest_somen  s    z"WorkerController.send_runtest_somec                 C  s   |   d¡ d S )NZruntests_allrÌ   r[   r   r   r   Úsend_runtest_allq  s    z!WorkerController.send_runtest_allc                 C  s   | j d|d� d S )NZstealrË   rÌ   rÎ   r   r   r   Ú
send_stealt  s    zWorkerController.send_stealc                 C  s2   | j s.z|  d¡ W n ty&   Y n0 d| _d S )NÚshutdownT)rµ   rÍ   r¡   r¶   r[   r   r   r   rÒ   w  s    zWorkerController.shutdownÚobject)r“   Úkwargsr   c                 K  s,   |   d|› d|› d�¡ | j ||f¡ dS )z4Send a named parametrized command to the other side.zsending command ú(**ú)N)r¸   rÂ   r‚   )rC   r“   rÔ   r   r   r   rÍ     s    zWorkerController.sendcommand)Ú	eventnamerÔ   r   c                 K  s*   |   d|› d|› d�¡ |  ||f¡ d S )Nzqueuing rÕ   rÖ   )r¸   rL   )rC   r×   rÔ   r   r   r   Únotify_inproc„  s    zWorkerController.notify_inprocz0tuple[str, dict[str, Any]] | Literal[Marker.END])Ú	eventcallr   c           	      C  sœ  �z4|t ju rL| j ¡ }| jsF|r,t|tƒr0d}| jd| |d� d| _W dS |\}}|dv rx|  d|› d|› d	�¡ �n¼|d
krš| j|fd| i|¤Ž �nš|dkr¼| j|fd| i|¤Ž �nx|dkræd| _|d | _	| jd| d� �nN|dv �r
| j|fd| i|¤Ž �n*|dv �rZ| 
dd¡}| jjj| j|d d�}|du�rH||_| j|| |d� nÚ|dk�rz| j|| |d d� nº|dk�rœ| j|fd| i|¤Ž n˜|dk�r¾| j|fd| i|¤Ž nv|dk�rî| j||d |d |d |d d� nF|d k�r&t|d! ƒ}| j|||d" |d |d# d$� ntd%|› �ƒ‚W n` t�yL   ‚ Y nL t�y–   tj ¡ }td&|ƒ | j |¡ |  ¡  | jd| |d� Y n0 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)rU   ÚerrorTN)Zcollectionstartz	ignoring ú(rÖ   ZworkerreadyrU   Zinternal_errorZworkerfinishedÚworkeroutputrÀ   )ZlogstartZ	logfinish)Z
testreportZcollectreportZteardownreportÚ
item_indexÚdata)r   rÞ   )rU   ÚrepZcollectionfinishÚids)rU   rà   Zruntest_protocol_completeZunscheduledZ
logwarningÚmessageÚcodeÚnodeid)rá   râ   rã   Z
fslocationZwarning_recordedZwarning_message_dataÚwhenÚlocation)Úwarning_messagerä   rã   rå   zunknown event: z!!!!!!!!!!!!!!!!!!!!)r¨   rª   rÂ   Z_getremoteerrorrµ   r9   ÚEOFErrorrØ   r¸   rÜ   Úpopr   rR   Zpytest_report_from_serializablerÝ   Úunserialize_warning_messager   ÚKeyboardInterruptÚBaseExceptionr   ZExceptionInfoZfrom_currentr›   Znotify_exceptionrÒ   )	rC   rÙ   Úerrr×   rÔ   rÝ   rß   ræ   Úexcinfor   r   r   rÃ   ˆ  s€    






ÿ




û
ÿû

z$WorkerController.process_from_remoteN)rƒ   r„   r…   Ú__annotations__r®   rE   r¼   Úpropertyr½   rV   rÉ   rÏ   rÐ   rÑ   rÒ   rÍ   rØ   rÃ   r   r   r   r   rT     s   
rT   rq   zwarnings.WarningMessage)rÞ   r   c           	      C  sþ   dd l }| d rŽ| | d ¡}t|| d ƒ}d }| d d ur`z|| d Ž }W n ty^   Y n0 |d u r–dj| d | d | d d�}t|ƒ}n| d }| d r¼| | d ¡}t|| d	 ƒ}nd }||d
œ}tjjD ]}|d
v ràqÒ| | ||< qÒtjf 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á   Úcategory)	Ú	importlibÚimport_moduler6   Ú	TypeErrorÚformatÚWarningÚwarningsÚWarningMessageÚ_WARNING_DETAILS)	rÞ   rô   rð   rñ   rá   Úmessage_textró   rÔ   Ú	attr_namer   r   r   ré   Ö  s8    ý

ré   )#Ú
__future__r   Úcollections.abcr   Úenumr‹   rc   Úpathlibr   r‰   r²   Útypingr   r   r   r   r/   rù   r2   r   Zxdist.pluginr	   Zxdist.remoter«   r
   r   r   r   ZRSyncr~   r§   ÚEnumr¨   rT   ré   r   r   r   r   Ú<module>   s8    ', 8