+
    Dfj!                    *   R t ^ RIHt ^ RIt^ RIt^ RIHtHt ^ RIH	t	H
t
Ht ^ RIHt ^RIHtHtHt ^RIHt ]! R4      t ! R	 R
]4      t ! R R]4      t ! R R4      t ! R R]
],          4      t ! R R4      t ! R R]4      t ! R R]4      tR# )z.
Tests for L{twisted._threads._threadworker}.
)annotationsN)ThreadErrorlocal)CallableGenericTypeVar)SynchronousTestCase)AlreadyQuit
LockWorkerThreadWorker)
SimpleLockTc                      ] tR t^tRtRtR# )FakeQueueEmptyz0
L{FakeQueue}'s C{get} has exhausted the queue.
 N__name__
__module____qualname____firstlineno____doc____static_attributes__r       I/usr/lib/python3/dist-packages/twisted/_threads/test/test_threadworker.pyr   r      s    r   r   c                      ] tR t^tRtRtR# )WouldDeadlockzZ
If this were a real lock, you'd be deadlocked because the lock would be
double-acquired.
r   Nr   r   r   r   r   r      s    r   r   c                  2    ] tR t^#tRtR R ltR R ltRtR# )
FakeThreadz
A fake L{threading.Thread}.

@ivar target: A target function to run.

@ivar started: Has this thread been started?
@type started: L{bool}
c                    V ^8  d   QhRRRR/# )   targetCallable[[], object]returnNoner   )formats   "r   __annotate__FakeThread.__annotate__-   s      3  r   c                     Wn         RV n        R# )z'
Create a L{FakeThread} with a target.
FN)r    started)selfr    s   &&r   __init__FakeThread.__init__-   s     r   c                   V ^8  d   QhRR/# r   r"   r#   r   )r$   s   "r   r%   r&   4   s      t r   c                    RV n         R# )z
Set the "started" flag.
TN)r(   r)   s   &r   startFakeThread.start4   s     r   )r(   r    N)r   r   r   r   r   r*   r0   r   r   r   r   r   r   #   s     r   r   c                  >    ] tR t^;tRtR R ltR R ltR R ltRtR	# )
	FakeQueuez
A fake L{Queue} implementing C{put} and C{get}.

@ivar items: A lit of items placed by C{put} but not yet retrieved by
    C{get}.
@type items: L{list}
c                   V ^8  d   QhRR/# r-   r   )r$   s   "r   r%   FakeQueue.__annotate__D   s     ! !$ !r   c                    . V n         R# )z
Create a L{FakeQueue}.
Nitemsr/   s   &r   r*   FakeQueue.__init__D   s     !
r   c                    V ^8  d   QhRRRR/# )r   itemr   r"   r#   r   )r$   s   "r   r%   r5   J   s          d  r   c                <    V P                   P                  V4       R# )z^
Put an item into the queue for later retrieval by L{FakeQueue.get}.

@param item: any object
N)r8   append)r)   r;   s   &&r   putFakeQueue.putJ   s     	

$r   c                   V ^8  d   QhRR/# )r   r"   r   r   )r$   s   "r   r%   r5   R   s     ! !Q !r   c                p    V P                   '       g   \        4       hV P                   P                  ^ 4      # )z:
Get an item.

@return: an item previously put by C{put}.
)r8   r   popr/   s   &r   getFakeQueue.getR   s)     zzz ""zz~~a  r   r7   N)	r   r   r   r   r   r*   r>   rC   r   r   r   r   r3   r3   ;   s    ! ! !r   r3   c                  >    ] tR t^]tRtR R ltR R ltR R ltRtR	# )
FakeLockz]
A stand-in for L{threading.Lock}.

