
    bi::                       d dl mZ d dlmZ d dlmZmZmZmZ d dl	m
Z
mZmZmZmZ d dlZd dlmZmZmZmZ d dlmZmZmZmZ d Zd	 Zd
 Zd Zd"dZd#d$dZd%d&dZ d'dZ!d(dZ"e	 	 	 d)	 	 	 	 	 	 	 	 	 d*d       Z#e	 	 	 	 	 	 	 	 	 	 d+d       Z#dedf	 	 	 	 	 	 	 	 	 d,dZ#d-dZ$e%fdZ& ed      Z'd.dZ(d Z)d/dZ*d#dZ+d Z,d Z- G d d      Z.d  Z/d! Z0y)0    )annotations)defaultdict)
CollectionIterableMappingMutableMapping)AnyLiteralTypeVarcastoverloadN)DependenciesMappingTaskRefconvert_legacy_graphexecute_graph)GraphKey	NoDefault
no_defaultc                :    	 t        |        y# t        $ r Y yw xY w)zIs x hashable?

    Examples
    --------

    >>> ishashable(1)
    True
    >>> ishashable([1])
    False

    See Also
    --------
    iskey
    TF)hash	TypeErrorxs    D/home/cdr/jupyterlab/.venv/lib/python3.12/site-packages/dask/core.py
ishashabler      s#    Q s    	c                    ddl m}m} t        | |      rt        | |       S t	        |       t
        u xr | xr t        | d         S )zIs x a runnable task?

    A task is a tuple with a callable first argument

    Examples
    --------

    >>> inc = lambda x: x + 1
    >>> istask((inc, 1))
    True
    >>> istask(1)
    False
    r   )DataNode	GraphNode)dask._task_specr   r   
isinstancetypetuplecallable)r   r   r   s      r   istaskr%   (   sB     4!Ya***7e44hqtn4    c              #     K   | D ]Q  }t        |      rt        |      E d{    "t        |t              rt         t        |      E d{    N| S y7 87 w)z(A generator to preorder-traverse a task.N)r%   preorder_traversalr!   list)taskitems     r   r(   r(   =   sW       $<)$///d#J)$///J/ 0s!   AA+AAAAc                ^    t        |t              rt        d t        | |      D              S | S )Nc              3  :   K   | ]  \  }}t        ||        y wN)lists_to_tuples).0rks      r   	<genexpr>z"lists_to_tuples.<locals>.<genexpr>L   s     Ftq!_Q*Fs   )r!   r)   r#   zip)reskeyss     r   r/   r/   J   s(    $Fs3~FFFJr&   c                V     t        |t              rt         fd|D              S  |   S )Nc              3  6   K   | ]  }t        |        y wr.   )_pack_result)r0   r2   results     r   r3   z_pack_result.<locals>.<genexpr>R   s     ;\&!,;s   )r!   r)   r#   )r:   r6   s   ` r   r9   r9   P   s(    $;d;;;$<r&   c           	         t        |      D ]  }|| vst        | d       |i }t        | t        |       t        |      z        }t	        ||t        t        |g                  }t        ||      S )zGet value from Dask

    Examples
    --------

    >>> inc = lambda x: x + 1
    >>> d = {'x': 1, 'y': (inc, 'x')}

    >>> get(d, 'x')
    1
    >>> get(d, 'y')
    2
    z is not a key in the graph)all_keys)r6   )flattenKeyErrorr   setr   r9   )dskoutcacher2   dsk2r:   s         r   getrD   V   s|     S\ =C<aS :;<<= }c#hU.CDD4S#-@AF$$r&   Fc                8   ddl m} g }|rg }|D ]  }t        |      }|t        u r%|r#t	        |d         r|j                  |dd        ;|t        u r|j                  |       U|t        u r |j                  |j                                }t        ||      r|j                  |j                         t        |t              r|j                  |j                         	 || v r|j                  |        |}|r|r|S t        |      S # t        $ r Y 	w xY w)a  Returns the keys in `keys` that are also in `tasks`

    Examples
    --------
    >>> inc = lambda x: x + 1
    >>> add = lambda x, y: x + y
    >>> dsk = {'x': 1,
    ...        'y': (inc, 'x'),
    ...        'z': (add, 'x', 'y'),
    ...        'w': (inc, 'z'),
    ...        'a': (add, (inc, 'x'), 1)}

    >>> keys_in_tasks(dsk, ['x', 'y', 'j'])  # doctest: +SKIP
    {'x', 'y'}
    r   )r      N)r    r   r"   r#   r$   extendr)   dictvaluesr!   dependenciesr   appendkeyr   r?   )r6   tasksas_listr   retworkwtyps           r   keys_in_tasksrS   o   s      *C
 	Aq'Ce|hqtnAabE"AAHHJ'Ay)ANN+Aw'AEE"Dy

