B
    T\bk              .   @   s  d dl mZmZmZ d dlZd dlZd dlZd dlZd dlZd dl	Z	d dl
Z
d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlZd dlmZ d	d
lmZmZmZmZmZmZ d	dlm Z  d	dl!m"Z" e# Z$e$dkrdZ$dd Z%dd Z&dd Z'edd Z(dd Z)edddZ*edddZ+ede,dfdd Z-ed!d" Z.edd#d$Z/ed%d& Z0G d'd( d(e1Z2ee,d)d*fd+d,Z3d-d. Z4dd/d0Z5dd1d2Z6d3d4 Z7e8e9e:e;e<e=e>e?e@eAeBeCeDeEeFeGeHeIeJeKeLeMeNeOePeQeReSeTe,eUeVeWeXeYe8eZe[e\e]e^e_e`eaebecg-Zder$edeef e8egeheiejekelemeneoepeqgZrdd5d6ZsG d7d8 d8e1Ztd9d: Zud;d< Zvd=d> Zwd?d@ Zxdg fdAdBZydCdD ZzdEdF Z{dGdH Z|dIdJ Z}dKdL Z~dMdN ZdOdP ZdQdR ZdSdT ZdUdV Zi ZG dWdX dXe1ZG dYdZ dZe1ZG d[d\ d\e1Ze ZG d]d^ d^e1Zdd_d`Zdadb ZG dcdd dde1Zdedf Zdgdh Zdidj Zdkdl Zdmdn Zdodpdqdrdsdtdudvdwdxd	d	dyZdzd{ e D Zed|d{ e D  ed}d{ e D  d~d Zdd ZdS )    )absolute_importdivisionprint_functionN)ENOENT)contextmanager)import_module)Integral)Lock)WeakValueDictionary   )get_named_args
getargspecPY3unicodebind_methodIterator)get_deps)	key_splitasciizutf-8c                s4   t |d ttfr( fddt| D S  | S dS )z Apply function inside nested lists

    >>> inc = lambda x: x + 1
    >>> deepmap(inc, [[1, 2], [3, 4]])
    [[2, 3], [4, 5]]

    >>> add = lambda x, y: x + y
    >>> deepmap(add, [[1, 2], [3, 4]], [[10, 20], [30, 40]])
    [[11, 22], [33, 44]]
    r   c                s   g | ]}t  f| qS  )deepmap).0items)funcr   )lib/python3.7/site-packages/dask/utils.py
<listcomp>)   s    zdeepmap.<locals>.<listcomp>N)
isinstancelistr   zip)r   Zseqsr   )r   r   r      s    r   c             C   s<   |s|S d}|}xt |tr.|d7 }|d }qW t|| |S )Nr   r   )r   r   ndeepmap)r   seqnZtmpr   r   r   homogeneous_deepmap.   s    r"   c                sX   dkr fdd|D S dkr6 fdd|D S t |trL |d S  |S dS )z Call a function on every element within a nested container

    >>> def inc(x):
    ...     return x + 1
    >>> L = [[1, 2], [3, 4, 5]]
    >>> ndeepmap(2, inc, L)
    [[2, 3], [4, 5, 6]]
    r   c                s   g | ]} |qS r   r   )r   item)r   r   r   r   D   s    zndeepmap.<locals>.<listcomp>c                s   g | ]}t d   |qS )r   )r   )r   r#   )r   r!   r   r   r   F   s    r   N)r   r   )r!   r   r    r   )r   r!   r   r   :   s    	
r   c              g   s$   y
d V  W n | k
r   Y nX d S )Nr   )
exceptionsr   r   r   ignoringM   s    
r%   c             C   s*   yt | S  tk
r$   t|Y nX dS )zrAttempt to import a required dependency.

    Raises a RuntimeError if the requested module is not available.
    N)r   ImportErrorRuntimeError)mod_nameZ	error_msgr   r   r   import_requiredU   s    r)    c             c   s   d|  d } tj| |d\}}t| t| z
