
    daf$                       d Z ddlZddlmZmZ ddlmZmZmZ ddlm	Z	 ddl
mZmZ ddlZddlZddlZddlZddlZddlZddlZddlZ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 dd	lmZ 	 dd
lmZ  ej>                  d       dZ d Z!d Z"d Z# G d de$      Z% G d dejL                        Z' G d dejP                        Z) G d de)      Z* G d de)      Z+ G d de)      Z, G d de)      Z- G d d ejL                        Z. G d! d"e)      Z/ G d# d$e)      Z0 G d% d&ejb                        Z1 G d' d(ejd                        Z3 ejh                  ejj                  du d)       G d* d+ejd                               Z6 G d, d-ejn                        Z7 G d. d/ejd                        Z8 G d0 d1ejr                        Z9 G d2 d3ejt                        Z: G d4 d5ejv                        Z; G d6 d7ejx                        Z< G d8 d9ejP                        Z= G d: d;ejP                        Z> G d< d=ejP                        Z?e@d>k(  r ej                          yy# e$ r dZY w xY w)?z!
Tests for the threading module.
    N)threading_helperrequires_subprocess)verbosecpython_only	os_helper)import_module)assert_python_okassert_python_failure)mock)
lock_tests)support)interpretersT)module)netbsd5zhp-ux11c                 j   t         j                  s t        j                  d      |       S t        j
                  t        v r t        j                  d      |       S t         j                  r t        j                  d      |       S t        j                  d      rt        j                  d      S | S )Nzrequires working os.fork()z*due to known OS bug related to thread+forkz?libasan has a pthread_create() dead lock related to thread+forkTthreadz'TSAN doesn't support threads after fork)	r   has_fork_supportunittestskipsysplatformplatforms_to_skipHAVE_ASAN_FORK_BUGcheck_sanitizer)tests    ./root/Python-3.12.4/Lib/test/test_threading.pyskip_unless_reliable_forkr   +   s    ##:x}}9:4@@
||((Jx}}IJ4PP!!_x}}^_`deed+}}FGGK    c                 F     t        j                  t        du d      |       S )z>Decorator to skip a test if subinterpreters are not supported.Nzsubinterpreters required)r   skipIfr   )meths    r   requires_subinterpretersr#   7   s)    78??<4/577;= =r   c                     | j                  t        t        dt        j                         t        j                  t        _        y )N
excepthook)
addCleanupsetattr	threadingr%   __excepthook__)testcases    r   restore_default_excepthookr+   =   s*    L):N:NO$33Ir   c                   $    e Zd Zd Zd Zd Zd Zy)Counterc                     d| _         y )Nr   valueselfs    r   __init__zCounter.__init__D   s	    
r   c                 .    | xj                   dz  c_         y N   r/   r1   s    r   inczCounter.incF       

a
r   c                 .    | xj                   dz  c_         y r5   r/   r1   s    r   deczCounter.decH   r8   r   c                     | j                   S Nr/   r1   s    r   getzCounter.getJ   s    zzr   N)__name__
__module____qualname__r3   r7   r:   r=    r   r   r-   r-   C   s    r   r-   c                       e Zd Zd Zd Zy)
TestThreadc                 ~    t         j                  j                  | |       || _        || _        || _        || _        y )Nname)r(   Threadr3   r*   semamutexnrunning)r2   rF   r*   rH   rI   rJ   s         r   r3   zTestThread.__init__N   s7    !!$T!2 	
 r   c                    t        j                          dz  }t        rt        d| j                  |dz  fz         | j                  5  | j
                  5  | j                  j                          t        r$t        | j                  j                         d       | j                  j                  | j                  j                         d       d d d        t        j                  |       t        rt        d| j                  d       | j
                  5  | j                  j                          | j                  j                  | j                  j                         d       t        r2t        d	| j                  | j                  j                         fz         d d d        d d d        y # 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   y xY w)
Ng     @ztask %s will run for %.1f usecg    .Aztasks are running   taskdoner   z$%s is finished. %d tasks are running)randomr   printrF   rH   rI   rJ   r7   r=   r*   assertLessEqualtimesleepr:   assertGreaterEqual)r2   delays     r   runzTestThread.runU   s^   ')299eck*+ , YY 	< F!!#$--++-/BC--dmm.?.?.A1E	F JJufdii0 <!!#001B1B1DaH@99dmm&7&7&9:; <	<	< 	<F F< <	< 	<s?   GA9F+AGBF7G+F4	0G7G 	<GGN)r>   r?   r@   r3   rV   rA   r   r   rC   rC   M   s    !<r   rC   c                       e Zd Zd Zd Zy)BaseTestCasec                 6    t        j                         | _        y r<   )r   threading_setup_threadsr1   s    r   setUpzBaseTestCase.setUpo   s    (88:r   c                 x    t        j                  | j                    t        j                  j                          y r<   )r   threading_cleanupr[   r   r   reap_childrenr1   s    r   tearDownzBaseTestCase.tearDownr   s$    **DMM:""$r   N)r>   r?   r@   r\   r`   rA   r   r   rX   rX   n   s    ;%r   rX   c                   t   e Zd ZdZed        Zd Zed        Zd Zd Z	d Z
d Zd	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zed        Zed        Zd Ze ej8                   eed      d      d               Ze ej8                   eed      d      d               Z  ejB                  e"jF                  e$v d       e%jL                          ej8                   eed      d      d/d                     Z'd/dZ(d Z)d Z*d  Z+d! Z,d" Z-ed#        Z.d$ Z/d% Z0d& Z1d' Z2ed(        Z3d) Z4d* Z5d+ Z6d, Z7d- Z8y.)0ThreadTestsi'  c                    d }t        j                  d      }| j                  |j                  d       t        j                  d      }| j                  |j                  d       t        j                  |d      }| j                  |j                  d       t        j
                  j                  t         dd	
      5  t        j                  d      }| j                  |j                  d       d d d        t        j
                  j                  t         dd
      5  t        j                         }| j                  |j                  d       d d d        t        j
                  j                  t         dd
      5  t        j                  |      }| j                  |j                  d       d d d        y # 1 sw Y   xY w# 1 sw Y   wxY w# 1 sw Y   y xY w)Nc                       y r<   rA   rA   r   r   funcz#ThreadTests.test_name.<locals>.func|       Dr   myname1rE   {   123myname2)targetrF   _counter   )return_value zThread-2rL   zThread-3   rk   zThread-5 (func))r(   rG   assertEqualrF   r   patchobject)r2   re   r   s      r   	test_namezThreadTests.test_namez   su   !!y1i0 !!s+e, !!I>i0ZZy*1E 	6%%2.FV[[*5	6 ZZy*1E 	6%%'FV[[*5	6 ZZy*1E 	=%%T2FV[[*;<	= 	=	6 	6	6 	6	= 	=s$   3F="1G	3G=G	GGc                 F    dg}d}dg}d}dgf}dg}| fdf| fdf| fdf| fdf| fd	f| fd
