
    F\hq                         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  S r	S r
S r\R                  SS j5       rSS jr\R                  SS j5       r " S	 S
5      rS\4S jr\" 5       rSS.S jrg)    N)supportc                  ^    [         R                  " 5       [        [        R                  5      4$ N)_thread_countlen	threading	_dangling     4/usr/lib/python3.13/test/support/threading_helper.pythreading_setupr      s    >>S!4!4555r   c                  l   U u  pSn[         R                  " USS9 H8  n[        [        R                  5      n[
        R                  " 5       nXa::  d  M8    g    S[         l        [         R                  " SUS SU SU S	W S[        W5       3
5        U H  n[         R                  " S
U< 35        M     g )Ng      ?FerrorTz2threading_cleanup() failed to clean up threads in .1fz  seconds
  before: thread count=z, dangling=z
  after: thread count=zDangling thread: )
r   sleeping_retrylistr	   r
   r   r   environment_alteredprint_warningr   )original_values
orig_countorig_ndanglingtimeout_dangling_threadscountthreads           r   threading_cleanupr      s    !0JG##G59  	 3 34  : #'Gc] "",[8H I!!&{37G3H2I	KL
 # 1&<= #r   c                 F   ^  [         R                  " T 5      U 4S j5       nU$ )z{Use this function when threads are being used.  This will
ensure that the threads are cleaned up even when the test fails.
c                  N   > [        5       n T" U 6 [        U6   $ ! [        U6   f = fr   )r   r   )argskeyfuncs     r   	decoratorreap_threads.<locals>.decorator>   s)    	$;s#s#s    
$)	functoolswraps)r$   r%   s   ` r   reap_threadsr)   :   s(     __T$ $ r   c              #     #    U c  [         R                  n [        R                  " 5       n Sv   [        R
                  " 5       n[         R                  " U SS9 H4  n[         R                  " 5         [        R                  " 5       nXA::  d  M4    g   [        R
                  " 5       U-
  nSWU-
   SUS SU SU S	3	n[        U5      e! [        R
                  " 5       n[         R                  " U SS9 H4  n[         R                  " 5         [        R                  " 5       nXA::  d  M4    f    [        R
                  " 5       U-
  nSWU-
   SUS SU SU S	3	n[        U5      e= f7f)
a   
bpo-31234: Context manager to wait until all threads created in the with
statement exit.

Use _thread.count() to check if threads exited. Indirectly, wait until
threads exit the internal t_bootstrap() C function of the _thread module.

threading_setup() and threading_cleanup() are designed to emit a warning
if a test leaves running threads in the background. This context manager
is designed to cleanup threads started by the _thread.start_new_thread()
which doesn't allow to wait for thread exit, whereas thread.Thread has a
join() method.
NFr   z!wait_threads() failed to cleanup z threads after r   z seconds (count: z, old count: ))	r   SHORT_TIMEOUTr   r   time	monotonicr   
gc_collectAssertionError)r   	old_count
start_timer   r   dtmsgs          r   wait_threads_exitr5   H   s\     '' I&^^%
''u=A NN$E!	 > !J.B6uy7H6I J$$&s8 ,#WM)A?C !%% ^^%
''u=A NN$E!	 > !J.B6uy7H6I J$$&s8 ,#WM)A?C !%%s)   )E$C AE$:E$AE!':E!!E$c                     Uc  [         R                  nU R                  U5        U R                  5       (       a  SUS S3n[	        U5      eg)z[Join a thread. Raise an AssertionError if the thread is still alive
after timeout seconds.
Nzfailed to join the thread in r   z seconds)r   r,   joinis_aliver0   )r   r   r4   s      r   join_threadr9   k   sM     ''
KK-gc](CS!! r   c              #   .  #     SS K n[        U 5      n / n  U  H$  nUR                  5         UR	                  U5        M&     S v    U(       a  U" 5         [        R                  " 5       n[        SS5       H  nUS-  nU H4  nUR                  [        U[        R                  " 5       -
  S5      5        M6     U Vs/ s H  oDR                  5       (       d  M  UPM     nnU(       d    O4[
        R                  (       d  M  [        S[        U5      U4-  5        M     U Vs/ s H  oDR                  5       (       d  M  UPM     nnU(       a9  Ub  UR                  [         R"                  5        [%        S[        U5      -  5      eg ! [         a    S n GNf = f!   [
        R                  (       a"  [        S[        U 5      [        U5      4-  5        e = fs  snf s  snf ! U Vs/ s H  oDR                  5       (       d  M  UPM     Os  snf nnU(       a9  Ub  UR                  [         R"                  5        [%        S[        U5      -  5      ef = f!  U(       a  U" 5         [        R                  " 5       n[        SS5       H  nUS-  nU H4  nUR                  [        U[        R                  " 5       -
  S5      5        M6     U Vs/ s H  oDR                  5       (       d  M  UPM     Os  snf nnU(       d    O4[
        R                  (       d  M  [        S[        U5      U4-  5        M     U Vs/ s H  oDR                  5       (       d  M  UPM     Os  snf nnU(       a9  Ub  UR                  [         R"                  5        [%        S[        U5      -  5      ef ! U Vs/ s H  oDR                  5       (       d  M  UPM     Os  snf nnU(       a9  Ub  UR                  [         R"                  5        [%        S[        U5      -  5      ef = f= f7f)	Nr   z/Can't start %d threads, only %d threads started      <   g{Gz?z7Unable to join %d threads during a period of %d minuteszUnable to join %d threads)faulthandlerImportErrorr   startappendr   verboseprintr   r-   r.   ranger7   maxr8   dump_tracebacksysstdoutr0   )threadsunlockr>   startedtendtimer   s          r   start_threadsrN   w   s6     7mGGQ		q!  		Qnn&G B<2 AFF3w)994@A !&->g1g>??? '*-g,)@A B ( #*:'QZZ\q'G:+ //

;$%@3w<%OPP C  	G7|S\23 4 ? ;':'QZZ\q':G:+ //

;$%@3w<%OPP !	Qnn&G B<2 AFF3w)994@A !&->g1g>>??? '*-g,)@A B ( #*:'QZZ\q':G:+ //

;$%@3w<%OPP  #*:'QZZ\q':G:+ //

;$%@3w<%OPP s  PF P*F I A5G ;GGG ?G P G<GAPFPFP:GI G PI$H HA	IPPA5N	K,
%K,
+$NN0P4MMA	PP$O OA	PPPc                   0    \ rS rSrSrS rS rS rS rSr	g)	catch_threading_exception   a  
Context manager catching threading.Thread exception using
threading.excepthook.

Attributes set when an exception is caught:

* exc_type
* exc_value
* exc_traceback
* thread

See threading.excepthook() documentation for these attributes.

These attributes are deleted at the context manager exit.

Usage:

    with threading_helper.catch_threading_exception() as cm:
        # code spawning a thread which raises an exception
        ...

        # check the thread exception, use cm attributes:
        # exc_type, exc_value, exc_traceback, thread
        ...

    # exc_type, exc_value, exc_traceback, thread attributes of cm no longer
    # exists at this point
    # (to avoid reference cycles)
c                 J    S U l         S U l        S U l        S U l        S U l        g r   )exc_type	exc_valueexc_tracebackr   	_old_hookselfs    r   __init__"catch_threading_exception.__init__   s&    !r   c                     UR                   U l         UR                  U l        UR                  U l        UR                  U l        g r   )rS   rT   rU   r   )rX   r"   s     r   _hookcatch_threading_exception._hook   s1    !//kkr   c                 Z    [         R                  U l        U R                  [         l        U $ r   )r	   
excepthookrV   r\   rW   s    r   	__enter__#catch_threading_exception.__enter__   s     "--#zz	r   c                 >    U R                   [        l        U ?U ?U ?U ?g r   )rV   r	   r_   rS   rT   rU   r   )rX   exc_infos     r   __exit__"catch_threading_exception.__exit__   s#    #~~	MNKr   )rV   rU   rS   rT   r   N)
__name__
__module____qualname____firstlineno____doc__rY   r\   r`   rd   __static_attributes__r   r   r   rP   rP      s    <"
r   rP   returnc                      [         R                  S:X  a  [         R                  R                  $ [         R                  S:X  a  gg)a]  Detect whether Python can start new threads.

Some WebAssembly platforms do not provide a working pthread
implementation. Thread support is stubbed and any attempt
to create a new thread fails.

- wasm32-wasi does not have threading.
- wasm32-emscripten can be compiled with or without pthread
  support (-s USE_PTHREADS / __EMSCRIPTEN_PTHREADS__).

emscriptenwasiFT)rG   platform_emscripten_infopthreadsr   r   r   _can_start_threadrs      s6     |||###,,,		 r   F)modulec                     SnU (       a"  [         (       d  [        R                  " U5      eg[        R                  " [         U5      $ )z~Skip tests or modules that require working threading.

Can be used as a function/class decorator or to skip an entire module.
zrequires threading supportN)can_start_threadunittestSkipTest
skipUnless)rt   r4   s     r   requires_working_threadingrz      s>    
 'C##C((   ""#3S99r   r   )r   
contextlibr'   rG   r	   r-   rw   testr   r   r   r)   contextmanagerr5   r9   rN   rP   boolrs   rv   rz   r   r   r   <module>r      s       
    6>< & &D	" 'Q 'QT6 6r4 & %& ). 
:r   