o
    US`cZb                     @   s  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
mZ ddlmZ ddlmZmZmZ ddlmZ ddlmZ dd	lmZmZmZmZ dd
lmZ dd Zdd Zdd Zdd Zdd Z dd Z!dd Z"ej#$dg dej#$dddgej#$dddgdd  Z%d!d" Z&d#d$ Z'd%d& Z(d'd( Z)d)d* Z*e +d+Z,d,d- Z-d.d/ Z.d0d1 Z/d2d3 Z0d4d5 Z1d6d7 Z2d8d9 Z3d:d; Z4d<d= Z5d>d? Z6ej#j7ed@dAdBdC Z8dDdE Z9dFdG Z:dS )H    N)current_async_library_cvar)	TrioTokencurrent_trio_token   )_core)EventCapacityLimitersleep)wait_all_tasks_blocked)buggy_pypy_asyncgens)to_thread_run_synccurrent_default_thread_limiterfrom_thread_runfrom_thread_run_sync)ki_selfc                     s   t   d fdd	} t }dd }| t|d|dI d H  dd }| t|dtf|dI d H  d	d }| t|d
|dI d H  dd }| t|dtf|dI d H  d S )Nc                    sr   g  fdd}t j|dd}|  | r*td tdI d H  | sd|fdf|gks7J d S )	Nc               
      sv   z dt f  d}  d| f W d S  ty: } zt|  dt|f W Y d }~d S d }~ww )Nstart
trio_tokengoterror)append	threadingcurrent_threadBaseExceptionprinttype)xexcdo_in_trio_threadfnrecordr    B/usr/local/lib/python3.10/dist-packages/trio/tests/test_threads.pythreadfn   s    z<test_do_in_trio_thread.<locals>.check_case.<locals>.threadfnT)targetdaemonZyawn{Gz?r   f)r   Threadr   is_aliver   r	   )r   r    expectedr   r$   child_threadtrio_threadr   r#   
check_case   s   	z*test_do_in_trio_thread.<locals>.check_casec                 S   s"   t  rJ | dt f dS )Nr(   r   )r   currently_ki_protectedr   r   r   r!   r"   r"   r#   r(   1      z!test_do_in_trio_thread.<locals>.f)r   r   r   c                 S   s"   t  rJ | dt f tNr(   )r   r0   r   r   r   
ValueErrorr1   r"   r"   r#   r(   8   r2   r   c                    s2   t  rJ t  I d H  | dt f dS )Nr(      )r   r0   
checkpointr   r   r   r1   r"   r"   r#   r(   ?   
   )r   r5   c                    s2   t  rJ t  I d H  | dt f tr3   )r   r0   r6   r   r   r   KeyErrorr1   r"   r"   r#   r(   G   r7   N)r   r   r   r   r   r4   r   r8   )r/   tokenr(   r"   r-   r#   test_do_in_trio_thread   s   r;   c                     sx   t t tdd  W d    n1 sw   Y  dd } t t t|  W d    d S 1 s5w   Y  d S )Nc                   S      d S r9   r"   r"   r"   r"   r#   <lambda>R       z9test_do_in_trio_thread_from_trio_thread.<locals>.<lambda>c                         d S r9   r"   r"   r"   r"   r#   fooT      z4test_do_in_trio_thread_from_trio_thread.<locals>.foo)pytestraisesRuntimeErrorr   r   )r@   r"   r"   r#   'test_do_in_trio_thread_from_trio_threadP   s   
"rE   c                     s0   t    fdd} t|   ddhksJ d S )Nc                     s   t   dd fdd fdd} tj| d}|  td | r5td	I d H  | s*td
 |  td d S )Nc               
   S   sX   t d t r
J t d zt  W dd l} t d|   d S dd l} t d|   w )Nzin Trio threadr   r   finally)r   r   r0   r   sysexc_info)rG   r"   r"   r#   trio_thread_fnc   s   zTtest_run_in_trio_thread_ki.<locals>.check_run_in_trio_thread.<locals>.trio_thread_fnc                      s      d S r9   r"   r"   )rI   r"   r#   trio_thread_afnn   s   
zUtest_run_in_trio_thread_ki.<locals>.check_run_in_trio_thread.<locals>.trio_thread_afnc                      sx   zt d td W n ty   t d  d Y nw z	td W d S  ty;   t d  d Y d S w )Nrunningr   ok1ok2)r   r   KeyboardInterruptaddr   r"   )r!   r:   rJ   rI   r"   r#   external_thread_fnq   s   zXtest_run_in_trio_thread_ki.<locals>.check_run_in_trio_thread.<locals>.external_thread_fn)r%   Zwaitingr'   zwaited, joiningdone)	r   r   r   r)   r   r   r*   r	   join)rP   threadr1   )r:   rJ   rI   r#   check_run_in_trio_thread`   s   z<test_run_in_trio_thread_ki.<locals>.check_run_in_trio_threadrL   rM   )setr   run)rT   r"   r1   r#   test_run_in_trio_thread_ki[   s   
'rW   c                     s\   g t    fddfdd fdd} t| }|  ddgks,J d S )	Nc                      s,    d    tdd I d H  d S )Nsleepingc                 S   s   t jjS r9   )r   ZAbortZ	SUCCEEDED)_r"   r"   r#   r=          zMtest_await_in_trio_thread_while_main_exits.<locals>.trio_fn.<locals>.<lambda>)r   rU   r   Zwait_task_rescheduledr"   )evr!   r"   r#   trio_fn   s   
z;test_await_in_trio_thread_while_main_exits.<locals>.trio_fnc                    s4   z	t | d W d S  tjy    d Y d S w )Nr   	cancelled)r   r   Z	Cancelledr   )r:   )r!   r\   r"   r#   	thread_fn   s
   z=test_await_in_trio_thread_while_main_exits.<locals>.thread_fnc                     sB   t  } tj| fd}|    I d H  dgksJ |S )N)r%   argsrX   )r   r   r   r)   r   wait)r:   rS   )r[   r!   r^   r"   r#   main   s   z8test_await_in_trio_thread_while_main_exits.<locals>.mainrX   r]   )r   r   rV   rR   )ra   rS   r"   )r[   r!   r^   r\   r#   *test_await_in_trio_thread_while_main_exits   s   
rb   c                     s   t  } dd }t|dI d H \}}|dksJ || ksJ dd }tt}t|I d H  W d    n1 s:w   Y  t|jj |jjd | ksOJ d S )Nc                 S   s   | t  fS r9   )r   r   )r   r"   r"   r#   r(         z$test_run_in_worker_thread.<locals>.f   c                   S   s   t t r9   )r4   r   r   r"   r"   r"   r#   g   rc   z$test_run_in_worker_thread.<locals>.gr   )	r   r   r   rB   rC   r4   r   valuer_   )r.   r(   r   r,   re   excinfor"   r"   r#   test_run_in_worker_thread   s   rh   c               	      s  d gfdd  fdd} g t  }t 4 I d H $}|| |d t I d H  dgks4J |j  W d   I d H  n1 I d H sIw   Y  d dksVJ |d  d dkrlt	
d	 d dksag d d< t 4 I d H M}|| |d
 t I d H  |j  tjdd tdD ]	}t I d H  qW d    n1 sw   Y  dgksJ |d  W d   I d H  n1 I d H sw   Y  t }|  | |d