ff}|D ]X  \  }}	 j                  |	|      5  t        j                  |	|      }
|
j                          |
j	                          d d d        Z y # 1 sw Y   exY w)Nr6   r6   strrx   c                 (    j                  | d      S r5   rr   argr2   s    r   <lambda>z0ThreadTests.test_args_argument.<locals>.<lambda>   s    4#3#3C#; r   c                 (    j                  | d      S r5   r{   r|   s    r   r~   z0ThreadTests.test_args_argument.<locals>.<lambda>   s    D$4$4S!$< r   c                 (    j                  | d      S Nrx   r{   r|   s    r   r~   z0ThreadTests.test_args_argument.<locals>.<lambda>   s    4#3#3C#? r   c                 (    j                  | d      S r   r{   r|   s    r   r~   z0ThreadTests.test_args_argument.<locals>.<lambda>   s    D$4$4S%$@ r   c                 *    j                  | dg      S r5   r{   r|   s    r   r~   z0ThreadTests.test_args_argument.<locals>.<lambda>   s    (8(8qc(B r   c                 (    j                  | d      S )Nrw   r{   r|   s    r   r~   z0ThreadTests.test_args_argument.<locals>.<lambda>   s    (8(8d(C r   rk   args)subTestr(   rG   startjoin)r2   num_list	num_tuplestr_list	str_tuplelist_in_tupletuple_in_list
test_casesr   rk   ts   `          r   test_args_argumentzThreadTests.test_args_argument   s     3	7	 ;<<=?@@ABCCD

 ' 	LD&V$7 $$F>	 	 s   8BB 	c                 ~    t        j                         }t        j                  j	                  | t        |             y r<   )r(   Lockr   r   check_disallow_instantiationtyper2   locks     r   test_disallow_instantiationz'ThreadTests.test_disallow_instantiation   s(     ~~11$T
Cr   c                    d}t        j                  d      }t        j                         }t               }g }t	        |      D ]k  }t        d|z  | |||      }|j                  |       | j                  |j                         | j                  t        |      d       |j                          m t        t         d      rXt        d |D              t        j                         hz  }| j                  d |       | j!                  t#        |      |dz          t$        rt'        d	       |D ]  }|j)                          | j+                  |j-                                | j/                  |j                  d
       | j1                  |j                         | j                  t        |      d        t$        rt'        d       | j!                  |j3                         d
       y )N
   rL   r/   z<thread %d>z^<TestThread\(.*, initial\)>$get_native_idc              3   4   K   | ]  }|j                     y wr<   )	native_id).0r   s     r   	<genexpr>z/ThreadTests.test_various_ops.<locals>.<genexpr>   s     :QQ[[:s   r6   z!waiting for all tasks to completer   z#^<TestThread\(.*, stopped -?\d+\)>$zall tasks done)r(   BoundedSemaphoreRLockr-   rangerC   appendassertIsNoneidentassertRegexreprr   hasattrsetr   assertNotInrr   lenr   rP   r   assertFalseis_aliveassertNotEqualassertIsNotNoner=   )	r2   NUMTASKSrH   rI   
numrunningthreadsir   
native_idss	            r   test_various_opszThreadTests.test_various_ops   s     ))2!Y
x 	A=?D$zJANN1agg&T!W&FGGGI	 9o.:'::i>U>U>W=XXJT:.S_hl;56 	NAFFHQZZ\*+  )T!W&LM	N "#)1-r   c                    | j                  t        j                         j                         fd}t        j                         g t        j                         5  t        j                  |d      }j                          | j                  d   |       d d d        t        j                  d   = y # 1 sw Y   xY w)Nc                      j                  t        j                         j                          j	                          y r<   )r   r(   current_threadr   r   )rN   r   s   r   fz9ThreadTests.test_ident_of_no_threading_threads.<locals>.f   s'    LL11399:HHJr   rA   r   )r   r(   r   r   Eventr   wait_threads_exit_threadstart_new_threadwaitrr   _active)r2   r   tidrN   r   s      @@r   "test_ident_of_no_threading_threadsz.ThreadTests.test_ident_of_no_threading_threads   s    Y557==>	  //1 	,**1b1CIIKU1Xs+	,
 eAh'	, 	,s    <B99Cc                     t         rt        d       	 t        j                  d       | j                          t        j                  d       y # t        j
                  $ r t        j                  d      w xY w)Nz!with 256 KiB thread stack size...i   4platform does not support changing thread stack sizer   	r   rP   r(   
stack_sizer   errorr   SkipTestr   r1   s    r   test_various_ops_small_stackz(ThreadTests.test_various_ops_small_stack   sm    56	H  ( 	Q	 }} 	H##FH H	H   A )A7c                     t         rt        d       	 t        j                  d       | j                          t        j                  d       y # t        j
                  $ r t        j                  d      w xY w)Nzwith 1 MiB thread stack size...i   r   r   r   r1   s    r   test_various_ops_large_stackz(ThreadTests.test_various_ops_large_stack   sm    34	H  * 	Q	 }} 	H##FH H	Hr   c                 n   d }t        j                         }|j                          t        j                         5  t        j                  ||f      }|j                          d d d        | j                  t         j                         | j                  t         j                  |   t         j                         | j                  t         j                  |   j                                | j                  t        t         j                  |         d       t         j                  |= y # 1 sw Y   xY w)Nc                 L    t        j                          | j                          y r<   )r(   r   release)rI   s    r   r   z*ThreadTests.test_foreign_thread.<locals>.f  s     $$&MMOr   _DummyThread)r(   r   acquirer   r   r   r   assertInr   assertIsInstancer   
assertTruer   r   r   )r2   r   rI   r   s       r   test_foreign_threadzThreadTests.test_foreign_thread  s    	  //1 	**1uh7CMMO	 	c9,,-i//4i6L6LM	))#.779:i//45~Fc"	 	s   (D++D4c                   	
 t        d      }|j                  j                  }|j                  |j                  f|_         G d dt              	|j	                  	      }t        j                         }| j                  |t               | j                  |d       	  |||      }	 	 # 	$ r Y nw xY w	 | j                  d       n# t        $ r Y nw xY wt        j                         t        j                         
 G 	
fddt        j                         } |       }d|_        |j%                          t&        rt)        d	       t&        rt)        d
        |d|      }| j                  |d       t&        rt)        d       j+                         }| j-                  |       t&        rt)        d       | j/                  |j0                         t&        rt)        d        ||j2                  |      }| j                  |d       t&        rt)        d       
j+                  t4        j6                         | j-                  |j0                         t&        rt)        d       |j0                  r|j9                          y y )Nctypesc                       e Zd Zy)<ThreadTests.test_PyThreadState_SetAsyncExc.<locals>.AsyncExcN)r>   r?   r@   rA   r   r   AsyncExcr      s    r   r   r   Tr6   c                       e Zd Z fdZy):ThreadTests.test_PyThreadState_SetAsyncExc.<locals>.Workerc                     t        j                         | _        d| _        	 	 j	                          t        j                  d       &# $ r d| _        j	                          Y y w xY w)NFTg?)r(   	get_identidfinishedr   rR   rS   )r2   r   worker_saw_exceptionworker_starteds    r   rV   z>ThreadTests.test_PyThreadState_SetAsyncExc.<locals>.Worker.runD  sb    #--/ %/&**,

3    /$(DM(,,./s   'A
 
A)(A)Nr>   r?   r@   rV   )r   r   r   s   r   Workerr   C  s    
/r   r   z    started worker threadz     trying nonsensical thread idz,    waiting for worker thread to get startedz"    verifying worker hasn't exitedz2    attempting to raise asynch exception in workerz5    waiting for worker to say it caught the exceptiontimeoutz    all OK -- joining worker)r   	pythonapiPyThreadState_SetAsyncExcc_ulong	py_objectargtypes	Exceptionr(   r   r   intassertGreaterfailrr   UnboundLocalErrorr   rG   daemonr   r   rP   r   r   r   r   r   r   SHORT_TIMEOUTr   )r2   r   set_async_exc	exceptionr   resultr   r   retr   r   r   s            @@@r   test_PyThreadState_SetAsyncExcz*ThreadTests.test_PyThreadState_SetAsyncExc  s!   x(((BB"(..&2B2B!C	y 	 $$X.	 !!#c3'3"	-"3	2F   			VQ'  		 #*(0	/ 	/Y%% 	/ H		-. 45r9-# @A!!#67$FGqttY/#IJ!!'*?*?!@

#01::FFH s$   B+ +B32B37C
 
	CCc                 >   d }t         j                  }|t         _        	 t        j                  d       }| j                  t         j                  |j
                         | j                  |t         j                  v d       |t         _        y # |t         _        w xY w)Nc                  *    t        j                         r<   )r(   ThreadErrorr   s    r   fail_new_threadz7ThreadTests.test_limbo_cleanup.<locals>.fail_new_threadt  s    ''))r   c                       y r<   rA   rA   r   r   r~   z0ThreadTests.test_limbo_cleanup.<locals>.<lambda>y      r   rq   z:Failed to cleanup _limbo map on failure of Thread.start().)r(   _start_new_threadrG   assertRaisesr   r   r   _limbo)r2   r   r   r   s       r   test_limbo_cleanupzThreadTests.test_limbo_cleanupr  s~    	*%77&5	#	<  5Ai33QWW=Y%%%LN +<I'*;I's   A#B Bc                     t        j                  d      r| j                  d       t        d       t	        dd      \  }}}| j                  |d       y )NTr   TSAN would report thread leakr   -caN  if 1:
            import ctypes, sys, time, _thread

            # This lock is used as a simple event variable.
            ready = _thread.allocate_lock()
            ready.acquire()

            # Module globals are cleared before __del__ is run
            # So we save the functions in class dict
            class C:
                ensure = ctypes.pythonapi.PyGILState_Ensure
                release = ctypes.pythonapi.PyGILState_Release
                def __del__(self):
                    state = self.ensure()
                    self.release(state)

            def waitingThread():
                x = C()
                ready.release()
                time.sleep(100)

            _thread.start_new_thread(waitingThread, ())
            ready.acquire()  # Be sure the other thread is waiting.
            sys.exit(42)
            *   )r   r   skipTestr   r
   rr   r2   rcouterrs       r   test_finalize_running_threadz(ThreadTests.test_finalize_running_thread  sR     ""$/ MM9:h,T 4 C2 	R r   c                 j    t        j                  d      r| j                  d       t        dd       y )NTr   r  r  aP  if 1:
            import sys, threading

            # A deadlock-killer, to prevent the
            # testsuite to hang forever
            def killer():
                import os, time
                time.sleep(2)
                print('program blocked; aborting')
                os._exit(2)
            t = threading.Thread(target=killer)
            t.daemon = True
            t.start()

            # This is the trace function
            def func(frame, event, arg):
                threading.current_thread()
                return func

            sys.settrace(func)
            )r   r   r  r	   r1   s    r   test_finalize_with_tracez$ThreadTests.test_finalize_with_trace  s0     ""$/ MM9:   	r   c                     t        dd      \  }}}| j                  |j                         d       | j                  |d       y )Nr  a  if 1:
                import threading
                from time import sleep

                def child():
                    sleep(1)
                    # As a non-daemon thread we SHOULD wake up and nothing
                    # should be torn down yet
                    print("Woke up, sleep function is:", sleep)

                threading.Thread(target=child).start()
                raise SystemExit
            s5   Woke up, sleep function is: <built-in function sleep>r   r	   rr   stripr	  s       r   test_join_nondaemon_on_shutdownz+ThreadTests.test_join_nondaemon_on_shutdown  sG     ( / C 	D	Fc"r   c                    t         j                  }t        j                         }	 t	        dd      D ]p  }t        j
                  |dz         t        j                  d       }|j                          |j                           |       }| j                  ||d||fz         r 	 t        j
                  |       y # t        j
                  |       w xY w)Nr6   d   g-C6*?c                       y r<   rA   rA   r   r   r~   z7ThreadTests.test_enumerate_after_join.<locals>.<lambda>  r   r   rq   z&#1703448 triggered after %d trials: %s)
r(   	enumerater   getswitchintervalr   setswitchintervalrG   r   r   r   )r2   enumold_intervalr   r   ls         r   test_enumerate_after_joinz%ThreadTests.test_enumerate_after_join  s     "",,.
	01c] G%%a&j1$$L9	F  A<1vEGG !!,/C!!,/s   A?B< <Cc                     G d dt               }t        |         |d      }t        j                  |      }|j                  j                          ~| j                   |       dt        j                   |             z          |d      }t        j                  |      }|j                  j                          ~| j                   |       dt        j                   |             z         y )Nc                       e Zd Zd Zd Zy)DThreadTests.test_no_refcycle_through_target.<locals>.RunSelfFunctionc                     || _         t        j                  | j                  | fd| i      | _        | j                  j                          y )Nyet_another)rk   r   kwargs)should_raiser(   rG   _runr   r   )r2   r$  s     r   r3   zMThreadTests.test_no_refcycle_through_target.<locals>.RunSelfFunction.__init__  sD     %1!'..dii59G7DT6JL !!#r   c                 (    | j                   rt        y r<   )r$  
SystemExit)r2   	other_refr"  s      r   r%  zIThreadTests.test_no_refcycle_through_target.<locals>.RunSelfFunction._run  s    $$$$ %r   N)r>   r?   r@   r3   r%  rA   r   r   RunSelfFunctionr     s    $%r   r)  F)r$  z%d references still around)msgT)	rt   r+   weakrefrefr   r   r   r   getrefcount)r2   r)  cyclic_objectweak_cyclic_objectraising_cyclic_objectweak_raising_cyclic_objects         r   test_no_refcycle_through_targetz+ThreadTests.test_no_refcycle_through_target  s    	%f 	% 	#4('U;$[[7!!#,.:!oo.@.BCD 	 	F !0T B%,[[1F%G"$$))+!46:!oo.H.JKL 	 	Nr   c                 h   t        j                         }| j                  t        d      5  |j	                          d d d        | j                  t        d      5  |j                  d       d d d        | j                  t        d      5  |j                          d d d        | j                  t        d      5  |j                  d       d d d        t        j                         }| j                  t        d      5  |j                          d d d        t        j                         }|j                          | j                  t        d      5  |j                          d d d        | j                  t        d	      5  t        j                          d d d        | j                  t        d
      5  t        j                          d d d        y # 1 sw Y   xY w# 1 sw Y   sxY w# 1 sw Y   QxY w# 1 sw Y   .xY w# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   y xY w)Nzget the daemon attributezset the daemon attributeTzget the name attributezset the name attributerF   zuse is_set()zuse notify_all()zuse active_count()zuse current_thread())r(   rG   assertWarnsRegexDeprecationWarningisDaemon	setDaemongetNamesetNamer   isSet	Conditionr   	notifyAllactiveCountcurrentThread)r2   r   econds       r   test_old_threading_apiz"ThreadTests.test_old_threading_api
  s    ""#5#>@ 	JJL	 ""#5#>@ 	KK	 ""#5#<> 	IIK	 ""#5#<> 	IIf	 OO""#5~F 	GGI	 ""$""#57IJ 	NN	 ""#57KL 	$!!#	$""#57MN 	&##%	& 	&1	 		 		 		 	
	 	
	 		$ 	$	& 	&s_   GG
G*9G7=HH?H2H(GG'*G47HHHH%(H1c                     t        j                         }| j                  dt        |             d|_        | j                  dt        |             y Nr   T)r(   rG   r   r   r   r   r2   r   s     r   test_repr_daemonzThreadTests.test_repr_daemon)  s=    47+hQ(r   c                 &   t        j                         }| j                  |j                         t        j                  d      }| j                  |j                         t        j                  d      }| j	                  |j                         y )NFr   T)r(   rG   r   r   r   rD  s     r   test_daemon_paramzThreadTests.test_daemon_param/  sd    "E*"D)!r   c                 p    d}t        d|      \  }}}| j                  |d       | j                  |d       y )Na  if 1:
            import _thread, threading, os, time, warnings

            def background_thread(evt):
                # Creates and registers the _DummyThread instance
                threading.current_thread()
                evt.set()
                time.sleep(10)

            evt = threading.Event()
            _thread.start_new_thread(background_thread, (evt,))
            evt.wait()
            assert threading.active_count() == 2, threading.active_count()
            with warnings.catch_warnings(record=True) as ws:
                warnings.filterwarnings(
                        "always", category=DeprecationWarning)
                if os.fork() == 0:
                    assert threading.active_count() == 1, threading.active_count()
                    os._exit(0)
                else:
                    assert ws[0].category == DeprecationWarning, ws[0]
                    assert 'fork' in str(ws[0].message), ws[0]
                    os.wait()
        r  r   r	   rr   r2   code_r  r  s        r   test_dummy_thread_after_forkz(ThreadTests.test_dummy_thread_after_fork7  s=    0 'tT23c"c"r   c                 H   t        j                         }| j                  t         j                  |       t        j
                  j                  d       t        d      D ]  }t        j                  d       }|j                          t        j                  t        d      5  t        j                         x}dk(  r(t        j                  |j!                         rdnd	       n'|j#                          t        j$                  |d	
       d d d         y # 1 sw Y   xY w)Ngư>   c                       y r<   rA   rA   r   r   r~   z6ThreadTests.test_is_alive_after_fork.<locals>.<lambda>b  r   r   rq   ignorecategoryactionr      r   exitcode)r   r  r&   r  r   r   r   r(   rG   r   warningscatch_warningsr5  osfork_exitr   r   wait_process)r2   r  r   r   pids        r   test_is_alive_after_forkz$ThreadTests.test_is_alive_after_forkW  s     ,,.--|< 	&&t,r 	;A  5AGGI((2D08: ;779$C*HH1::<RR8FFH((r:; ;		;; ;s   $A)DD!	c                     t        j                         } j                  |j                  d        j                  |j                  t        j
                         j                          j                  |j                  t        j                                 fd}t        j                  |      }|j                          |j                          y )N
MainThreadc                       j                  t        j                         j                  t        j                         j                         y r<   )r   r(   main_threadr   r   r1   s   r   r   z'ThreadTests.test_main_thread.<locals>.ft  s5    	 5 5 7 = = ) 8 8 : @ @Br   rq   )
r(   rd  rr   rF   r   r   r   rG   r   r   )r2   mainr   ths   `   r   test_main_threadzThreadTests.test_main_threadn  s    $$&L1Y%=%=%?%E%EFY%8%8%:;	B Q'


	r   waitpidztest needs os.waitpid()c                     d}t        d|      \  }}}|j                         j                  dd      }| j                  |d       | j                  |d       y )Na!  if 1:
            import os, threading
            from test import support

            ident = threading.get_ident()
            pid = os.fork()
            if pid == 0:
                print("current ident", threading.get_ident() == ident)
                main = threading.main_thread()
                print("main", main.name)
                print("main ident", main.ident == ident)
                print("current is main", threading.current_thread() is main)
            else:
                support.wait_process(pid, exitcode=0)
        r  ro   r   zHcurrent ident True
