
    i'                    >   S r SSKJr  SSKJr  SSKrSSKJr  SSKrSSK	r	SSK
Jr  SSKJr  SSKrSSKrSSKJr  \R$                  SS	 j5       r\R$                  SS
 j5       rSS jr " S S5      r      SS jr        SS jr " S S5      r " S S5      rg)a&  
Implement -f aka looponfailing for pytest.

NOTE that we try to avoid loading and depending on application modules
within the controlling process (the one that starts repeatedly test
processes) otherwise changes to source code can crash
the controlling process which should best never happen.
    )annotations)SequenceN)Path)Any)TerminalWriter)
visit_pathc           	     P    U R                  SS5      nUR                  SSSSSSS	9  g )
Nxdistz"distributed and subprocess testingz-fz--looponfail
store_true
looponfailFzdRun tests in subprocess: wait for files to be modified, then re-run failing test set until all pass.)actiondestdefaulthelp)getgroup
_addoption)parsergroups     O/var/www/html/ai-image-ml/venv/lib/python3.13/site-packages/xdist/looponfail.pypytest_addoptionr      s:    OOG%IJE	2      c                    U R                  S5      (       a;  U R                  SS5      nU(       a  [        R                  " S5      e[        U 5        gg )Nr   usepdbFz(--pdb is incompatible with --looponfail.   )	getoptionpytest
UsageErrorlooponfail_main)configr   s     r   pytest_cmdline_mainr    (   sH    %%!!(E2##$NOOr   c                   [        U 5      nU R                  S5      nU(       d  [        R                  " 5       /nU Vs/ s H  n[        U5      PM     nn[	        U5      n  UR                  5         UR                  (       d  UR                  (       a  M5  [        UR                  US9  UR                  SS9  MY  s  snf ! [         a    [        5          g f = f)Nlooponfailroots)failreportsrootdirsg       @)checkinterval)RemoteControlgetinir   cwdStatRecorder	loop_oncefailures
wasfailingrepr_pytest_looponfailinfowaitonchangeKeyboardInterruptprint)r   remotecontrolconfig_rootsrootr$   statrecorders         r   r   r   3   s    !&)M==!23L
|'34|tT
|H4)L##% ))m.F.F&)22X %%C%8  5  s   B;!AC   CCc                  f    \ rS rSr% S\S'   SS jrSS jrSS jrSS jrSS jr	SS	 jr
SS
 jrSrg)r&   H   execnet.Gatewaygatewayc                    Xl         / U l        g N)r   r+   )selfr   s     r   __init__RemoteControl.__init__K   s    #%r   c                    U R                   R                  R                  (       a%  SR                  S U 5       5      n[	        SU5        g g )N c              3  8   #    U  H  n[        U5      v   M     g 7fr:   )str).0xs     r   	<genexpr>&RemoteControl.trace.<locals>.<genexpr>Q   s     04a3q664s   zRemoteControl:)r   optiondebugjoinr0   )r;   argsmsgs      r   traceRemoteControl.traceO   s9    ;;##((0400C"C( $r   c                .    [         R                  " S5      $ )Nz!execmodel=main_thread_only//popen)execnetmakegatewayr;   s    r   initgatewayRemoteControl.initgatewayT   s    ""#FGGr   c                  ^ [        U S5      (       a  [        SU R                  -  5      eU R                  S5        U R	                  5       U l        U R                  R                  [        U R                  R                  [        U R                  R                  5      S9=U l        nUR                  5       n[        5       mSU4S jjnUR                  U5        g )Nr8   zalready have gateway %rzsetting up worker session)rI   option_dictc                p   > TR                   R                  U 5        TR                   R                  5         g r:   )_filewriteflush)souts    r   rW   "RemoteControl.setup.<locals>.writee   s!    IIOOAIIOOr   )rY   rA   returnNone)hasattr
ValueErrorr8   rK   rQ   remote_execinit_worker_sessionr   rI   varsrF   channelreceiver   setcallback)r;   rc   remote_outchannelrW   rZ   s       @r   setupRemoteControl.setupW   s    4##6EFF

