U
    /e3                     @  sJ  U d dl 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	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Zd dlZd dlZd dlmZ d dlmZ d dlmZmZmZmZmZ d dlmZm Z  d dl!m"Z"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*m+Z+ d dl,m-Z- d dl.m/Z/ d dl0m1Z1 d dl2m3Z3 d dl2m4Z5 d dl2m6Z6m7Z7m8Z8m9Z9 d dl:Z:d dl;Z;d dl<Z=zd dl>Z>W n e?k
r   dZ>Y nX d dl@ZAd dlBmCZC d dlDmEZE d dlFZFd dlFmGZG d dlHmIZJ d dlHmKZK d dlHmLZM d dlNmOZO d dlPmQZQ d dlRm.Z. zd dlSmTZT W n e?k
rl   eU ZTY nX eQr~d dlVZ	nd dlWZ	eXeY ZZZ[e3rd dl\m]Z] e]dZ^e8dZ_d Z`d!aad"d# Zbd$d% Zcd&d' ZdeAjed(d) Zfdd,d-Zgdd/d0Zhd1d2 Zidd4d5Zjdd6d7Z4G d8d9 d9ZkG d:d; d;Zldd<d=Zmdd>d?d@ZnG dAdB dBZoe"dCdD Zpe"dEdF ZqdGdH ZrdIdJdKdLdMZse9dNdNdOdPdQZte9d!dRdSdTdUdVdWdXdQZtdd!dRdSdYdQZtG dZdV dVZudd\d]ZveAjed^d_ Zwe=jxy  d`da ZzddcddZ{dedf Z|dgdh Z}didj Z~ddkdlZdmdn ZIdodpdqdrdsZddJdUdudvdwZdJdxdydzd{Zd|d} Zeeffd~dZejdfddZG dd dejZdd Zeddd Zeddd ZddddddddddddddddddgZeAjeefddZdd Ze"ddJddddZdd ZdddddZeZG dd deZG dd deZddddddddZdd Ze dRddZeeej dJddddZdd ZG ddÄ dÃZe ZdddJddŜddǄZddddddddddќ	Zddӄ Ze$dԃZded< d!ad3d!d֜dddTdd؜ddڄZdTdۜdd݄ZG dd߄ d߃ZdS )    )annotationsN)TimeoutError)deque)Callable
Collection	ContainerKeysView
ValuesView)CancelledErrorThreadPoolExecutor)contextmanagersuppress)
ContextVar)	timedelta)wraps)md5)cache_from_source)PickleBuffer)sleep)
ModuleType)TYPE_CHECKING)Any)ClassVarIteratorTypeVaroverload)gen)IOLoop)istask)ensure_bytes)	key_split)parse_timedelta)get_template)WINDOWS)time)thread_state)	ParamSpecPTZ__no_default__Fc               	   C  s   t jd} t| }| dkrtsdg}ddlm}m} || D ]6\}}zt	
| W n tk
rj   Y q@X || q@|| da|S )a  Create a multiprocessing context

    The context type is controlled by the
    ``distributed.worker.multiprocessing-method`` configuration key.

    Returns
    -------
    multiprocessing.BaseContext
        The multiprocessing context

    Notes
    -----
    Repeated calls with the same method will return the same object
    (since multiprocessing.get_context returns singleton instances).
    z)distributed.worker.multiprocessing-methodZ
forkserverdistributedr   )optional_packagesrequired_packagesT)daskconfiggetmultiprocessingZget_context_forkserver_preload_setZdistributed.versionsr*   r+   	importlibimport_moduleImportErrorappendZset_forkserver_preload)methodctxZpreloadr*   r+   pkg_ r9   5/tmp/pip-unpacked-wheel-g426oqom/distributed/utils.pyget_mp_contextW   s    

r;   c                 C  sp   z,t | }|t|jt|jB kr*W dS W n tk
rD   Y qlY nX z
| j} W q  tk
rh   Y qlY q X q dS )zE
    Whether the function takes an argument with the given name.
    TF)inspectgetfullargspecsetargs
kwonlyargs	TypeError__wrapped__AttributeError)funcargnameZargspecr9   r9   r:   has_arg}   s    



rF   c                   C  s    t dk	rt t jd S dS dS )z;
    Get the maximum number of open files per process.
    Nr   i   )resourceZ	getrlimitZRLIMIT_NOFILEr9   r9   r9   r:   get_fileno_limit   s    rH   c              
   C  s   t  |t j}zz$|| |f | d }|W W nS  tk
r } zJtd| |f t t 	t 
 ||t jt jd }|d d  W Y W S d }~X Y nX W 5 |  X d S )Nr   zQCouldn't detect a suitable IP address for reaching %r, defaulting to hostname: %s   )socket
SOCK_DGRAMcloseconnectgetsocknameOSErrorwarningswarnRuntimeWarninggetaddrinfogethostnameIPPROTO_UDP)hostportfamilysockipeZ	addr_infor9   r9   r:   _get_ip   s.    
    *r\   8.8.8.8P   c                 C  s   t | |tjdS )z
    Get the local IP address through which the *host* is reachable.

    *host* defaults to a well-known Internet host (one of Google's public
    DNS servers).
    rX   )r\   rJ   AF_INETrV   rW   r9   r9   r:   get_ip   s    rb   2001:4860:4860::8888c                 C  s   t | |tjdS )z-
    The same as get_ip(), but for IPv6.
    r_   )r\   rJ   AF_INET6ra   r9   r9   r:   get_ipv6   s    re   c                 C  sd   t  }| |kr,t| }td| |||  D ]}|jtjkr4|j	  S q4td| ddS )z
    Get the local IPv4 address of a network interface.

    KeyError is raised if the interface doesn't exist.
    ValueError is raised if the interface does no have an IPv4 address
    associated with it.
    zG{!r} is not a valid network interface. Valid network interfaces are: {}z
