B
    't\H)                 @   s   d dl m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 ddlmZmZmZ ddlmZ dd	lmZ d
gZejZG dd
 d
eZdS )    )unicode_literalsN   )	EventLoop)Future)InputHookContext)AutoSelectorSelector	fd_to_int)ThreadWithFuture)wrap_in_current_contextPosixEventLoopc                   s|   e Zd ZdZef fdd	ZdddZdd Zd	d
 ZdddZ	dd Z
dddZdddZdd Zdd Zdd Z  ZS )r   z9
    Event loop for posix systems (Linux, Mac os X).
    c                s   t |tsttt|   d| _d| _g | _i | _	| | _
i | _t | _t| jd tjtj | j
| jd  d | _d S )NFr   )
issubclassr   AssertionErrorsuperr   __init__closed_running_calls_from_executor	_read_fdsselector_signal_handler_mappingsospipe_schedule_pipefcntlZF_SETFL
O_NONBLOCKregister_inputhook_context)selfr   )	__class__ =lib/python3.7/site-packages/prompt_toolkit/eventloop/posix.pyr      s    
zPosixEventLoop.__init__Nc             C   s~   t |tst|dks"t|s"t| jr0td| jr>tdz2d| _x| s\| | qHW | j	rn| | W dd| _X dS )z
        Keep running the event loop until `future` has been set.

        :param future: :class:`prompt_toolkit.eventloop.future.Future` object.
        NzEvent loop is already runningzEvent loop already closed.TF)

isinstancer   r   callabler   	Exceptionr   Zdone	_run_oncer   )r   future	inputhookr    r    r!   run_until_complete/   s    
z!PosixEventLoop.run_until_completec                sh  |r0 j d krt  _  fdd} j ||  d }|rdg }g }d }x|D ]}| jd krt jd d  jd d  } jd d = xl|D ]H\}	}
|
d kr||	 q|pt	 }|
|k r||	 q||	|
f qW qR j
|}|rR|| qRW |rFx|D ]} | qW x@|D ]\}}
 j||
d q(W nx|D ]\}} | qLW d S )Nc                s     | rdndg kS )zF True when there is input ready. The inputhook should return control. Nr   )_ready_for_reading)wait)r   r    r!   readyR   s    z'PosixEventLoop._run_once.<locals>.readyr   i   )_max_postpone_until)r   r   Zcall_inputhookr)   r   r   readr   append_nowr   get	_run_taskcall_from_executor)r   r'   r+   fdsZtasksZlow_priority_tasksZnowfdZcalls_from_executorcZmax_postpone_untilhandlert_r    )r   r!   r%   K   s@    

	


zPosixEventLoop._run_oncec          
   C   s@   y
|  W n0 t k
r: } z| d|i W dd}~X Y nX dS )aN  
        Run a task in the event loop. If it fails, print the exception.

        By default, the event loop is not supposed to exit if one fd callback
        raises an exception. Doing so, would leave many coroutines in a not
        cleaned-up state. If this happens, this is a bug, and we have to print
        the stack.
        Z	exceptionN)BaseExceptionZcall_exception_handler)r   r7   er    r    r!   r1      s
    	
zPosixEventLoop._run_taskc             C   s   | j |}|S )zI
        Return the file descriptors that are ready for reading.
        )r   select)r   Ztimeoutr3   r    r    r!   r)      s    z!PosixEventLoop._ready_for_readingc                sd    dkrd  t jdfkr2t  | } j|< n$ fdd}t  ||} j|< j||S )z
        Register a signal handler. Call `handler` when `signal` was received.
        The given handler will always be called in the same thread as the
        eventloop. (Like `call_from_executor`.)
        Nr   c                 s      d S )N)r2   )a)r6   r   r    r!   call_signal_handler   s    z>PosixEventLoop.add_signal_handler.<locals>.call_signal_handler)signalSIG_IGNr   r0   )r   Zsignumr6   Zpreviousr=   r    )r6   r   r!   add_signal_handler   s    
z!PosixEventLoop.add_signal_handlerFc             C   s   t ||d}| |j |jS )z
        Run a long running function in a background thread.
        (This is recommended for code that could block the event loop.)
        Similar to Twisted's ``deferToThread``.
        )Zdaemon)r
   r2   startr&   )r   callbackZ_daemonZthr    r    r!   run_in_executor   s    zPosixEventLoop.run_in_executorc          
   C   sj   |dkst |tstt|}| j||f | jrfyt| jd d W n t	t
tfk
rd   Y nX dS )a  
        Call this function in the main event loop.
        Similar to Twisted's ``callFromThread``.

        :param _max_postpone_until: `None` or `time.time` value. For internal
            use. If the eventloop is saturated, consider this task to be low
            priority and postpone maximum until this timestamp. (For instance,
            repaint is done using low priority.)
        Nr      x)r"   floatr   r   r   r.   r   r   writeAttributeError
IndexErrorOSError)r   rB   r,   r    r    r!   r2      s    
z!PosixEventLoop.call_from_executorc             C   sP   | j r
td| _| j}d| _|r<t|d  t|d  | jrL| j  dS )zE
        Close the event loop. The loop must not be running.
        TNr   r   )r   r   r   r   r   closer   )r   Zschedule_piper    r    r!   rJ      s    
zPosixEventLoop.closec             C   s*   t |}t|}|| j|< | j| dS )z- Add read file descriptor to the event loop. N)r   r	   r   r   r   )r   r4   rB   r    r    r!   
add_reader
  s    
zPosixEventLoop.add_readerc             C   s*   t |}|| jkr| j|= | j| dS )z2 Remove read file descriptor from the event loop. N)r	   r   r   Z
unregister)r   r4   r    r    r!   remove_reader  s    
zPosixEventLoop.remove_reader)N)N)F)N)__name__
__module____qualname____doc__r   r   r(   r%   r1   r)   r@   rC   r2   rJ   rK   rL   __classcell__r    r    )r   r!   r      s   
E
#

)Z
__future__r   r   r   r>   Ztimebaser   r&   r   r'   r   r;   r   r   r	   Zutilsr
   contextr   __all__r/   r   r    r    r    r!   <module>   s   