@ivar acquired: Whether this lock is presently acquired.
c                   V ^8  d   QhRR/# r-   r   )r$   s   "r   r%   FakeLock.__annotate__d   s      $ r   c                    RV n         R# )z)
Create a lock in the un-acquired state.
FNacquiredr/   s   &r   r*   FakeLock.__init__d   s     r   c                   V ^8  d   QhRR/# )r   r"   boolr   )r$   s   "r   r%   rH   j   s       r   c                L    V P                   '       d   \        4       hRV n         R# )zH
Acquire the lock.  Raise an exception if the lock is already acquired.
T)rK   r   r/   s   &r   acquireFakeLock.acquirej   s     ===/!r   c                   V ^8  d   QhRR/# r-   r   )r$   s   "r   r%   rH   s   s       r   c                L    V P                   '       g   \        4       hRV n         R# )zN
Release the lock.  Raise an exception if the lock is not presently
acquired.
FN)rK   r   r/   s   &r   releaseFakeLock.releases   s    
 }}}-r   rJ   N)	r   r   r   r   r   r*   rP   rT   r   r   r   r   rF   rF   ]   s     r   rF   c                  >    ] tR t^}tRtR R ltR R ltR R ltRtR	# )
ThreadWorkerTestsz
Tests for L{ThreadWorker}.
c                   V ^8  d   QhRR/# r-   r   )r$   s   "r   r%   ThreadWorkerTests.__annotate__   s     = =t =r   c                Z   a  . S n         R V 3R llp\        V\        4       4      S n        R# )z$
Create a worker with fake threads.
c                    V ^8  d   QhRRRR/# )r   r    r!   r"   r   r   )r$   s   "r   r%   -ThreadWorkerTests.setUp.<locals>.__annotate__   s     	 	 4 	 	r   c                v   < \        V R 7      pVP                  4        SP                  P                  V4       V# ))r    )r   r0   fakeThreadsr=   )r    	newThreadr)   s   & r   startThread,ThreadWorkerTests.setUp.<locals>.startThread   s1    "&1IOO##I.r   N)r^   r   r3   worker)r)   r`   s   f r   setUpThreadWorkerTests.setUp   s)     .0	 	 #;	<r   c                   V ^8  d   QhRR/# r-   r   )r$   s   "r   r%   rY      s     % %$ %r   c                  a V P                  \        V P                  4      ^4       V P                  V P                  ^ ,          P                  R4       RoR V3R llpV P                  P                  V4       V P                  SR4       V P                  \        V P                  ^ ,          P                  4       V P                  SR4       R# )z
L{ThreadWorker} calls its C{createThread} callable to create a thread,
its C{createQueue} callable to create a queue, and then the thread's
target pulls work from that queue.
TFc                   V ^8  d   QhRR/# r-   r   )r$   s   "r   r%   HThreadWorkerTests.test_startsThreadAndPerformsWork.<locals>.__annotate__   s     	 	d 	r   c                    < R o R# TNr   )dones   r   doIt@ThreadWorkerTests.test_startsThreadAndPerformsWork.<locals>.doIt   s    Dr   N)	assertEquallenr^   r(   rb   doassertRaisesr   r    )r)   rl   rk   s   & @r    test_startsThreadAndPerformsWork2ThreadWorkerTests.test_startsThreadAndPerformsWork   s     	T--.2))!,44d;	 	 	tu%.$*:*:1*=*D*DEt$r   c                   V ^8  d   QhRR/# r-   r   )r$   s   "r   r%   rY      s     = =d =r   c                    V P                   P                  4        V P                  \        V P                   P                  4       V P                  \        V P                   P                  \
        4       R# )zr
