U
    luf                     @   s   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	m
Z
 d dlZejrnd dlmZmZmZmZmZ G dd de	ZdS )	    N)Future)gen)IOLoop)Resolveris_valid_ip)	GeneratorAnyListTupleDictc                   @   s`   e Zd ZdZddddZeeeddddZeedd	d
dZe	j
deeeddddZdS )CaresResolvera  Name resolver based on the c-ares library.

    This is a non-blocking and non-threaded resolver.  It may not produce the
    same results as the system resolver, but can be used for non-blocking
    resolution when threads cannot be used.

    ``pycares`` will not return a mix of ``AF_INET`` and ``AF_INET6`` when
    ``family`` is ``AF_UNSPEC``, so it is only recommended for use in
    ``AF_INET`` (i.e. IPv4).  This is the default for
    ``tornado.simple_httpclient``, but other libraries may default to
    ``AF_UNSPEC``.

    .. versionchanged:: 5.0
       The ``io_loop`` argument (deprecated since version 4.1) has been removed.

    .. deprecated:: 6.2
       This class is deprecated and will be removed in Tornado 7.0. Use the default
       thread-based resolver instead.
    N)returnc                 C   s$   t  | _tj| jd| _i | _d S )N)Zsock_state_cb)r   currentio_looppycaresZChannel_sock_state_cbchannelfds)self r   B/tmp/pip-unpacked-wheel-bmg6zs32/tornado/platform/caresresolver.py
initialize$   s    
zCaresResolver.initialize)fdreadablewritabler   c                 C   sz   |r
t jnd|rt jndB }|s6| j| | j|= n@|| jkrZ| j|| || j|< n| j|| j| || j|< d S )Nr   )	r   READWRITEr   Zremove_handlerr   Zupdate_handleradd_handler_handle_events)r   r   r   r   stater   r   r   r   )   s    

zCaresResolver._sock_state_cb)r   eventsr   c                 C   s:   t j}t j}|tj@ r|}|tj@ r(|}| j|| d S N)r   ZARES_SOCKET_BADr   r   r   r   Z
process_fd)r   r   r    Zread_fdZwrite_fdr   r   r   r   5   s    

zCaresResolver._handle_eventsr   z*Generator[Any, Any, List[Tuple[int, Any]]])hostportfamilyr   c           
      #   s   t |r|g}nLt  | j|| fdd  V \}}|rVtd|tj||f |j}g }|D ]f}d|krxt	j
}	nd|krt	j}	nt	j}	|t	jkr||	krtd||	f |tt|	||ff qd|S )Nc                    s     | |fS r!   )Z
set_result)resulterrorZfutr   r   <lambda>H       z'CaresResolver.resolve.<locals>.<lambda>z/C-Ares returned error %s: %s while resolving %s.:z%Requested socket family %d but got %d)r   r   r   gethostbynameIOErrorr   errnostrerror	addressessocketAF_INETAF_INET6	AF_UNSPECappendtypingcastint)
r   r"   r#   r$   r0   r%   r&   Zaddrinfoaddressaddress_familyr   r'   r   resolve>   s:      


zCaresResolver.resolve)r   )__name__
__module____qualname____doc__r   r8   boolr   r   r   	coroutinestrr;   r   r   r   r   r      s   	   r   )r   r1   Ztornado.concurrentr   Ztornador   Ztornado.ioloopr   Ztornado.netutilr   r   r6   TYPE_CHECKINGr   r   r	   r
   r   r   r   r   r   r   <module>   s   