|V  W d tj|rtj|rdt	
| ntt t| W d Q R X X d S )N.)dir)lstriptempfileZmkstemposcloseremovepathexistsisdirshutilrmtreer%   OSError)	extensionr,   Zhandlefilenamer   r   r   tmpfile`   s    



r:   c             c   st   t j| d}z
|V  W d tj|rntj|rPtt t	| W d Q R X ntt t
| W d Q R X X d S )N)r,   )r.   Zmkdtempr/   r2   r3   r4   r%   r7   r5   r6   r1   )r,   dirnamer   r   r   tmpdirr   s    


r<   wc             c   s`   t |dL}|||d}z||  W d y|  W n tk
rH   Y nX X |V  W d Q R X d S )N)r8   )mode)r:   writer0   AttributeError)textr8   openr>   r9   fr   r   r   filetext   s    rD   c          	   c   s.   t  }t |  z
d V  W d t | X d S )N)r/   getcwdchdir)Znew_cwdZold_cwdr   r   r   changed_cwd   s
    

rG   c          
   c   s2   t |  }t| |V  W d Q R X W d Q R X d S )N)r<   rG   )r,   r;   r   r   r   tmp_cwd   s    

rH   c               c   s
   d V  d S )Nr   r   r   r   r   noop_context   s    rI   c               @   s$   e Zd ZdZdZdd Zdd ZdS )IndexCallablez Provide getitem syntax for functions

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

    >>> I = IndexCallable(inc)
    >>> I[3]
    4
    )fnc             C   s
   || _ d S )N)rK   )selfrK   r   r   r   __init__   s    zIndexCallable.__init__c             C   s
   |  |S )N)rK   )rL   keyr   r   r   __getitem__   s    zIndexCallable.__getitem__N)__name__
__module____qualname____doc__	__slots__rM   rO   r   r   r   r   rJ      s   	rJ   tTc             c   s   |r
t  nt  xV|  D ]J\}}||d| }z|| W dy|  W n tk
rb   Y nX X qW t| V  x6| D ].}tj	|rzt
t t| W dQ R X qzW W dQ R X dS )a6   Dumps a number of textfiles to disk

    d - dict
        a mapping from filename to text like {'a.csv': '1,1
2,2'}

    Since this is meant for use in tests, this context manager will
    automatically switch to a temporary current directory, to avoid
    race conditions when running tests in parallel.
    r=   N)rH   rI   r   r?   r0   r@   r   r/   r2   r3   r%   r7   r1   )drB   r>   Z
use_tmpdirr9   rA   rC   r   r   r   	filetexts   s    


rW   c             C   s2   t | trt| } t | ttfr.ttt| } | S )z Make nested iterators concrete lists

    >>> data = [[1, 2], [3, 4]]
    >>> seq = iter(map(iter, data))
    >>> concrete(seq)
    [[1, 2], [3, 4]]
    )r   r   r   tuplemapconcrete)r    r   r   r   rZ      s
    
rZ   c       
      C   s   ddl }t|}|dg| }|d|d s4tt|dk sDtt||jjs^|j|}|	| }|j
| dd}xBtt|dd |dd D ] \}\}}	||||k||	k @ < qW |S )z Pseudorandom array of integer indexes

    >>> pseudorandom(5, [0.5, 0.5], random_state=123)
    array([1, 0, 0, 1, 1], dtype=int8)

    >>> pseudorandom(10, [0.5, 0.2, 0.2, 0.1], random_state=5)
    array([0, 2, 0, 3, 0, 1, 2, 1, 0, 0], dtype=int8)
    r   Nr      Zi1)dtype)numpyr   ZcumsumZallcloseAssertionErrorlenr   randomRandomStateZrandom_sampleempty	enumerater   )