interface z doesn't have an IPv4 addressN)
psutilnet_if_addrslistkeys
ValueErrorformatrX   rJ   r`   address)Zifnamerg   Zallowed_ifnamesinfor9   r9   r:   get_ip_interface   s     rn   r9   c                   s|   t jttj|  dd | D } sxz I dH }W n0 tk
rj   t j fdd}|   Y nX ||j	< q |S )a!  Wait on many tasks at the same time

    Err once any of the tasks err.

    See https://github.com/tornadoweb/tornado/issues/1546

    Parameters
    ----------
    args: futures to wait for
    quiet_exceptions: tuple, Exception
        Exception types to avoid logging if they fail
    c                 S  s   g | ]}d qS Nr9   .0r8   r9   r9   r:   
<listcomp>   s     zAll.<locals>.<listcomp>Nc               	   3  s4   t jD ]$} z
| V  W q
  k
r,   Y q
X q
dS zWatch unfinished tasks

                Otherwise if they err they get logged in a way that is hard to
                control.  They need some other task to watch them so that they
                are not orphaned
                Nrh   Z_unfinishedZtaskquiet_exceptionsZtasksr9   r:   quiet   s
    
zAll.<locals>.quiet
r   ZWaitIteratormapasyncioensure_futuredonenext	Exception	coroutineZcurrent_indexr?   rw   resultsresultrx   r9   rv   r:   All   s    r   c                   s~   t jttj|  dd | D } szz I dH }W n0 tk
rj   t j fdd}|   Y nX ||j	< qzq |S )a  Wait on many tasks at the same time and return when any is finished

    Err once any of the tasks err.

    Parameters
    ----------
    args: futures to wait for
    quiet_exceptions: tuple, Exception
        Exception types to avoid logging if they fail
    c                 S  s   g | ]}d qS ro   r9   rp   r9   r9   r:   rr     s     zAny.<locals>.<listcomp>Nc               	   3  s4   t jD ]$} z
| V  W q
  k
r,   Y q
X q
dS rs   rt   ru   rv   r9   r:   rx     s
    
zAny.<locals>.quietry   r   r9   rv   r:   r     s    
r   c                   @  s   e Zd ZdZdd ZdS )NoOpAwaitablezAn awaitable object that always returns None.

    Useful to return from a method that can be called in both asynchronous and
    synchronous contextsc                 C  s   dd }|   S )Nc                     s   d S ro   r9   r9   r9   r9   r:   f2  s    z"NoOpAwaitable.__await__.<locals>.f)	__await__)selfr   r9   r9   r:   r   1  s    zNoOpAwaitable.__await__N)__name__
__module____qualname____doc__r   r9   r9   r9   r:   r   +  s   r   c                   @  s,   e Zd ZdZedd ZdddddZdS )SyncMethodMixina$  
    A mixin for adding an `asynchronous` attribute and `sync` method to a class.

    Subclasses must define a `loop` attribute for an associated
    `tornado.IOLoop`, and may also add a `_asynchronous` attribute indicating
    whether the class should default to asynchronous behavior.
    c                 C  s   t | jt| dddS )z!Are we running in the event loop?_asynchronousF)default)in_async_callloopgetattrr   r9   r9   r:   asynchronousA  s    zSyncMethodMixin.asynchronousN)r   callback_timeoutc                O  s\   t |}|dkr| j}|r<|||}|dk	r8t||}|S t| j|f|d|i|S dS )z`Call `func` with `args` synchronously or asynchronously depending on
        the calling contextNr   )_parse_timedeltar   r{   wait_forsyncr   )r   rD   r   r   r?   kwargsfuturer9   r9   r:   r   F  s$    
 zSyncMethodMixin.sync)r   r   r   r   propertyr   r   r9   r9   r9   r:   r   8  s   
r   c                 C  s>   z| j t kW S  tk
r8   | j  s2| Y S Y dS X dS )z3Whether this call is currently within an async callFN)asyncio_loopr{   get_running_loopRuntimeError
is_running)r   r   r9   r9   r:   r   W  s    
r   )r   c          
   
     s   t dj rtdt t 	d 
 tj 	
f	dd}fddfdd	}	| dk	r|st
d
 dn s|d qrΈ\}}}	||	n
S dS )z;
    Run coroutine in loop running in separate thread.
    szIOLoop is closedNc                   3  s   zpzNt krtdtjV   d k	r>ttV W n t	k
rl   t
 Y nX W 5    X d S )Nz)sync() called from thread of running loop)r>   	threading	get_identr   r   Zmomentr{   r   r|   r   sysexc_infor9   )	r?   r   r[   errorrD   r   r   main_tidr   r9   r:   r   o  s    


zsync.<locals>.fc                     s    d k	r    d S ro   )cancelr9   )r   r9   r:   r     s    zsync.<locals>.cancelc                   s2   z | W S  tk
r,      Y nX d S ro   )waitKeyboardInterruptadd_callbacktimeout)r   r[   r   r9   r:   r     s
    
zsync.<locals>.waitztimed out after z s.
   )r   r   Z	is_closedr   r   Eventr   r   r   r   r   is_setwith_traceback)
r   rD   r   r?   r   r   r   typexctbr9   )r?   r   r   r[   r   rD   r   r   r   r   r   r:   r   c  s(    




r   c                   @  sz   e Zd ZU dZe Zded< e	 Z
dddZdd	 Zd
d ZdddZdd Zdd Zdd Zdd Zedd ZdS )
LoopRunnerag  
    A helper to start and stop an IO loop in a controlled way.
    Several loop runners can associate safely to the same IO loop.

    Parameters
    ----------
    loop: IOLoop (optional)
        If given, this loop will be re-used, otherwise an appropriate one
        will be looked up or created.
    asynchronous: boolean (optional, default False)
        If false (the default), the loop is meant to run in a separate
        thread and will be started if necessary.
        If true, the loop is meant to run in the thread this
        object is instantiated from, and will not be started automatically.
    zJClassVar[weakref.WeakKeyDictionary[IOLoop, tuple[int, LoopRunner | None]]]
_all_loopsNFc              	   C  s   |d krT|rJzt   W n$ tk
r<   tjdtdd Y nX t | _qtt | _n |j	
 sntjdtdd || _|| _d | _d| _| j | j| jd W 5 Q R X d S )NzQConstructing a LoopRunner(asynchronous=True) without a running loop is deprecated   
