
    >ie<                    h   d dl mZ d dlmZ d dlmZmZmZ d dlm	Z	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
 Zd:dZd:dZd;d<dZd=dZd>dZe	 	 	 d?d@d$            ZedAd'            ZdedfdBd)ZdCd+Zefd,Z  ed-          Z!dDd1Z"d2 Z#dEd3Z$d:d4Z%d5 Z&d6 Z' G d7 d8          Z(d9 Z)dS )F    )annotations)defaultdict)
CollectionIterableMapping)AnyLiteralTypeVarcastoverload)GraphKey	NoDefault
no_defaultc                H    	 t          |            dS # t          $ r Y dS w xY w)zIs x hashable?

    Examples
    --------

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

    See Also
    --------
    iskey
    TF)hash	TypeErrorxs    )lib/python3.11/site-packages/dask/core.py
ishashabler   
   s9    Qt   uus    
!!c                \    t          |           t          u o| o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   )typetuplecallabler   s    r   istaskr       s)     77e44hqtnn4    c                    t          |          rdS 	 || v rdS n# t          $ r Y nw xY wt          |t                    r|D ]}t	          | |          r dS dS )zWhether ``x`` has anything to compute.

    Returns True if:
    - ``x`` is a task
    - ``x`` is a key in ``dsk``
    - ``x`` is a list that contains any tasks or keys
    TF)r   	Exception
isinstancelist	has_tasks)dskr   is      r   r"   r"   1   s     ayy t884    !T  	 	Aa   tt5s    
''c              #     K   | D ]_}t          |          rt          |          E d{V  't          |t                    rt          V  t          |          E d{V  [|V  `dS )z(A generator to preorder-traverse a task.N)r   preorder_traversalr    r!   )taskitems     r   r&   r&   G   s         $<< 	)$//////////d## 	JJJ)$//////////JJJJ r   c                ~    t          |t                    r't          d t          | |          D                       S | S )Nc              3  <   K   | ]\  }}t          ||          V  d S N)lists_to_tuples).0rks      r   	<genexpr>z"lists_to_tuples.<locals>.<genexpr>V   s0      FFtq!_Q**FFFFFFr   )r    r!   r   zip)reskeyss     r   r,   r,   T   s?    $ GFFs3~~FFFFFFJr   Nc                    t          | t                    rfd| D             S t          |           r#| d         | dd         }} |fd|D              S t          |           s| S | v r|          S | S )a  Do the actual work of collecting data and executing a function

    Examples
    --------

    >>> inc = lambda x: x + 1
    >>> add = lambda x, y: x + y
    >>> cache = {'x': 1, 'y': 2}

    Compute tasks against a cache
    >>> _execute_task((add, 'x', 1), cache)  # Compute task in naive manner
    2
    >>> _execute_task((add, (inc, 'x'), 1), cache)  # Support nested computation
    3

    Also grab data from cache
    >>> _execute_task('x', cache)
    1

    Support nested lists
    >>> list(_execute_task(['x', 'y'], cache))
    [1, 2]

    >>> list(map(list, _execute_task([['x', 'y'], ['y', 'x']], cache)))
    [[1, 2], [2, 1]]

    >>> _execute_task('foo', cache)  # Passes through on non-keys
    'foo'
    c                0    g | ]}t          |          S  _execute_taskr-   acaches     r   
<listcomp>z!_execute_task.<locals>.<listcomp>y   s#    555Aa''555r   r      Nc              3  8   K   | ]}t          |          V  d S r+   r7   r9   s     r   r0   z _execute_task.<locals>.<genexpr>   s-      <<!mAu--<<<<<<r   )r    r!   r   r   )argr;   r#   funcargss    `   r   r8   r8   Z   s    < #t 55555555	 VSWd t<<<<t<<<==__ 
	Sz
r   c                V   t          |t                    rt          |          n|gD ]}|| vrt          | d          |i }t	          |           D ]}| |         }t          ||          }|||<    t          ||          }t          |t                    r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)r    r!   flattenKeyErrortoposortr8   r,   )r#   outr;   r/   keyr'   results          r   getrI      s     (T22=WS\\\ = =C<<a;;;<<< }}}  3xtU++c