r!   prandom_statenpZcpxoutiZlowZhighr   r   r   pseudorandom   s    	
,rk   c                sn   ddl }t fdddD s*|j   d|  d }t|j||jd| d	f}t	|| ksjt
|S )
a  Return a list of arrays that can initialize
    ``np.random.RandomState``.

    Parameters
    ----------
    n : int
        Number of arrays to return.
    random_state : int or np.random.RandomState, optional
        If an int, is used to seed a new ``RandomState``.
    r   Nc             3   s   | ]}t  |V  qd S )N)hasattr)r   attr)rf   r   r   	<genexpr>  s    z$random_state_data.<locals>.<genexpr>)ZnormalZbetabytesZuniformip     )r]   r[   )r^   allra   rb   ro   r   Z
frombufferZuint32Zreshaper`   r_   )r!   rf   rg   Zrandom_datalr   )rf   r   random_state_data  s    rs   c             C   s   t | tpt | to|  S )zj
    >>> is_integer(6)
    True
    >>> is_integer(42.0)
    True
    >>> is_integer('abc')
    False
    )r   r   float
is_integer)rj   r   r   r   ru     s    	ru   c             C   s   | t krdS | tkrdS yt| }W n tk
r8   dS X y|jd dkoRt| t}W n tk
rn   d}Y nX |r~|jr~dS |jdkrdnt	|j}t	|j| | dkS )a   Does this function take multiple arguments?

    >>> def f(x, y): pass
    >>> takes_multiple_arguments(f)
    True

    >>> def f(x): pass
    >>> takes_multiple_arguments(f)
    False

    >>> def f(x, y=None): pass
    >>> takes_multiple_arguments(f)
    False

    >>> def f(*args): pass
    >>> takes_multiple_arguments(f)
    True

    >>> class Thing(object):
    ...     def __init__(self, a): pass
    >>> takes_multiple_arguments(Thing)
    False

    FTr   rL   Nr   )
ONE_ARITY_BUILTINSMULTI_ARITY_BUILTINSr   	Exceptionargsr   typevarargsdefaultsr`   )r   r{   specZis_constructorZ	ndefaultsr   r   r   takes_multiple_arguments0  s     

r~   c               @   sJ   e Zd ZdZdddZdddZdddZd	d
 Zdd Ze	dd ZdS )DispatchzSimple single dispatch.Nc             C   s   i | _ i | _|r|| _d S )N)_lookup_lazyrP   )rL   namer   r   r   rM   a  s    zDispatch.__init__c                s"    fdd}|dk	r||S |S )z7Register dispatch of `func` on arguments of type `type`c                s4   t tr&x$D ]} ||  qW n
|  j< | S )N)r   rX   registerr   )r   rU   )rL   rz   r   r   wrapperi  s
    


z"Dispatch.register.<locals>.wrapperNr   )rL   rz   r   r   r   )rL   rz   r   r   g  s    zDispatch.registerc                s"    fdd}|dk	r||S |S )z
        Register a registration function which will be called if the
        *toplevel* module (e.g. 'pandas') is ever loaded.
        c                s   |  j < | S )N)r   )r   )rL   toplevelr   r   r   x  s    
z'Dispatch.register_lazy.<locals>.wrapperNr   )rL   r   r   r   r   )rL   r   r   register_lazys  s    zDispatch.register_lazyc             C   s   | j }y|| }W n tk
r&   Y nX |S |jd\}}}y| j|}W n tk
rb   Y nX |  | |S x6t|dd D ] }||kr|| ||< || S qW t	d
|dS )z8Return the function implementation for the given ``cls``r+   r   NzNo dispatch for {0})r   KeyErrorrQ   	partitionr   popdispatchinspectZgetmro	TypeErrorformat)rL   clsZlkimplr   _r   Zcls2r   r   r   r   ~  s$    
zDispatch.dispatchc             O   s   |  t|}||f||S )zJ
        Call the corresponding method based on type of argument.
        )r   rz   )rL   argry   kwargsmethr   r   r   __call__  s    zDispatch.__call__c             C   s0   y|  t}|jS  tk
r*   d| j S X d S )NzSingle Dispatch for %s)r   objectrS   r   rP   )rL   r   r   r   r   rS     s
    