L{ThreadWorker.quit} causes future calls to L{ThreadWorker.do} and
L{ThreadWorker.quit} to raise L{AlreadyQuit}.
N)rb   quitrq   r	   rp   listr/   s   &r   test_quitPreventsFutureCalls.ThreadWorkerTests.test_quitPreventsFutureCalls   sH    
 	+t{{'7'78+t{{~~t<r   )r^   rb   N)	r   r   r   r   r   rc   rr   rx   r   r   r   r   rW   rW   }   s    =%(= =r   rW   c                  n    ] tR t^tRtR R ltR R ltR R ltR R	 ltR
 R lt	R R lt
R R ltRtR# )LockWorkerTestsz
Tests for L{LockWorker}.
c                   V ^8  d   QhRR/# r-   r   )r$   s   "r   r%   LockWorkerTests.__annotate__   s     7 74 7r   c                z    \        4       pVP                  4        V P                  \        VP                  4       R# )zM
The L{FakeLock} test fixture will alert us if there's a potential
deadlock.
N)rF   rP   rq   r   )r)   locks   & r   test_fakeDeadlock!LockWorkerTests.test_fakeDeadlock   s(    
 z-6r   c                   V ^8  d   QhRR/# r-   r   )r$   s   "r   r%   r}      s     
5 
5 
5r   c                    \        4       pV P                  \        VP                  4       VP	                  4        VP                  4       pV P                  RV4       V P                  \        VP                  4       R# )zS
The L{FakeLock} test fixture will alert us if there's a potential
double-release.
N)rF   rq   r   rT   rP   assertIs)r)   r   noResults   &  r   test_fakeDoubleRelease&LockWorkerTests.test_fakeDoubleRelease   sU    
 z+t||4<<>dH%+t||4r   c                   V ^8  d   QhRR/# r-   r   )r$   s   "r   r%   r}      s     / /D /r   c                  aaa \        4       p\        4       o\        SV4      pRoRoR VVV3R llpVP                  V4       V P	                  SR4       V P	                  SR4       V P	                  SP
                  R4       R# )zX
L{LockWorker.do} immediately performs the work it's given, while the
lock is acquired.
Fc                   V ^8  d   QhRR/# r-   r   )r$   s   "r   r%   HLockWorkerTests.test_doExecutesImmediatelyWithLock.<locals>.__annotate__   s     	% 	%d 	%r   c                 $   < R oSP                   o R# rj   rJ   )rK   rk   r   s   r   work@LockWorkerTests.test_doExecutesImmediatelyWithLock.<locals>.work   s    D}}Hr   TN)r   rF   r
   rp   rn   rK   )r)   storagerb   r   rK   rk   r   s   &   @@@r   "test_doExecutesImmediatelyWithLock2LockWorkerTests.test_doExecutesImmediatelyWithLock   st    
 'zD'*	% 	%
 			$t$4(.r   c                   V ^8  d   QhRR/# r-   r   )r$   s   "r   r%   r}      s     1 1$ 1r   c                   aaaaaa \        4       o\        S\        4       4      o. o. o^ oR VVVVVV3R lloSP                  S4       V P	                  S^^.4       V P	                  SRR.4       R# )zi
If L{LockWorker.do} is called recursively, it postpones the inner call
until the outer one is complete.
c                   V ^8  d   QhRR/# r-   r   )r$   s   "r   r%   >LockWorkerTests.test_doUnwindsReentrancy.<locals>.__annotate__   s     	 	d 	r   c                    < S^,          oSP                  S4       S P                  SP                  4       \        S4      ^8  d   SP                  S4       S^,          oR# )   N)r=   rK   ro   rp   )rK   levellevelsr   r   rb   s   r   r   6LockWorkerTests.test_doUnwindsReentrancy.<locals>.work   sG    QJEMM% OODMM*6{Q		$QJEr   TN)rF   r
   r   rp   rn   )r)   rK   r   r   r   r   rb   s   &@@@@@@r   test_doUnwindsReentrancy(LockWorkerTests.test_doUnwindsReentrancy   sh    
 zD%'*	 	 			$!Q(D$<0r   c                   V ^8  d   QhRR/# r-   r   )r$   s   "r   r%   r}      s     8 84 8r   c                   \        4       p\        P                  ! V4      p\        V\	        4       4      p?V P                  V! 4       R4       VP                  4        \        P                  ! 4        V P                  V! 4       R4       V P                  \        VP                  4       V P                  \        VP                  \        4       R# )zx
L{LockWorker.quit} frees the resources associated with its lock and
causes further calls to C{do} and C{quit} to fail.
N)rF   weakrefrefr
   r   assertIsNotrv   gccollectr   rq   r	   rp   rw   )r)   r   r   rb   s   &   r   	test_quitLockWorkerTests.test_quit   s    
 zkk$D%'*%