1	$ ) * 3's3x' ! s   !D	DDc                    t        |       }|t        u r t        d t        t        |       D              S |t        t
        t        hv S )zReturn True if the given object is a potential dask key; False otherwise.

    The definition of a key in a Dask graph is any str, int, float, or tuple
    thereof.

    See Also
    --------
    ishashable
    validate_key
    dask.typing.Key
    c              3  2   K   | ]  }t        |        y wr.   )iskey)r0   is     r   r3   ziskey.<locals>.<genexpr>   s     6586   )r"   r#   allr   intfloatstr)rL   rR   s     r   rV   rV      s>     s)C
e|6T%%56663s###r&   c                   t        |       ryt        |       }|t        u r0d}	 t        t	        t        |             D ]  \  }}t        |        	 t        d| d| d      # t        $ r}t        d|d| d      |d}~ww xY w)zLValidate the format of a dask key.

    See Also
    --------
    iskey
    Nz4Composite key contains unexpected key type at index=z (key=)zUnexpected key type )rV   r"   r#   	enumerater   validate_keyr   )rL   rR   indexpartes        r   r`   r`      s     Sz
s)C
e|	(eS)9: #tT"# *3%w#;
<<	  	G3(RST	s   ,A" "	B+A>>Bc                     y r.    r@   rL   r*   rN   s       r   get_dependenciesrg      s     r&   c                     y r.   re   rf   s       r   rg   rg      s     r&   c                \    || |   }n|t         ur|}nt        d      t        | |g|      S )a  Get the immediate tasks on which this task depends

    Examples
    --------
    >>> inc = lambda x: x + 1
    >>> add = lambda x, y: x + y
    >>> dsk = {'x': 1,
    ...        'y': (inc, 'x'),
    ...        'z': (add, 'x', 'y'),
    ...        'w': (inc, 'z'),
    ...        'a': (add, (inc, 'x'), 1)}

    >>> get_dependencies(dsk, 'x')
    set()

    >>> get_dependencies(dsk, 'y')
    {'x'}

    >>> get_dependencies(dsk, 'z')  # doctest: +SKIP
    {'x', 'y'}

    >>> get_dependencies(dsk, 'w')  # Only direct dependencies
    {'z'}

    >>> get_dependencies(dsk, 'a')  # Ignore non-keys
    {'x'}

    >>> get_dependencies(dsk, task=(inc, 'x'))  # provide tasks directly
    {'x'}
    zProvide either key or task)rN   )r   
ValueErrorrS   )r@   rL   r*   rN   args        r   rg   rg      s=    H #h	Z	566seW55r&   c           	         | j                         D ci c]  \  }}|t        | |       }}}t        |      }||fS c c}}w )aN  Get dependencies and dependents from dask dask graph

    >>> inc = lambda x: x + 1
    >>> dsk = {'a': 1, 'b': (inc, 'a'), 'c': (inc, 'b')}
    >>> dependencies, dependents = get_deps(dsk)
    >>> dependencies
    {'a': set(), 'b': {'a'}, 'c': {'b'}}
    >>> dependents  # doctest: +SKIP
    {'a': {'b'}, 'b': {'c'}, 'c': set()}
    )r*   )itemsrg   reverse_dict)r@   r2   vrJ   