zDispatch.__doc__)N)N)N)
rP   rQ   rR   rS   rM   r   r   r   r   propertyr   r   r   r   r   _  s   


r   c          
   C   sB   yt |  W n. tk
r< } z|jtkr, W dd}~X Y nX dS )z,
    Ensure that a file does not exist.
    N)r/   unlinkr7   errnor   )r9   er   r   r   ensure_not_exists  s
    
r   c             C   sP   |   }|dks|dr|S d|krHd|krHd| kr>| d S | d S n| S d S )Nz>>>z>>> #z+SKIPz
# doctest:z, +SKIPz  # doctest: +SKIP)strip
startswith)linestrippedr   r   r   _skip_doctest  s    
r   c             C   s&   | d krdS d dd | dD S )Nr*   
c             S   s   g | ]}t |qS r   )r   )r   r   r   r   r   r     s    z skip_doctest.<locals>.<listcomp>)joinsplit)docr   r   r   skip_doctest  s    r   c                s   |  d  fddtt d D }t }xtt| D ]d\}}||krd| } | || |<  |d  dt| dt|  |d < q<|| q<W d S )Nr   c                sD   i | ]<} |d   rt dd  |d    D r |  |qS )r   c             s   s   | ]}|d kV  qdS )-Nr   )r   cr   r   r   rn     s    z*extra_titles.<locals>.<dictcomp>.<genexpr>)rq   r   )r   rj   )linesr   r   
<dictcomp>  s    z extra_titles.<locals>.<dictcomp>r   zExtra r   )	r   ranger`   setsortedr   replaceaddr   )r   Ztitlesseenrj   titleZ	new_titler   )r   r   extra_titles  s    
r   c                s    fdd}|S )a  Decorator to attach original class's docstring to the wrapped method.

    Parameters
    ----------
    original_klass: type
        Original class which the method is derived from
    version : str
        Original package version which supports the wrapped method
    ua_args : list
        List of keywords which Dask doesn't support. Keywords existing in
        original but not in Dask will automatically be added.
    c                s  | j yt}|j}|d kr$d}y&t|  t|} fdd|D }W n tk
rb   g }Y nX tdkrz| t|dkrd}ddd |D }|| | }t|}t	|}|| _| S  t
k
r   jdd t| fdd	}|S X d S )
Nr*   c                s   g | ]}| kr|qS r   r   )r   m)method_argsr   r   r     s    z1derived_from.<locals>.wrapper.<locals>.<listcomp>r   zV
        Notes
        -----
        Dask doesn't support the following argument(s).

c             S   s   g | ]}d  |qS )z        * {0}
)r   )r   ar   r   r   r     s    r+   c                 s2   d  }d k	r&d}|| 7 }t|d S )Nz#Base package doesn't support '{0}'.z) Use {0} {1} or later to use this method.)r   NotImplementedError)ry   r   msgZmsg2)method_namemodule_nameversionr   r   wrapped	  s
    
z.derived_from.<locals>.wrapper.<locals>.wrapped)rP   getattrrS   r   
ValueErrorr`   extendr   r   r   r@   rQ   r   	functoolswraps)methodZoriginal_methodr   Zoriginal_argsZnot_supportedZnotery   r   )original_klassua_argsr   )r   r   r   r   r     s4    


zderived_from.<locals>.wrapperr   )r   r   r   r   r   )r   r   r   r   derived_from  s    +r   c             C   s   t | tjrt| jS t | tr&| jS t| ddp4d}tt| ddpHd}d|kr`d|kr`| j	S d|krvd|krv| j
S y| j}|d	krd
S |S  tk
r   t| S X dS )zGet the name of a function.rQ   Nr*   rP   toolzZcurryZmultipledispatchZ
Dispatcherz<lambda>lambda)r   r   partialfuncnamer   methodcallerr   r   rz   Z	func_namer   rP   r@   str)r   r   Z	type_namer   r   r   r   r     s"    

