B
    +dc                 @   sz   d Z ddlZddlm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dZdd Zd	d
 Zdd Zdd ZdS )z*Patch asyncio to allow nested event loops.    N)contextmanagersuppress)heappopc             C   s*   t   t  t  | pt } t|  dS )z/Patch asyncio to make its event loop reentrant.N)_patch_asyncio_patch_task_patch_tornadoasyncioget_event_loop_patch_loop)loop r   Y/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/nest_asyncio.pyapply   s
    r   c              C   s   dddd} ddd}t tdr&d	S tjd
krdtjj t_ tj_tj_tjj	 t_
 tj_tj_
tjdk rtjjjtj_tjjjt_tjdkr| t_ t_t_| | t_dt_d	S )z:Patch asyncio module to use pure Python tasks and futures.F)debugc            S   s   yt  }W n. tk
r:   t  }t | t| Y nX || t | }z
||S |	 s|
  tt j || W d Q R X X d S )N)r   r	   RuntimeErrornew_event_loopset_event_loopr
   	set_debugensure_futurerun_until_completedonecancelr   CancelledError)mainr   r   taskr   r   r   run   s    



z_patch_asyncio.<locals>.run   c             S   s    t  }|d krt   }|S )N)events_get_running_loopget_event_loop_policyr	   )
stacklevelr   r   r   r   _get_event_loop*   s    z'_patch_asyncio.<locals>._get_event_loop_nest_patchedN)r      r   )r      r   )r   	   r   T)r   )hasattrr   sysversion_infotasks_PyTaskTask_CTaskfutures	_PyFutureFuture_CFuture_current_tasks	all_tasksr   r!   r	   r   r"   )r   r!   r   r   r   r      s    




r   c                s    fdd}fdd}dd }t dd t d	d
  dd }t| drPdS t| tjsltdt|  | j}||_||_	||_
||_||_d|_tjdkot|tj|_tjdk r|j|_d|_dS )z Patch loop to make it reentrant.c          
      sH   | 0  |  x|    | jrP qW W d Q R X W d Q R X d| _d S )NF)	_run_once	_stopping)self)manage_asyncgens
manage_runr   r   run_foreverF   s    z _patch_loop.<locals>.run_foreverc          	      sf    | T t j|| d}||k	r&d|_x| sB|   | jr(P q(W | sTtd| S Q R X d S )N)r   Fz+Event loop stopped before Future completed.)r   r   _log_destroy_pendingr   r3   r4   r   result)r5   futuref)r7   r   r   r   N   s    

z'_patch_loop.<locals>.run_until_completec             S   s   | j }| j}x|r&|d jr&t| qW |s2| jr6dn$|rXtt|d j|   ddnd}| j	
|}| | |  | j }x(|r|d j|k rt|}|| qW x0tt|D ] }|sP | }|js|  qW d}dS )zu
        Simplified re-implementation of asyncio's _run_once that
        runs handles as they become ready.
        r   iQ N)_ready
_scheduled
_cancelledr   r4   minmax_whentime	_selectorselect_process_events_clock_resolutionappendrangelenpopleft_run)r5   readyZ	scheduledtimeout
event_listend_timehandle_r   r   r   r3   \   s(    "
z_patch_loop.<locals>._run_oncec          	   s   s   |    | j}t }zHt | _t|  |  jd7  _| jrV| j	dkrV| 
| j dV  W d|| _t| |  jd8  _| jr| jdkr| j	dk	r| j	j}| j	  |dk	r| j| d| _	X dS )zSet up the loop for running.   Nr   )_check_closed
_thread_idr   r   	threading	get_ident_set_running_loop_num_runs_pending_is_proactorloopZ_self_reading_future	call_soonZ_loop_self_readingZ_ovr   Z	_proactorZ_unregister)r5   Zold_thread_idZold_running_loopovr   r   r   r7   {   s,    







z_patch_loop.<locals>.manage_runc          	   s   sn   t tdsd S t }z2| | j | jd k	r@tj| j| jd d V  W d | d | jd k	rhtj|  X d S )Nget_asyncgen_hooks)	firstiter	finalizerF)	r&   r'   r]   _set_coroutine_origin_tracking_debug
_asyncgensset_asyncgen_hooks_asyncgen_firstiter_hook_asyncgen_finalizer_hook)r5   old_agen_hooksr   r   r   r6      s    





z%_patch_loop.<locals>.manage_asyncgensc             S   s   dS )z2Do not throw exception if loop is already running.Nr   )r5   r   r   r   _check_running   s    z#_patch_loop.<locals>._check_runningr"   NzCan't patch loop of type %sr   nt)r   r$   r   T)r   r&   
isinstancer   BaseEventLoop
ValueErrortype	__class__r8   r   r3   rg   Z_check_runnungrY   osname
issubclassZProactorEventLooprZ   r'   r(   Z_set_coroutine_wrapperr`   r"   )r   r8   r   r3   rg   clsr   )r6   r7   r   r
   C   s*    

r
   c                 s   d fdd	} t j}t|dr$dS tjdkrl fdd} fdd	}|t j_|t j_t jj |j	| |_	n|j |j
| |_
d
|_dS )zCPatch the Task's step and enter/leave methods to make it reentrant.Nc          
      sD     | j}z| | W d |d kr4 | jd  n
| | j< X d S )N)get_looppop)r   excZ	curr_task)
curr_tasks	step_origr   r   step   s    z_patch_task.<locals>.stepr"   )r   r$   r   c                s   | | < d S )Nr   )r   r   )rv   r   r   
enter_task   s    z_patch_task.<locals>.enter_taskc                s     | d  d S )N)rt   )r   r   )rv   r   r   
leave_task   s    z_patch_task.<locals>.leave_taskT)N)r   r+   r&   r'   r(   r)   _enter_task_leave_taskr1   _Task__stepZ_stepr"   )rx   r+   ry   rz   r   )rv   rw   r   r      s     


r   c              C   s@   dt jkr<ddlm}  tj| _tj| jkr<|  jtjf7  _dS )zo
    If tornado is imported before nest_asyncio, make tornado aware of
    the pure-Python asyncio Future.
    tornador   N)r'   modulesZtornado.concurrent
concurrentr   r/   ZFUTURES)Ztcr   r   r   r      s
    
r   )N)__doc__r   Zasyncio.eventsr   rn   r'   rV   
contextlibr   r   heapqr   r   r   r
   r   r   r   r   r   r   <module>   s   

-{$