I d H  W d    n1 sw   Y  |jsJ d S )Nc                    s   d d< |    d d< d S )Nblockingr   finished)get)q)registerr"   r#   r(      s   z1test_run_in_worker_thread_cancellation.<locals>.fc              	      s:    d zt | |dI d H W  d S  d w )Nr   cancellableexit)r   r   )rl   ro   )r(   r!   r"   r#   child   s
   
z5test_run_in_worker_thread_cancellation.<locals>.childTr   r   rj   r'   Fshield
   )stdlib_queueQueuer   open_nursery
start_soonr
   cancel_scopecancelputtimer	   CancelScoperanger6   cancelled_caught)rq   rl   nurseryrY   scoper"   )r(   r!   rm   r#   &test_run_in_worker_thread_cancellation   sH   (



(
r   c                    s   | tjdd t  t  fddfdd}t|  d   }| r8t	
d | s/|  \}}d|vsDJ d|vsJJ d S )NZIDLE_TIMEOUTr'   c                      s       t  d S r9   )rk   r{   r   r   r"   )q1q2r"   r#   r^      s   z6test_run_in_worker_thread_abandoned.<locals>.thread_fnc               	      sp    fdd} t  4 I d H }||  t I d H  |j  W d   I d H  d S 1 I d H s1w   Y  d S )Nc                      s   t  ddI d H  d S )NTrn   r   r"   r^   r"   r#   rq     s   z@test_run_in_worker_thread_abandoned.<locals>.main.<locals>.child)r   rw   rx   r
   ry   rz   )rq   r   r   r"   r#   ra      s   