r   c             C   s*   | j r| j dkr| jS | j d | j S dS )z
    Return the name of a type

    Examples
    --------
    >>> typename(int)
    'int'

    >>> from dask.core import literal
    >>> typename(literal)
    'dask.core.literal'
    builtinsr+   N)rQ   rP   )typr   r   r   typename1  s    r   c             C   s4   t | tr| S t| dr |  S d}t||  dS )z Turn string or bytes to bytes

    >>> ensure_bytes(u'123')
    b'123'
    >>> ensure_bytes('123')
    b'123'
    >>> ensure_bytes(b'123')
    b'123'
    encodez<Object %s is neither a bytes object nor has an encode methodN)r   ro   rl   r   r   )sr   r   r   r   ensure_bytesD  s    


r   c             C   s4   t | tr| S t| dr |  S d}t||  dS )z Turn string or bytes to bytes

    >>> ensure_unicode(u'123')
    '123'
    >>> ensure_unicode('123')
    '123'
    >>> ensure_unicode(b'123')
    '123'
    decodez<Object %s is neither a bytes object nor has an encode methodN)r   r   rl   r   r   )r   r   r   r   r   ensure_unicodeV  s    


r   c             C   s   | ||  | S )z

    >>> digit(1234, 0, 10)
    4
    >>> digit(1234, 1, 10)
    3
    >>> digit(1234, 2, 10)
    2
    >>> digit(1234, 3, 10)
    1
    r   )r!   kbaser   r   r   digith  s    r   c             C   s   t | }|||< t|S )zB

    >>> insert(('a', 'b', 'c'), 0, 'x')
    ('x', 'b', 'c')
    )r   rX   )tupZlocvalLr   r   r   insertw  s    r   c                sB   dd l }t| \ }|j fddtfdd  D S )Nr   c                s.    |  sdS dt fdd |  D  }|S )Nr   c             3   s   | ]} |V  qd S )Nr   )r   dep_key)max_depth_by_depsr   r   rn     s    z>dependency_depth.<locals>.max_depth_by_deps.<locals>.<genexpr>)max)rN   rV   )depsr   r   r   r     s    z+dependency_depth.<locals>.max_depth_by_depsc             3   s   | ]} |V  qd S )Nr   )r   r   )r   r   r   rn     s    z#dependency_depth.<locals>.<genexpr>)r   r   Zmemoizer   keys)Zdskr   r   r   )r   r   r   dependency_depth  s    r   c             C   s.   x(dD ] }| dk rd| |f S | d } qW d S )N)ro   ZKBMBGBTBg      @z%3.1f %sr   )Znumrh   r   r   r   memory_repr  s    
r   c                s   dd |D }t dd | D } t dd tt| | D }ddt|   |   t |  }dd	d
d |D  }d fdd|D }d|||||gS )zFormats an ascii table for given columns and rows.

    Parameters
    ----------
    columns : list
        The column names
    rows : list of tuples
        The rows in the table. Each tuple must be the same length as
        ``columns``.
    c             S   s   g | ]}t d d |D qS )c             s   s   | ]}t |V  qd S )N)r   )r   rj   r   r   r   rn     s    z(asciitable.<locals>.<listcomp>.<genexpr>)rX   )r   rr   r   r   r     s    zasciitable.<locals>.<listcomp>c             s   s   | ]}t |V  qd S )N)r   )r   rj   r   r   r   rn     s    zasciitable.<locals>.<genexpr>c             s   s*   | ]"\}}t t tt|t|V  qd S )N)r   rY   r`   )r   rh   r   r   r   r   rn     s   |z	 %%-%ds |z+%s++c             s   s   | ]}d |d  V  qdS )r      Nr   )r   r=   r   r   r   rn     s    r   c             3   s   | ]} | V  qd S )Nr   )r   r   )row_templater   r   rn     s    )rX   r   r`   r   )columnsZrowsZwidthsheaderZbardatar   )r   r   
