U
    bh                     @   sf   d 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 dgZe	jG d	d dZdS )
zPromise implementation.    N)deque)
WeakMethodref   )Thenable)reraisepromisec                   @   s~   e Zd ZdZeedsdZdddZedd	 Z	d
d Z
dd Zdd Zdd ZdddZdddZdddZedd ZdS )r   a~  Promise of future evaluation.

    This is a special implementation of promises in that it can
    be used both for "promise of a value" and lazy evaluation.
    The biggest upside for this is that everything in a promise can also be
    a promise, e.g. filters, callbacks and errbacks can all be promises.

    Usage examples:

    .. code-block:: python

        >>> p = promise()
        >>> p.then(promise(print, ('OK',)))  # noqa
        >>> p.on_error = promise(print, ('ERROR',))  # noqa
        >>> p(20)
        OK, 20
        >>> p.then(promise(print, ('hello',)))  # noqa
        hello, 20


        >>> p.throw(KeyError('foo'))
        ERROR, KeyError('foo')


        >>> p2 = promise()
        >>> p2.then(print)  # noqa
        >>> p2.cancel()
        >>> p(30)

    Example:
    .. code-block:: python

        from vine import promise, wrap

        class Protocol:

            def __init__(self):
                self.buffer = []

            def receive_message(self):
                return self.read_header().then(
                    self.read_body).then(
                        wrap(self.prepare_body))

            def read(self, size, callback=None):
                callback = callback or promise()
                tell_eventloop_to_read(size, callback)
                return callback

            def read_header(self, callback=None):
                return self.read(4, callback)

            def read_body(self, header, callback=None):
                body_size, = unpack('>L', header)
                return self.read(body_size, callback)

            def prepare_body(self, value):
                self.buffer.append(value)
    pypy_version_info)funargskwargsreadyfailedvalueignore_resultreason
_svpending
_lvpendingon_error	cancelledweak__weakref____dict__NFc                 C   s   || _ || _| j||d| _|p"d| _|p,i | _d| _d| _d | _d | _	d | _
d | _|| _d| _|d k	rr| | | jr| jrt|std S )Nr
   r    F)r   r   _get_fun_or_weakrefr
   r   r   r   r   r   r   r   r   r   r   thencallableAssertionError)selfr
   r   r   callbackr   r   r   r   r   1/tmp/pip-unpacked-wheel-wrrz14qk/vine/promises.py__init__T   s"    


zpromise.__init__c                 C   s&   |s| S t | rt| S t| S dS )zbReturn the callable or a weak reference.

        Handles both bound and unbound methods.
        N)inspectismethodr   r   r   r   r   r!   r   o   s
    
zpromise._get_fun_or_weakrefc                 C   s.   | j r
dndt| j dt| d| j S )Nz<{0} --> {1!r}>z<{0}>z@0xx)r
   formattype__name__idr   r   r   r!   __repr__}   s     zpromise.__repr__c              	   C   sl   d| _ zL| jd k	r| j  | jd k	r:| jD ]}|  q,t| jtrP| j  W 5 d  | _ | _| _X d S )NT)r   r   r   r   cancel
isinstancer   )r   pendingr   r   r!   r,      s    




zpromise.cancelc                 O   s  d }| j rd S |r| j| n| j}|r4t| jf|n| j}| | j}|d k	rz<| jrj||| d}i }n|||}|fi f | _\}}W q tk
r   | 	  Y S X n||f | _\}}d| _
| j}	|	d k	rz|	|| W 5 d | _X n.| j}
z|
r|
 }||| qW 5 d | _X |S )Nr   T)r   r   dictr   _fun_is_aliver
   r   r   	Exceptionthrowr   r   r   popleft)r   r   r   retvalZ
final_argsZfinal_kwargsr
   caZck	svpending	lvpendingpr   r   r!   __call__   s<    


zpromise.__call__c                 C   s   | j r| S | jS N)r   r
   )r   r
   r   r   r!   r0      s    zpromise._fun_is_alivec                 C   s   t |tst||d}| jr(|  |S | jr<|| j n| jrV| j	\}}||| | j
d kr| j}|d k	rd t|g | _| _
n
|| _|S | j
| |S )N)r   )r-   r   r   r   r,   r   r2   r   r   r   r   r   r   append)r   r    r   r   r   r6   r   r   r!   r      s$    



zpromise.thenc                 C   sL   | j sH|d k	r|n
t d }d| | _| _| jrH| j| j|f | j d S )Nr   T)r   sysexc_infor   r   r   r   r   )r   excr   r   r!   throw1   s
    zpromise.throw1Tc              
   C   s   | j st d }|d k	r|n|}z^| | | j}|d k	rVz|| W 5 d | _X n(| j}z|rr|	 | q^W 5 d | _X W 5 | jd kr|r|d kr|d ks||kr tt||| X d S )Nr   )
r   r<   r=   r   r   r'   r?   r   r   r3   )r   r>   tb	propagateZcurrent_excr6   r7   r   r   r!   r2      s&    

zpromise.throwc                 C   s   | j r| j S | jgS r:   )r   r   r*   r   r   r!   	listeners   s    zpromise.listeners)NNNNNFF)N)N)NNT)r(   
__module____qualname____doc__hasattrr<   	__slots__r"   staticmethodr   r+   r,   r9   r0   r   r?   r2   propertyrB   r   r   r   r!   r      s(   <
       

&


)rE   r#   r<   collectionsr   weakrefr   r   Zabstractr   utilsr   __all__registerr   r   r   r   r!   <module>   s   