stacklevelzGConstructing LoopRunner(loop=loop) without a running loop is deprecatedF)r   N)r{   r   r   rP   rQ   DeprecationWarningr   current_loopr   r   r   _loop_thread_started_lockr   
setdefault)r   r   r   r9   r9   r:   __init__  s0    

zLoopRunner.__init__c              	   C  s   | j  |   W 5 Q R X dS )z
        Start the IO loop if required.  The loop is run in a dedicated
        thread.

        If the loop is already running, this method does nothing.
        N)r   _start_unlockedr   r9   r9   r:   start  s    zLoopRunner.startc                   s  | j r
t| j| j \}}| js0|d k	s0|dkrN|d |f| j| j< d| _ d S | jd ks\t|dkshtt t  d gd gfdd| jf fdd	}tj|dd	}d|_	|
  jd
d d| _ d }||k	rP d d d k	r:td ts:td ts2tdd d |d d f| j| j< n0d d ksft|| _|d | f| j| j< d S )Nr      Tc                     s   t   d<   d S Nr   )r   current_threadr>   r9   )	in_threadloop_evtr9   r:   loop_cb  s    z+LoopRunner._start_unlocked.<locals>.loop_cbc              
     s`   |   zFz| j s |   W n* tk
rL } z|d< W 5 d }~X Y nX W 5    X d S r   )r   r>   r   r   r   r   )r   r[   )done_evtr   	start_excr9   r:   run_loop  s    

z,LoopRunner._start_unlocked.<locals>.run_loopzIO loop)targetnamer   r      znot an exception: )r   AssertionErrorr   r   r   r   r   r   Threaddaemonr   r   
isinstancer   r   rA   )r   countreal_runnerr   threadZactual_threadr9   )r   r   r   r   r   r:   r     sF    


 zLoopRunner._start_unlockedr   c              	   C  s    | j  | | W 5 Q R X dS )zv
        Stop and close the loop if it was created by us.
        Otherwise, just mark this object "stopped".
        N)r   _stop_unlockedr   r   r9   r9   r:   stop  s    zLoopRunner.stopc                 C  sj   | j s
d S d| _ | j| j \}}|dkr>|d |f| j| j< n(|dksJt| j| j= |d k	rf|| d S )NFr   )r   r   r   r   
_real_stop)r   r   r   r   r9   r9   r:   r     s    
zLoopRunner._stop_unlockedc              	   C  sf   | j d k	st| j d k	rbz@| j| jj | j j|d tt | j  W 5 Q R X W 5 d | _ X d S )Nr   )	r   r   r   r   r   joinr   KeyErrorrL   r   r9   r9   r:   r   )  s    

zLoopRunner._real_stopc                 C  s   | j S )zP
        Return True between start() and stop() calls, False otherwise.
        )r   r   r9   r9   r:   
is_started4  s    zLoopRunner.is_startedc                 O  sJ   | j rt| j|f||S |   zt| j|f||W S |   X dS )z
        Convenience helper: start the loop if needed,
        run sync(func, *args, **kwargs), then stop the loop again.
        N)r   r   r   r   r   )r   rD   r?   r   r9   r9   r:   run_sync:  s    zLoopRunner.run_syncc                 C  s&   | j }|j s tjdtdd | j S )NzGAccessing the loop property while the loop is not running is deprecatedr   r   )r   r   r   rP   rQ   r   )r   r   r9   r9   r:   r   H  s    
zLoopRunner.loop)NF)r   )r   r   r   r   weakrefWeakKeyDictionaryr   __annotations__r   Lockr   r   r   r   r   r   r   r   r   r   r   r9   r9   r9   r:   r     s   



9
r   c                  k  s   i }| D ],}zt t|||< W q tk
r2   Y qX q|  D ]\}}tt|| q>z
d V  W 5 | D ]<}z|| }W n tk
r   tt| Y qdX tt|| qdX d S ro   )r   r%   rC   itemssetattrr   delattr)r   oldkvr9   r9   r:   set_thread_stateT  s     
r   c              	   c  sZ   t jt | }t|d}|| W 5 Q R X z
|V  W 5 t j|rTt | X d S )Nw)	ospathr   tempfile
gettempdiropenwriteexistsremove)filenametextfnr   r9   r9   r:   tmp_textj  s    
r   c                  C  s,   dt jkrdS ddlm}  t|  dddk	S )zWDetermine if we're running within an IPython kernel

    >>> is_kernel()
    False
    IPythonFr   get_ipythonkernelN)r   modulesr   r   r   r   r9   r9   r:   	is_kernelw  s    
r   objectstr)xreturnc                 C  s   t | tr| d S t | tr| d dkr>| ddd dS t| dkrZtd| rZdS | d d	kr| d
 d dd S t| S nt | t	rt
|  S dS dS )av  A more fine-grained version of key_split.

    >>> key_split_group(('x-2', 1))
    'x-2'
    >>> key_split_group("('x-2', 1)")
    'x-2'
    >>> key_split_group('ae05086432ca935f6eba409a8ecd4896')
    'data'
    >>> key_split_group('<module.submodule.myclass object at 0xdaf372')
    'myclass'
    >>> key_split_group('x')
    'x'
    >>> key_split_group('x-1')
    'x'
    r   (,r   z()"'    z[a-f0-9]{32}data<z<>.ZOtherN)r   tupler   splitstriplenrematchr    byteskey_split_groupdecode)r   r9   r9   r:   r    s    



r  Callable[P, T]rD   r   c                C  s   d S ro   r9   )rD   r9   r9   r:   
log_errors  s    r  r   pdbunroll_stackboolint
_LogErrors)r  r  r   c                 C  s   d S ro   r9   r  r9   r9   r:   r    s    c               C  s   t ||d}| r|| S |S )a  Log any errors and then reraise them.

    This can be used:

    - As a context manager::

        with log_errors(...):
            ...

    - As a bare function decorator::

        @log_errors
        def func(...):
            ...

    - As a function decorator with parameters::

        @log_errors(...)
        def func(...):
            ...

    Parameters
    ----------
    pdb: bool, optional
        Set to True to break into the debugger in case of exception
    unroll_stack: int, optional
        Number of levels of stack to unroll when determining the module's name for the
        purpose of logging. Normally you should omit this. Set to 2 if you are writing a
        helper function, context manager, or decorator.
    r  )r  )rD   r  r  ler9   r9   r:   r    s    c                   @  sR   e Zd ZU dZded< ded< dddddZddd	d
dZdd Zdd ZdS )r  r  r  r  r  r  c                 C  s   || _ || _d S ro   r  )r   r  r  r9   r9   r:   r     s    z_LogErrors.__init__r  r  c                  sB    j d7  _ t r( fdd}n fdd}t |S )Nr   c               
     s,     | |I d H W  5 Q R  S Q R X d S ro   r9   r?   r   rD   r   r9   r:   wrapper  s    z$_LogErrors.__call__.<locals>.wrapperc               
     s&     | |W  5 Q R  S Q R X d S ro   r9   r  r  r9   r:   r    s    )r  r<   iscoroutinefunctionr   )r   rD   r  r9   r  r:   __call__  s
    
z_LogErrors.__call__c                 C  s   | S ro   r9   r   r9   r9   r:   	__enter__  s    z_LogErrors.__enter__c                 C  s   ddl m} |r t||tjfr$d S t }|| j }t|d }|j	}zt
|}	|	| W n tk
rv   Y nX | jrdd l}
|
  d S )Nr   )CommClosedError)Zdistributed.commr   
issubclassr   ZReturnr<   stackr  	getmoduler   logging	getLogger	exceptionr   r  	set_trace)r   exc_type	exc_value	tracebackr   r"  framemodmodnameloggerr  r9   r9   r:   __exit__  s    

z_LogErrors.__exit__N)	r   r   r   	__slots__r   r   r  r  r/  r9   r9   r9   r:   r    s   
r)   c                 C  sR   t | trtt|  } d}t|}|jD ] }t |tjr,|j}|	|  q,|S )zK
    Change all StreamHandlers for the given logger to the given level
    N)
r   r   r   r$  upperr%  handlersStreamHandlerlevelsetLevel)r4  rootr   r.  handlerr9   r9   r:   silence_logging	  s    


r8  c                 C  sz   | sd} t jt jg}|D ]X}zt | d|t j}W n( t jk
rZ } z|}W 5 d}~X Y qX |d d d   S q|dS )a%  Ensure that address is an IP address

    Examples
    --------
    >>> ensure_ip('localhost')
    '127.0.0.1'
    >>> ensure_ip('')  # Maps as localhost for binding e.g. 'tcp://:8811'
    '127.0.0.1'
    >>> ensure_ip('123.123.123.123')  # pass through IP addresses
    '123.123.123.123'
    	localhosti  Nr   rI   )rJ   r`   rd   rS   SOCK_STREAMgaierror)hostnameZfamiliesZfamr   r[   r   r9   r9   r:   	ensure_ip  s       r=  c                    sh   t  \} } tjddtjddtjddtjddg} rdt fdd	|D rd j qB S )