main MainThread
main ident True
current is main True
r	   decodereplacerr   r2   rL  rM  r  r  datas         r   test_main_thread_after_forkz'ThreadTests.test_main_thread_after_fork{  sZ     'tT23zz|##D"-c"2	3r   c                     d}t        d|      \  }}}|j                         j                  dd      }| j                  |j                  d      d       | j                  |d       y )Na  if 1:
            import os, threading, sys, warnings
            from test import support

            def func():
                ident = threading.get_ident()
                with warnings.catch_warnings(record=True) as ws:
                    warnings.filterwarnings(
                            "always", category=DeprecationWarning)
                    pid = os.fork()
                    if pid == 0:
                        print("current ident", threading.get_ident() == ident)
                        main = threading.main_thread()
                        print("main", main.name, type(main).__name__)
                        print("main ident", main.ident == ident)
                        print("current is main", threading.current_thread() is main)
                        # stdout is fully buffered because not a tty,
                        # we have to flush before exit.
                        sys.stdout.flush()
                    else:
                        assert ws[0].category == DeprecationWarning, ws[0]
                        assert 'fork' in str(ws[0].message), ws[0]
                        support.wait_process(pid, exitcode=0)

            th = threading.Thread(target=func)
            th.start()
            th.join()
        r  rj  ro   utf-8zTcurrent ident True
main Thread-1 (func) Thread
main ident True
current is main True
rk  rn  s         r   /test_main_thread_after_fork_from_nonmain_threadz;ThreadTests.test_main_thread_after_fork_from_nonmain_thread  sc    8 'tT23zz|##D"-G,b12	r   due to known OS bugc                     d|z  }t        ddd|      \  }}}|j                         j                  dd      }| j                  |j                         d       | j                  ||rdndd|d	z   d
z          y )NaC  if 1:
            import os, threading, sys, traceback, _thread
            from test import support

            def func(lock):
                ident = threading.get_ident()
                if %s:
                    # call current_thread() before fork to allocate DummyThread
                    current = threading.current_thread()
                    print("current", current.name, type(current).__name__)
                print("ident in _active", ident in threading._active)
                # flush before fork, so child won't flush it again
                sys.stdout.flush()
                pid = os.fork()
                if pid == 0:
                    print("current ident", threading.get_ident() == ident)
                    main = threading.main_thread()
                    print("main", main.name, type(main).__name__)
                    print("main ident", main.ident == ident)
                    print("current is main", threading.current_thread() is main)
                    print("_dangling", [t.name for t in list(threading._dangling)])
                    # stdout is fully buffered because not a tty,
                    # we have to flush before exit.
                    sys.stdout.flush()
                    try:
                        threading._shutdown()
                        os._exit(0)
                    except:
                        traceback.print_exc()
                        sys.stderr.flush()
                        os._exit(1)
                else:
                    try:
                        support.wait_process(pid, exitcode=0)
                    except Exception:
                        # avoid 'could not acquire lock for
                        # <_io.BufferedWriter name='<stderr>'> at interpreter shutdown,'
                        traceback.print_exc()
                        sys.stderr.flush()
                    finally:
                        lock.release()

            join_lock = _thread.allocate_lock()
            join_lock.acquire()
            th = _thread.start_new_thread(func, (join_lock,))
            join_lock.acquire()
        z-Wzignore::DeprecationWarningr  rj  ro   zcurrent Dummy-1 _DummyThread
