B
    a                 @   s@  U d Z ddlZddlZddlZddlZddlmZmZ ddlmZ ddl	m
Z
 ddlZddlmZ e
 Ze
ed< G dd	 d	eZejd
ddZejd
ddZejdkreZneZG dd deZG dd deejZG dd deejZee_G dd dejZG dd deZdZ dd Z!de!_"dd Z#dddddgZ$dS )z8AsyncIO support for zmq

Requires asyncio and Python 3.
    N)SelectorEventLoopFuture)Union)WeakKeyDictionary)_future
_selectorsc               @   s   e Zd ZdZdS )ProactorSelectorThreadWarningzWarning class for notifying about the extra thread spawned by tornado

    We automatically support proactor via tornado's AddThreadSelectorEventLoopN)__name__
__module____qualname____doc__ r   r   //tmp/pip-unpacked-wheel-xvwjx0np/zmq/asyncio.pyr      s   r   )returnc                s    t krt   S ttdrt tjryddlm} W n tk
rR   tdY nX t	j
dtdd |  t  <  j fdd	}| _S  S d
S )zGet selector-compatible loop

    Returns an object with ``add_reader`` family of methods,
    either the loop itself or a SelectorThread instance.

    Workaround Windows proactor removal of
    *reader methods, which we need for zmq sockets.
    ProactorEventLoopr   )AddThreadSelectorEventLoopa  Proactor event loop does not implement add_reader family of methods required for zmq. zmq will work with proactor if tornado >= 6.1 can be found. Use `asyncio.set_event_loop_policy(WindowsSelectorEventLoopPolicy())` or install 'tornado>=6.1' to avoid this error.a   Proactor event loop does not implement add_reader family of methods required for zmq. Registering an additional selector thread for add_reader support via tornado. Use `asyncio.set_event_loop_policy(WindowsSelectorEventLoopPolicy())` to avoid this warning.   )
stacklevelc                  s    _ t d     d S )N)closer   popr   )asyncio_loop
loop_closeselector_loopr   r   _close_selector_and_loopJ   s    z7_get_selector_windows.<locals>._close_selector_and_loopN)r   hasattrasyncio
isinstancer   Ztornado.platform.asyncior   ImportErrorRuntimeErrorwarningswarnRuntimeWarningr   )r   r   r   r   )r   r   r   r   _get_selector_windows   s&    
r"   c             C   s   | S )zno-op on non-Windowsr   )loopr   r   r   _get_selector_noopW   s    r$   win32c               @   s$   e Zd ZeZejZejZ	dd Z
dS )_AsyncIOc             C   s   t  S )N)r   Zget_event_loop)selfr   r   r   _default_loopg   s    z_AsyncIO._default_loopN)r	   r
   r   r   Z_Future	selectorsEVENT_WRITE_WRITE
EVENT_READ_READr(   r   r   r   r   r&   b   s   r&   c               @   s    e Zd ZdZdd Zdd ZdS )Pollerz1Poller returning asyncio.Future for poll results.c                sH   t |}|| j@ r&|| fdd || j@ rD|| fdd dS )z"Schedule callback for a raw socketc                 s     S )Nr   )args)fr   r   <lambda>r       z*Poller._watch_raw_socket.<locals>.<lambda>c                 s     S )Nr   )r/   )r0   r   r   r1   t   r2   N)_get_selectorr-   
add_readerr+   Z
add_writer)r'   r#   socketZevtr0   selectorr   )r0   r   _watch_raw_socketn   s
    

zPoller._watch_raw_socketc             G   s.   t |}x |D ]}|| || qW dS )z$Unschedule callback for a raw socketN)r3   remove_readerZremove_writer)r'   r#   Zsocketsr6   r5   r   r   r   _unwatch_raw_socketsv   s    

zPoller._unwatch_raw_socketsN)r	   r
   r   r   r7   r9   r   r   r   r   r.   k   s   r.   c               @   s4   e Zd ZdZeZdZedd Zdd Z	dd Z
dS )	Socketz<Socket returning asyncio Futures for send/recv/poll methods.Nc             C   s   | j d krt| j| _ | j S )N)_Socket__selectorr3   io_loop)r'   r   r   r   	_selector   s    
zSocket._selectorc                s    j  j fdd dS )z#initialize the ioloop event handlerc                  s     ddS )Nr   )Z_handle_eventsr   )r'   r   r   r1      r2   z'Socket._init_io_state.<locals>.<lambda>N)r=   r4   _fd)r'   r   )r'   r   _init_io_state   s    zSocket._init_io_statec             C   s   | j  s| j| j dS )zEclear any ioloop event handler

        called once at close
        N)r<   Z	is_closedr=   r8   r>   )r'   r   r   r   _clear_io_state   s    
zSocket._clear_io_state)r	   r
   r   r   r.   Z_poller_classr;   propertyr=   r?   r@   r   r   r   r   r:   ~   s   r:   c               @   s   e Zd ZdZeZdZdS )Contextz/Context for creating asyncio-compatible SocketsN)r	   r
   r   r   r:   _socket_classZ	_instancer   r   r   r   rB      s   rB   c                   s"   e Zd ZdZd fdd	Z  ZS )ZMQEventLoopz}DEPRECATED: AsyncIO eventloop using zmq_poll.

    pyzmq sockets should work with any asyncio event loop as of pyzmq 17.
    Nc                s   t   tt| |S )N)_deprecatedsuperrD   __init__)r'   r6   )	__class__r   r   rG      s    zZMQEventLoop.__init__)N)r	   r
   r   r   rG   __classcell__r   r   )rH   r   rD      s   rD   c               C   s$   t jr
d S dt _tjdtdd d S )NTzsZMQEventLoop and zmq.asyncio.install are deprecated in pyzmq 17. Special eventloop integration is no longer needed.   )r   )rE   calledr   r    DeprecationWarningr   r   r   r   rE      s    rE   Fc               C   s
   t   dS )z(DEPRECATED: No longer needed in pyzmq 17N)rE   r   r   r   r   install   s    rM   )%r   r   r)   sysr   r   r   typingr   weakrefr   ZzmqZ_zmqr   r   __annotations__r!   r   ZAbstractEventLoopr"   r$   platformr3   objectr&   Z_AsyncPollerr.   Z_AsyncSocketr:   rC   rB   rD   Z_looprE   rK   rM   __all__r   r   r   r   <module>   s>   7
		