Nr)   ZworkerZ	schedulertornadozgen.pyZ
concurrentZfuturesc                 3  s   | ]}| j jjkV  qd S ro   )tb_framef_codeco_filename)rq   bexc_tracebackr9   r:   	<genexpr>D  s    z get_traceback.<locals>.<genexpr>)r   r   r   r   r   anytb_next)r(  r)  badr9   rC  r:   get_traceback<  s    rI  '  c              	   C  sh   t t| |kr`zt| dt| d| W S  tk
r\   tdt| t| d|  Y S X n| S dS )z/Truncate exception to be about a certain lengthzLong error messageN)r
  r   typer   )r[   nr9   r9   r:   truncate_exceptionK  s    $rM  c                 C  s2   t | }|tk	r.|tk	r.td| d| ddS )z'Validate a key as received on a stream.zUnexpected key type z	 (value: )N)rK  r   r  rA   )r   r   r9   r9   r:   validate_keyV  s    rO  c                 C  s@   t | p>t| tkr"ttt| p>t| tko>ttt|  S )zPossibly contains a nested task)r   rK  rh   rF  rz   _maybe_complexdictvaluesru   r9   r9   r:   rP  ]  s    rP  c                 C  s   |   dkrdS d}| |}|s&dS || }z2||}| |   t||  t|  W dS  tk
rt   Y nX |t| d }qdS )a  Seek current file to next byte after a delimiter bytestring

    This seeks the file to the next byte following the delimiter.  It does
    not return anything.  Use ``file.tell()`` to see location afterwards.

    Parameters
    ----------
    file: a file
    delimiter: bytes
        a delimiter like ``b'
'`` or message sentinel
    blocksize: int
        Number of bytes to read from the file at once.
    r   N    )tellreadindexseekr
  rj   )file	delimiter	blocksizelastr   fullir9   r9   r:   seek_delimiterh  s    

"r^  c                 C  st   |r\|  | t| |d |  }||| 8 }|  ||  t| |d |  }|}|| }|  | | |}|S )a$  Read a block of bytes from a file

    Parameters
    ----------
    f: file
        File-like object supporting seek, read, tell, etc..
    offset: int
        Byte offset to start read
    length: int
        Number of bytes to read
    delimiter: bytes (optional)
        Ensure reading starts and stops at delimiter bytestring

    If using the ``delimiter=`` keyword argument we ensure that the read
    starts and stops at delimiter boundaries that follow the locations
    ``offset`` and ``offset + length``.  If ``offset`` is zero then we
    start at zero.  The bytestring returned WILL include the
    terminating delimiter string.

    Examples
    --------

    >>> from io import BytesIO  # doctest: +SKIP
    >>> f = BytesIO(b'Alice, 100\nBob, 200\nCharlie, 300')  # doctest: +SKIP
    >>> read_block(f, 0, 13)  # doctest: +SKIP
    b'Alice, 100\nBo'

    >>> read_block(f, 0, 13, delimiter=b'\n')  # doctest: +SKIP
    b'Alice, 100\nBob, 200\n'

    >>> read_block(f, 10, 10, delimiter=b'\n')  # doctest: +SKIP
    b'Bob, 200\nCharlie, 300'
    i   )rW  r^  rT  rU  )r   offsetlengthrY  r   endr  r9   r9   r:   