zident in _active 
zmcurrent ident True
main MainThread _MainThread
main ident True
current is main True
_dangling ['MainThread']
rk  )r2   create_dummyrL  rM  r  r  ro  s          r   /test_main_thread_after_fork_from_foreign_threadz;ThreadTests.test_main_thread_after_fork_from_foreign_thread  s    .\ ].b 't-I4QUV3zz|##D"-r*>J:PR,\,<B?@66	7r   c                 (    | j                  d       y )NT)rw  )rx  )r2   rw  s     r   -test_main_thread_after_fork_from_dummy_threadz9ThreadTests.test_main_thread_after_fork_from_dummy_thread   s    <<$<Or   c                     d}t        d|      \  }}}|j                         }| j                  |d       | j                  |j                         dgdz         y )Na  if 1:
            import gc, threading

            main_thread = threading.current_thread()
            assert main_thread is threading.main_thread()  # sanity check

            class RefCycle:
                def __init__(self):
                    self.cycle = self

                def __del__(self):
                    print("GC:",
                          threading.current_thread() is main_thread,
                          threading.main_thread() is main_thread,
                          threading.enumerate() == [main_thread])

            RefCycle()
            gc.collect()  # sanity check
            x = RefCycle()
        r  r   zGC: True True Truerm   )r	   rl  rr   
splitlinesrn  s         r    test_main_thread_during_shutdownz,ThreadTests.test_main_thread_during_shutdown  sZ    ( 'tT23zz|c"*./!3	5r   c                 L    d}t        d|      \  }}}| j                  |d       y )Na  if 1:
            import os
            import threading
            import time
            import random

            def random_sleep():
                seconds = random.random() * 0.010
                time.sleep(seconds)

            class Sleeper:
                def __del__(self):
                    random_sleep()

            tls = threading.local()

            def f():
                # Sleep a bit so that the thread is still running when
                # Py_Finalize() is called.
                random_sleep()
                tls.x = Sleeper()
                random_sleep()

            threading.Thread(target=f).start()
            random_sleep()
        r  r   rJ  r2   rL  r
  r  r  s        r   test_finalization_shutdownz&ThreadTests.test_finalization_shutdown   s-    4 (d3Cc"r   c                 T   t        j                         t        j                         j                          j                          fd}t        j                  |      }| j                  |j                  d        |j                          j                          | j                  |j                                |j                  }| j                  |j                  d      d       j                          | j                  |j                  t        j                        d       | j                  |j                                |j                          | j                  |j                                | j                  |j                         |j                          y )Nc                  p    j                           j                          t        j                  d       y )N{Gz?)r   r   rR   rS   finishstarteds   r   r   z'ThreadTests.test_tstate_lock.<locals>.fI  s#    OONNJJtr   rq   r   r   F)r   allocate_lockr   r(   rG   assertIs_tstate_lockr   r   r   r   r   r   r   r   r   )r2   r   r   tstate_lockr  r  s       @@r   test_tstate_lockzThreadTests.test_tstate_lockC  s'   '')&&(	
 A&annd+		

% nn,,Q,7? 	++G4I4I+JER 	

%&!..)	r   c                 (   t        j                         t        j                         j                          j                          fd}t        j                  |      }|j                          j                          | j                  dt        |             j                          d}t        d      D ]&  }|t        |      v r nt        j                  d       ( | j                  |t        |             |j                          y )Nc                  F    j                           j                          y r<   )r   r   r  s   r   r   z(ThreadTests.test_repr_stopped.<locals>.fl  s    OONNr   rq   r  stoppedi  r  )r   r  r   r(   rG   r   r   r   r   r   rR   rS   r   )r2   r   r   LOOKING_FORr   r  r  s        @@r   test_repr_stoppedzThreadTests.test_repr_stoppedf  s    '')&&(	 A&		ia)  s 	Ad1g%JJt	 	k47+	r   c                 8   t        dd      D ]   }t        j                  |      }t        |      D cg c]"  }t        j                  |j                        $ }}|D ]  }|j                           |D ]  }|j                           t        |      D cg c]"  }t        j                  |j                        $ }}|D ]  }|j                           |D ]  }|j                           | j                  t        |j                          y c c}w c c}w )Nr6   r   rq   )
r   r(   r   rG   r   r   r   r   r  
ValueError)r2   limitbsrM  r   r   s         r   test_BoundedSemaphore_limitz'ThreadTests.test_BoundedSemaphore_limit  s   1b\ 	6E++E2B %e. !''rzz: .G . 	  !&e. !''rzz: .G . 	 j"**5	6..s   'D'Dc                    fdd fdd _         t        j                         }t        j                         	 t	        j                         dd l}|j                         t        d      D ]	  }          	 t        j                  |       t	        j                  |       y # t        j                  |       t	        j                  |       w xY w)Nc                     S r<   rA   frameeventr}   
noop_traces      r   r  z9ThreadTests.test_frame_tstate_tracing.<locals>.noop_trace  	    r   c               3      K   	 d w)N	generatorrA   rA   r   r   r  z8ThreadTests.test_frame_tstate_tracing.<locals>.generator  s     !! s   	c                  ^     j                            _         t         j                         S r<   )gennext)callbackr  s   r   r  z7ThreadTests.test_frame_tstate_tracing.<locals>.callback  s%    ||#({%%r   r   rL   )r  r   gettracesettracer(   	_testcapicall_in_temporary_c_threadr   )r2   	old_tracer  r   r  r  r  s       @@@r   test_frame_tstate_tracingz%ThreadTests.test_frame_tstate_tracing  s    		"	& LLN	Z 	*z* 00: a 
 LL#y) LL#y)s   AB0 0,Cc                    fdt        j                         }	 t        j                         t        j                         }| j                  |       t        j                  |       y # t        j                  |       w xY w)Nc                     S r<   rA   r  s      r   r  z-ThreadTests.test_gettrace.<locals>.noop_trace  r  r   )r(   r  r  rr   )r2   r  
trace_funcr  s      @r   test_gettracezThreadTests.test_gettrace  sf    	 &&(		*z*"++-JZ
3y)Iy)s   ;A- -Bc                    d }t        j                         }t        j                         t        j                         g fd}	 t        j                  |      }|j	                          j                          t        j                  |       j                          |j                          | j                  d |g       | j                  t        j                         |       | j                  t        j                         |       t        j                  |       | j                  t        j                         |       | j                  t        j                         |       y # t        j                  |       w xY w)Nc                       y r<   rA   r   s    r   fnz1ThreadTests.test_gettrace_all_threads.<locals>.fn      tr   c                      j                  t        j                                 j                          j	                          j                  t        j                                y r<   )r   r   r  r   r   )first_checksecond_checktrace_funcss   r   checkerz6ThreadTests.test_gettrace_all_threads.<locals>.checker  sA    s||~.OOs||~.r   rq   )r(   r  r   rG   r   r   settrace_all_threadsr   r   rr   r   )r2   r  r  r  r   r  r  r  s        @@@r   test_gettrace_all_threadsz%ThreadTests.test_gettrace_all_threads  s   &&(	oo' (	/	6  0AGGI**2.FFH[4*5Y//126S\\^R0**95++-y93 **95   CE2 2F	c                    d }t        j                         }	 t        j                  |       | j                  |t        j                                t        j                  |       y # t        j                  |       w xY w)Nc                       y r<   rA   r   s    r   r  z'ThreadTests.test_getprofile.<locals>.fn  r  r   )r(   
getprofile
setprofilerr   )r2   r  old_profiles      r   test_getprofilezThreadTests.test_getprofile  s\    **,	.  $R!5!5!78  -I  -s   9A( (A?c                    d }t        j                         }t        j                         t        j                         g fd}	 t        j                  |      }|j	                          j                          t        j                  |       j                          |j                          | j                  d |g       | j                  t        j                         |       | j                  t        j                         |       t        j                  |       | j                  t        j                         |       | j                  t        j                         |       y # t        j                  |       w xY w)Nc                       y r<   rA   r   s    r   r  z3ThreadTests.test_getprofile_all_threads.<locals>.fn  r  r   c                      j                  t        j                                 j                          j	                          j                  t        j                                y r<   )r   r   r  r   r   )r  profile_funcsr  s   r   r  z8ThreadTests.test_getprofile_all_threads.<locals>.checker  sC      !12OO  !12r   rq   )r(   r  r   rG   r   r   setprofile_all_threadsr   r   rr   r   )r2   r  r  r  r   r  r  r  s        @@@r   test_getprofile_all_threadsz'ThreadTests.test_getprofile_all_threads  s   **,oo' (	3	:  0AGGI,,R0FFH]T2J7Y113R8S^^-r2,,[9--/=);7 ,,[9r  c                    dD ]  }| j                  |      5  t        j                         }t        j                  |j                  |      }|j                          |j                  }|s!| j                  |t        j                         n | j                  |t        j                         |j                          |j                          | j                  |t        j                         d d d         y # 1 sw Y   xY w)N)FTrG  )rk   r   )r   r(   r   rG   r   r   r  r   _shutdown_locksr   r   r   )r2   r   r  r   r  s        r   test_shutdown_lockszThreadTests.test_shutdown_locks  s    # 	IFV, I!)"))FK $11MM+y/H/HI$$[)2K2KL 		   i.G.GH'I I	II Is   CC88D	c                 d    t        dd      \  }}}| j                  |j                         d       y )Nr  a(  if 1:
            import threading

            class Atexit:
                def __del__(self):
                    print("thread_dict.atexit = %r" % thread_dict.atexit)

            thread_dict = threading.local()
            thread_dict.atexit = "value"

            atexit = Atexit()
        s   thread_dict.atexit = 'value')r	   rr   rstripr	  s       r   test_locals_at_exitzThreadTests.test_locals_at_exit#  s4     ( / C 	'FGr   c                      G d dt               } |       }t        j                  |      }|j                          |j	                          | j                  |j                         y )Nc                       e Zd Zd Zd Zd Zy)6ThreadTests.test_boolean_target.<locals>.BooleanTargetc                     d| _         y NFranr1   s    r   r3   z?ThreadTests.test_boolean_target.<locals>.BooleanTarget.__init__:  s	     r   c                      yr  rA   r1   s    r   __bool__z?ThreadTests.test_boolean_target.<locals>.BooleanTarget.__bool__<  s    r   c                     d| _         y )NTr  r1   s    r   __call__z?ThreadTests.test_boolean_target.<locals>.BooleanTarget.__call__>  s	    r   N)r>   r?   r@   r3   r  r  rA   r   r   BooleanTargetr  9  s    ! r   r  rq   )rt   r(   rG   r   r   r   r  )r2   r  rk   r   s       r   test_boolean_targetzThreadTests.test_boolean_target4  sI    
	 F 	  !!0

