B
    ÛT•\µ  ã               @   sj   d dl mZmZmZ d dlmZ ddgZG dd„ deƒZdd„ Z	edd	d
„ƒZ
dd„ ZG dd„ deƒZdS )é    )Úabsolute_importÚdivisionÚprint_function)ÚcontextmanagerÚCallbackÚadd_callbacksc               @   sL   e Zd ZdZeƒ Zddd„Zedd„ ƒZdd„ Z	d	d
„ Z
dd„ Zdd„ ZdS )r   ac   Base class for using the callback mechanism

    Create a callback with functions of the following signatures:

    >>> def start(dsk):
    ...     pass
    >>> def start_state(dsk, state):
    ...     pass
    >>> def pretask(key, dsk, state):
    ...     pass
    >>> def posttask(key, result, dsk, state, worker_id):
    ...     pass
    >>> def finish(dsk, state, failed):
    ...     pass

    You may then construct a callback object with any number of them

    >>> cb = Callback(pretask=pretask, finish=finish)  # doctest: +SKIP

    And use it either as a context manager over a compute/get call

    >>> with cb:  # doctest: +SKIP
    ...     x.compute()  # doctest: +SKIP

    Or globally with the ``register`` method

    >>> cb.register()  # doctest: +SKIP
    >>> cb.unregister()  # doctest: +SKIP

    Alternatively subclass the ``Callback`` class with your own methods.

    >>> class PrintKeys(Callback):
    ...     def _pretask(self, key, dask, state):
    ...         print("Computing: {0}!".format(repr(key)))

    >>> with PrintKeys():  # doctest: +SKIP
    ...     x.compute()  # doctest: +SKIP
    Nc             C   s6   |r
|| _ |r|| _|r|| _|r(|| _|r2|| _d S )N)Ú_startÚ_start_stateÚ_pretaskÚ	_posttaskÚ_finish)ÚselfÚstartZstart_stateZpretaskZposttaskZfinish© r   ú-lib/python3.7/site-packages/dask/callbacks.pyÚ__init__1   s    zCallback.__init__c                s$   dddddg}t ‡ fdd„|D ƒƒS )Nr   r	   r
   r   r   c             3   s   | ]}t ˆ |d ƒV  qd S )N)Úgetattr)Ú.0Úi)r   r   r   ú	<genexpr>@   s    z%Callback._callback.<locals>.<genexpr>)Útuple)r   Zfieldsr   )r   r   Ú	_callback=   s    zCallback._callbackc             C   s   t | ƒ| _| j ¡  | S )N)r   Ú_cmÚ	__enter__)r   r   r   r   r   B   s    

zCallback.__enter__c             G   s   | j j|Ž  d S )N)r   Ú__exit__)r   Úargsr   r   r   r   G   s    zCallback.__exit__c             C   s   t j | j¡ d S )N)r   ÚactiveÚaddr   )r   r   r   r   ÚregisterJ   s    zCallback.registerc             C   s   t j | j¡ d S )N)r   r   Úremover   )r   r   r   r   Ú
unregisterM   s    zCallback.unregister)NNNNN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__Úsetr   r   Úpropertyr   r   r   r   r    r   r   r   r   r      s   &
c             C   s(   | rdd„ t | Ž D ƒS dddddgS dS )z>Take an iterable of callbacks, return a list of each callback.c             S   s   g | ]}d d„ |D ƒ‘qS )c             S   s   g | ]}|r|‘qS r   r   )r   r   r   r   r   ú
<listcomp>T   s    z/unpack_callbacks.<locals>.<listcomp>.<listcomp>r   )r   Úfr   r   r   r'   T   s    z$unpack_callbacks.<locals>.<listcomp>r   N)Úzip)Zcbsr   r   r   Úunpack_callbacksQ   s    r*   Nc             c   s<   | dk}|rt jtƒ  } t _z| p$dV  W d|r6| t _X dS )zÌAllows callbacks to work with nested schedulers.

    Callbacks will only be used by the first started scheduler they encounter.
    This means that only the outermost scheduler will use global callbacks.Nr   )r   r   r%   )Ú	callbacksZglobal_callbacksr   r   r   Úlocal_callbacksY   s    r,   c             C   s*   t | tƒr| jS t | tƒr| S tdƒ‚dS )z Normalizes a callback to a tuplez.Callbacks must be either `Callback` or `tuple`N)Ú
isinstancer   r   r   Ú	TypeError)Úcbr   r   r   Únormalize_callbacki   s
    

r0   c               @   s(   e Zd ZdZdd„ Zdd„ Zdd„ ZdS )	r   aÇ  Context manager for callbacks.

    Takes several callbacks and applies them only in the enclosed context.
    Callbacks can either be represented as a ``Callback`` object, or as a tuple
    of length 4.

    Examples
    --------
    >>> def pretask(key, dsk, state):
    ...     print("Now running {0}").format(key)
    >>> callbacks = (None, pretask, None, None)
    >>> with add_callbacks(callbacks):    # doctest: +SKIP
    ...     res.compute()
    c             G   s"   dd„ |D ƒ| _ tj | j ¡ d S )Nc             S   s   g | ]}t |ƒ‘qS r   )r0   )r   Úcr   r   r   r'   ƒ   s    z*add_callbacks.__init__.<locals>.<listcomp>)r+   r   r   Úupdate)r   r+   r   r   r   r   ‚   s    zadd_callbacks.__init__c             C   s   d S )Nr   )r   r   r   r   r   †   s    zadd_callbacks.__enter__c             C   s    x| j D ]}tj |¡ qW d S )N)r+   r   r   Údiscard)r   ÚtypeÚvalueÚ	tracebackr1   r   r   r   r   ‰   s    zadd_callbacks.__exit__N)r!   r"   r#   r$   r   r   r   r   r   r   r   r   s   s   )N)Z
__future__r   r   r   Ú
contextlibr   Ú__all__Úobjectr   r*   r,   r0   r   r   r   r   r   Ú<module>   s   I