read_block  s    "


rb  c                 C  s   t jdtdd t| S )a  Attempt to turn `s` into bytes.

    Parameters
    ----------
    s : Any
        The object to be converted. Will correctly handled

        * str
        * bytes
        * objects implementing the buffer protocol (memoryview, ndarray, etc.)

    Returns
    -------
    b : bytes

    Raises
    ------
    TypeError
        When `s` cannot be converted

    Examples
    --------
    >>> ensure_bytes('123')
    b'123'
    >>> ensure_bytes(b'123')
    b'123'
    z`distributed.utils.ensure_bytes` is deprecated. Please switch to `dask.utils.ensure_bytes`. This will be removed in `2022.6.0`.r   r   )rP   rQ   r   _ensure_bytes)r   r9   r9   r:   r     s    r   z-bytes | bytearray | memoryview | PickleBuffer
memoryview)objr   c                 C  s\   t | tst| } | js"tt S | js4tt| S | jdksH| jdkrTt|  S | S dS )z5Ensure `obj` is a 1-D contiguous `uint8` `memoryview`r   BN)	r   rd  nbytes	bytearray
contiguousndimrk   r   raw)re  r9   r9   r:   ensure_memoryview  s    

rl   )rV   r   c              
   C  sP   t  t jt j6}|| df |d | d }|W  5 Q R  S Q R X dS )zReturn a probably-open port

    There is a chance that this port will be taken by the operating system soon
    after returning from this function.
    r   r   N)rJ   r`   r:  bindlistenrN   )rV   r   rW   r9   r9   r:   	open_port  s
    
rp  zlist[ModuleType])r   r   c           
   	   C  s:  t j| \}}t j|\}}g }d}|dkrH|tjkr>|}|| |dkrvt| }tt t 	| W 5 Q R X |dkr| tjkrtj
d|  dd t| gD }|| g }	|std| njt  |dk	rtj
d| z2|D ](}td	|| |	tt| qW 5 |dk	r4tj	| X |	S )
z*Loads modules for a file (.py, .zip, .egg)N).pyrq  )z.eggz.zipz.pyzr   c                 s  s   | ]}|j V  qd S ro   )r   )rq   Zmod_infor9   r9   r:   rE    s     zimport_file.<locals>.<genexpr>zFound nothing to import from %szReload module %s from %s file)r   r   r  splitextr   r4   r   r   rO   r   insertpkgutiliter_modulesextendr.  warningr1   invalidate_cachesrm   reloadr2   )
r   	directoryr   r   extZnames_to_importZtmp_python_pathZ
cache_filenamesZloadedr9   r9   r:   import_file  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 ro   r   rq   r]  r9   r9   r:   rE  7  s     z(asciitable.<locals>.<listcomp>.<genexpr>)r  rq   rr9   r9   r:   rr   7  s     zasciitable.<locals>.<listcomp>c                 s  s   | ]}t |V  qd S ro   r~  r  r9   r9   r:   rE  8  s     zasciitable.<locals>.<genexpr>c                 s  s*   | ]"\}}t t tt|t|V  qd S ro   )maxrz   r
  )rq   r   cr9   r9   r:   rE  9  s     |z	 %%-%ds |z+%s++c                 s  s   | ]}d |d  V  qdS )-r   Nr9   )rq   r   r9   r9   r:   rE  <  s     
c                 3  s   | ]} | V  qd S ro   r9   r  Zrow_templater9   r:   rE  =  s     )r  zipr
  r   )columnsZrowsZwidthsheaderbarr  r9   r  r:   
asciitable,  s    r  c                 C  s<   t | |rt| S z| jW S  tk
r6   t|  Y S X dS )z(Number of bytes of a frame or memoryviewN)r   r
  rg  rC   )r+  Z_bytes_liker9   r9   r:   rg  A  s    
rg  c              	   C  s   t |}|jr|jrptj| rfz*t| }||}W 5 Q R X |rJ|W S W n tt	fk
rd   Y nX t
d q
td| ddS )z@Reads a JSON file from disk that may be being written as we readg?zCould not load file after zs.N)Deadlineafterexpires	remainingr   r   r   r   rj   r   r   r   )r   loadr   deadliner   cfgr9   r9   r:   json_load_robustL  s    



r  c                      sT   e Zd ZU dZe Zded< dd fdd
Zdd	 Z	d
d Z
edd Z  ZS )DequeHandlerz3A logging.Handler that records records into a dequez'ClassVar[weakref.WeakSet[DequeHandler]]
_instancesrJ  )rL  c                  s*   t |d| _ t j|| | j|  d S )N)maxlen)r   superr   r  add)r   rL  r?   r   	__class__r9   r:   r   b  s    zDequeHandler.__init__c                 C  s   | j | d S ro   )r   r4   )r   recordr9   r9   r:   emitg  s    zDequeHandler.emitc                 C  s   | j   dS )z)
        Clear internal storage.
        N)r   clearr   r9   r9   r:   r  j  s    zDequeHandler.clearc                 C  s   t | jD ]}|  q
dS )zG
        Clear the internal storage of all live DequeHandlers.
        N)rh   r  r  )clsinstr9   r9   r:   clear_all_instancesp  s    z DequeHandler.clear_all_instances)r   r   r   r   r   WeakSetr  r   r   r  r  classmethodr  __classcell__r9   r9   r  r:   r  ]  s   
r  c                  C  s2   t jjj D ]} t | jD ]}|  qqdS )znPython 2's logger's locks don't survive a fork event

    https://github.com/dask/distributed/issues/1491
    N)r$  Loggermanager
loggerDictri   r%  r2  
createLock)r   r7  r9   r9   r:   reset_logger_locksy  s    r  i  c                 C  s   |t | jkS ro   )r<   	signature
parameters)rD   keywordr9   r9   r:   has_keyword  s    r  c                 C  s   | d k	rt | trLzddlm} || } W n  tk
rJ   td|  Y nX t | jtjjrb| j} t | tjjrdd | j	D }||kS dS )Nr   )r2   z&Module for command %s is not availablec                 S  s    h | ]}t |tjjr|jqS r9   )r   clickcoreOptionZhuman_readable_namerq   pr9   r9   r:   	<setcomp>  s   z&command_has_keyword.<locals>.<setcomp>F)
r   r   r1   r2   r3   mainr  r  Commandparams)cmdr   r2   Z
cmd_paramsr9   r9   r:   command_has_keyword  s    
r  z#440154z#471669z#472A79z#433C84z#3C4D8Az#355D8Cz#2E6C8Ez#287A8Ez#23898Dz#1E978Az#20A585z#2EB27Cz#45BF6Fz#64CB5Dz#88D547z#AFDC2Ez#D7E219z#FDE724c                 C  s6   t t|  }t| d d d}||t|  S )N      )r   r   encoder  	hexdigestr
  )r   palettehrL  r9   r9   r:   color_of  s    r  c                 C  s   t | pt| S ro   )r<   r  r   is_coroutine_function)r   r9   r9   r:   r    s    r  zstr | float | timedeltazIterator[None])durationmsgr   c                 c  s@   t  }dV  t  }|| }|t| kr<tj|j|ddd dS )zGenerate a UserWarning if the operation in this context takes longer than
    *duration* and print *msg*

    The message may include a format string `{duration}` which will be formatted
    to include the actual duration it took
    N)r  r   r   )r$   r   rP   rQ   rk   )r  r  r   r   Zdiffr9   r9   r:   warn_on_duration  s    r  c              
   C  sB   t jd}t jdrd}nd}|jf ttjt|| |dS )Nzdistributed.dashboard.linkz(distributed.scheduler.dashboard.tls.certhttpshttp)schemerV   rW   )	r,   r-   r.   rk   toolzmerger   environrQ  )rV   rW   templater  r9   r9   r:   format_dashboard_link  s    r  z"int | str | Collection[int] | Nonezlist[int] | list[None])rW   r   c                 C  s   t | trTd| krTtt| d\}}||krBtd|d|tt||d S t | trht| gS t | tsz| dkr| gS t | trt	dd | D st
| t| S t
| dS )a  Parse input port information into list of ports

    Parameters
    ----------
    port : int, str, list[int], None
        Input port or ports. Can be an integer like 8787, a string for a
        single port like "8787", string for a sequential range of ports like
        "8000:8200", a collection of ints, or None.

    Returns
    -------
    ports : list
        List of ports

    Examples
    --------
    A single port can be specified using an integer:

    >>> parse_ports(8787)
    [8787]

    or a string:

    >>> parse_ports("8787")
    [8787]

    A sequential range of ports can be specified by a string which indicates
    the first and last ports which should be included in the sequence of ports:

    >>> parse_ports("8787:8790")
    [8787, 8788, 8789, 8790]

    An input of ``None`` is also valid and can be used to indicate that no port
    has been specified:

    >>> parse_ports(None)
    [None]

    :zzWhen specifying a range of ports like port_start:port_stop, port_stop must be greater than port_start, but got port_start=z and port_stop=r   Nc                 s  s   | ]}t |tV  qd S ro   )r   r  r  r9   r9   r:   rE    s     zparse_ports.<locals>.<genexpr>)r   r   rz   r  r  rj   rh   ranger   allrA   )rW   Z
port_startZ	port_stopr9   r9   r:   parse_ports  s     (


r  c                   @  s   e Zd ZdZdd ZdS )Logz7A container for newline-delimited string of log entriesc                 C  s   t dj| dS )Nzlog.html.j2)logr"   renderr   r9   r9   r:   _repr_html_$  s    zLog._repr_html_Nr   r   r   r   r  r9   r9   r9   r:   r  !  s   r  c                   @  s   e Zd ZdZdd ZdS )Logsz>A container for a dict mapping names to strings of log entriesc                 C  s   t dj| dS )Nzlogs.html.j2)Zlogsr  r   r9   r9   r:   r  +  s    zLogs._repr_html_Nr  r9   r9   r9   r:   r  (  s   r  zdict[str, AnyType]zCallable | Nonezstr | ModuleType | Nonez	list[str])dr  r  r   c                   s   ddl m} |s|r| D ]r}t||st||s|rT|rTtd|||||f q|rrtd|| d| qtd|| d| qdd  t fd	d
|  D g S )a  Convert a kwargs dictionary into a list of CLI keywords

    Parameters
    ----------
    d : dict
        The keywords to convert
    cls : callable
        The callable that consumes these terms to check them for validity
    cmd : string or object
        A string with the name of a module, or the module containing a
        click-generated command with a "main" function, or the function itself.
        It may be used to parse a module's custom arguments (that is, arguments that
        are not part of Worker class), such as nworkers from dask worker CLI or
        enable_nvlink from dask-cuda-worker CLI.

    Examples
    --------
    >>> cli_keywords({"x": 123, "save_file": "foo.txt"})
    ['--x', '123', '--save-file', 'foo.txt']

    >>> from dask.distributed import Worker
    >>> cli_keywords({"x": 123}, Worker)
    Traceback (most recent call last):
    ...
    ValueError: Class distributed.worker.Worker does not support keyword x
    r   )typenamez0Neither class %s or module %s support keyword %szClass z does not support keyword zModule c                 S  s0   t | }d|kr,d|kr,d|kr,d| d }|S )N '"r~  )r   outr9   r9   r:   convert_valuea  s    z#cli_keywords.<locals>.convert_valuec                 3  s*   | ]"\}}d | dd  |gV  qdS )z--r8   r  N)replacerq   r   r   r  r9   r:   rE  h  s     zcli_keywords.<locals>.<genexpr>)
dask.utilsr  r  r  rj   sumr   )r  r  r  r  r   r9   r  r:   cli_keywords/  s,     r  c                 C  s   t jj| d k	S ro   )xmletreeElementTree
fromstring)r   r9   r9   r:   is_valid_xmll  s    r  zDask-Offload)max_workersZthread_name_prefixAnyType)r   r   c                 C  sH   z|  dd\}}W n tk
r2   t|  Y S X t|}t||S )zReturn the fully qualified term

    Examples
    --------
    >>> import_term("math.sin") # doctest: +SKIP
    <function math.sin(x, /)>
    r  r   )rsplitrj   r1   r2   r   )r   module_name	attr_namemoduler9   r9   r:   import_termt  s    
r  c                   s0   t  }t |t fddI d H S )Nc                     s   j f S ro   )runr9   r?   contextr   r   r9   r:   <lambda>  rS  zoffload.<locals>.<lambda>)r{   r   contextvarsZcopy_contextZrun_in_executor_offload_executor)r   r?   r   r   r9   r  r:   offload  s     r  c                   @  s,   e Zd Zdd Zdd Zdd Zdd Zd	S )
EmptyContextc                 C  s   d S ro   r9   r   r9   r9   r:   r    s    zEmptyContext.__enter__c                 C  s   d S ro   r9   r   r(  r)  r*  r9   r9   r:   r/    s    zEmptyContext.__exit__c                   s   d S ro   r9   r   r9   r9   r:   
__aenter__  s    zEmptyContext.__aenter__c                   s   d S ro   r9   r  r9   r9   r:   	__aexit__  s    zEmptyContext.__aexit__N)r   r   r   r  r/  r  r  r9   r9   r9   r:   r    s   r  z
list[dict])addrsdefault_listen_ipr   c              
   C  s   |dkrd}t | tr | d} t | ts0| g} g }| D ]}zt|}W n ttfk
r`   Y nX t |trv|d}t |ttfrt|dkr|d t|d  }}qt|dkr|d \}}qt|nt |tr|}|}|	||d q8|S )	a  
    Examples
    --------
    >>> clean_dashboard_address(8787)
    [{'address': '', 'port': 8787}]
    >>> clean_dashboard_address(":8787")
    [{'address': '', 'port': 8787}]
    >>> clean_dashboard_address("8787")
    [{'address': '', 'port': 8787}]
    >>> clean_dashboard_address("8787")
    [{'address': '', 'port': 8787}]
    >>> clean_dashboard_address("foo:8787")
    [{'address': 'foo', 'port': 8787}]
    >>> clean_dashboard_address([8787, 8887])
    [{'address': '', 'port': 8787}, {'address': '', 'port': 8887}]
    >>> clean_dashboard_address(":8787,:8887")
    [{'address': '', 'port': 8787}, {'address': '', 'port': 8887}]
    z0.0.0.0rm  r  r  r   r   r   )rl   rW   )