asciitable  s    r   c             C   s4   t dd |D r dd |D }| d| d S )Nc             s   s   | ]}t |t V  qd S )N)r   r   )r   rh   r   r   r   rn     s    zput_lines.<locals>.<genexpr>c             S   s   g | ]}t |qS r   )r   )r   rh   r   r   r   r     s    zput_lines.<locals>.<listcomp>r   )anyr?   r   )Zbufr   r   r   r   	put_lines  s    r   c               @   sD   e Zd ZdZdZedd Zdd Zdd Zd	d
 Z	dd Z
e
ZdS )r   z
    Return a callable object that calls the given method on its operand.

    Unlike the builtin `operator.methodcaller`, instances of this class are
    serializable
    )r   c             C   s   | j S )N)r   )rL   r   r   r   <lambda>  s    zmethodcaller.<lambda>c             C   s,   |t krt | S t| }||_|t |< |S )N)_method_cacher   __new__r   )r   r   rL   r   r   r   r     s    
zmethodcaller.__new__c             O   s   t || j||S )N)r   r   )rL   objry   r   r   r   r   r     s    zmethodcaller.__call__c             C   s   t | jffS )N)r   r   )rL   r   r   r   
__reduce__  s    zmethodcaller.__reduce__c             C   s   d| j j| jf S )Nz<%s: %s>)	__class__rP   r   )rL   r   r   r   __str__  s    zmethodcaller.__str__N)rP   rQ   rR   rS   rT   r   r   r   r   r   r   __repr__r   r   r   r   r     s   r   c               @   s4   e Zd ZdZdZdd Zdd Zdd Zd	d
 ZdS )
