
    F\h6Y                        S SK r S SKrS SKrS SKrS SKrS SKrS SKrS SKrS SK	r	S SK
r
S SKrS SKrS SKJrJrJr  S SKJr  S SKJrJr  SSKJr  SSKJrJr  SSKJr  SS	KJrJrJ r J!r!  SS
K"J#r#  SSK$J%r%J&r&J'r'J(r(J)r)J*r*J+r+  SSK,J-r-J.r.  \(       a  S SK/r/S SK0r0Sr1\1\#:  d   eSr2\2\1:  d   eSr3Sr4 " S S5      r5\Rl                  " SSS9 " S S5      5       r7 " S S5      r8\9r:\;\S   \74   \;\S   \:4   -  r<\<\8-  r= " S S\>5      r? " S S\>5      r@SrA " S S\
R                  5      rCS \D\C   S!\9S-  4S" jrE " S# S$5      rFg)%    N)AnyLiteralTextIO)support)	os_helper
MS_WINDOWS   )Logger)
TestResultState)TestResults)RunTestsWorkerRunTestsJsonFileJsonFileType)PROGRESS_MIN_TIME)StrPathTestNameformat_durationprint_warningcountpluralget_signal_name)create_worker_processUSE_PROCESS_GROUPg      >@g     r@g      N@c                   0    \ rS rSrSrS rS rS rS rSr	g)	MultiprocessIterator4   z8A thread-safe iterator over tests for multiprocess mode.c                 D    [         R                  " 5       U l        Xl        g N)	threadingLocklock
tests_iter)selfr$   s     3/usr/lib/python3.13/test/libregrtest/run_workers.py__init__MultiprocessIterator.__init__8   s    NN$	$    c                     U $ r     r%   s    r&   __iter__MultiprocessIterator.__iter__<   s    r)   c                     U R                      U R                  c  [        e[        U R                  5      sS S S 5        $ ! , (       d  f       g = fr    )r#   r$   StopIterationnextr,   s    r&   __next__MultiprocessIterator.__next__?   s/    YY&##( YYs	   (?
Ac                 ^    U R                      S U l        S S S 5        g ! , (       d  f       g = fr    r#   r$   r,   s    r&   stopMultiprocessIterator.stopE   s    YY"DO YYs   
,r5   N)
__name__
__module____qualname____firstlineno____doc__r'   r-   r2   r6   __static_attributes__r+   r)   r&   r   r   4   s    B%)#r)   r   T)slotsfrozenc                   H    \ rS rSr% \\S'   Sr\S-  \S'   Sr\S-  \S'   Sr	g)MultiprocessResultJ   resultNworker_stdouterr_msgr+   )
r8   r9   r:   r;   r   __annotations__rD   strrE   r=   r+   r)   r&   rA   rA   J   s$     $M3:$GS4Zr)   rA   c                       \ rS rSrSrSrg)WorkerThreadExitedR   z)Indicates that a worker thread has exitedr+   N)r8   r9   r:   r;   r<   r=   r+   r)   r&   rI   rI   R   s    3r)   rI   Fc                       \ rS rSrSrg)
ExitThreadZ   r+   N)r8   r9   r:   r;   r=   r+   r)   r&   rL   rL   Z   s    r)   rL   c                   H   ^  \ rS rSrS\S\S-  S\S-  S\4U 4S jjrSrU =r$ )	WorkerError^   	test_namerE   Nstdoutstatec                 V   > [        XS9n[        XSU5      U l        [        TU ]  5         g )NrS   )r   rA   	mp_resultsuperr'   )r%   rQ   rE   rR   rS   rC   	__class__s         r&   r'   WorkerError.__init___   s(    
 I3+FGDr)   )rV   )	r8   r9   r:   r;   r   rG   r'   r=   __classcell__rX   s   @r&   rO   rO   ^   s9    $* t 	 r)   rO   z<not running>c            
         ^  \ rS rSrS\SSSS4U 4S jjrS\4S jrS#S	 jrS#S
 jr	 S$S\