#r   c                     d }t        j                         5  t        j                  |      j	                          d d d        y # 1 sw Y   y xY w)Nc                       y r<   rA   rA   r   r   noopz0ThreadTests.test_leak_without_join.<locals>.noopJ  rf   r   rq   )r   r   r(   rG   r   )r2   r  s     r   test_leak_without_joinz"ThreadTests.test_leak_without_joinG  s?     	//1 	2D)//1	2 	2 	2s   %AAc                     t        j                  d      }t        d|      \  }}}| j                  |d       | j                  |d       y )Na  
            import _thread
            import sys

            event = _thread.allocate_lock()
            event.acquire()

            def import_threading():
                import threading
                event.release()

            if 'threading' in sys.modules:
                raise Exception('threading is already imported')

            _thread.start_new_thread(import_threading, ())

            # wait until the threading module is imported
            event.acquire()
            event.release()

            if 'threading' not in sys.modules:
                raise Exception('threading is not imported')

            # don't wait until the thread completes
        r  r   )textwrapdedentr	   rr   r  s        r   test_import_from_another_threadz+ThreadTests.test_import_from_another_threadO  sK        2 (d3Cc"c"r   c                     d}t        d|      \  }}}| j                  |j                         d       | j                  d|       y )Na6  if 1:
            import _thread

            def f():
                print("shouldn't be printed")

            class AtFinalization:
                def __del__(self):
                    print("OK")
                    _thread.start_new_thread(f, ())
            at_finalization = AtFinalization()
        r     OKs/   can't create new thread at interpreter shutdown)r	   rr   r  r   rK  s        r   %test_start_new_thread_at_finalizationz1ThreadTests.test_start_new_thread_at_finalizationp  sB     'tT23e,H#Nr   N)F)9r>   r?   r@   maxDiffr   ru   r   r   r   r   r   r   r   r   r  r  r  r  r  r2  rA  rE  rH  r   rN  r`  rg  r   
skipUnlessr   r[  rp  rs  r!   r   r   r   r   requires_forkrx  rz  r}  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  rA   r   r   rb   rb   w   s   G= =46 D D".H( 	 	 #.Up<#!J<#(0"NB&>)" # #> ; ;, XY/1JK3 L 32 XY/1JK% L %N X__S\\%668MNWXY/1JK<7 L  O<7|P5:!#F!F66$ &* &*P
*4:.8: I I.H"$&2#BOr   rb   c                       e Zd Zd Zd Zed        Zed        Z ej                  e
j                  ev d      d        Zd Zed        Zed	        Zy
)ThreadJoinOnShutdownc                     d|z   }t        d|      \  }}}|j                         j                  dd      }| j                  |d       y )Na  if 1:
            import sys, os, time, threading

            # a thread, which waits for the main program to terminate
            def joiningfunc(mainthread):
                mainthread.join()
                print('end of thread')
                # stdout is fully buffered because not a tty, we have to flush
                # before exit.
                sys.stdout.flush()
        
r  rj  ro   zend of main
end of thread
rk  )r2   scriptr
  r  r  ro  s         r   _run_and_joinz"ThreadJoinOnShutdown._run_and_join  sP    
 
 (f5Czz|##D"-=>r   c                 *    d}| j                  |       y )Nzif 1:
            import os
            t = threading.Thread(target=joiningfunc,
                                 args=(threading.current_thread(),))
            t.start()
            time.sleep(0.1)
            print('end of main')
            r  r2   r  s     r   test_1_join_on_shutdownz,ThreadJoinOnShutdown.test_1_join_on_shutdown  s     	6"r   c                 *    d}| j                  |       y )Na  if 1:
            from test import support

            childpid = os.fork()
            if childpid != 0:
                # parent process
                support.wait_process(childpid, exitcode=0)
                sys.exit(0)

            # child process
            t = threading.Thread(target=joiningfunc,
                                 args=(threading.current_thread(),))
            t.start()
            print('end of main')
            r  r  s     r   test_2_join_in_forked_processz2ThreadJoinOnShutdown.test_2_join_in_forked_process  s     	6"r   c                 *    d}| j                  |       y )Na  if 1:
            from test import support

            main_thread = threading.current_thread()
            def worker():
                childpid = os.fork()
                if childpid != 0:
                    # parent process
                    support.wait_process(childpid, exitcode=0)
                    sys.exit(0)

                # child process
                t = threading.Thread(target=joiningfunc,
                                     args=(main_thread,))
                print('end of main')
                t.start()
                t.join() # Should not block: main_thread is already stopped

            w = threading.Thread(target=worker)
            w.start()
            r  r  s     r   !test_3_join_in_forked_from_threadz6ThreadJoinOnShutdown.test_3_join_in_forked_from_thread  s    
* 	6"r   rt  c                     t        j                  d      r| j                  d       d}t        d|      \  }}}| j	                  |       y )NTr   r  a  if True:
            import os
            import random
            import sys
            import time
            import threading

            thread_has_run = set()

            def random_io():
                '''Loop for a while sleeping random tiny amounts and doing some I/O.'''
                import test.test_threading as mod
                while True:
                    with open(mod.__file__, 'rb') as in_f:
                        stuff = in_f.read(200)
                        with open(os.devnull, 'wb') as null_f:
                            null_f.write(stuff)
                            time.sleep(random.random() / 1995)
                    thread_has_run.add(threading.current_thread())

            def main():
                count = 0
                for _ in range(40):
                    new_thread = threading.Thread(target=random_io)
                    new_thread.daemon = True
                    new_thread.start()
                    count += 1
                while len(thread_has_run) < count:
                    time.sleep(0.001)
                # Trigger process shutdown
                sys.exit(0)

            main()
            r  )r   r   r  r	   r   r2   r  r
  r  r  s        r   test_4_daemon_threadsz*ThreadJoinOnShutdown.test_4_daemon_threads  sK    
 ""$/ MM9:!D (f5Cr   c                     d}t        d|      \  }}}| j                  |d       | j                  |j                         d       | j                  |d       y )Na  if True:
            import threading
            import time

            def thread2():
                time.sleep(0.05)
                print("OK")

            def thread1():
                time.sleep(0.05)
                t2 = threading.Thread(target=thread2)
                t2.start()

            t = threading.Thread(target=thread1)
            t.start()
            # do not join() -- the interpreter waits for non-daemon threads to
            # finish.
            r  r   r  r   r  r  s        r   test_thread_from_threadz,ThreadJoinOnShutdown.test_thread_from_thread  sS    $ (f5Cc"e,Qr   c                 ,   d }t        j                  t        d      5  g }t        d      D ]9  }t	        j
                  |      }|j                  |       |j                          ; |D ]  }|j                           	 d d d        y # 1 sw Y   y xY w)Nc                      t        j                         } | dkD  rt        j                  | d       y t        j                  d       y )Nr   2   rW  )r[  r\  r   r^  r]  )r_  s    r   do_fork_and_waitzIThreadJoinOnShutdown.test_reinit_tls_after_fork.<locals>.do_fork_and_wait  s/    '')CQw$$S26r   rR  rS     rq   )	rY  rZ  r5  r   r(   rG   r   r   r   )r2   r  r   r   r   s        r   test_reinit_tls_after_forkz/ThreadJoinOnShutdown.test_reinit_tls_after_fork  s    
	 $$.@,46 
	 G2Y $$,<=q!	
  
	 
	 
	s   A!B

