U
    /e!                     @  s  d dl mZ d dlZd dlZd dlmZ d dlmZ d/dddd	d
dZddddddZ	dddddZ
d0ddddddZd1ddddddZd2dddd	ddZdddddZdddd d!Zdddd"d#Zd$d$d%dd&d'd(Zd3d)d*d+d,Zd4dd*d-d.ZdS )5    )annotationsN)registry)get_ip_interfaceFstrboolztuple[str, str])addrstrictreturnc                 C  sZ   t | tstd| jj | d\}}}|rB|sBd|  }t||sRtj	d}||fS )z
    Split address into its scheme and scheme-dependent location string.

    >>> parse_address('tcp://127.0.0.1')
    ('tcp', '127.0.0.1')

    If strict is set to true the address must have a scheme.
    zexpected str, got %r://zKInvalid url scheme. Must include protocol like tcp://localhost:8000. Got %szdistributed.comm.default-scheme)

isinstancer   	TypeError	__class____name__
rpartition
ValueErrordaskconfigget)r   r   schemeseplocmsg r   ?/tmp/pip-unpacked-wheel-g426oqom/distributed/comm/addressing.pyparse_address   s    	
r   )r   r   r	   c                 C  s   |  d| S )zb
    Undo parse_address().

    >>> unparse_address('tcp', '127.0.0.1')
    'tcp://127.0.0.1'
    r
   r   )r   r   r   r   r   unparse_address#   s    r   )r   r	   c                 C  s   t t|  S )z
    Canonicalize address, adding a default scheme if necessary.

    >>> normalize_address('tls://[::1]')
    'tls://[::1]'
    >>> normalize_address('[::1]')
    'tcp://[::1]'
    )r   r   )r   r   r   r   normalize_address-   s    	r   zstr | tuple[str, int]zstr | int | Noneztuple[str, int])addressdefault_portr	   c           	        s   t  tr S  fdd} fdd}d kr> d\}  dr dd d	\}}}|sj|  |sv| }q|d
s|  |dd }n. d
\}}}|s|}| }nd
|kr|  |t|fS )zB
    Parse an endpoint address given in the form "host:port".
    c                     s   t d dd S )Nzinvalid address z'; maybe: ipv6 needs brackets like [::1]r   r   )r   r   r   _failB   s    
zparse_host_port.<locals>._failc                     s   d krt d S )Nzmissing port number in address r   r   r   r   r   r   _defaultG   s    z!parse_host_port.<locals>._defaultr
   [   N]:)r   tuplesplit
startswith	partitionr   int)	r   r   r    r"   _hostr   tailportr   r!   r   parse_host_port9   s,    


r0   z
int | None)r-   r/   r	   c                 C  s<   d| kr|  dsd|  d} |dk	r4|  d| S | S dS )z!
    Undo parse_host_port().
    r&   r#   r%   N)r)   )r-   r/   r   r   r   unparse_host_portf   s
    r1   c                 C  sN   t | |d\}}t|}z||W S  tk
rH   td| Y nX dS )a[  
    Get a (host, port) tuple out of the given address.
    For definition of strict check parse_address
    ValueError is raised if the address scheme doesn't allow extracting
    the requested information.

    >>> get_address_host_port('tcp://1.2.3.4:80')
    ('1.2.3.4', 80)
    >>> get_address_host_port('tcp://[::1]:80')
    ('::1', 80)
    )r   z4don't know how to extract host and port for address N)r   r   get_backendget_address_host_portNotImplementedErrorr   )r   r   r   r   backendr   r   r   r3   r   s    
r3   c                 C  s    t | \}}t|}||S )a  
    Return a hostname / IP address identifying the machine this address
    is located on.

    In contrast to get_address_host_port(), this function should always
    succeed for well-formed addresses.

    >>> get_address_host('tcp://1.2.3.4:80')
    '1.2.3.4'
    )r   r   r2   get_address_hostr   r   r   r5   r   r   r   r6      s    
r6   c                 C  s&   t | \}}t|}t|||S )ah  
    Get a local listening address suitable for reaching *addr*.

    For instance, trying to reach an external TCP address will return
    a local TCP address that's routable to that external address.

    >>> get_local_address_for('tcp://8.8.8.8:1234')
    'tcp://192.168.1.68'
    >>> get_local_address_for('tcp://127.0.0.1:1234')
    'tcp://127.0.0.1'
    )r   r   r2   r   get_local_address_forr7   r   r   r   r8      s    
r8   c                 C  s&   t | \}}t|}t|||S )a  
    Apply scheme-specific address resolution to *addr*, replacing
    all symbolic references with concrete location specifiers.

    In practice, this can mean hostnames are resolved to IP addresses.

    >>> resolve_address('tcp://localhost:8786')
    'tcp://127.0.0.1:8786'
    )r   r   r2   r   resolve_addressr7   r   r   r   r9      s    

r9   z
str | Noner+   )host_argport_argr   r	   c                 C  sn   t | pd\}}t||dk	r |n|\}}|dkrV|rV|t|krVtd|  d| t||}t||}|S )zF
    Process the *host* and *port* CLI options.
    Return a URI.
     Nr   z)port number given twice in options: host z
 and port )r   r0   r+   r   r1   r   )r:   r;   r   r   r   r-   r/   r   r   r   r   uri_from_host_port   s    
 

r=   list)r	   c                   sd   dd }t dd | |||fD rJ fddtt|| |||f D S t| ||| gS dS )a  Get a list of addresses if the inputs are lists

    This is like ``address_from_user_args`` except that it also accepts lists
    for some of the arguments.  If these arguments are lists then it will map
    over them accordingly.

    Examples
    --------
    >>> addresses_from_user_args(host="127.0.0.1", protocol=["inproc", "tcp"])
    ["inproc://127.0.0.1:", "tcp://127.0.0.1:"]
    c                 S  s    t | ttfr| S t| S d S N)r   r'   r>   	itertoolsrepeat)objr   r   r   listify   s    z)addresses_from_user_args.<locals>.listifyc                 s  s   | ]}t |ttfV  qd S r?   )r   r'   r>   ).0xr   r   r   	<genexpr>   s     z+addresses_from_user_args.<locals>.<genexpr>c                   s*   g | ]"\}}}}t |||| d qS ))r-   r/   	interfaceprotocolpeersecurityr   )address_from_user_args)rD   hpiprr   rI   rJ   r   r   
<listcomp>   s   

z,addresses_from_user_args.<locals>.<listcomp>N)anyzipmaprK   )r-   r/   rG   rH   rI   rJ   r   rC   r   rP   r   addresses_from_user_args   s    
      rU   c           	      C  s   |r|j r|sd}|r0|dr0|d\}}}|dkrR| sD|sD|rNtdndS |rp| rhtd|| nt|} |r| rd| kr|d |  } | s|rt| ||}nd}|r|d |dd  }|S )	z?Get an address to listen on from common user provided argumentsZtlsr
   Zinplacez=Can not specify inproc protocol and host or port or interfacez	inproc://z'Can not specify both interface and hostr<   )Zrequire_encryptionendswithr   r   r   r=   r(   )	r-   r/   rG   rH   rI   rJ   r   r,   r   r   r   r   rK     s,    rK   )F)N)N)F)NNNNNNr   )NNNNNNr   )
__future__r   r@   r   Zdistributed.commr   Zdistributed.utilsr   r   r   r   r0   r1   r3   r6   r8   r9   r=   rU   rK   r   r   r   r   <module>   s>   
 -       1       