./'')!%!9!9!!T[[//0 ": "
 	
w
 .5__->	 	%%e,r   c                h   [        U S5      (       aW  U R                  R                  5       (       d6  U R                  SU R                  5        U R                  R	                  5         U ?[        U S5      (       a9  U R                  SU R
                  5        U R
                  R                  5         U ?g g )Nrc   closingr8   exiting)r^   rc   isclosedrK   closer8   exitrP   s    r   ensure_teardownRemoteControl.ensure_teardownk   s    4##<<((**

9dll3""$4##JJy$,,/LL $r   c                    U R                  SU R                  5        U R                  R                  U R                  5         U R                  R	                  5       U R                  5         $ ! U R                  R                   a,    [        R                  " 5       S   nU R                  SU5        e f = f! U R                  5         f = f)Nsending   ERROR)	rK   r+   rc   sendrd   ro   RemoteErrorsysexc_info)r;   es     r   
runsessionRemoteControl.runsessionv   s    
	#JJy$--0LLdmm,||++-   " <<++ LLN1%

7A&
   "s   AB7 A. .AB44B7 7C	c                
   U R                  5         U R                  =(       a    [        U R                  5      U l        U R	                  5       nUu  p#nU(       a  g / nU H  nXe;  d  M
  UR                  U5        M     XPl        g r:   )rg   r+   lenr,   rz   append)r;   resultr+   reportscollection_faileduniq_failuresfailures          r   r*   RemoteControl.loop_once   sk    

-->C,>"/5,,M#/!((1 $ *Mr   )rc   r   r+   r8   r,   Nr   pytest.Configr\   r]   rI   objectr\   r]   )r\   r7   r\   r]   )r\   z!tuple[list[str], list[str], bool])__name__
__module____qualname____firstlineno____annotations__r<   rK   rQ   rg   ro   rz   r*   __static_attributes__ r   r   r&   r&   H   s,    &)
H-(	#*r   r&   c                    [        5       nU (       a3  UR                  SSSS9  U  H  nU(       d  M  UR                  USS9  M     UR                  SSSS9  U H  nUR                  SU 3SS9  M     g )N#LOOPONFAILINGT)bold)redzwaiting for changesz### Watching:   )r   sepline)r#   r$   trreportrootdirs        r   r-   r-      sw     
	B
sO$/!FvD) " FF3%DF1
"7),48 r   c                F   SS K nSS KnU R                  R                  5       nUR	                  S5      =Ul        Ul        U R                  U5        / nUR                   Hn  nU(       d  M  UR                  R                  U5      (       d1  UR                  S5      (       d  UR                  R                  U5      nUR                  U5        Mp     XdR                  S S & SSKJn  UR                  U[!        U5      5      n	Xl        SSKJn
  U
" X5      R)                  5         g )Nr   wz.__path_hook__)Config)WorkerFailSession)osrw   r8   
newchannelmakefilestdoutstderrru   pathisabsendswithabspathr~   r   r   fromdictargslistrI   xdist.looponfailr   main)rc   rI   rT   r   rw   
outchannelnewpathspr   r   r   s              r   ra   ra      s    
 ++-J(11#66CJLLHXX177==##AJJ7G,H,HGGOOA&OOA  HHQK   d4j9FK2f&++-r   c                      \ rS rSrS
S jrSS jr\R                  SS j5       r\R                  SS j5       r	\R                  SS j5       r
SS jrSrg	)r      c                    Xl         X l        / U l        SU l        UR                  R                  U 5        SUR                  l        SUR                  l        g )NF)	r   rc   recorded_failuresr   pluginmanagerregisterrF   r   r   )r;   r   rc   s      r   r<   WorkerFailSession.__init__   sH    QS!&%%d+#( $r   c                    U R                   R                  R                  (       a)  [        SR	                  [        [        U5      5      5        g g )Nr?   )r   rF   rG   r0   rH   maprA   )r;   rI   s     r   DEBUGWorkerFailSession.DEBUG   s1    ;;###((3sD>*+ $r   c                P   Xl         U R                  U l        U R                   R                  n UR	                  U R                  =(       d    S 5      nUR                  XR                  US9  UR                  US9  g! [
        R                   a    UR	                  S 5      n NQf = f)N)sessionr   items)r   T)