r   r   r  rh   r  rA   rj   r  r
  r4   )r  r  	addressesaddrrV   rW   r9   r9   r:   clean_dashboard_address  s2    






r   zdask.config.deserializezdask.config.serializezdask.utils.format_byteszdask.utils.format_timezdask.utils.funcnamezdask.utils.parse_byteszdask.utils.parse_timedeltazdask.utils.typenamezdask.utils.tmpfile)	Zdeserialize_for_cliZserialize_for_cliZformat_bytesZformat_timefuncnameZparse_bytesr!   r  Ztmpfilec                 C  sL   | t kr4t |  }tj|  d| dtdd t|S tdt d|  d S )NzC is deprecated and will be removed in a future release. Please use z	 instead.r   )categoryr   zmodule z has no attribute )_deprecationsrP   rQ   FutureWarningr  rC   r   )r   Zuse_insteadr9   r9   r:   __getattr__  s    r  _recursive_to_dict_seenzContextVar[set[int]])excludememberszContainer[str])re  r  r  r   c             	     s  t | ttttfs| dkr| S t | ttfr4t| S |rP fddt	| D } zt
 }W n tk
rv   t }Y nX | }t
|}z>t| |krt| W &S t| drtrt| W 
S |t|  daz| j dW W S daX |t|  t| dr| j dW S t | tttttttfrL fd	d
| D W S t | tri }|  D ]R\}}t| d}t| d}z|||< W n" t k
r   ||t|< Y nX qd|W S t| W S |j| X dS )a  Recursively convert arbitrary Python objects to a JSON-serializable
    representation. This is intended for debugging purposes only.

    The following objects are supported:

    list, tuple, set, frozenset, deque, dict, dict_keys, dict_values
        Descended into these objects recursively. Python-specific collections are
        converted to JSON-friendly variants.
    Classes that define ``_to_dict(self, *, exclude: Container[str] = ())``:
        Call the method and dump its output
    Classes that define ``_to_dict_no_nest(self, *, exclude: Container[str] = ())``:
        Like above, but prevents nested calls (see below)
    Other Python objects
        Dump the output of ``repr()``
    Objects already encountered before, regardless of type
        Dump the output of ``repr()``. This breaks circular references and shortens the
        output.

    Parameters
    ----------
    exclude:
        A list of attribute names to be excluded from the dump.
        This will be forwarded to the objects ``_to_dict`` methods and these methods
        are required to accept this parameter.
    members:
        If True, convert the top-level Python object to a dict of its public members

    **``_to_dict_no_nest`` vs. ``_to_dict``**

    The presence of the ``_to_dict_no_nest`` method signals ``recursive_to_dict`` to
    have a mutually exclusive full dict representation with other objects that also have
    the ``_to_dict_no_nest``, regardless of their class. Only the outermost object in a
    nested structure has the method invoked; all others are
    dumped as their string repr instead, even if they were not encountered before.

    Example:

    .. code-block:: python

        >>> class Person:
        ...     def __init__(self, name):
        ...         self.name = name
        ...         self.children = []
        ...         self.pets = []
        ...
        ...     def _to_dict_no_nest(self, exclude=()):
        ...         return recursive_to_dict(self.__dict__, exclude=exclude)
        ...
        ...     def __repr__(self):
        ...         return self.name

        >>> class Pet:
        ...     def __init__(self, name):
        ...         self.name = name
        ...         self.owners = []
        ...
        ...     def _to_dict_no_nest(self, exclude=()):
        ...         return recursive_to_dict(self.__dict__, exclude=exclude)
        ...
        ...     def __repr__(self):
        ...         return self.name

        >>> alice = Person("Alice")
        >>> bob = Person("Bob")
        >>> charlie = Pet("Charlie")
        >>> alice.children.append(bob)
        >>> alice.pets.append(charlie)
        >>> bob.pets.append(charlie)
        >>> charlie.owners[:] = [alice, bob]
        >>> recursive_to_dict({"people": [alice, bob], "pets": [charlie]})
        {
            "people": [
                {"name": "Alice", "children": ["Bob"], "pets": ["Charlie"]},
                {"name": "Bob", "children": [], "pets": ["Charlie"]},
            ],
            "pets": [
                {"name": "Charlie", "owners": ["Alice", "Bob"]},
            ],
        }

    If we changed the methods to ``_to_dict``, the output would instead be:

    .. code-block:: python

        {
            "people": [
                {
                    "name": "Alice",
                    "children": [
                        {
                            "name": "Bob",
                            "children": [],
                            "pets": [{"name": "Charlie", "owners": ["Alice", "Bob"]}],
                        },
                    ],
                    pets: ["Charlie"],
                ],
                "Bob",
            ],
            "pets": ["Charlie"],
        }

    Also notice that, if in the future someone will swap the creation of the
    ``children`` and ``pets`` attributes inside ``Person.__init__``, the output with
    ``_to_dict`` will change completely whereas the one with ``_to_dict_no_nest`` won't!
    Nc                   s0   i | ](\}}| d s| krt|s||qS )r8   )