Bc                 X   g }t        d      D ]:  }t        j                  d       }|j                  |       |j	                          < 	 t        j                  t        d      5  t        j                         }|dk(  rLt        t        j                               dk(  rt        j                  d       n-t        j                  d	       nt        j                  |d
       d d d        |D ]  }|j!                           y # 1 sw Y   !xY w# |D ]  }|j!                           w xY w)Nr  c                  ,    t        j                  d      S )Ng333333?)rR   rS   rA   r   r   r~   zKThreadJoinOnShutdown.test_clear_threads_states_after_fork.<locals>.<lambda>8  s    C r   rq   rR  rS  r   r6   3   4   rW  )r   r(   rG   r   r   rY  rZ  r5  r[  r\  r   r   _current_framesr]  r   r^  r   )r2   r   r   r   r_  s        r   $test_clear_threads_states_after_forkz9ThreadJoinOnShutdown.test_clear_threads_states_after_fork1  s    
 r 	A  (@AANN1GGI	
	((2D08: 
;ggi!83..01Q6((r:
;  
; 
;  s%   D 'A=D$D D	D D)N)r>   r?   r@   r  r  r   r  r  r   r!   r   r   r   r  r  r  r  rA   r   r   r  r    s    ?"
# # #& # #6 X__S\\%668MN, O,\ 0  2  r   r  c                   p    e Zd Zd Zd Zd Zed        Zed        Z	dddddd	Z
ed
        Zed        Zy)SubinterpThreadingTestsc                    t        j                         \  }}| j                  t         j                  |       | j                  t         j                  |       t	        t         d      rt        j
                  |d       ||fS )Nset_blockingF)r[  piper&   closer   r  )r2   rws      r   r  zSubinterpThreadingTests.pipeO  sV    wwy1!$!$2~&OOAu%1vr   c                 
   | j                         \  }}t        j                  d|fz        }t        j                  j                  |      }| j                  |d       | j                  t        j                  |d      d       y )Na  
            import os
            import random
            import threading
            import time

            def random_sleep():
                seconds = random.random() * 0.010
                time.sleep(seconds)

            def f():
                # Sleep a bit so that the thread is still running when
                # Py_EndInterpreter is called.
                random_sleep()
                os.write(%d, b"x")

            threading.Thread(target=f).start()
            random_sleep()
        r   r6      x	r  r  r  r   r   run_in_subinterprr   r[  readr2   r
  r  rL  r   s        r   test_threads_joinz)SubinterpThreadingTests.test_threads_joinW  sr     yy{1  $ d%  & ll++D1a A-r   c                 
   | j                         \  }}t        j                  d|fz        }t        j                  j                  |      }| j                  |d       | j                  t        j                  |d      d       y )Na  
            import os
            import random
            import threading
            import time

            def random_sleep():
                seconds = random.random() * 0.010
                time.sleep(seconds)

            class Sleeper:
                def __del__(self):
                    random_sleep()

            tls = threading.local()

            def f():
                # Sleep a bit so that the thread is still running when
                # Py_EndInterpreter is called.
                random_sleep()
                tls.x = Sleeper()
                os.write(%d, b"x")

            threading.Thread(target=f).start()
            random_sleep()
        r   r6   r  r  r  s        r   test_threads_join_2z+SubinterpThreadingTests.test_threads_join_2s  sr    
 yy{1  2 d3  4 ll++D1a A-r   c                    | j                         \  }}d}d}d}t        j                         }|j                  d| d|d| d|d| d|d       |j	                          | j                  t        j                  |d	      |       | j                  t        j                  |d	      |       | j                  t        j                  |d	      |       y )
N   I   F   Dzif True:
            import os
            import threading
            import time

            done = False

            def notify_fini():
                global done
                done = True
                os.write(z, z)
                t.join()
            threading._register_atexit(notify_fini)

            def task():
                while not done:
                    time.sleep(0.1)
                os.write(z\)
            t = threading.Thread(target=task)
            t.start()

            os.write()
            r6   )r  r   createrV   r	  rr   r[  r  )r2   r_interpw_interpINTERPFINIDONEinterps          r   test_threads_join_with_no_mainz6SubinterpThreadingTests.test_threads_join_with_no_main  s    !YY[($$&

 
 #2dX . #2dX . Zr& ,+ 	. 	1-v61-t41-t4r   c                    dt         j                  j                   d}d|d}t         j                  j                         5  t	        d|      \  }}}d d d        | j                  dj                                y # 1 sw Y   *xY w)Nzif 1:
            import os
            import threading
            import time

            def f():
                # Make sure the daemon thread is still running when
                # Py_EndInterpreter is called.
                time.sleep(zJ)
            threading.Thread(target=f, daemon=True).start()
            zKif 1:
            import _testcapi

            _testcapi.run_in_subinterp(r  r  z:Fatal Python error: Py_EndInterpreter: not the last thread)r   r   r   SuppressCrashReportr
   r   rl  )r2   subinterp_coder  r
  r  r  s         r   test_daemon_threads_fatal_errorz7SubinterpThreadingTests.test_daemon_threads_fatal_error  s     !LL667 8
 "	$
 \\--/ 	?0v>LBS	? ,-0ZZ\	;	? 	?s   A==BTFalloweddaemon_allowedr   c          	      <   t        j                  d| d| d      }t        j                  d|d| d| d      }t        j                  j	                         5  t        d|      \  }}}d d d        |j                         S # 1 sw Y   j                         S xY w)	Nz
            import test.support
            import threading
            def func():
                print('this should not have run!')
            t = threading.Thread(target=func, daemon=r  z#
            t.start()
            zh
            import test.support
            test.support.run_in_subinterp_with_config(
                z,
                use_main_obmalloc=True,
                allow_fork=True,
                allow_exec=True,
                allow_threads=z',
                allow_daemon_threads=zp,
                check_multi_interp_extensions=False,
                own_gil=False,
            )
            r  )r  r  r   r   r#  r	   rl  )	r2   before_startr'  r(  r   r$  r  rM  r  s	            r   _check_allowedz&SubinterpThreadingTests._check_allowed  s    
 " .6
 7=X >N *   &  " #  'i (&&4%5 6"  \\--/ 	7(v6IAq#	7zz|	7zz|s   BBc                 P    | j                  ddd      }| j                  d|       y )NFr&  RuntimeError)r+  r   r2   r  s     r   test_threads_not_allowedz0SubinterpThreadingTests.test_threads_not_allowed  s0    !!  " 

 	nc*r   c                 6   | j                  d      5  | j                  ddd      }| j                  d|       d d d        | j                  d      5  | j                  dddd      }| j                  d|       d d d        y # 1 sw Y   KxY w# 1 sw Y   y xY w)Nzvia Thread()TFr&  r-  zvia Thread.daemon setterzt.daemon = True)r   r+  r   r.  s     r   test_daemon_threads_not_allowedz7SubinterpThreadingTests.test_daemon_threads_not_allowed  s    \\.) 	/%%$ & C
 MM.#.	/ \\45 	/%%!$	 & C MM.#.	/ 	/	/ 	/	/ 	/s   'B(BBBN)ro   )r>   r?   r@   r  r  r  r#   r!  r   r%  r+  r/  r1  rA   r   r   r  r  N  sv    .8#.J #5 #5J ; ;,#&*#> + + / /r   r  c                   h    e Zd Zd Zd Zd Zd Zd Z e       d        Z	d Z
d Zd	 Zd
 Zd Zd Zy)ThreadingExceptionTestsc                     t        j                         }|j                          | j                  t        |j                         |j                          y r<   )r(   rG   r   r  r-  r   r2   r   s     r   test_start_thread_againz/ThreadingExceptionTests.test_start_thread_again  s6    !!#,5r   c                 l    t        j                         }| j                  t        |j                         y r<   )r(   r   r  r-  r   )r2   r   s     r   test_joining_current_threadz3ThreadingExceptionTests.test_joining_current_thread  s&    "113,(;(;<r   c                 l    t        j                         }| j                  t        |j                         y r<   )r(   rG   r  r-  r   r5  s     r   test_joining_inactive_threadz4ThreadingExceptionTests.test_joining_inactive_thread  s$    !!#,4r   c                     t        j                         }|j                          | j                  t        t
        |dd       |j                          y rC  )r(   rG   r   r  r-  r'   r   r5  s     r   test_daemonize_active_threadz4ThreadingExceptionTests.test_daemonize_active_thread"  s8    !!#,4Hr   c                 l    t        j                         }| j                  t        |j                         y r<   )r(   r   r  r-  r   r   s     r   test_releasing_unacquired_lockz6ThreadingExceptionTests.test_releasing_unacquired_lock(  s"    ~~,5r   c                 |   d}d}t        j                  t        j                  d|gt         j                  t         j                        }|j                         \  }}|j                         j                  dd      }| j                  |j                  dd|j                         z          | j                  ||       y )	Na  if True:
            import threading

            def recurse():
                return recurse()

            def outer():
                try:
                    recurse()
                except RecursionError:
                    pass

            w = threading.Thread(target=outer)
            w.start()
            w.join()
            print('end of main thread')
            zend of main thread
r  )stdoutstderrrj  ro   r   zUnexpected error: )

subprocessPopenr   
executablePIPEcommunicaterl  rm  rr   
returncode)r2   r  expected_outputpr@  rA  ro  s          r   test_recursion_limitz,ThreadingExceptionTests.test_recursion_limit,  s    " 1cnndF;$.OOJOOM}}&&tR0q*>*PQ/r   c                     d}t        d|      \  }}}| j                  |d       |j                         }| j                  d|       | j                  d|       | j                  d|       | j	                  d|       y )Na  if True:
            import threading
            import time

            running = False
            def run():
                global running
                running = True
                while running:
                    time.sleep(0.01)
                1/0
            t = threading.Thread(target=run)
            t.start()
            while not running:
                time.sleep(0.01)
            running = False
            t.join()
            r  r   Exception in thread"Traceback (most recent call last):ZeroDivisionErrorUnhandled exceptionr	   rr   rl  r   r   r  s        r   test_print_exceptionz,ThreadingExceptionTests.test_print_exceptionL  sv    $ (f5Cc"jjl+S1:C@)3/.4r   c                     d}t        d|      \  }}}| j                  |d       |j                         }| j                  d|       | j                  d|       | j                  d|       | j	                  d|       y )Na  if True:
            import sys
            import threading
            import time

            running = False
            def run():
                global running
                running = True
                while running:
                    time.sleep(0.01)
                1/0
            t = threading.Thread(target=run)
            t.start()
            while not running:
                time.sleep(0.01)
            sys.stderr = None
            running = False
            t.join()
            r  r   rL  rM  rN  rO  rP  r  s        r   %test_print_exception_stderr_is_none_1z=ThreadingExceptionTests.test_print_exception_stderr_is_none_1g  sv    ( (f5Cc"jjl+S1:C@)3/.4r   c                     d}t        d|      \  }}}| j                  |d       | j                  d|j                                y )Na  if True:
            import sys
            import threading
            import time

            running = False
            def run():
                global running
                running = True
                while running:
                    time.sleep(0.01)
                1/0
            sys.stderr = None
            t = threading.Thread(target=run)
            t.start()
            while not running:
                time.sleep(0.01)
            running = False
            t.join()
            r  r   rO  )r	   rr   r   rl  r  s        r   %test_print_exception_stderr_is_none_2z=ThreadingExceptionTests.test_print_exception_stderr_is_none_2  sD    ( (f5Cc".

=r   c                      d}t        d|       y )Na9  if True:
            import time
            import threading
            import _thread

            def f():
                try:
                    f()
                except RecursionError:
                    f()

            def g():
                try:
                    raise ValueError()
                except* ValueError:
                    f()

            def h():
                time.sleep(1)
                _thread.interrupt_main()

            t = threading.Thread(target=h)
            t.start()
            g()
            t.join()
            r  )r
   r  s     r   test_print_exception_gh_102056z6ThreadingExceptionTests.test_print_exception_gh_102056  s    6 	dF+r   c                    d  G fddt         j                        } |       }|j                          |j                          | j	                  |j
                         | j                  |j
                  t               d |_        y )Nc                        r<   rA   rA   r   r   