.z1test_run_in_worker_thread_abandoned.<locals>.mainzException in thread)setattrr   _thread_cacheru   rv   rV   r{   rk   r*   r|   r	   Z
readouterr)Zcapfdmonkeypatchra   rS   outerrr"   )r   r   r^   r#   #test_run_in_worker_thread_abandoned   s   
	

r   MAX)r5      rt   rz   FTuse_default_limiterc           
   	      s  d|  }t  t  |rt }|j}| |_d nt| }| }|zG dd dd_d_d_d_	t
 fdd fdd}t
 4 I d H d}td	 g }t|D ]}	|t  |||d
  t I d H  q_ rtd |d  I d H  t I d H  j	| ks| j| krtdI d H  j	| ks| j| ks  W d   I d H  n1 I d H sw   Y  j| ksJ  r|jdkrtdI d H  |jdksшj|ksJ jdksJ W ||_d S ||_w )Nr   c                   @   s   e Zd ZdS )z0test_run_in_worker_thread_limiter.<locals>.stateN)__name__
__module____qualname__r"   r"   r"   r#   state9  s    r   r   c                    s   t d t| jd %  jd7  _ jd7  _tjj_ jd7  _W d    n1 s5w   Y       jd8  _ jd8  _W d    n1 sYw   Y  t d d S )Nzthread_fn startr   rd   zthread_fn exiting)	r   r   rz   ranrK   max
high_waterparkedr`   )ry   )gatelockr   r:   r"   r#   r^   C  s   z4test_run_in_worker_thread_limiter.<locals>.thread_fnc                    sX   t  }t| dI d H  W d    n1 sw   Y  td|j |   d S )N)limiterro   zrun_thread finished, cancelled:)r   r}   r   r   r   rU   )eventry   )rz   limiter_argr^   r"   r#   
run_threadS  s   
z5test_run_in_worker_thread_limiter.<locals>.run_threadZspawningz'waiting for first cancellation to clearr'   )r   r   Lockr   Ztotal_tokensr   r   r   rK   r   r   r   rw   r   r~   r   rx   r
   r`   
statisticsZtasks_waitingr	   rU   borrowed_tokens)
r   rz   r   ZCOUNTcZorig_total_tokensr   r   eventsir"   )rz   r   r   r   r   r^   r:   r#   !test_run_in_worker_thread_limiter  sZ   	
(

r   c                     sD   g  G  fddd} t dd |  dI d H   ddgks J d S )Nc                       $   e Zd Z fddZ fddZdS )z?test_run_in_worker_thread_custom_limiter.<locals>.CustomLimiterc                    s     d || _d S Nacquirer   Z	_borrowerselfZborrowerr1   r"   r#   acquire_on_behalf_of  s   