startswithcallabler  r  r9   r:   
<dictcomp>j  s   
   z%recursive_to_dict.<locals>.<dictcomp>_to_dict_no_nestTFr  _to_dictc                   s   g | ]}t | d qS )r  )recursive_to_dict)rq   elr  r9   r:   rr     s     z%recursive_to_dict.<locals>.<listcomp>)!r   r  floatr  r   rK  r  reprr<   
getmembersr  r.   LookupErrorr>   copyvarresetidhasattr_to_dict_no_nest_flagr  r  r  rh   r  	frozensetr   r   r	   rQ  r   r  rA   )re  r  r  seentokresr   r   r9   r  r:   r    sT    m


r  r   c                  C  s   ddl m}  | S )zIs the interpreter shutting down now?

    This is a variant of ``sys.is_finalizing`` which can return True inside the ``__del__``
    method of classes defined inside the distributed package.
    r   _python_shutting_down)r)   r!  r   r9   r9   r:   is_python_shutting_down  s    r"  c                   @  s   e Zd ZU dZded< ded< ddddd	Zeddd d
ddZeddddZ	eddddZ
eddddZeddddZeddddZdS )r  z<Utility class tracking a deadline and the progress toward itzfloat | None
expires_atr  
started_atNr#  c                 C  s   || _ t | _d S ro   )r#  r$   r$  )r   r#  r9   r9   r:   r     s    zDeadline.__init__)r  r   c                 C  s,   t  }|dk	r|| n|}| |}||_|S )zgCreate a new ``Deadline`` that expires in ``duration`` seconds
        or never if ``duration`` is NoneNr$   r$  )r  r  r$  r#  r  r9   r9   r:   r    s
    zDeadline.afterr  c                 C  s   | j dkrdS | j | j S )zpSeconds between the creation and expiration time of the deadline
        if the deadline expires, None otherwiseN)r#  r$  r   r9   r9   r:   r    s    
