
    Lg                        d dl mZ d dlmZ d dlmZ d dlmZ ddgZ G d d      Z	d Z
edd
       Zd Z G d d      Zy	)    )annotations)Callable)contextmanager)ClassVarCallbackadd_callbacksc                  b    e Zd ZU dZ e       Zded<   	 ddZedd       Z	d Z
d Zdd	Zdd
Zy)r   a  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)

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

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

    Or globally with the ``register`` method

    >>> cb.register()
    >>> cb.unregister()

    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()
    z*ClassVar[set[tuple[Callable | None, ...]]]activeNc                `    |r|| _         |r|| _        |r|| _        |r|| _        |r|| _        y y N_start_start_state_pretask	_posttask_finish)selfstartstart_statepretaskposttaskfinishs         .lib/python3.12/site-packages/dask/callbacks.py__init__zCallback.__init__4   s<     DK +D#DM%DN!DL     c                4     g d}t         fd|D              S )Nr   c              3  8   K   | ]  }t        |d         y wr   )getattr).0ir   s     r   	<genexpr>z%Callback._callback.<locals>.<genexpr>E   s     <VWT1d+Vs   )tuple)r   fieldss   ` r   	_callbackzCallback._callbackB   s    O<V<<<r   c                Z    t        |       | _        | j                  j                          | S r   )r   _cm	__enter__r   s    r   r'   zCallback.__enter__G   s#     &r   c                6     | j                   j                  |  y r   )r&   __exit__)r   argss     r   r*   zCallback.__exit__L   s    4 r   c                V    t         j                  j                  | j                         y r   )r   r
   addr$   r(   s    r   registerzCallback.registerO   s    DNN+r   c                V    t         j                  j                  | j                         y r   )r   r
   remover$   r(   s    r   
unregisterzCallback.unregisterR   s    t~~.r   )NNNNN)returnztuple[Callable | None, ...])r2   None)__name__
__module____qualname____doc__setr
   __annotations__r   propertyr$   r'   r*   r.   r1    r   r   r   r   
   sK    %N :=F6> QU" = =
!,/r   c                v    | r)t        |  D cg c]  }|D cg c]  }|s|	 c} c}}S g dS c c}w c c}}w )z>Take an iterable of callbacks, return a list of each callback.)r;   r;   r;   r;   r;   )zip)cbsfr    s      r   unpack_callbacksr@   V   s=    
-0#Y7YA#AqA#Y77## $7s   	50055Nc              #     K   | du }|r$t         j                  t               c} t         _        	 | xs d |r| t         _        yy# |r| t         _        w w xY ww)zAllows 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
   r8   )	callbacksglobal_callbackss     r   local_callbacksrD   ^   sX      !D(%-__ce"	8?(o2'HO 'HO s   +AA AAAc                t    t        | t              r| j                  S t        | t              r| S t	        d      )z Normalizes a callback to a tuplez.Callbacks must be either `Callback` or `tuple`)
isinstancer   r$   r"   	TypeError)cbs    r   normalize_callbackrI   n   s1    "h||	B		HIIr   c                  "    e Zd ZdZd Zd Zd Zy)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                    |D cg c]  }t        |       c}| _        t        j                  j	                  | j                         y c c}w r   )rI   rB   r   r
   update)r   rB   cs      r   r   zadd_callbacks.__init__   s:    9BCA,Q/Ct~~. Ds   A	c                     y r   r;   r(   s    r   r'   zadd_callbacks.__enter__   s    r   c                d    | j                   D ]!  }t        j                  j                  |       # y r   )rB   r   r
   discard)r   typevalue	tracebackrM   s        r   r*   zadd_callbacks.__exit__   s"    AOO##A&  r   N)r4   r5   r6   r7   r   r'   r*   r;   r   r   r   r   x   s    /'r   r   )
__future__r   collections.abcr   
contextlibr   typingr   __all__r   r@   rD   rI   r   r;   r   r   <module>rY      sQ    " $ % 
'I/ I/X$ ( (J' 'r   