3&&F#t . --Mr   Fr3   Collection[Key]tasksIterable[Any]as_listboolc                   g }|rg }|D ]}t          |          }|t          u r5|r3t          |d                   r|                    |dd                    O|t          u r|                    |           n|t
          u r(|                    |                                           	 || v r|                    |           # t          $ r Y w xY w|}||r|nt          |          S )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   extendr!   dictvaluesappendr   set)r3   rK   rM   retworkwtyps          r   keys_in_tasksrY      s     C
  	 	Aq''Ce|||hqtnn|AabbE""""AAHHJJ''''Dyy

1    D!  " '33s3xx's   )C
CCrG   objectreturnc                    t          |           }|t          u r,t          d t          t          |           D                       S |t          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, bytes, int, float, or tuple
    thereof.

    See Also
    --------
    ishashable
    validate_key
    dask.typing.Key
    c              3  4   K   | ]}t          |          V  d S r+   )iskey)r-   r$   s     r   r0   ziskey.<locals>.<genexpr>   s(      66588666666r   )r   r   allr   bytesintfloatstr)rG   rX   s     r   r^   r^      sS     s))C
e||66T%%5%56666665#uc***r   Nonec                j    t          |           s#t          dt          |            d| d          dS )z"Validate the format of a dask key.zUnexpected key type z	 (value: )N)r^   r   r   rG   s    r   validate_keyrh      sE    :: MKtCyyKK3KKKLLLM Mr   .r#   r   
Key | Noner'   Key | NoDefaultLiteral[False]set[Key]c                    d S r+   r6   r#   rG   r'   rM   s       r   get_dependenciesro      	     Cr   Literal[True]	list[Key]c                    d S r+   r6   rn   s       r   ro   ro      rp   r   set[Key] | list[Key]c                t    |	| |         }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'}
    NzProvide either key or task)rM   )r   
ValueErrorrY   )r#   rG   r'   rM   r?   s        r   ro   ro      sM    H #h	Z		5666seW5555r   /tuple[dict[Key, set[Key]], dict[Key, set[Key]]]c                j      fd                                  D             }t          |          }||fS )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()}
    c                :    i | ]\  }}|t          |           S ))r'   ro   )r-   r/   vr#   s      r   
<dictcomp>zget_deps.<locals>.<dictcomp>/  s-    MMMAA'!444MMMr   )itemsreverse_dict)r#   dependencies
dependentss   `  r   get_depsr   $  s?     NMMMMMMLl++J##r   c              #     K   t          | t                    r| V  dS | D ].}t          ||          rt          ||          E d{V  *|V  /dS )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    rc   rC   )seqr   r(   s      r   rC   rC   4  s      $ #s 					 	 	D$	** "49===========



		 	r   T_dMapping[T_, Iterable[T_]]dict[T_, set[T_]]c                    t          t                    }t          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   rT   addr}   rQ   )r   rH   _addr/   valsvals         r   r~   r~   S  su     (33'7'7F7D7799 ! !4q		 	! 	!CDa    	!<<r   c                T   t          |           }|t          u r| rt          | d                   sE	 |t                    u r| k    rS n# t          $ r Y nw xY w|t          u rfd| D             S | S g }h}| dd         D ]}t          |          }|t          u r)|r't          |d                   rt          |          }n1|t          u rfd|D             }n	 ||v r}n# t          $ r Y nw xY w|                    |           | dd         t          |          z   S )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   c                2    g | ]}t          |          S r6   subsr-   r   rG   r   s     r   r<   zsubs.<locals>.<listcomp>w  s%    444!DC%%444r   r=   Nc                2    g | ]}t          |          S r6   r   r   s     r   r<   zsubs.<locals>.<listcomp>  s%    22243$$222r   )r   r   r   r   r!   r   r   rS   )r'   rG   r   	type_tasknewargshash_keyr?   type_args    ``     r   r   r   d  s    T

I4HT!W,=,=	DII%%$#++
 	 	 	D	44444t4444GuHABBx  99u#a&)9)9sC%%CC22222c222CC(??C   s8eGnn$$s#   A 
AA#C**
C76C7c                    | }nt          |t                    s|g}|sg }t                      }t                      } fd D             |D ]/}||v r|g}|r!|d         }	|	|v r|                                 $|                    |	           g }
|	         D ]o}||vrg||v rMi }|d         }|d         |k    r1t          |           ||                                <   |d         |k    1t          |           ||<   t          |          t          fdD                       }|                                g}|                    |           ||d         k    rE||d                  }t          ||j	                  }|                    |           ||d         k    E|
                                 |r|c c S d                    d |D                       }t          d|z            |
                    |           q|
r|                    |
           nU|s|                    |	           |                    |	           |                    |	           |                                 |!1|rg S |S )	Nc                2    i | ]}|t          |          S r6   rz   )r-   r/   r#   s     r   r|   z_toposort.<locals>.<dictcomp>  s&    AAA+C33AAAr   c                H    i | ]}|                     |                   S r6   )intersection)r-   r/   r   inplays     r   r|   z_toposort.<locals>.<dictcomp>  s-    UUUQ 3 3LO D DUUUr   r   rg   z->c              3  4   K   | ]}t          |          V  d S r+   )rc   )r-   r   s     r   r0   z_toposort.<locals>.<genexpr>  s(      -D-Dc!ff-D-D-D-D-D-Dr   zCycle detected in Dask: %s)r    r!   rT   popr   lenr~   rS   min__getitem__reversejoinRuntimeErrorrP   remove)r#   r3   returncycler   ordered	completedseenrG   nodescur
next_nodesnxt
prioritiesprevr   cycledepsr   s   `  `             @r   	_toposortr     s    |d## v  I 55DAAAASAAA = =) 9	)Ci		HHSMMM J#C( $+ $+i''d{{
 &(
$Ry#Bi3..7::6FJuyy{{3 $Bi3..+.z??*:
3 "%Z%1UUUUUfUUU& &

 "'T***"eAh.. $.eBi#8D#&t1G#H#H#HD!LL... #eAh.. & U#(LLLLL$(II-D-De-D-D-D$D$DE"./Ke/S"T"TT%%c*** Z(((( # (NN3'''c"""C   		s  9	t  	Nr   c                $    t          | |          S )z:Return a list of keys of dask sorted in topological order.)r   r   )r#   r   s     r   rE   rE     s    S|44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)r3   r   r   r   r3   s     r   getcycler     s    & QTt44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dS )literalzBA small serializable object to wrap literal values without copyingdatac                    || _         d S r+   r   )selfr   s     r   __init__zliteral.__init__  s    			r   c                :    dt          | j                  j        z  S )Nzliteral<type=%s>)r   r   __name__r   s    r   __repr__zliteral.__repr__  s    !DOO$<<<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
    yr   N)	r   