S\S\S-  S\S-  4S jjrS\R                  S\4S jrS\R                  S\\\S-  4   4S jrS\S\S\
4S jrS\
S\S\\S-  \\   4   4S jrS\S\4S jrS\S\S-  S\S\\\4   4S jrS\S\4S jrS#S jrS#S jrS \SS4S! jr S"r!U =r"$ )%WorkerThreadl   	worker_idrunner
RunWorkersreturnNc                 L  > [         TU ]  5         Xl        UR                  U l        UR                  U l        UR
                  U l        UR                  U l        UR                  U l        [        U l
        [        R                  " 5       U l        S U l        SU l        SU l        g )NF)rW   r'   r_   runtestspendingoutputworker_timeouttimeoutlog_NOT_RUNNINGrQ   time	monotonic
start_time_popen_killed_stopped)r%   r_   r`   rX   s      r&   r'   WorkerThread.__init__m   sv    "~~mm,,::%..*48r)   c                    SU R                    3/nU R                  5       (       a  UR                  S5        OUR                  S5        U R                  nU(       a  UR                  SU 35        U R                  nUbN  [
        R                  " 5       U R                  -
  nUR                  SUR                   3S[        U5       345        SSR                  U5      -  $ )	NzWorkerThread #runningstoppedztest=zpid=ztime=z<%s> )r_   is_aliveappendrQ   rn   rk   rl   rm   extendpidr   join)r%   infotestpopendts        r&   __repr__WorkerThread.__repr__{   s      012==??KK	"KK	"~~KK%v'!DOO3BKK4		{+ !4 568 9&&r)   c                    U R                   nUc  g U R                  (       a  g SU l        [        (       a  U  S3nOU  S3n[        SU 3[        R
                  SS9   [        (       a0  [        R                  " UR                  [        R                  5        g UR                  5         g ! [         a     g [         a  n[        SU SU< 35         S nAg S nAff = f)NTz process groupz processzKill )fileflushzFailed to kill z: )rn   ro   r   printsysstderroskillpgry   signalSIGKILLkillProcessLookupErrorOSErrorr   )r%   r}   whatexcs       r&   _killWorkerThread._kill   s    =<<V>*DV8$DdVn3::T:	=  		%))V^^4

! 	  	=OD6C7;<<	=s$   :B) B) )
C5	C>CCc                 2    SU l         U R                  5         g )NT)rp   r   r,   s    r&   r6   WorkerThread.stop   s    

r)   rd   	output_fdtmp_dirc                 R   [        XU5      nX@l        SU l         U R                  (       a  U R	                  5         [
        e UR                  U R                  S9nUc   eUU R                  5         S U l        $ ! [        R                   a,    U R                  (       a  [
        eU R	                  5         S n O%[         a    U R                  (       a  [
        ee f = f U R                  5         S U l        g !   U R	                  5         e = f! U R                  5         S U l        f = f)NFrh   )r   rn   ro   rp   r   rL   waitrh   _wait_completed
subprocessTimeoutExpiredr   )r%   rd   r   r   r}   retcodes         r&   _run_processWorkerThread._run_process   s	   %h7C'	}} 

  **T\\*:***4   "DK5 ,, 
== %$ 

   == %$ 
   "DK	JJL  "DKs5   'C7 A: :=C7C7 9"CC7 7D

D D&stackc                     [         (       a  [        R                  " 5       nO[        R                  R
                  n[        R                  " SUSS9nUR                  U5        U$ )z/Create stdout temporary file (file descriptor).w+backslashreplace)encodingerrors)	r   localegetencodingr   rR   r   tempfileTemporaryFileenter_context)r%   r   r   stdout_files       r&   create_stdoutWorkerThread.create_stdout   sY     : ))+Hzz**H ,,T6>4FH 	K(r)   c                    U R                   R                  5       nU(       a  [        S[        R                  5      nSnX44$ [
        R                  " SSS9nUR                  U5        UR                  5       n[        (       a3  [        R                  " U5      n[        U[        R                  5      nX44$ [        U[        R                  5      nX44$ )zCreate JSON file.Nr   utf8r   )rd   json_file_use_stdoutr   r   STDOUTr   r   r   filenor   msvcrtget_osfhandleWINDOWS_HANDLEUNIX_FD)r%   r   r   	json_filejson_tmpfilejson_fdjson_handles          r&   create_json_fileWorkerThread.create_json_file   s      $}}AAC |':':;IL (( $11$HL-"))+Gz $*#7#7#@$[%1%@%@B	 (( %Wl.B.BC	((r)   rQ   r   c                 L   U4nU R                   R                  (       a  U R                   R                  U5      nOS n0 nU(       a  U Vs/ s H  ofS4PM     snUS'   U R                   R                  (       a
  SUS'   SUS'   U R                   R                  " SUUS.UD6$ s  snf )NTmatch_testsverboseFoutput_on_failure)testsr   r+   )rd   rerunget_match_testsr   create_worker_runtests)r%   rQ   r   r   r   kwargsr|   s          r&   r   #WorkerThread.create_worker_runtests  s    ==--77	BKK!#>I$JkdD\k$JF=!==** $F9*/F&'}}33   		 %Ks   
B!worker_runtests	stdout_fdc                    [         R                  (       du  [        R                  " SS9n[        R
                  R                  U5      n U R                  UX#5      n[        R                  " U5      n[        R                  " U5        XE4$ U R                  X5      n/ nXE4$ ! [        R                  " U5      n[        R                  " U5        f = f)Ntest_python_)prefix)r   is_wasir   mkdtempr   pathabspathr   listdirr   rmtree)r%   r   r   r   r   	tmp_filess         r&   run_tmp_filesWorkerThread.run_tmp_files  s    
  &&n=Gggoog.G*++O,5@ JJw/	  )
 ## ''CGI## JJw/	  )s   
B! !.Cr   c                     UR                  S5         UR                  5       R                  5       $ ! [         a,  n[	        U R
                  SU 3S [        R                  S9eS nAff = f)Nr   zCannot read process stdout: )rR   rS   )seekreadstrip	ExceptionrO   rQ   r   
WORKER_BUG)r%   r   r   s      r&   read_stdoutWorkerThread.read_stdout0  sh    	6##%++-- 	6 dnn <SEB%)$)$4$46 6	6s   1 
A''A""A'r   rR   c                     Ub"  UR                  S5        UR                  5       nOkUR                  [        R                  :X  a%  UR                  S5      u  p5nUR                  5       nO(UR                  SS9 nUR                  5       nS S S 5        W(       d$  [        U R                  SU[        R                  S9e [        R                  " U5      n	X4$ ! , (       d  f       NS= f! [         a-  nSU 3n[        U R                  X[        R                  S9eS nAff = f! [         a-  nSU 3n[        U R                  X[        R                  S9eS nAff = f)	Nr   
r   r   z$Failed to read worker process JSON: rU   z
empty JSONz%Failed to parse worker process JSON: )r   r   	file_typer   r   
rpartitionrstripopenr   rO   rQ   r   r   r   	from_json)
r%   r   r   rR   worker_json_json_fpr   rE   rC   s
             r&   	read_jsonWorkerThread.read_json<  sC   	6'!!!$*//1$$(;(;;)/):):4)@&;^^V^4"),,.K 5 dnnlF$)$4$46 6	6))+6F - 54 	6 =SEBGdnng$)$4$46 6		6  	6 >cUCGdnng$)$4$46 6		6sY   $C( AC( *C( 9C
C( >D" 
C%!C( %C( (
D2(DD"
E,(EEc           
         [         R                  " 5        nU R                  U5      nU R                  U5      u  pEU R	                  X5      nU R                  UUR                  5       5      u  pxU R                  U5      n	Uc$  [        U R                  U	S [        R                  S9eUS:w  aA  [        U5      n
U
(       a  U SU
 S3n[        U R                  SU 3U	[        R                  S9eU R                  XEU	5      u  pS S S 5        W(       aA  SU S[        U5       S	S
R!                  [#        U5      5       3nW	U-  n	WR%                  5         ['        WW	5      $ ! , (       d  f       Nb= f)N)rR   rE   rS   r    ()z
Exit code rU   z

Warning -- z leaked temporary files (): , )
contextlib	ExitStackr   r   r   r   r   r   rO   rQ   r   TIMEOUTr   WORKER_FAILEDr   lenrz   sortedset_env_changedrA   )r%   rQ   r   r   r   r   r   r   r   rR   namerC   msgs                r&   _runtestWorkerThread._runtest^  sm   !!#u,,U3K&*&;&;E&B#I"99)OO "&!3!3O4?4F4F4H"JG %%k2F!$..*.(-7 7 !|&w/!(	D63G!$..Jwi2H&(-(;(;= = "^^IVLNF- $0 !!* ,9~&c$))F94E*F)GIC cMF""$!&&11? $#s   C+E
E+c                    U R                   R                  nU R                   R                  n U R                  (       d   [	        U R
                  5      n[        R                  " 5       U l	        X0l
         U R                  U5      n[        U l
        [        R                  " 5       U R                  -
  UR                  l        U R"                  R%                  SU45        UR                  R'                  X5      (       a  OU R                  (       d  M  U R"                  R%                  [1        5       5        g ! [         a     M1  f = f! [         a  nUR                  n S nANS nAff = f! [        U l
        f = f! [(         a     Nt[*         a3    U R"                  R%                  S[,        R.                  " 5       45         Nf = f! U R"                  R%                  [1        5       5        f = f)NFT)rd   	fail_fastfail_env_changedrp   r1   re   r0   rk   rl   rm   rQ   r   rO   rV   rj   rC   durationrf   put	must_stoprL   BaseException	traceback
format_excrI   )r%   r   r   rQ   rV   r   s         r&   runWorkerThread.run  sg   MM++	==99	2mm $T\\ 2I #'.."2!*2 $i 8I &2DN,0NN,<t,N	  )	 23##--iJJ% mmm0 KKOO.01+ %  # . #I. &2DN  	 	<KKOOT9#7#7#9:;	< KKOO.01s   E<  D8  E< 6E	 A9E<  G E< 8
EE< G EE< 	
E)E$E, $E))E, ,E99E< <
GG 9GG GG %G,c           	          U R                   nUc  [        S5      e UR                  [        5        g ! [        R
                  [        4 a,  n[        SU  S[        [        5       SU< 35         S nAg S nAff = f)Nz5Should never access `._popen` before calling `.run()`zFailed to wait for z completion (timeout=r   )	rn   
ValueErrorr   WAIT_COMPLETED_TIMEOUTr   r   r   r   r   )r%   r}   r   s      r&   r   WorkerThread._wait_completed  sz    =TUU	&JJ-.))73 	&/v 6&&56L&M%Nc G% & &	&s   2 A8"A33A8rm   c                     U R                  S5        U R                  5       (       d  g [        R                  " 5       U-
  nU R	                  SU  S[        U5       35        U[        :  a  [        SU  S[        U5       35        g M  )Ng      ?zWaiting for z thread for zFailed to join z in )rz   rv   rk   rl   ri   r   WAIT_KILLED_TIMEOUTr   )r%   rm   r~   s      r&   wait_stoppedWorkerThread.wait_stopped  s|     IIcN==??!J.BHH|D6ob6I5JKL''vT/":M9NOP r)   )ro   rn   rp   ri   rf   re   rd   rm   rQ   rh   r_   rb   Nr    )#r8   r9   r:   r;   intr'   rG   r   r   r6   r   r   r   r   r   r   r   tupler   r   r   r   listr   r   r   r   rA   r   r  r   floatr
  r=   rZ   r[   s   @r&   r]   r]   l   si   # |  '# ' =8 04-^ - -%n-8;d
-^:#7#7 F ,)j&:&: )uXvX\}E\?] ), X R` $$^ $!$$).sTz4=/H)I$.
6v 
6# 
6  8   6D=     "'
C"8  D 2(  2/A  2D2<&u   r)   r]   workersrb   c                 8   / nU  Hk  nUR                   nU[        :X  a  M  [        R                  " 5       UR                  -
  nU[
        :  d  MI  U S[        U5       S3nUR                  U5        Mm     U(       d  g S[        U5       SSR                  U5       3$ )Nr   r   z	running (r   r   )
rQ   rj   rk   rl   rm   r   r   rw   r   rz   )r  rs   workerrQ   r~   texts         r&   get_runningr    s    G$$	$^^ 1 11""[?2#6"7q9DNN4   s7|nC		'(:';<<r)   c            
           \ rS rSrS\S\S\S\SS4
S jrSS	 jr	SS
 jr
S\S-  4S jrS\SS4S jrS\S\4S jrSS jrSrg)ra   i  num_workersrd   loggerresultsrb   Nc                    Xl         X l        UR                  U l        UR                  U l        X@l        SU l        [        R                  " 5       U l        UR                  5       n[        U5      U l        UR                  U l        U R                  b,  [        U R                  S-  U R                  S-   5      U l        OS U l        / U l        U R                  R!                  5       nUb  [        U R                   U5      U l         g g )Nr   g      ?i,  )r  rd   ri   display_progressr  live_worker_countqueueQueuerf   
iter_testsr   re   rh   minrg   r  get_jobs)r%   r  rd   r  r  r$   jobss          r&   r'   RunWorkers.__init__  s    & :: & 7 7$+!"16((*
+J7''<<# 14DLL34FW]H]0^D"&D+-}}%%'  #4#3#3T:D r)   c                 f   [        SU R                  S-   5       Vs/ s H  n[        X5      PM     snU l        U R                  R                  5       nUb  [        US5      nOSn[        U R                  5      n[        USS5      nSU SU SU 3nU R                  (       aA  U R                  b4  US	[        U R                  5      < S
[        U R                  5      < S3-  nU R                  U5        U R                   H(  nUR                  5         U =R                  S-  sl        M*     g s  snf )Nr	   r|   r   process	processeszRun z in parallel using z worker z (timeout: z, worker timeout: r   )ranger  r]   r  rd   r!  r   r   r   rh   rg   r   ri   startr  )r%   indexr"  r   nworkersr&  r   r  s           r&   start_workersRunWorkers.start_workers  s   %*1d.>.>.B%CE%CE %U1%CE}}%%'$'EEt||$8Y<	eW/8I;0<<D//;&t||4&t':':;= >C 	llFLLN""a'" #!Es   D.c                     [         R                  " 5       nU R                   H  nUR                  5         M     U R                   H  nUR	                  U5        M     g r    )rk   rl   r  r6   r
  )r%   rm   r  s      r&   stop_workersRunWorkers.stop_workers  sA    ^^%