itemgetterz
    Return a callable object that gets an item from the operand

    Unlike the builtin `operator.itemgetter`, instances of this class are
    serializable
    )indexc             C   s
   || _ d S )N)r   )rL   r   r   r   r   rM     s    zitemgetter.__init__c             C   s
   || j  S )N)r   )rL   rh   r   r   r   r     s    zitemgetter.__call__c             C   s   t | jffS )N)r   r   )rL   r   r   r   r     s    zitemgetter.__reduce__c             C   s   t | t |ko| j|jkS )N)rz   r   )rL   otherr   r   r   __eq__  s    zitemgetter.__eq__N)	rP   rQ   rR   rS   rT   rM   r   r   r   r   r   r   r   r     s   r   c               @   s    e Zd ZdZeeZdd ZdS )MethodCachezAttribute access on this object returns a methodcaller for that
    attribute.

    Examples
    --------
    >>> a = [1, 3, 3]
    >>> M.count(a, 3) == a.count(3)
    True
    c             C   s   t tS )N)r   r   )rL   r   r   r   r     s    zMethodCache.<lambda>N)rP   rQ   rR   rS   staticmethodr   __getattr____dir__r   r   r   r   r     s   	r   c               @   s`   e Zd Ze ZdddZdd Zdd Zdd	 Zd
d Z	dd Z
dd Zdd Zdd ZeZdS )SerializableLockNc             C   sH   |pt t | _| jtjkr.tj| j | _nt | _| jtj| j< d S )N)r   uuidZuuid4tokenr   _lockslockr	   )rL   r   r   r   r   rM     s
    zSerializableLock.__init__c             O   s   | j j||S )N)r  acquire)rL   ry   r   r   r   r   r  "  s    zSerializableLock.acquirec             O   s   | j j||S )N)r  release)rL   ry   r   r   r   r   r  %  s    zSerializableLock.releasec             C   s   | j   d S )N)r  	__enter__)rL   r   r   r   r  (  s    zSerializableLock.__enter__c             G   s   | j j|  d S )N)r  __exit__)rL   ry   r   r   r   r  +  s    zSerializableLock.__exit__c             C   s
   | j  S )N)r  locked)rL   r   r   r   r  .  s    zSerializableLock.lockedc             C   s   | j S )N)r   )rL   r   r   r   __getstate__1  s    zSerializableLock.__getstate__c             C   s   |  | d S )N)rM   )rL   r   r   r   r   __setstate__4  s    zSerializableLock.__setstate__c             C   s   d| j j| jf S )Nz<%s: %s>)r   rP   r   )rL   r   r   r   r   7  s    zSerializableLock.__str__)N)rP   rQ   rR   r
   r   rM   r  r  r  r  r  r  r  r   r   r   r   r   r   r     s   
r   c             C   sF   ddl m} ddlm} || g|d}||jkr@|   S t S )z_Get an instance of the appropriate lock for a certain situation based on
       scheduler used.r   )multiprocessing)get_scheduler)collections	scheduler)	r*   r	  r   r
  getZget_contextZManagerr	   r   )Z
collectionr  r	  r
  Z
actual_getr   r   r   get_scheduler_lock=  s    
r  c             C   sH   t | tkr| S t| dr@i }x| j D ]}|| q*W |S t| S )Ndicts)rz   dictrl   r  valuesupdate)rV   resultZddr   r   r   ensure_dictK  s    
r  c               @   s6   e Zd ZdZedd Zedd Zed
ddZd	S )OperatorMethodMixinz.A mixin for dynamically implementing operatorsc             C   s   |j }|dr|dd }n|dkr*d}d|}|dkrPt| || | n>t| || | |dkrndS d	|}t| || j|d
d dS )z bind operator to this class r   Nr[   invinvertz__{0}__)absr  negpos)eqgtgeltlenegetitemz__r{0}__T)r  )rP   endswithr   r   _get_unary_operator_get_binary_operator)r   opr   r   Zrmethr   r   r   _bind_operatorY  s    


z"OperatorMethodMixin._bind_operatorc             C   s   t dS )z- Must return a method used by unary operator N)r   )r   r%  r   r   r   r#  q  s    z'OperatorMethodMixin._get_unary_operatorFc             C   s   t dS )z. Must return a method used by binary operator N)r   )r   r%  r  r   r   r   r$  v  s    z(OperatorMethodMixin._get_binary_operatorN)F)rP   rQ   rR   rS   classmethodr&  r#  r$  r   r   r   r   r  V  s
   r  c              O   sD   | d}| d}t| }x|D ]\}}||| q"W |||S )zi

    >>> from operator import add
    >>> partial_by_order(5, function=add, other=[(1, 10)])
    15
    functionr   )r   r   r   )ry   r   r(  r   Zargs2rj   r   r   r   r   partial_by_order|  s    

r)  c                s@   ddl m  t| do>| jo>t| do>t fdd| jD  S )z Is this object a numpy array or something similar?

    Examples
    --------
    >>> import numpy as np
    >>> x = np.ones(5)
    >>> is_arraylike(x)
    True
    >>> is_arraylike(5)
    False
    >>> is_arraylike('cat')
    False
    r   )is_dask_collectionshaper]   c             3   s   | ]} |V  qd S )Nr   )r   r!   )r*  r   r   rn     s    zis_arraylike.<locals>.<genexpr>)r   r*  rl   r+  r   )rh   r   )r*  r   is_arraylike  s    
r,  c             C   s   dd t d| D S )a  
    Sorting `key` function for performing a natural sort on a collection of
    strings

    See https://en.wikipedia.org/wiki/Natural_sort_order

    Parameters
    ----------
    s : str
        A string that is an element of the collection being sorted

    Returns
    -------
    tuple[str or int]
        Tuple of the parts of the input string where each part is either a
        string or an integer

    Examples
    --------
    >>> a = ['f0', 'f1', 'f2', 'f8', 'f9', 'f10', 'f11', 'f19', 'f20', 'f21']
    >>> sorted(a)
    ['f0', 'f1', 'f10', 'f11', 'f19', 'f2', 'f20', 'f21', 'f8', 'f9']
    >>> sorted(a, key=natural_sort_key)
    ['f0', 'f1', 'f2', 'f8', 'f9', 'f10', 'f11', 'f19', 'f20', 'f21']
    c             S   s    g | ]}|  rt|n|qS r   )isdigitint)r   partr   r   r   r     s   z$natural_sort_key.<locals>.<listcomp>z(\d+))rer   )r   r   r   r   natural_sort_key  s    r1  c                s8    fddt dtt dd D }tttj|S )zV Return the factors of an integer

    https://stackoverflow.com/a/6800214/616616
    c             3   s&   | ]} | d kr| | gV  qdS )r   Nr   )r   rj   )r!   r   r   rn     s    zfactors.<locals>.<genexpr>r   g      ?)r   r.  powr   r   reducer   __add__)r!   r    r   )r!   r   factors  s    &r5  c             C   s   |  dd} | d  s d|  } x*tt| d ddD ]}| |  s6P q6W |d }| d| }| |d }yt|}W n  tk
r   td| Y nX yt|  }W n  t	k
r   td	| Y nX || }t
|S )
a   Parse byte string to numbers

    >>> parse_bytes('100')
    100
    >>> parse_bytes('100 MB')
    100000000
    >>> parse_bytes('100M')
    100000000
    >>> parse_bytes('5kB')
    5000
    >>> parse_bytes('5.4 kB')
    5400
    >>> parse_bytes('1kiB')
    1024
    >>> parse_bytes('1e6')
    1000000
    >>> parse_bytes('1e6 kB')
    1000000000
    >>> parse_bytes('MB')
    1000000
    >>> parse_bytes('5 foos')  # doctest: +SKIP
    ValueError: Could not interpret 'foos' as a byte unit
     r*   r   1r   r[   Nz$Could not interpret '%s' as a numberz'Could not interpret '%s' as a byte unit)r   r-  r   r`   isalphart   r   
