U
    d                     @   sf   d Z ddlZddlmZ ddl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)ref
WeakMethod   )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(object):

            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__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-1j4yz0ik/vine/promises.py__init__S   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   n   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    r/      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   r1   r   r   r   r   r   r   append)r   r   r   r   r   r5   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   r2   )r   r=   tb	propagateZcurrent_excr5   r6   r   r   r    r1      s&    

zpromise.throwc                 C   s   | j r| j S | jgS r9   )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+   r8   r/   r   r>   r1   propertyrA   r   r   r   r    r      s(   <
       

&


)rD   r;   collectionsr   r"   weakrefr   r   Zabstractr   utilsr   __all__registerr   r   r   r   r    <module>   s   