B
     ‹d%  ã               @   s¦   d Z ddlZddlZddlZddlZddlmZ G dd„ deƒZddd„Zdd	d
„Z	dd„ Z
e ¡ e
_e ¡ e
_dd„ Zejd dkrdd„ Zndd„ Zddd„ZdS )zSupport for Future chaining.é    Né   )ÚFuturec               @   s$   e Zd ZdZddd„Zddd„ZdS )	ÚThenableFuturez*Thenable* `Future` subclass.Nc             C   s   t | ||ƒS )z.Return ``then(self, on_success, on_failure)``.)Úthen)ÚselfÚ
on_successÚ
on_failure© r	   úa/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/mpi4py/futures/aplus.pyr      s    zThenableFuture.thenc             C   s
   t | |ƒS )z#Return ``catch(self, on_failure)``.)Úcatch)r   r   r	   r	   r
   r      s    zThenableFuture.catch)NN)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r	   r	   r	   r
   r      s   
r   c             C   s(   |   ¡ }tjt|||d}|  |¡ |S )a  JavaScript-like (`Promises/A+`_) support for Future chaining.

    Args:
        future: Input future instance.
        on_success (optional): Function to be called when the input future is
            successfully resolved. Once the input future is resolved, its
            result value is the input for `on_success`. If `on_success` is
            ``None``, the output future (i.e., the one returned by this
            function) will be resolved directly with the result of the input
            future. If `on_success` returns a future instance, the result
            future is chained to the output future. Otherwise, the result of
            `on_success` is used to resolve the output future.
        on_failure (optional): Function to be called when the input future is
            rejected. The Exception instance picked up from the rejected future
            is the input value for `on_failure`. If `on_failure` is ``None``,
            the output future (i.e., the one returned by this function) will be
            rejected directly with the exception of the input future.

    Returns:
        Output future to be resolved once in input future is resolved
        and either `on_success` or `on_failure` completes.

    .. _Promises/A+: https://promisesaplus.com/

    )r   r   )Ú	__class__Ú	functoolsÚpartialÚ_done_cbÚadd_done_callback)Úfuturer   r   Ú
new_futureÚdone_cbr	   r	   r
   r      s    
r   c             C   s$   |dkrt | ddd„ ƒS t | d|ƒS )aJ  Close equivalent to ``then(future, None, on_failure)``.

    Args:
        future: Input future instance.
        on_failure (optional): Function to be called when the input future is
            rejected. If `on_failure` is ``None``, the output future will be
            resolved with ``None`` thus ignoring the exception.

    Nc             S   s   d S )Nr	   )Úexcr	   r	   r
   Ú<lambda>L   ó    zcatch.<locals>.<lambda>)r   )r   r   r	   r	   r
   r   A   s    
r   c          	   C   st   t jd t j}y||  }W n$ tk
r>   t ¡ }||| < Y nX ||kr\td |t|ƒ¡ƒ‚| 	|¡ W d Q R X d S )NzOCircular future chain detected: Future {0} is already in the resolved chain {1})
Ú
_chain_logÚlockÚregistryÚKeyErrorÚweakrefÚWeakSetÚRuntimeErrorÚformatÚsetÚadd)r   r   r   Úlogr	   r	   r
   r   P   s    r   c             C   s$   t | |ƒ t t| ¡}| |¡ d S )N)r   r   r   r   r   )r   r   r   r	   r	   r
   Ú_chain_futured   s    
r&   é   c              C   s   t  ¡ d } | S )Nr   )ÚsysÚexc_info)r   r	   r	   r
   Ú_sys_exceptionk   s    r*   c              C   s   t  ¡ d } d | _| S )Nr   )r(   r)   Ú__traceback__)r   r	   r	   r
   r*   o   s    c             C   sâ   |  ¡ s|  ¡  d S | ¡ r(|  ¡  d S y8| ¡ }|r>||ƒ}t|tƒrTt| |ƒ n
|  |¡ W n| tk
rÜ   t	ƒ }|s†|  
|¡ nRy,||ƒ}t|tƒr¦|  
|¡ n
|  |¡ W n$ tk
rÖ   t	ƒ }|  
|¡ Y nX Y nX d S )N)ÚdoneÚcancelÚ	cancelledÚresultÚ
isinstancer   r&   Ú
set_resultÚBaseExceptionr*   Úset_exception)r   r   r   r   r/   Ú	exceptionr	   r	   r
   r   u   s2    

r   )NN)N)NN)r   r(   r   Ú	threadingr   Z_corer   r   r   r   r   ÚLockr   ÚWeakKeyDictionaryr   r&   Úversion_infor*   r   r	   r	   r	   r
   Ú<module>   s    
#