__module____qualname____doc__	__slots__r   r   r   r   r6   r   r   r   r     s[        LLI  = = =' ' '    r   r   c                    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!   rQ   r   r   s    r   quoter   )  sA     ayy DGGtOOtAww$

}Hr   r+   )F)r3   rJ   rK   rL   rM   rN   )rG   rZ   r[   rN   )rG   rZ   r[   rd   )...)
r#   r   rG   ri   r'   rj   rM   rk   r[   rl   )
r#   r   rG   ri   r'   rj   rM   rq   r[   rr   )
r#   r   rG   ri   r'   rj   rM   rN   r[   rt   )r#   r   r[   rw   )r   r   r[   r   )NFN)*
__future__r   collectionsr   collections.abcr   r   r   typingr   r	   r
   r   r   dask.typingr   r   r   r   r   r   r"   r&   r,   r8   rI   rY   r^   rh   ro   r   r!   rC   r   r~   r   r   rE   r   r   r   r   r6   r   r   <module>r      s   " " " " " " # # # # # # 9 9 9 9 9 9 9 9 9 9 8 8 8 8 8 8 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 9 9  ,5 5 5"  ,
 
 
  + + + +\   :"( "( "( "( "(J+ + + +$M M M M 
 !	    
 
   
 &	+6 +6 +6 +6 +6\$ $ $ $       8 WT]]   "$% $% $%NX X X Xv5 5 5 5
5 5 5,! ! !,       $    r   