o
    br                     @   sp   d Z ddlZddlmZmZmZmZmZ ddlm	Z	 ddl
mZ ddlmZ G dd deZG d	d
 d
eZdS )z*
Tests for C{await} support in Deferreds.
    N)DeferredensureDeferredfailmaybeDeferredsucceed)Clock)Failure)TestCasec                   @   s   e Zd ZdZdS )SampleExceptionz2
    A specific sample exception for testing.
    N)__name__
__module____qualname____doc__ r   r   H/usr/lib/python3/dist-packages/twisted/internet/test/test_defer_await.pyr
      s    r
   c                   @   s`   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd Zdd Zdd ZdS )
AwaitTestsz@
    Tests for using Deferreds in conjunction with PEP-492.
    c                 C   s"   t  }| }| |t| dS )z<
        C{Deferred.__await__} returns an iterable.
        N)r   	__await__assertEqualiter)selfdawaitedDeferredr   r   r   test_awaitReturnsIterable"   s   z$AwaitTests.test_awaitReturnsIterablec                    sX    fdd}dd  | }|  |tj t|}|  |t | |}| |d dS )zU
        L{Deferred.fromCoroutine} will turn a coroutine into a L{Deferred}.
        c                     s$   t d} | I d H    I d H }|S )Nbarr   r   resrun2r   r   run/   s
   
z2AwaitTests.test_deferredFromCoroutine.<locals>.runc                        t d} | I d H }|S Nfoor   r   r   r   r   r   5      
z3AwaitTests.test_deferredFromCoroutine.<locals>.run2r"   N)assertIsInstancetypesCoroutineTyper   fromCoroutinesuccessResultOfr   )r   r   rr   r   r   r   r   test_deferredFromCoroutine*   s   

z%AwaitTests.test_deferredFromCoroutinec                 C   s.   dd }t | }| |}| |d dS )zc
        L{Deferred.fromCoroutine} allows a function to C{await} on a
        L{Deferred}.
        c                     r    r!   r   r   r   r   r   r   L   r#   z"AwaitTests.test_basic.<locals>.runr"   N)r   r'   r(   r   r   r   r   r   r   r   r   
test_basicF   s   
zAwaitTests.test_basicc                 C   s,   dd }t | }| |}| |d dS )zS
        L{ensureDeferred} allows a function to C{await} on a L{Deferred}.
        c                     r    r!   r   r   r   r   r   r   Z   r#   z0AwaitTests.test_basicEnsureDeferred.<locals>.runr"   N)r   r(   r   r+   r   r   r   test_basicEnsureDeferredU   s   

z#AwaitTests.test_basicEnsureDeferredc                 C   sD   dd }t | }| |}| t|jt | |jjd dS )z
        An exception in a coroutine scheduled with L{Deferred.fromCoroutine}
        will cause the returned L{Deferred} to fire with a failure.
        c                     s   t d} | I d H  td)Nr"   Oh no!)r   
ValueErrorr   r   r   r   r   i   s   
z&AwaitTests.test_exception.<locals>.run)r.   N)r   r'   failureResultOfr   typevaluer/   argsr+   r   r   r   test_exceptionc   s
   
zAwaitTests.test_exceptionc                    sR   dd }t |  fdd}| t| }| d|  | d|  dS )z
        When a Deferred is awaited upon that has already failed with a Failure
        that has a traceback, both the place that the synchronous traceback
        comes from and the awaiting line are shown in the traceback.
        c                   S   s   t  N)r
   r   r   r   r   raisesz   s   zCAwaitTests.test_synchronousDeferredFailureTraceback.<locals>.raisesc                          I d H S r6   r   r   itr   r   doomed      
zCAwaitTests.test_synchronousDeferredFailureTraceback.<locals>.doomed, in doomed
z, in raises
N)r   r1   r   r'   assertIngetTraceback)r   r7   r;   failurer   r9   r   (test_synchronousDeferredFailureTracebacks   s   z3AwaitTests.test_synchronousDeferredFailureTracebackc                    sj   dd }t    fdd}t | }| |  |  | |}| d|  | d|  dS )z
        When a Deferred is awaited upon that later fails with a Failure that
        has a traceback, both the place that the synchronous traceback comes
        from and the awaiting line are shown in the traceback.
        c                   S   s    zt   t y   t  Y S w r6   )r
   r   r   r   r   r   returnsFailure   s
   
zEAwaitTests.test_asyncDeferredFailureTraceback.<locals>.returnsFailurec                      r8   r6   r   r   r9   r   r   r;      r<   z=AwaitTests.test_asyncDeferredFailureTraceback.<locals>.doomedr=   z, in returnsFailure
N)r   r'   assertNoResulterrbackr1   r>   r?   )r   rB   r;   startedr@   r   r9   r   "test_asyncDeferredFailureTraceback   s   

z-AwaitTests.test_asyncDeferredFailureTracebackc                    s   t   g  fdd fdd}t| } d | ddg  d | g d	  d | g d	  d | g d
 | |}| |d dS )z
        A coroutine scheduled with L{Deferred.fromCoroutine} that awaits a
        L{Deferred} suspends its execution until the inner L{Deferred} fires.
        c                     s:    d t }  d| jd | I d H   d dS )N         Yay!appendr   	callLatercallbackr0   )reactorsectionsr   r   runone   s   


z'AwaitTests.test_twoDeep.<locals>.runonec                     sP    d  I d H }  d t } d|jd |I d H   d | S )NrH         rK   )resultr   rO   rQ   rP   r   r   r      s   



z$AwaitTests.test_twoDeep.<locals>.rung?rH   rG   皙?)rH   rG   rI   rR   )rH   rG   rI   rR   rS   rJ   N)r   r   r'   advancer   r(   r+   r   rU   r   test_twoDeep   s   





zAwaitTests.test_twoDeepc                    s.    fdd}  t| } |d dS )zO
        Awaiting an already failed Deferred will raise the exception.
        c               
      sP   zt tdI d H  W dS  ty' }  z | jd W Y d } ~ dS d } ~ ww )NBoom)rY   rH   r   )r   r/   r   r4   )er   r   r   test   s   z%AwaitTests.test_reraise.<locals>.testrH   N)r(   r   r'   r   )r   r\   r   r   r[   r   test_reraise   s   zAwaitTests.test_reraisec                    sB   t    fdd}t| } d | |}| |d dS )zd
        Awaiting a paused & chained Deferred will give the result when it has
        one.
        c                     sD   t  } t   |  fdd | d  d jd | I d H S )Nc                    s    S r6   r   )ignoredd2r   r   <lambda>   s    z7AwaitTests.test_chained.<locals>.test.<locals>.<lambda>r   bye)r   addCallbackrN   rM   r0   rO   r_   r   r\      s   

z%AwaitTests.test_chained.<locals>.testrV   rb   N)r   r   r'   rW   r(   r   )r   r\   r   r   r   rd   r   test_chained   s   	

zAwaitTests.test_chainedN)r   r   r   r   r   r*   r,   r-   r5   rA   rF   rX   r]   re   r   r   r   r   r      s    +r   )r   r%   twisted.internet.deferr   r   r   r   r   twisted.internet.taskr   twisted.python.failurer   twisted.trial.unittestr	   	Exceptionr
   r   r   r   r   r   <module>   s   