dependentss        r   get_depsrq     sK     BEMAA'!44MLMl+J## Ns   >c              #     K   t        | t              r|  y| D ](  }t        ||      rt        ||      E d{    %| * y7 w)aJ  

    >>> list(flatten([1]))
    [1]

    >>> list(flatten([[1, 2], [1, 2]]))
    [1, 2, 1, 2]

    >>> list(flatten([[[1], [2]], [[1], [2]]]))
    [1, 2, 1, 2]

    >>> list(flatten(((1, 2), (1, 2)))) # Don't flatten tuples
    [(1, 2), (1, 2)]

    >>> list(flatten((1, 2, [3, 4]))) # support heterogeneous
    [1, 2, 3, 4]
    )	containerN)r!   r\   r=   )seqrs   r+   s      r   r=   r=     sH     $ #s	 	D$	*"49===
		=s   7AAAT_c                    t        t              }t        j                  }| j                         D ]  \  }}||    |D ]  } |||   |         t	        |      S )z

    >>> a, b, c = 'abc'
    >>> d = {a: [b, c], b: [c]}
    >>> reverse_dict(d)  # doctest: +SKIP
    {'a': set([]), 'b': set(['a']}, 'c': set(['a', 'b'])}
    )r   r?   addrm   rH   )dr:   _addr2   valsvals         r   rn   rn   2  s`     (33'7F77D779 !4q	 	!Ca 	!! <r&   c           	     $   t        |       }|t        u r| rt        | d         s:	 |t        |      u r| |k(  r|S |t        u r| D cg c]  }t        |||       c}S | S g }|h}| dd D ]n  }t        |      }|t        u r|rt        |d         rt        |||      }n*|t        u r|D cg c]  }t        |||       }}n	 ||v r|}|j                  |       p | dd t        |      z   S # t        $ r Y w xY wc c}w c c}w # t        $ r Y Hw xY w)zPerform a substitution on a task

    Examples
    --------
    >>> def inc(x):
    ...     return x + 1

    >>> subs((inc, 'x'), 'x', 1)  # doctest: +ELLIPSIS
    (<function inc at ...>, 1)
    r   rF   N)r"   r#   r$   	Exceptionr)   subsr   rK   )	r*   rL   r{   	type_taskr   newargshash_keyrk   type_args	            r   r~   r~   C  s?    T
I4HT!W,=	DI%$#+
 /34!DC%44GuHABx 9u#a&)9sC%C.1243$2C2(?C 	s 8eGn$$)  		 5 3
  s/   C* C9(C> D*	C65C6	DDc                T   || }nt        |t              s|g}|sg }t               }t               }|t        |       }|D ]  }||v r	|g}|s|d   }	|	|v r|j	                          |j                  |	       g }
||	   D ]:  }||vs	||v ri }|d   }|d   |k7  r&t        |       ||j	                         <   |d   |k7  r&t        |       ||<   t        |      }t        |D ci c]  }||j                  ||          c}      }|j	                         g}|j                  |       ||d   k7  r9||d      }t        ||j                        }|j                  |       ||d   k7  r9|j                          |r|c c S dj                  d |D              }t        d|z        |
j                  |       = |
r|j                  |
       nE|sj                  |	       |j                  |	       |j!                  |	       |j	                          |r͐ |rg S S c c}w )Nr   )rL   z->c              3  2   K   | ]  }t        |        y wr.   )r\   )r0   r   s     r   r3   z_toposort.<locals>.<genexpr>  s     -Dc!f-DrX   zCycle detected in Dask: %s)r!   r)   r?   r   poprw   lenrn   intersectionrK   min__getitem__reversejoinRuntimeErrorrG   remove)r@   r6   returncyclerJ   ordered	completedseenrL   nodescur
next_nodesnxt
prioritiesprevinplayr2   rp   cycledepss                      r   	_toposortr   j  sR    |d#v I 5D*3/ =))Ci		HHSM J#C( $+i'd{
 &(
$Ry#Bi3.7::6FJuyy{3 $Bi3.+.z?*:
3 "%Z%1NTUQ 3 3LO DDU&

 "'T*"eAh. $.eBi#8D#&t1G1G#HD!LL. #eAh. &#(L$(II-De-D$DE"./Ke/S"TT%%c*I$+L Z( #NN3'c"C 		s 	=| 	NA Vs   'H%c                    t        | |      S )z:Return a list of keys of dask sorted in topological order.)rJ   r   )r@   rJ   s     r   toposortr     s    S|44r&   c                    t        | |d      S )ax  Return a list of nodes that form a cycle if Dask is not a DAG.

    Returns an empty list if no cycle is found.

    ``keys`` may be a single key or list of keys.

    Examples
    --------

    >>> inc = lambda x: x + 1
    >>> d = {'x': (inc, 'z'), 'y': (inc, 'x'), 'z': (inc, 'y')}
    >>> getcycle(d, 'x')
    ['x', 'z', 'y', 'x']

    See Also
    --------
    isdag
    T)r6   r   r   rx   r6   s     r   getcycler     s    & QTt44r&   c                    t        | |       S )an  Does Dask form a directed acyclic graph when calculating keys?

    ``keys`` may be a single key or list of keys.

    Examples
    --------

    >>> inc = lambda x: x + 1
    >>> inc = lambda x: x + 1
    >>> isdag({'x': 0, 'y': (inc, 'x')}, 'y')
    True
    >>> isdag({'x': (inc, 'y'), 'y': (inc, 'x')}, 'y')
    False

    See Also
    --------
    getcycle
    )r   r   s     r   isdagr     s    & 4   r&   c                  ,    e Zd ZdZdZd Zd Zd Zd Zy)literalzBA small serializable object to wrap literal values without copyingdatac                    || _         y r.   r   )selfr   s     r   __init__zliteral.__init__  s	    	r&   c                F    dt        | j                        j                  z  S )Nzliteral<type=%s>)r"   r   __name__r   s    r   __repr__zliteral.__repr__   s    !DO$<$<<<r&   c                (    t         | j                  ffS r.   )r   r   r   s    r   
__reduce__zliteral.__reduce__  s    $))&&r&   c                    | j                   S r.   r   r   s    r   __call__zliteral.__call__  s    yyr&   N)	r   
__module____qualname____doc__	__slots__r   r   r   r   re   r&   r   r   r     s    LI='r&   r   c                x    t        |       s"t        |       t        u st        |       t        u rt	        |       fS | S )a$  Ensure that this value remains this value in a dask graph

    Some values in dask graph take on special meaning. Sometimes we want to
    ensure that our data is not interpreted but remains literal.

    >>> add = lambda x, y: x + y
    >>> quote((add, 1, 2))
    (literal<type=tuple>,)
    )r%   r"   r)   rH   r   r   s    r   quoter   
  s0     ayDGtOtAw$
}Hr&   c                    t        |       dk(  rt        |      S t        t        |      | d   z        }t        j                  ||      D cg c]  }t        | dd |       c}S c c}w )zgReshape iterator to nested shape

    >>> reshapelist((2, 3), range(6))
    [[0, 1, 2], [3, 4, 5]]
    rF   r   N)r   r)   rZ   toolz	partitionreshapelist)shapert   nrb   s       r   r   r     s\     5zQCyC58#$9>C9PQE!"It,QQQs   A%)r:   r   r6   
list | Keyreturnr	   r.   )r@   r   rA   r   rB   zMutableMapping | Noner   r	   )F)r6   zCollection[Key]rM   zIterable[Any]rN   bool)rL   objectr   r   )rL   r   r   None)...)
r@   r   rL   
Key | Noner*   Key | NoDefaultrN   zLiteral[False]r   zset[Key])
r@   r   rL   r   r*   r   rN   zLiteral[True]r   z	list[Key])
r@   r   rL   r   r*   r   rN   r   r   zset[Key] | list[Key])r@   r   r   z/tuple[dict[Key, set[Key]], dict[Key, set[Key]]])rx   zMapping[T_, Iterable[T_]]r   zdict[T_, set[T_]])NFN)1
__future__r   collectionsr   collections.abcr   r   r   r   typingr	   r
   r   r   r   r   r    r   r   r   r   dask.typingr   r   r   r   r   r%   r(   r/   r9   rD   rS   rV   r`   rg   rq   r)   r=   ru   rn   r~   r   r   r   r   r   r   r   re   r&   r   <module>r      sx   " # I I 8 8   : 9,5*
%2((V$$=. 
 !			  	
  
 
		  	
  
 &	+6	+6	+6 +6 	+6
 +6\$    8 T]"$%NZz5
5,!, $
Rr&   