ceT"+v{{3+vyy$7r   c                   V ^8  d   QhRR/# r-   r   )r$   s   "r   r%   r}     s      #  #t  #r   c                  a aaaaaa \        4       o\        P                  ! S4      p\        S\	        4       4      oRoRoRoR VVV V3R llpR VVV3R lloSP                  V4       S P                  SR4       S P                  SR4       S P                  SP                  R4       >\        P                  ! 4        S P                  V! 4       R4       R# )z
If L{LockWorker.quit} is invoked during a call to L{LockWorker.do}, all
recursive work scheduled with L{LockWorker.do} will be completed and
the lock will be released.
FNc                   V ^8  d   QhRR/# r-   r   )r$   s   "r   r%   ;LockWorkerTests.test_quitWhileWorking.<locals>.__annotate__  s     	" 	" 	"r   c                    < SP                  S4       SP                  4        SP                  \        SP                   \        4       R o R# rj   )rp   rv   rq   r	   rw   )phase1completephase2r)   rb   s   r   phase15LockWorkerTests.test_quitWhileWorking.<locals>.phase1  s3    IIfKKMk699d;!Nr   c                   V ^8  d   QhRR/# r-   r   )r$   s   "r   r%   r     s     	+ 	+ 	+r   c                 $   < R oS P                   oR# rj   rJ   )r   phase2acquiredphase2completes   r   r   5LockWorkerTests.test_quitWhileWorking.<locals>.phase2  s    !N!]]Nr   T)rF   r   r   r
   r   rp   rn   rK   r   r   r   )	r)   r   r   r   r   r   r   r   rb   s	   f  @@@@@@r   test_quitWhileWorking%LockWorkerTests.test_quitWhileWorking  s     zkk$D%'*	" 	"	+ 	+
 			&...


ceT"r   c                   V ^8  d   QhRR/# r-   r   )r$   s   "r   r%   r}   '  s     8 84 8r   c                     ! R R\         4      pV! \        4       \        4       4      pV P                  \        VP
                  \        4       R# )z
If L{LockWorker.do} is called concurrently with L{LockWorker.quit}, and
C{quit} wins the race before C{do} gets the lock attribute, then
L{AlreadyQuit} will be raised.
c                  V    ] tR tRt]R R l4       t]P                  R R l4       tRtR# )ALockWorkerTests.test_quitWhileGettingLock.<locals>.RacyLockWorkeri.  c                   V ^8  d   QhRR/# )r   r"   SimpleLock | Noner   )r$   s   "r   r%   NLockWorkerTests.test_quitWhileGettingLock.<locals>.RacyLockWorker.__annotate__0  s      0 r   c                	L    V P                  4        V P                  R ,          pV# )_lock)rv   __dict__)r)   its   & r   r   GLockWorkerTests.test_quitWhileGettingLock.<locals>.RacyLockWorker._lock/  s    		!%w!7	r   c                    V ^8  d   QhRRRR/# )r   valuer   r"   r#   r   )r$   s   "r   r%   r   6  s     / /#4 / /r   c                	"    WP                   R &   R# )r   N)r   )r)   r   s   &&r   r   r   5  s    ).g&r   r   N)r   r   r   r   propertyr   setterr   r   r   r   RacyLockWorkerr   .  s,     
 \\/ /r   r   N)r
   rF   r   rq   r	   rp   rw   )r)   r   rb   s   &  r   test_quitWhileGettingLock)LockWorkerTests.test_quitWhileGettingLock'  s6    		/Z 		/  
EG4+vyy$7r   r   N)r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r{   r{      s0    7
5/*108  #D8 8r   r{   )r   
__future__r   r   r   	threadingr   r   typingr   r   r   twisted.trial.unittestr    r	   r
   r   _threadworkerr   r   	Exceptionr   r   r   r3   rF   rW   r{   r   r   r   <module>r      s    # 	  ( - - 6 4 4 &CLY I  0!
 !D @.=+ .=bL8) L8r   