bare_raisezOThreadingExceptionTests.test_bare_raise_in_brand_new_thread.<locals>.bare_raise  s    r   c                       e Zd ZdZ fdZy)OThreadingExceptionTests.test_bare_raise_in_brand_new_thread.<locals>.Issue27558Nc                 P    	          y # t         $ r}|| _        Y d }~y d }~ww xY wr<   )r   exc)r2   r^  rZ  s     r   rV   zSThreadingExceptionTests.test_bare_raise_in_brand_new_thread.<locals>.Issue27558.run  s&    #L  #"DHH#s    	% %)r>   r?   r@   r^  rV   )rZ  s   r   
Issue27558r\    s    C#r   r_  )r(   rG   r   r   r   r^  r   r-  )r2   r_  r   rZ  s      @r   #test_bare_raise_in_brand_new_threadz;ThreadingExceptionTests.test_bare_raise_in_brand_new_thread  sb    		#)) 	# VZZ(fjj,7
r   c                    d }| j                  t        j                  t        j                         t	        d      D cg c]  }t        j                  |       }}|D ]"  }|j                          |j                          $ y c c}w )Nc                      t        t        j                  dd      5 } | j                  d       t	        j
                          d d d        y # 1 sw Y   y xY w)Nr  rr  )encoding )openr   TESTFNwrite	tracebackformat_stack)fps    r   modify_filezQThreadingExceptionTests.test_multithread_modify_file_noerror.<locals>.modify_file  sB    i&&g> )"&&() ) )s   &AAr  rq   )	r&   r   unlinkrf  r   r(   rG   r   r   )r2   rk  r   r   r   s        r   $test_multithread_modify_file_noerrorz<ThreadingExceptionTests.test_multithread_modify_file_noerror  sy    	)
 		(()*:*:; 3Z
 K0
 
  	AGGIFFH		
s   BN)r>   r?   r@   r6  r8  r:  r<  r>  r   rJ  rQ  rS  rU  rW  r`  rm  rA   r   r   r3  r3    sP    >56 0 0>565:>2,>*r   r3  c                       e Zd Zd Zy)ThreadRunFailc                     t        d      )N
run failedr  r1   s    r   rV   zThreadRunFail.run  s    &&r   Nr   rA   r   r   ro  ro    s    'r   ro  c                   `     e Zd Z fdZd Zej                  d        Zd Zd Z	d Z
d Z xZS )ExceptHookTestsc                 8    t        |        t        | 	          y r<   )r+   superr\   )r2   	__class__s    r   r\   zExceptHookTests.setUp  s    "4(r   c                    t        j                  d      5 }t        d      }|j                          |j	                          d d d        j                         j                         }| j                  dj                   d|       | j                  d|       | j                  d|       | j                  d|       y # 1 sw Y   ~xY w)	NrA  excepthook threadrE   Exception in thread :
#Traceback (most recent call last):
z   raise ValueError("run failed")zValueError: run failed)	r   captured_outputro  r   r   getvaluer  r   rF   )r2   rA  r   s      r   test_excepthookzExceptHookTests.test_excepthook  s    $$X. 	&"(;<FLLNKKM	
 "((*,V[[M=vF<fE8&A.7	 	s   -C  C	c                 .   t        j                  d      5 }	 t        d      # t        $ rU}t	        j
                  g t        j                         d       }	 t	        j                  |       d }n# d }w xY wY d }~nd }~ww xY w	 d d d        n# 1 sw Y   nxY wj                         j                         }| j                  dt	        j                          d|       | j                  d|       | j                  d|       | j                  d|       y )NrA  bugrz  r{  r|  z  raise ValueError("bug")zValueError: bug)r   r}  r  r   r(   ExceptHookArgsr   exc_infor%   r~  r  r   r   )r2   rA  r^  r   s       r   test_excepthook_thread_Nonez+ExceptHookTests.test_excepthook_thread_None  s     $$X. 		 &  ''   //0G#,,.0G$0GH ((.  D4DD  		  		  		  "((*,Y-@-@-B,C3GP<fE16:'0sC   B#	B+A<A0-A<0A44A<7B<BBBc                     G d dt         j                        }t        j                  d      5 } |       }|j	                          |j                          d d d        | j                  j                         d       y # 1 sw Y   *xY w)Nc                       e Zd Zd Zy)4ExceptHookTests.test_system_exit.<locals>.ThreadExitc                 .    t        j                  d       y r5   )r   exitr1   s    r   rV   z8ExceptHookTests.test_system_exit.<locals>.ThreadExit.run  s    r   Nr   rA   r   r   
ThreadExitr    s    r   r  rA  ro   )r(   rG   r   r}  r   r   rr   r~  )r2   r  rA  r   s       r   test_system_exitz ExceptHookTests.test_system_exit  sm    	)) 	
 $$X. 	&\FLLNKKM	
 	*B/	 	s   (B  B	c                    d fd}	 t        j                  t        d|      5  t               }|j	                          |j                          d d d        | j                  j                  t               | j                  t        j                        d       | j                  j                  j                  j                         | j                  j                         d y # 1 sw Y   xY w# d w xY w)Nc                 
    | y r<   rA   )	hook_argsr   s    r   hookz4ExceptHookTests.test_custom_excepthook.<locals>.hook  s    Dr   r%   rq  )r   	swap_attrr(   ro  r   r   rr   exc_typer  rx   	exc_valueexc_traceback__traceback__r  r   )r2   r  r   r   s      @r   test_custom_excepthookz&ExceptHookTests.test_custom_excepthook  s    		""9lDA &
 T]]J7S0,?T//1M1MNMM$++v. D  Ds#   C8 +C,BC8 ,C51C8 8C<c                    d }d fd}t        j                  t        d|      5  t        j                  t        d|      5  t        j                  d      5 }t               }|j                          |j                          d d d        d d d        d d d        | j                  j                         d       | j                  d       y # 1 sw Y   LxY w# 1 sw Y   PxY w# 1 sw Y   TxY w)Nc                     t        d      )Nthreading_hook failedrr  r   s    r   threading_hookzCExceptHookTests.test_custom_excepthook_fail.<locals>.threading_hook0  s    455r   c                     t        |      y r<   ry   )r  r  r  err_strs      r   sys_hookz=ExceptHookTests.test_custom_excepthook_fail.<locals>.sys_hook5  s    )nGr   r%   rA  z#Exception in threading.excepthook:
r  )
r   r  r(   r   r}  ro  r   r   rr   r~  )r2   r  r  rA  r   r  s        @r   test_custom_excepthook_failz+ExceptHookTests.test_custom_excepthook_fail/  s    	6 	% y,G 	sL(;	$$X.	28"_FLLNKKM	 	 	 	*?	A"9:	 	 	 	 	 	s;   C'C+CCC'CCC$	 C''C0c                 8   d }d } |       }t        j                  t        d|      5   |       }t        j                  t        _         |       }d d d        | j                  |       | j                  |       | j                  |d       y # 1 sw Y   @xY w)Nc                      t        j                  d      5 } t        d      }|j                          |j	                          d d d        | j                         S # 1 sw Y    j                         S xY w)NrA  ry  rE   )r   r}  ro  r   r   r~  )outputr   s     r   
run_threadz<ExceptHookTests.test_original_excepthook.<locals>.run_threadE  s]    ((2 f&,?@ ??$$	 ??$$s   -AA3c                 :    t        dt        j                         y )NzRunning a thread failed)file)rP   r   rA  r   s    r   r  z@ExceptHookTests.test_original_excepthook.<locals>.threading_hookL  s    +#**=r   r%   zRunning a thread failed
)r   r  r(   r)   r%   rr   r   )r2   r  r  default_outputcustom_hook_outputrecovered_outputs         r   test_original_excepthookz(ExceptHookTests.test_original_excepthookD  s    	%	> $y,G 	,!+#,#;#;I )|	,
 	)9:N,>?+-HI	, 	,s   (BB)r>   r?   r@   r\   r  r   r   r  r  r  r  r  __classcell__)rw  s   @r   rt  rt    s<    
8 1 1(0*;*Jr   rt  c                       e Zd Zd Zd Zd Zy)
TimerTestsc                 n    t         j                  |        g | _        t        j                         | _        y r<   )rX   r\   callback_argsr(   r   callback_eventr1   s    r   r\   zTimerTests.setUp\  s'    4 'oo/r   c                    t        j                  d| j                        }|j                          | j                  j                          |j                  j                  d       d|j                  d<   | j                  j                          t        j                  d| j                        }|j                          | j                  j                          | j                  t        | j                        d       | j                  | j                  di fdi fg       |j                          |j                          y )Nr  blahbarfoorm   rA   )r(   Timer_callback_spyr   r  r   r   r   r#  clearrr   r   r  r   )r2   timer1timer2s      r    test_init_immutable_default_argsz+TimerTests.test_init_immutable_default_argsa  s     t'9'9:  "6"$e!!#t'9'9:  "T//0!4++r2hR-ABr   c                     | j                   j                  |d d  |j                         f       | j                  j	                          y r<   )r  r   copyr  r   )r2   r   r#  s      r   r  zTimerTests._callback_spyr  s7    !!47FKKM":;!r   N)r>   r?   r@   r\   r  r  rA   r   r   r  r  Z  s    0
""r   r  c                   0    e Zd Z eej
                        Zy)	LockTestsN)r>   r?   r@   staticmethodr(   r   locktyperA   r   r   r  r  v  s    INN+Hr   r  c                   0    e Zd Z eej
                        Zy)PyRLockTestsN)r>   r?   r@   r  r(   _PyRLockr  rA   r   r   r  r  y  s    I../Hr   r  zRLock not implemented in Cc                   0    e Zd Z eej
                        Zy)CRLockTestsN)r>   r?   r@   r  r(   _CRLockr  rA   r   r   r  r  |  s    I--.Hr   r  c                   0    e Zd Z eej
                        Zy)
