U
    ڲg                     @  s<  d Z ddlmZ ddlZddlZddlZddlmZ ddlm	Z	m
Z
mZmZmZ ddlmZ z,ddlmZmZ ddlmZ dd	lmZ W n ek
r   ed
Y nX ddlmZ ddlmZ erddlmZ e Ze e_e Z e e _dddddZ!dddddZ"dddddZ#G dd deZ$G dd dZ%dS )z
DNS query support
    )annotationsN)randint)AnyDefaultDict
NamedTupleSequenceTYPE_CHECKING)defaultdict)ResolverCache)r
   )DNSExceptionzBthe module psycopg._dns requires the package 'dnspython' installed   )errors)conninfo)SRVdict[str, Any]paramsreturnc           	        s   t dt g }g }g }t| I dH D ]\}|ddk	rH||d  |ddk	rd||d  |ddk	r(|t|d  q(|  }d	|}|r||d< d	|}|r||d< d	|}|r||d< |S )a  
    Perform async DNS lookup of the hosts and return a new params dict.

    .. deprecated:: 3.1
        The use of this function is not necessary anymore, because
        `psycopg.AsyncConnection.connect()` performs non-blocking name
        resolution automatically.
    z@from psycopg 3.1, resolve_hostaddr_async() is not needed anymoreNhosthostaddrport,)
warningswarnDeprecationWarningr   Zconninfo_attempts_asyncgetappendstrcopyjoin)	r   hostsZ	hostaddrsZportsattemptoutZshostsZ
shostaddrsZsports r$   0/tmp/pip-unpacked-wheel-b_ea6rx_/psycopg/_dns.pyresolve_hostaddr_async'   s2    	


r&   c                 C  s   t  | S )z/Apply SRV DNS lookup as defined in :RFC:`2782`.)Rfc2782Resolverresolver   r$   r$   r%   resolve_srvN   s    r*   c                   s   t  | I dH S )z$Async equivalent of `resolve_srv()`.N)r'   resolve_asyncr)   r$   r$   r%   resolve_srv_asyncS   s    r,   c                   @  s6   e Zd ZU ded< ded< dZded< dZded	< dS )
HostPortr   r   r   FbooltotryNz
str | Nonetarget)__name__
__module____qualname____annotations__r/   r0   r$   r$   r$   r%   r-   X   s   
r-   c                   @  s   e Zd ZdZe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Z
dd	dddZddd	dddZdd	ddddZdddddZdS )r'   zImplement SRV RR Resolution as per RFC 2782

    The class is organised to minimise code duplication between the sync and
    the async paths.
    z9^(?P<service>_[^\.]+)\.(?P<proto>_[^\.]+)\.(?P<target>.+)r   r   c                 C  sN   |  |}|s|S g }|D ]&}|jr6|| | q|| q| ||S )5Update the parameters host and port after SRV lookup.)_get_attemptsr/   extend_resolve_srvr   _return_paramsselfr   attemptshpshpr$   r$   r%   r(   h   s    
zRfc2782Resolver.resolvec                   sT   |  |}|s|S g }|D ],}|jr<|| |I dH  q|| q| ||S )r5   N)r6   r/   r7   _resolve_srv_asyncr   r9   r:   r$   r$   r%   r+   w   s    
zRfc2782Resolver.resolve_asynczlist[HostPort]c                 C  s,  | dtj ddrg S | dtj dd}|d}t| dtj dd}|d}t|d	krv|t|9 }t|t|krtd
t| dt| dg }d}t||D ]d\}}	| j	
|}
|
s|	 dkrd}|
r|
dnd}t||	d|d}nt||	d}|| q|r(|S g S )z
        Return the list of host, and for each host if SRV lookup must be tried.

        Return an empty list if no lookup is requested.
        r   Z
PGHOSTADDR r   ZPGHOSTr   r   ZPGPORTr   zcannot match z hosts with z port numbersFsrvTr0   N)r   r   r/   r0   r   r   )r   osenvironsplitr   leneOperationalErrorzip	re_srv_rrmatchlowergroupr-   r   )r;   r   Zhost_argZhosts_inZport_argZports_inr#   Z	srv_foundr   r   mr0   r>   r$   r$   r%   r6      s.    

zRfc2782Resolver._get_attemptsr-   )r>   r   c                 C  s8   zt |jd}W n tk
r*   d}Y nX | ||S Nr   r$   )resolverr(   r   r   _get_solved_entriesr;   r>   ansr$   r$   r%   r8      s
    
zRfc2782Resolver._resolve_srvc                   s>   zt |jdI d H }W n tk
r0   d}Y nX | ||S rO   )async_resolverr(   r   r   rQ   rR   r$   r$   r%   r?      s
    
z"Rfc2782Resolver._resolve_srv_asynczSequence[SRV])r>   entriesr   c                 C  sd   |s.|j r*|j dkr*t|j |jdgS g S t|dkrPt|d j dkrPg S dd | |D S )NrA   rB   r   r   .c                 S  s*   g | ]"}t t|jd t|jdqS )rV   rB   )r-   r   r0   rstripr   ).0entryr$   r$   r%   
<listcomp>   s   z7Rfc2782Resolver._get_solved_entries.<locals>.<listcomp>)r0   r   rL   r-   rF   r   sort_rfc2782)r;   r>   rU   r$   r$   r%   rQ      s    z#Rfc2782Resolver._get_solved_entries)r   r=   r   c                 C  sJ   |st d| }ddd |D |d< ddd |D |d< |S )Nz!no host found after SRV RR lookupr   c                 s  s   | ]}|j V  qd S N)r   rX   r>   r$   r$   r%   	<genexpr>   s     z1Rfc2782Resolver._return_params.<locals>.<genexpr>r   c                 s  s   | ]}t |jV  qd S r\   )r   r   r]   r$   r$   r%   r^      s     r   )rG   rH   r   r    )r;   r   r=   r#   r$   r$   r%   r9      s    
zRfc2782Resolver._return_paramsz	list[SRV])rS   r   c                 C  s   t t}g }|D ]}||j | qt| D ]\}}t|dkrV||d  q2|jdd d tdd |D }|r2t	d|}d}	t
|D ]\}
}|	|j7 }	|	|kr qq|| ||j8 }||
= qxq2|S )zM
        Implement the priority/weight ordering defined in RFC 2782.
        r   r   c                 S  s   | j S r\   weight)entr$   r$   r%   <lambda>       z.Rfc2782Resolver.sort_rfc2782.<locals>.<lambda>)keyc                 s  s   | ]}|j V  qd S r\   r_   )rX   ra   r$   r$   r%   r^      s     z/Rfc2782Resolver.sort_rfc2782.<locals>.<genexpr>)r	   listpriorityr   sorteditemsrF   sortsumr   	enumerater`   )r;   rS   Z
prioritiesr#   rY   prirU   Ztotal_weightrZcsumira   r$   r$   r%   r[      s*    




zRfc2782Resolver.sort_rfc2782N)r1   r2   r3   __doc__recompilerJ   r(   r+   r6   r8   r?   rQ   r9   r[   r$   r$   r$   r%   r'   _   s   
'r'   )&ro   
__future__r   rC   rp   r   randomr   typingr   r   r   r   r   collectionsr	   Zdns.resolverr
   r   Zdns.asyncresolverZAsyncResolverZdns.exceptionr   ImportErrorr@   r   rG   r   Zdns.rdtypes.IN.SRVr   rP   cacherT   r&   r*   r,   r-   r'   r$   r$   r$   r%   <module>   s8   
'