ó
¦–Õ\c           @` s  d  d l  m Z m Z m Z d  d l m Z d d l m Z m Z d „  Z	 d „  Z
 d „  Z d „  Z d	 „  Z d d
 „ Z d d „ Z d d e d „ Z d „  Z e d „ Z d „  Z d „  Z d e d d „ Z d d „ Z d „  Z d „  Z d e f d „  ƒ  YZ d „  Z d S(   i    (   t   absolute_importt   divisiont   print_function(   t   chaini   (   t   addt   incc         C` s+   y t  |  ƒ t SWn t k
 r& t SXd S(   sq    Is x hashable?

    Examples
    --------

    >>> ishashable(1)
    True
    >>> ishashable([1])
    False
    N(   t   hasht   Truet	   TypeErrort   False(   t   x(    (    s(   lib/python2.7/site-packages/dask/core.pyt
   ishashable   s
    
c         C` s&   t  |  ƒ t k o% |  o% t |  d ƒ S(   sÉ    Is 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
    i    (   t   typet   tuplet   callable(   R
   (    (    s(   lib/python2.7/site-packages/dask/core.pyt   istask   s    c         C` sr   t  | ƒ r t Sy | |  k r# t SWn t k
 r7 n Xt | t ƒ rn x$ | D] } t |  | ƒ rN t SqN Wn  t S(   s­   Whether ``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
    (   R   R   t	   Exceptiont
   isinstancet   listt	   has_tasksR	   (   t   dskR
   t   i(    (    s(   lib/python2.7/site-packages/dask/core.pyR   +   s    c         c` sx   xq |  D]i } t  | ƒ r8 xT t | ƒ D] } | Vq& Wq t | t ƒ rk t Vx! t | ƒ D] } | VqY Wq | Vq Wd S(   s(   A generator to preorder-traverse a task.N(   R   t   preorder_traversalR   R   (   t   taskt   itemR   (    (    s(   lib/python2.7/site-packages/dask/core.pyR   A   s    c         C` s0   t  | t ƒ r, t d „  t |  | ƒ Dƒ ƒ S|  S(   Nc         s` s$   |  ] \ } } t  | | ƒ Vq d  S(   N(   t   lists_to_tuples(   t   .0t   rt   k(    (    s(   lib/python2.7/site-packages/dask/core.pys	   <genexpr>R   s    (   R   R   R   t   zip(   t   rest   keys(    (    s(   lib/python2.7/site-packages/dask/core.pyR   P   s    c         C` s¨   t  |  t ƒ r/ g  |  D] } t | | ƒ ^ q St |  ƒ r| |  d |  d } } g  | D] } t | | ƒ ^ qW } | | Œ  St |  ƒ sŒ |  S|  | k r  | |  S|  Sd S(   s“   Do the actual work of collecting data and executing a function

    Examples
    --------

    >>> 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'
    i    i   N(   R   R   t   _execute_taskR   R   (   t   argt   cacheR   t   at   funct   argst   args2(    (    s(   lib/python2.7/site-packages/dask/core.pyR    V   s     "
c         C` sÖ   xP t  | t ƒ r t | ƒ n | g D]* } | |  k r% t d j | ƒ ƒ ‚ q% q% W| d k rh i  } n  x7 t |  ƒ D]) } |  | } t | | ƒ } | | | <qu Wt | | ƒ } t  | t ƒ rÒ t | | ƒ } n  | S(   s®    Get value from Dask

    Examples
    --------

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

    >>> get(d, 'x')
    1
    >>> get(d, 'y')
    2
    s   {0} is not a key in the graphN(	   R   R   t   flattent   KeyErrort   formatt   Nonet   toposortR    R   (   R   t   outR"   R   t   keyR   t   result(    (    s(   lib/python2.7/site-packages/dask/core.pyt   get€   s    +	
c   
      C` s2  | d k	 r |  | } n! | d k	 r. | } n t d ƒ ‚ g  } | g } xÒ | rg  } x¹ | D]± } t | ƒ }	 |	 t k r¤ | r¤ t | d ƒ r¤ | | d 7} q_ |	 t k r½ | | 7} q_ |	 t k rÜ | | j ƒ  7} q_ y  | |  k rû | j | ƒ n  Wq_ t	 k
 rq_ Xq_ W| } qL W| r(| St
 | ƒ S(   sy   Get the immediate tasks on which this task depends

    Examples
    --------
    >>> 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'}
    s   Provide either key or taski    i   N(   R*   t
   ValueErrorR   R   R   R   t   dictt   valuest   appendR   t   set(
   R   R-   R   t   as_listR!   R.   t   workt   new_workt   wt   typ(    (    s(   lib/python2.7/site-packages/dask/core.pyt   get_dependencies   s0    			"
c         ` s2   ‡  f d †  ˆ  j  ƒ  Dƒ } t | ƒ } | | f S(   s   Get dependencies and dependents from dask dask graph

    >>> dsk = {'a': 1, 'b': (inc, 'a'), 'c': (inc, 'b')}
    >>> dependencies, dependents = get_deps(dsk)
    >>> dependencies
    {'a': set(), 'b': {'a'}, 'c': {'b'}}
    >>> dependents
    {'a': {'b'}, 'b': {'c'}, 'c': set()}
    c         ` s+   i  |  ]! \ } } t  ˆ  d  | ƒ| “ q S(   R   (   R:   (   R   R   t   v(   R   (    s(   lib/python2.7/site-packages/dask/core.pys
   <dictcomp>ã   s   	(   t   itemst   reverse_dict(   R   t   dependenciest
   dependents(    (   R   s(   lib/python2.7/site-packages/dask/core.pyt   get_depsÙ   s    
c         c` se   t  |  t ƒ r |  VnJ xG |  D]? } t  | | ƒ rX x' t | d | ƒD] } | VqF Wq | Vq Wd S(   sJ  

    >>> 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]
    t	   containerN(   R   t   strR'   (   t   seqRA   R   t   item2(    (    s(   lib/python2.7/site-packages/dask/core.pyR'   é   s    c         C` s~   t  |  j ƒ  ƒ t  t j |  j ƒ  ƒ ƒ } d „  | Dƒ } x< |  j ƒ  D]. \ } } x | D] } | | j | ƒ q[ WqH W| S(   s¢   

    >>> a, b, c = 'abc'
    >>> d = {a: [b, c], b: [c]}
    >>> reverse_dict(d)  # doctest: +SKIP
    {'a': set([]), 'b': set(['a']}, 'c': set(['a', 'b'])}
    c         S` s   i  |  ] } t  ƒ  | “ q S(    (   R4   (   R   t   t(    (    s(   lib/python2.7/site-packages/dask/core.pys
   <dictcomp>  s   	 (   R   R   R   t   from_iterableR2   R<   R   (   t   dt   termsR.   R   t   valst   val(    (    s(   lib/python2.7/site-packages/dask/core.pyR=     s    +c         C` sÔ  t  |  ƒ } | t k o+ |  o+ t |  d ƒ s› y& | t  | ƒ k rS |  | k rS | SWn t k
 rg n X| t k r— g  |  D] } t | | | ƒ ^ q{ S|  Sg  } x|  d D]} t  | ƒ } | t k rõ | rõ t | d ƒ rõ t | | | ƒ } n¼ | t k r)g  | D] } t | | | ƒ ^ q} nˆ | t  | ƒ k r±yD t | ƒ t | ƒ k r~t d „  t | | ƒ Dƒ ƒ r~| } n  Wq±t	 t
 f k
 r­| | k r®| } q®q±Xn  | j | ƒ q¬ W|  d  t | ƒ S(   s‚    Perform a substitution on a task

    Examples
    --------

    >>> subs((inc, 'x'), 'x', 1)  # doctest: +SKIP
    (inc, 1)
    i    i   c         s` s9   |  ]/ \ } } t  | ƒ t  | ƒ k o0 | | k Vq d  S(   N(   R   (   R   t   aat   bb(    (    s(   lib/python2.7/site-packages/dask/core.pys	   <genexpr>5  s   (   R   R   R   R   R   t   subst   lent   allR   R   t   AttributeErrorR3   (   R   R-   RJ   t	   type_taskR
   t   newargsR!   t   type_arg(    (    s(   lib/python2.7/site-packages/dask/core.pyRM     s6    	"#"(!c         ` s  | d  k r ˆ  } n t | t ƒ s0 | g } n  | s? g  } n  t ƒ  } t ƒ  } | d  k r| t ‡  f d †  ˆ  Dƒ ƒ } n  x‚| D]z} | | k r› qƒ n  | g } xV| rü| d }	 |	 | k rÓ | j ƒ  q§ n  | j |	 ƒ g  }
 xÀ | |	 D]´ } | | k rñ | | k r•| g } x' | d | k rA| j | j ƒ  ƒ qW| j | j ƒ  ƒ | j ƒ  | ri| Sd j	 d „  | Dƒ ƒ } t
 d | ƒ ‚ n  |
 j | ƒ qñ qñ W|
 r¿| j |
 ƒ q§ | sÕ| j |	 ƒ n  | j |	 ƒ | j |	 ƒ | j ƒ  q§ Wqƒ W| rg  S| S(   Nc         3` s$   |  ] } | t  ˆ  | ƒ f Vq d  S(   N(   R:   (   R   R   (   R   (    s(   lib/python2.7/site-packages/dask/core.pys	   <genexpr>W  s    iÿÿÿÿs   ->c         s` s   |  ] } t  | ƒ Vq d  S(   N(   RB   (   R   R
   (    (    s(   lib/python2.7/site-packages/dask/core.pys	   <genexpr>t  s    s   Cycle detected in Dask: %s(   R*   R   R   R4   R1   t   popR   R3   t   reverset   joint   RuntimeErrort   extendt   remove(   R   R   t   returncycleR>   t   orderedt	   completedt   seenR-   t   nodest   curt
   next_nodest   nxtt   cycle(    (   R   s(   lib/python2.7/site-packages/dask/core.pyt	   _toposortA  sX    						

	
c         C` s   t  |  d | ƒS(   s;    Return a list of keys of dask sorted in topological order.R>   (   Rc   (   R   R>   (    (    s(   lib/python2.7/site-packages/dask/core.pyR+   †  s    c         C` s   t  |  d | d t ƒS(   s[   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
    --------

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

    See Also
    --------
    isdag
    R   RZ   (   Rc   R   (   RG   R   (    (    s(   lib/python2.7/site-packages/dask/core.pyt   getcycle‹  s    c         C` s   t  |  | ƒ S(   sQ   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
    >>> isdag({'x': 0, 'y': (inc, 'x')}, 'y')
    True
    >>> isdag({'x': (inc, 'y'), 'y': (inc, 'x')}, 'y')
    False

    See Also
    --------
    getcycle
    (   Rd   (   RG   R   (    (    s(   lib/python2.7/site-packages/dask/core.pyt   isdag   s    t   literalc           B` s8   e  Z d  Z d Z d „  Z d „  Z d „  Z d „  Z RS(   sB   A small serializable object to wrap literal values without copyingt   datac         C` s   | |  _  d  S(   N(   Rg   (   t   selfRg   (    (    s(   lib/python2.7/site-packages/dask/core.pyt   __init__¹  s    c         C` s   d t  |  j ƒ j S(   Ns   literal<type=%s>(   R   Rg   t   __name__(   Rh   (    (    s(   lib/python2.7/site-packages/dask/core.pyt   __repr__¼  s    c         C` s   t  |  j f f S(   N(   Rf   Rg   (   Rh   (    (    s(   lib/python2.7/site-packages/dask/core.pyt
   __reduce__¿  s    c         C` s   |  j  S(   N(   Rg   (   Rh   (    (    s(   lib/python2.7/site-packages/dask/core.pyt   __call__Â  s    (   Rg   (   Rj   t
   __module__t   __doc__t	   __slots__Ri   Rk   Rl   Rm   (    (    (    s(   lib/python2.7/site-packages/dask/core.pyRf   µ  s   			c         C` s/   t  |  ƒ s t |  ƒ t k r+ t |  ƒ f S|  S(   s   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.

    >>> quote((add, 1, 2))  # doctest: +SKIP
    (literal<type=tuple>,)
    (   R   R   R   Rf   (   R
   (    (    s(   lib/python2.7/site-packages/dask/core.pyt   quoteÆ  s    	N(   t
   __future__R    R   R   t	   itertoolsR   t
   utils_testR   R   R   R   R   R   R   R*   R    R/   R	   R:   R@   R   R'   R=   RM   Rc   R+   Rd   Re   t   objectRf   Rq   (    (    (    s(   lib/python2.7/site-packages/dask/core.pyt   <module>   s(   					*<			+E		