zTtest_run_in_worker_thread_custom_limiter.<locals>.CustomLimiter.acquire_on_behalf_ofc                    s     d || jksJ d S Nreleaser   r   r1   r"   r#   release_on_behalf_of  s   
zTtest_run_in_worker_thread_custom_limiter.<locals>.CustomLimiter.release_on_behalf_ofNr   r   r   r   r   r"   r1   r"   r#   CustomLimiter  s    r   c                   S   r<   r9   r"   r"   r"   r"   r#   r=     r>   z:test_run_in_worker_thread_custom_limiter.<locals>.<lambda>r   r   r   r   )r   r"   r1   r#   (test_run_in_worker_thread_custom_limiter  s
   	r   c                     s   g G fddd} |  }t t}tdd |dI d H  W d    n1 s*w   Y  |jjd u s7J ddgks?J g i  t t}t fdd|dI d H  W d    n1 s`w   Y  t|jjtsnJ ddgksvJ d S )	Nc                       r   )zCtest_run_in_worker_thread_limiter_error.<locals>.BadCapacityLimiterc                    s     d d S r   )r   r   r1   r"   r#   r     s   zXtest_run_in_worker_thread_limiter_error.<locals>.BadCapacityLimiter.acquire_on_behalf_ofc                    s     d tr   )r   r4   r   r1   r"   r#   r        
zXtest_run_in_worker_thread_limiter_error.<locals>.BadCapacityLimiter.release_on_behalf_ofNr   r"   r1   r"   r#   BadCapacityLimiter  s    r   c                   S   r<   r9   r"   r"   r"   r"   r#   r=     r>   z9test_run_in_worker_thread_limiter_error.<locals>.<lambda>r   r   r   c                      s    d S )Nr   r"   r"   )dr"   r#   r=     rZ   )rB   rC   r4   r   rf   __context__
isinstancer8   )r   bsrg   r"   )r   r!   r#   'test_run_in_worker_thread_limiter_error  s    r   c                    s   dd }|  tjjd| t }|jdksJ tt}t	dd I d H  W d    n1 s1w   Y  dt
|jv s?J |jdksFJ d S )Nc                 W   s   t d)Nz!the engines canna take it captain)rD   )r   r_   r"   r"   r#   	bad_start  s   z:test_run_in_worker_thread_fail_to_spawn.<locals>.bad_startZstart_thread_soonr   c                   S   r<   r9   r"   r"   r"   r"   r#   r=     r>   z9test_run_in_worker_thread_fail_to_spawn.<locals>.<lambda>Zengines)r   r   r   ZThreadCacher   r   rB   rC   rD   r   strrf   )r   r   r   rg   r"   r"   r#   'test_run_in_worker_thread_fail_to_spawn  s   r   c                     0   dd } t  }t| I d H }||ksJ d S )Nc                  S      t tj} | S r9   r   r   r   callee_tokenr"   r"   r#   r^     r   z5test_trio_to_thread_run_sync_token.<locals>.thread_fnr   r   r   r^   Zcaller_tokenr   r"   r"   r#   "test_trio_to_thread_run_sync_token  
   r   c                     sL   dd } t jtdd t| I d H  W d    d S 1 sw   Y  d S )Nc                      r?   r9   r"   r"   r"   r"   r#   async_fn  rA   z=test_trio_to_thread_run_sync_expected_error.<locals>.async_fnexpected a sync functionmatch)rB   rC   	TypeErrorr   r   r"   r"   r#   +test_trio_to_thread_run_sync_expected_error  s
   "r   trio_test_contextvarc            
         s   t  } td dd }t|I d H \}}}|dksJ |d ks$J || ks*J dd }t|I d H \}}}}t }t }	|dksGJ |dksMJ |dksUJ d|d u s[J |	dksaJ d S )	Nra   c                  S   s   t  } t }| |t fS r9   )r   rk   r   r   r   )rf   sniffio_cvar_valuer"   r"   r#   r(     s   z3test_trio_to_thread_run_sync_contextvars.<locals>.fc                  S   s2   t  } t d t  }t }| ||t fS )Nworker)r   rk   rU   r   r   r   )parent_valueinner_valuer   r"   r"   r#   re     s   
z3test_trio_to_thread_run_sync_contextvars.<locals>.gr   zRThe contextvar value set on the worker would not propagate back to the main threadtrio)r   r   r   rU   r   rk   r   )
r.   r(   rf   r   r,   re   r   r   current_valueZsniffio_outer_valuer"   r"   r#   (test_trio_to_thread_run_sync_contextvars  s2   
r   c                     s|   dd } t | I d H }t|tsJ dd   fdd} tjtdd t | I d H  W d    d S 1 s7w   Y  d S )Nc                  S   r   r9   )r   r   current_time)	trio_timer"   r"   r#   r^   
  r   z1test_trio_from_thread_run_sync.<locals>.thread_fnc                      r?   r9   r"   r"   r"   r"   r#   r     rA   z0test_trio_from_thread_run_sync.<locals>.async_fnc                      s   t   d S r9   )r   r"   r   r"   r#   r^     rc   r   r   )r   r   floatrB   rC   r   )r^   r   r"   r   r#   test_trio_from_thread_run_sync  s   "r   c                     s   g fdd  fdd} t | I d H  ddgksJ dd }tjtd	d
 t t|I d H  W d    d S 1 s>w   Y  d S )Nc                      s   t    d d S )Nback in trio)r   r   r   r"   r1   r"   r#   back_in_trio_fn!  s   z2test_trio_from_thread_run.<locals>.back_in_trio_fnc                      s    d t  d S )N	in thread)r   r   r"   r   r!   r"   r#   r^   %  s   
z,test_trio_from_thread_run.<locals>.thread_fnr   r   c                   S   r<   r9   r"   r"   r"   r"   r#   sync_fn-     z*test_trio_from_thread_run.<locals>.sync_fnzappears to be synchronousr   )r   rB   rC   r   r   )r^   r   r"   r   r#   test_trio_from_thread_run  s   "r   c                     r   )Nc                  S   r   r9   r   r   r"   r"   r#   r^   7  r   z.test_trio_from_thread_token.<locals>.thread_fnr   r   r"   r"   r#   test_trio_from_thread_token4  r   r   c                     s2   dd } t  }t| |I d H }||ksJ d S )Nc                 S   s   t tj| d}|S )Nr   r   )r:   r   r"   r"   r#   r^   C  s   z4test_trio_from_thread_token_kwarg.<locals>.thread_fnr   r   r"   r"   r#   !test_trio_from_thread_token_kwarg@  s
   r   c                      s<   t t ttj W d    d S 1 sw   Y  d S r9   rB   rC   rD   r   r   r   r"   r"   r"   r#   test_from_thread_no_tokenL  s   "r   c                     s   t d dd } t| I d H \}}}}}}}}t  }	t }
|	|  kr,dks/J  J ||  kr?|  kr?dksBJ  J |dksHJ |
|  krSdksVJ  J ||  krad ksdJ  J d S )Nra   c            	      S   \   t  } t d t  }t }dd }t|\}}}t  }t }| |||||||fS )Nr   c                  S   s,   t  } t d t  }t }| ||fS Nback_in_mainr   rk   rU   r   back_parent_valueback_current_valuesniffio_cvar_back_valuer"   r"   r#   r   ]  s
   

zStest_trio_from_thread_run_sync_contextvars.<locals>.thread_fn.<locals>.back_in_main)r   rk   rU   r   r   )	thread_parent_valuethread_current_valuesniffio_cvar_thread_pre_valuer   r   r   r   thread_after_valuesniffio_cvar_thread_after_valuer"   r"   r#   r^   W  *   
z=test_trio_from_thread_run_sync_contextvars.<locals>.thread_fnr   r   r   )r   rU   r   rk   r   )r^   r   r   r   r   r   r   r   r   r   Zsniffio_cvar_out_valuer"   r"   r#   *test_trio_from_thread_run_sync_contextvarsT  s(   
(& r   c            
         s   t d dd } t| I d H \}}}}}}}}t  }	|	|  kr(dks+J  J ||  kr;|  kr;dks>J  J |dksDJ ||  krOd ksRJ  J |dksXJ d S )Nra   c            	      S   r   )Nr   c                     s.   t  } t d t  }t }| ||fS r   r   r   r"   r"   r#   async_back_in_main  s   

zTtest_trio_from_thread_run_contextvars.<locals>.thread_fn.<locals>.async_back_in_main)r   rk   rU   r   r   )	r   r   r   r   r   r   r   r   r   r"   r"   r#   r^     r   z8test_trio_from_thread_run_contextvars.<locals>.thread_fnr   r   r   )r   rU   r   rk   )
r^   r   r   r   r   r   r   r   r   r   r"   r"   r#   %test_trio_from_thread_run_contextvars  s&   
(&r   c                   C   s>   t t ttjdd W d    d S 1 sw   Y  d S )NzNot TrioTokentyper   r   r"   r"   r"   r#   4test_run_fn_as_system_task_catched_badly_typed_token  s   "r   c                     sN   dd } t  }tt t| |d W d    d S 1 s w   Y  d S )Nc                   S   s   J r9   r"   r"   r"   r"   r#   
not_called  r   z7test_from_thread_inside_trio_thread.<locals>.not_calledr   )r   r   rB   rC   rD   r   )r   r   r"   r"   r#   #test_from_thread_inside_trio_thread  s   "r   zpypy 7.2.0 is buggy)reasonc                     s>   g g fdd  fdd} t |  dgksJ d S )Nc                     s   z@d V  W t tj' tjdd tttdI d H  W d    n1 s'w   Y  W d    n1 s6w   Y   d d S t tj' tjdd tttdI d H  W d    n1 scw   Y  W d    n1 srw   Y   d w )NTrr   r   ok)	rB   rC   r   ZRunFinishedErrorr}   r   r   r	   r   r"   r1   r"   r#   agen  s     z2test_from_thread_run_during_shutdown.<locals>.agenc                      s&       d d I d H  d S )Nr   )r   asendr"   )r   saver"   r#   ra     s   z2test_from_thread_run_during_shutdown.<locals>.mainr   )r   rV   )ra   r"   )r   r!   r   r#   $test_from_thread_run_during_shutdown  s   
r   c                     s2   t  } t| tsJ t| }| | u sJ d S r9   )r   r   r   weakrefref)r:   Zweak_referencer"   r"   r#   "test_trio_token_weak_referenceable  s
   
r  c                     sT   G dd d} t t tt|  dI d H  W d    d S 1 s#w   Y  d S )Nc                   @   s   e Zd Zdd ZdS )z.test_unsafe_cancellable_kwarg.<locals>.BadBoolc                 S   s   t r9   )NotImplementedError)r   r"   r"   r#   __bool__  r   z7test_unsafe_cancellable_kwarg.<locals>.BadBool.__bool__N)r   r   r   r  r"   r"   r"   r#   BadBool  s    r  rn   )rB   rC   r  r   int)r  r"   r"   r#   test_unsafe_cancellable_kwarg  s
   "r  );contextvarsr   queueru   r|   r   rB   Zsniffior   Z
trio._corer   r    r   r   r   r	   testingr
   Z_core.tests.tutilr   _threadsr   r   r   r   Z_core.tests.test_kir   r;   rE   rW   rb   rh   r   r   markZparametrizer   r   r   r   r   r   
ContextVarr   r   r   r   r   r   r   r   r   r   r   Zskipifr   r  r  r"   r"   r"   r#   <module>   sZ    70<#h
	+54	