byte_sizeslowerr   r.  )r   rj   r   prefixsuffixr!   Z
multiplierr  r   r   r   parse_bytes  s&    r=  i  i@B i ʚ;l    J)l     I5 i   i   i   @l        l           )ZkBr   r   r   ZPBZKiBZMiBZGiBZTiBZPiBBr*   c             C   s   i | ]\}}||  qS r   )r:  )r   r   vr   r   r   r   	  s    r   c             C   s&   i | ]\}}|rd |kr||d qS )rj   r   r   )r   r   r?  r   r   r   r   
  s    c             C   s*   i | ]"\}}|rd |kr||dd qS )rj   Nr[   r   )r   r   r?  r   r   r   r     s    c             C   s`   yFt r|t| jkS t| tjr4|t| jj	kS |t| j	kS W n t
k
rZ   dS X d S )NF)r   r   Z	signatureZ
parametersr   r   r   r   r   ry   rx   )r   keywordr   r   r   has_keyword  s    rA  c             C   s.   t | ttfsdS | sdS dt| d  S d S )Nr   r   )r   r   rX   ndimlist)r    r   r   r   rB    s
    rB  )r*   N)N)N)N)N)T)NN)Z
__future__r   r   r   r   r   r/   r5   sysr.   r0  r   r   
contextlibr   	importlibr   Znumbersr   Z	threadingr	   r   weakrefr
   Zcompatibilityr   r   r   r   r   r   Zcorer   optimizationr   getdefaultencodingZsystem_encodingr   r"   r   r%   r)   r:   r<   rB   rD   rG   rH   rI   r   rJ   rW   rZ   rk   rs   ru   r   r  rq   r   bool	bytearrayro   callablechrr'  complexr  r,   rd   evalrt   r   	frozensethashhexidr.  iterr`   r   r   minnextoctordr   reprreversedroundslicer   r   r   sumrX   rz   varsr   
memoryviewrv   r   r   compiledelattrdivmodfilterr   rl   r   
issubclassrY   r2  setattrrw   r~   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   Mr   r  r  r  r)  r,  r1  r5  r=  r9  r   r  rA  rB  r   r   r   r   <module>   s    




/I;?
&	3