r   current_commandtrailsihookperform_collectr   r   pytest_collection_modifyitemsr   pytest_collection_finish)r;   r   hookr   s       r   pytest_collection#WorkerFailSession.pytest_collection   s    **||!!	2++DKK,?4@E 	**NN% 	+ 	
 	%%g%6    	2++D1E	2s   $A= =%B%$B%c                ^    UR                   (       a  U R                  R                  U5        g g r:   )failedr   r~   r;   r   s     r   pytest_runtest_logreport*WorkerFailSession.pytest_runtest_logreport   s"    ==""))&1 r   c                l    UR                   (       a#  U R                  R                  U5        SU l        g g )NT)r   r   r~   r   r   s     r   pytest_collectreport&WorkerFailSession.pytest_collectreport   s*    ==""))&1%)D" r   c                    U R                  S5         U R                  R                  5       nU R                  SU5        Xl        U R
                  R                  R                  U R
                  S9  / / p2U R                   HQ  nUR                  UR                  5        UR                  n[        [        USU5      5      nUR                  U5        MS     X#U R                  4nU R                  R                  U5        g ! [         a     g f = f)Nz:WORKER: received configuration, waiting for command trailsreceived)r   	reprcrash)r   rc   rd   r/   r   r   r   r    r   r~   nodeidlongreprrA   getattrr   ru   )r;   commandr   r#   replocr   s          r   r   WorkerFailSession.main   s    

OP	ll**,G 	

:w'&,,DKK,@ "))CMM#**%,,Cgc;45Cs#	 *
 t'='=>&! ! 		s   D   
DD)rc   r   r   r   r   r   r   N)r   r   rc   zexecnet.Channelr\   r]   r   )r   zpytest.Sessionr\   bool)r   zpytest.TestReportr\   r]   )r   zpytest.CollectReportr\   r]   r   )r   r   r   r   r<   r   r   hookimplr   r   r   r   r   r   r   r   r   r      sY    %, __  __2 2 __* *
"r   r   c                  N    \ rS rSrS	S jrS
S jrS
S jrSSS jjrSSS jjrSr	g)r)      c                >    Xl         0 U l        U R                  5         g r:   )rootdirlist	statcachecheck)r;   r   s     r   r<   StatRecorder.__init__   s    &57

r   c                    UR                  5       =(       a6    UR                  R                  S5      (       + =(       a    UR                  S:g  $ )N..pyc)is_filename
startswithsuffixr;   r   s     r   filStatRecorder.fil   s3    yy{P166#4#4S#99Pahh&>PPr   c                p    UR                   R                  S5      (       + =(       a    UR                  5       $ )Nr   )r   r   existsr   s     r   recStatRecorder.rec  s%    66$$S))8ahhj8r   c                d     U R                  5       nU(       a  g [        R                  " U5        M0  r:   )r   timesleep)r;   r%   changeds      r   r.   StatRecorder.waitonchange  s'    jjlGJJ}%	 r   c                   Sn0 nU R                    H  n[        X@R                  U R                  S9 H  nU R                  R                  US 5      n UR                  5       nXsU'   Ub  UR                  UR                  :w  d  UR                  UR                  :w  ai  Sn[        SU5        U(       aR  UR                  S:X  a@  UR                  S5      nUR                  5       (       a  [        R                  " U5        M  M  M  M  M  SnM     M     U R                  (       a  SnX0l        U$ ! [         a    U(       a  Sn GM   GM  f = f)NF)filterrecurseTz
# MODIFIEDz.pyr   )r   r   r   r   r   popstatst_mtimest_sizer0   r   with_suffixr   r   unlinkOSError)	r;   removepycfilesr   newstatr   r   oldstatcurstatpycfiles	            r   r   StatRecorder.check  s%   .0''G"788TXXN..,,T48'"iikG
 %,DM*#,,0@0@@&'//A&*G!,5-$++2F*.*:*:6*B#*??#4#4$&IIg$6 $5 3G~	  B #'- O (0 >>G -  '"& 's   D--E	E	)r   r   N)r   Sequence[Path]r\   r]   )r   r   r\   r   )g      ?)r%   floatr\   r]   )T)r   r   r\   r   )
r   r   r   r   r<   r   r   r.   r   r   r   r   r   r)   r)      s!    
Q9& r   r)   )r   zpytest.Parserr\   r]   )r   r   r\   z
int | Noner   )r#   zSequence[str]r$   r  r\   r]   )rc   z'execnet.Channel'rI   z	list[str]rT   zdict[str, 'Any']r\   r]   )__doc__
__future__r   collections.abcr   r   pathlibr   rw   r   typingr   _pytest._ior   rN   r   xdist._pathr   r   r   r    r   r&   r-   ra   r   r)   r   r   r   <module>r     s    # $ 	  
   &   " 
 
  *G* G*T99*89	9..
. ". 
	.>8" 8"v1 1r   