EventTestsN)r>   r?   r@   r  r(   r   	eventtyperA   r   r   r  r    s    Y__-Ir   r  c                   6    e Zd Z eej
                        Zd Zy)ConditionAsRLockTestsc                 &    | j                  d       y )Nz,Condition does not expose _recursion_count())r  r1   s    r   test_recursion_countz*ConditionAsRLockTests.test_recursion_count  s    DEr   N)r>   r?   r@   r  r(   r;  r  r  rA   r   r   r  r    s    I//0HFr   r  c                   0    e Zd Z eej
                        Zy)ConditionTestsN)r>   r?   r@   r  r(   r;  condtyperA   r   r   r  r    s    I//0Hr   r  c                   0    e Zd Z eej
                        Zy)SemaphoreTestsN)r>   r?   r@   r  r(   	SemaphoresemtyperA   r   r   r  r    s    9../Gr   r  c                   0    e Zd Z eej
                        Zy)BoundedSemaphoreTestsN)r>   r?   r@   r  r(   r   r  rA   r   r   r  r    s    9556Gr   r  c                   0    e Zd Z eej
                        Zy)BarrierTestsN)r>   r?   r@   r  r(   BarrierbarriertyperA   r   r   r  r    s    y001Kr   r  c                   ,    e Zd Zd Z e       d        Zy)MiscTestCasec                 d    t        |        dh}ddh}t        j                  | t        d||       y )Nr   r>  r=  )r(   r   )extranot_exported)r+   r   check__all__r(   )r2   r  r  s      r   test__all__zMiscTestCase.test__all__  s6    "4('7T9.F#(|	Er   c                    t        j                         5 }d}dd l}|j                  j	                  ||dz         }t        |d      5 }|j                  d       d d d        d}t        dd|d	| d
| d|d|j                  d      d      \  }}}	| j                  ||       | j                  |	d       d d d        y # 1 sw Y   gxY w# 1 sw Y   y xY w)N_thread_faker   z.pyr  zif True:
                    import _thread
                    globals().update(vars(_thread))
                    del _is_main_interpreter
                    s   success!r  zGif True:
                import sys
                sys.path.insert(0, z)
                import z*
                sys.modules['_thread'] = z!
                del sys.modules[z:]

                import threading
                print(rr  z, end='')
                r   )
r   temp_diros.pathpathr   re  rg  r	   rl  rr   )
r2   tempdirmodnamer[  filenameoutfilerH  rM  r  r  s
             r   2test_gh112826_missing__thread__is_main_interpreterz?MiscTestCase.test_gh112826_missing__thread__is_main_interpreter  s   ! 	'W$Gww||GWu_=Hh$    *O*4 6$$+; /y !**1 3!!( , '--g69 :	2 	KAsC S/2S#&1	' 	' 		' 	's$   2CB?AC?C	CCN)r>   r?   r@   r  r   r  rA   r   r   r  r    s    E ' 'r   r  c                   Z    e Zd Zd Zd Zd Zd Zd Zd Zd Z	e
j                  d        Zy	)
InterruptMainTestsc                     d }t        j                   ||      }| j                  t         j                   ||       | j                  t              5  t	        j
                          d d d        y # 1 sw Y   y xY w)Nc                     ddz   y )Nr6   r   rA   )signumr  s     r   handlerzLInterruptMainTests.check_interrupt_main_with_signal_handler.<locals>.handler  s	    aCr   )signalr&   r  rN  r   interrupt_main)r2   r  r  old_handlers       r   (check_interrupt_main_with_signal_handlerz;InterruptMainTests.check_interrupt_main_with_signal_handler  s]    	 mmFG4v{;01 	%""$	% 	% 	%s   A..A7c                 v   t        j                  |      }	 t        j                   |t         j                         t        j                  |       t        j                   |t         j
                         t        j                  |       t        j                   ||       y # t        j                   ||       w xY wr<   )r  	getsignalSIG_IGNr   r  SIG_DFL)r2   r  r  s      r   check_interrupt_main_noerrorz/InterruptMainTests.check_interrupt_main_noerror  sv    ""6*		+MM&&..1""6*MM&&..1""6* MM&'*FMM&'*s   A2B   B8c                     d }t        j                  |      }| j                  t              5  |j	                          |j                          d d d        |j                          y # 1 sw Y   xY w)Nc                  ,    t        j                          y r<   )r   r  rA   r   r   call_interruptzHInterruptMainTests.test_interrupt_main_subthread.<locals>.call_interrupt  s    ""$r   rq   )r(   rG   r  KeyboardInterruptr   r   )r2   r  r   s      r   test_interrupt_main_subthreadz0InterruptMainTests.test_interrupt_main_subthread  sX    	%N301 	GGIFFH	 	
	 	s   !A))A2c                     | j                  t              5  t        j                          d d d        y # 1 sw Y   y xY wr<   )r  r  r   r  r1   s    r   test_interrupt_main_mainthreadz1InterruptMainTests.test_interrupt_main_mainthread  s4     01 	%""$	% 	% 	%s   4=c                     | j                  t        j                         | j                  t        j                         y r<   )r  r  SIGINTSIGTERMr1   s    r   'test_interrupt_main_with_signal_handlerz:InterruptMainTests.test_interrupt_main_with_signal_handler  s&    55fmmD55fnnEr   c                     | j                  t        j                         | j                  t        j                         y r<   )r  r  r   r  r1   s    r   test_interrupt_main_noerrorz.InterruptMainTests.test_interrupt_main_noerror  s&    ))&--8))&..9r   c                     | j                  t        t        j                  d       | j                  t        t        j                  t        j
                         | j                  t        t        j                  d       y )Nr   i@B )r  r  r   r  r  NSIGr1   s    r   "test_interrupt_main_invalid_signalz5InterruptMainTests.test_interrupt_main_invalid_signal  sN    *g&<&<bA*g&<&<fkkJ*g&<&<gFr   c                     dg}dg}dg}d }t        j                  ||||f      }|j                          |d   s	 |d   sd|d<   |j                          | j	                  |d          y )NTFc                 F    d}d| d<   |d   r|r|dz  }ny 	 |d   rd|d<   y )Ni Tr   r6   rA   )r  continterrupted
iterationss       r   workerzAInterruptMainTests.test_can_interrupt_tight_loops.<locals>.worker  s=    $JGAJq'!OJ q' "KNr   r   r   )r(   rG   r   r   r   )r2   r
  r  r  r  r   s         r   test_can_interrupt_tight_loopsz1InterruptMainTests.test_can_interrupt_tight_loops  su    v'g		" F$0LM		!* !*Q	A'r   N)r>   r?   r@   r  r  r  r  r  r  r  r   reap_threadsr  rA   r   r   r  r    sA    %+	%F:G
 ""( #(r   r  c                       e Zd Zd Zd Zd Zy)AtexitTestsc                     t        dd      \  }}}| j                  |       | j                  |j                         d       y )Nr  zif True:
            import threading

            def run_last():
                print('parrot')

            threading._register_atexit(run_last)
        s   parrot)r	   r   rr   r  r	  s       r   test_atexit_outputzAtexitTests.test_atexit_output  s?    ' / C 	i0r   c                 F    t        dd      \  }}}| j                  |       y )Nr  aN  if True:
            import threading
            from unittest.mock import Mock

            mock = Mock()
            threading._register_atexit(mock)
            mock.assert_not_called()
            # force early shutdown to ensure it was called once
            threading._shutdown()
            mock.assert_called_once()
        )r	   r   r	  s       r   test_atexit_called_oncez#AtexitTests.test_atexit_called_once  s)    ' 
/ 
C 	r   c                     t        dd      \  }}}| j                  |       | j                  d|j                                y )Nr  zif True:
            import threading

            def func():
                pass

            def run_last():
                threading._register_atexit(func)

            threading._register_atexit(run_last)
        z2RuntimeError: can't register atexit after shutdown)r	   r   r   rl  r	  s       r   test_atexit_after_shutdownz&AtexitTests.test_atexit_after_shutdown+  sA     ( 
/ 
C 	J

	r   N)r>   r?   r@   r  r  r  rA   r   r   r  r    s    1r   r  __main__)B__doc__test.supportr   r   r   r   r   r   test.support.import_helperr   test.support.script_helperr	   r
   rO   r   r   r(   rR   r   r+  r[  rB  r  r  rh  rY  r   r   r   r   ModuleNotFoundErrorrequires_working_threadingr   r   r#   r+   rt   r-   rG   rC   TestCaserX   rb   r  r  r3  ro  rt  r  r  
RLockTestsr  r!   r  r  r  r  r  r  r  r  r  r  r  r>   re  rA   r   r   <module>r!     sX    > 9 9 4 N  
      	        ) ,  + +4 8 + 	=4f <!! <B%8$$ %HO, HOT J< JZ@/l @/FNl Nb'I$$ '
pJl pJf" "8,
$$ ,0:(( 0 ""d*,HI/*'' / J/.&& .FJ11 F1Z.. 10Z.. 07J<< 72:** 2#'8$$ #'LM(** M(`/(## /d zHMMO AA  Ls   .I II