zDeadline.durationr  c                 C  s
   | j dk	S )z!Whether the deadline ever expiresNr%  r   r9   r9   r:   r    s    zDeadline.expiresc                 C  s   t  | j S )z3Seconds that elapsed since the deadline was createdr&  r   r9   r9   r:   elapsed  s    zDeadline.elapsedc                 C  s$   | j dkrdS td| j t  S dS )z]Seconds remaining until the deadline expires if an expiry time is set,
        None otherwiseNr   )r#  r  r$   r   r9   r9   r:   r    s    
zDeadline.remainingc                 C  s
   | j dkS )z(Whether the deadline has already expiredr   )r  r   r9   r9   r:   expired  s    zDeadline.expired)N)N)r   r   r   r   r   r   r  r  r   r  r  r'  r  r(  r9   r9   r9   r:   r    s    
	r  )r]   r^   )rc   r^   )r9   )r9   )F)N)r)   )rJ  )N)rm  )NN)rm  )
__future__r   r{   r  	functoolsr1   r<   jsonr$  r/   r   rt  r  rJ   r   r   r   rP   r   xml.etree.ElementTreer  r   collectionsr   collections.abcr   r   r   r   r	   concurrent.futuresr
   r   
contextlibr   r   r   datetimer   r   hashlibr   importlib.utilr   pickler   r$   r   typesr   typingr   r   r  r   r   r   r   r  rf   Ztblib.pickling_supportZtblibrG   r3   Ztlzr  r>  r   Ztornado.ioloopr   r,   r   r  r   rc  r    r!   r   Zdask.widgetsr"   Zdistributed.compatibilityr#   Zdistributed.metricsZdask.contextr%   localZ!multiprocessing.popen_spawn_win32Z!multiprocessing.popen_spawn_posixr%  r   r.  Z_loggerZtyping_extensionsr&   r'   r(   Z
no_defaultr0   r;   rF   rH   memoizer\   rb   re   rn   r   r   r   r   r   r   r   r   r   r  r  r  r8  r=  Zpickling_supportinstallrI  rM  rO  rP  r^  rb  rl  rp  r}  r  r  rh  rg  r  r  Handlerr  r  	lru_cacher  r  r  r  r  r  r  r  r  r   r  rQ  r  r  r  r  finalizeshutdownr  r  r  Zempty_contextr   r  r  r  r   r  r  r"  r  r9   r9   r9   r:   <module>   sb   

&




(
(
7 ;

!#5



!
4&&


@	  =	6  '