llFKKM #llF
+ #r)   c                    U R                   R                  nU R                  S LnU R                  S:  al  U(       a  [        R
                  " [        SS9   U R                  R                  [        S9n[        U[        5      (       a  U =R                  S-  sl        Mz  U$ g ! [        R                   a     Of = fU(       d-  [        U R                  5      nU(       a  U R!                  U5        U R                  S:  a  M  Nb)Nr   T)exitr   r	   )rd   pgorh   r  faulthandlerdump_traceback_laterMAIN_PROCESS_TIMEOUTrf   getPROGRESS_UPDATE
isinstancerI   r  Emptyr  r  ri   )r%   r2  use_faulthandlerrC   rs   s        r&   _get_resultRunWorkers._get_result
  s    mm LL4 $$q(112F7;=Af&899**a/*  ;;  %dll3HHW%' $$q(s   AB" B" "B98B9rV   c                    UR                   nU R                  R                  n[        U5      nUR                  (       a  USUR                  -  -  nOGUR
                  (       a6  UR
                  [        :  a"  U(       d  US[        UR
                  5      -  -  nU(       d$  [        U R                  5      nU(       a  USU 3-  nU R                  U R                  U5        g )Nz (%s)z -- )rC   rd   r2  rG   rE   r   r   r   r  r  r  
test_index)r%   rV   rC   r2  r  rs   s         r&   display_resultRunWorkers.display_result&  s    !!mm6{Gi////Doo&//5F"FsGofoo>>>D!$,,/G$wi((doot4r)   itemc                 4   US   (       aR  US   n[        SU 35        [        S[        R                  S9nU R                  R                  X0R                  5        U$ U =R                  S-  sl        US   nUR                  nU R                  R                  X0R                  5        U R                  U5        U R                  R                  (       d  SnOUR                  [        R                  :g  nU(       a  UR                  nU(       a
  [        USS9  U$ )z&Returns True if test runner must stop.r   r	   zregrtest worker thread failed: z<regrtest worker>rU   T)r   )r   r   r   r   r  accumulate_resultrd   r>  rC   r?  r   rS   PASSEDrD   r   )r%   rA  r  rC   rV   show_stdoutrR   s          r&   _process_resultRunWorkers._process_result6  s    7aJ;J<HI 35;K;KLFLL**6==AM1G	!!&&v}}=I& }}..K "<<5<<7K,,FfD)r)   c                    U R                   R                  nU R                   R                  nU R                  5         SU l          U R                  5       nUc  O*U R                  U5      nUR                  X5      (       a  OM>  U R                  b  [        R                  " 5         U R                  R!                  5         U R#                  5         g ! [         a    [        5         SU R                  l         Ntf = f! U R                  b  [        R                  " 5         U R                  R!                  5         U R#                  5         f = f)Nr   T)rd   r   r   r+  r>  r;  rF  r   KeyboardInterruptr   r  interruptedrh   r3  cancel_dump_traceback_laterre   r6   r.  )r%   r   r   rA  rC   s        r&   r  RunWorkers.runS  s
   MM++	==99	 '')<--d3##I@@  ||'88: LL ! 	,G'+DLL$	, ||'88: LLs=   C C< 'C C< C %C96C< 8C99C< <AE
)r  r  ri   r  rf   re   r  rd   r>  rh   rg   r  r  )r8   r9   r:   r;   r  r   r
   r   r'   r+  r.  QueueOutputr;  rA   r?  r   rF  r  r=   r+   r)   r&   ra   ra     st    ;C ;8 ;;*5;:>;8(*,[4/ 85(: 5t 5 K J : r)   ra   )Gr   dataclassesr3  os.pathr   r  r   r   r   r   r!   rk   r   typingr   r   r   r|   r   test.supportr   r   r  r
   rC   r   r   r  r   rd   r   r   r   r   singler   utilsr   r   r   r   r   r   r   r  r   r   r   r   r7  r5  r  r	  r   	dataclassrA   rI   rG   ExcStrr  rM  QueueContentr   rL   rO   rj   Threadr]   r  r  ra   r+   r)   r&   <module>rX     sr          
     ' '  .  %   F F %D D D =
 ++ ++
   . ..    # #, T$/  04 4 
GEN$667%v@U:VV//	 	)  S9## Sl
=l+ =d
 =\  \ r)   