a
    'ghB                     @   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_policy_patch_tornadoasyncioget_event_loop_patch_looploop r   \/mounts/lovelace/software/anaconda3/envs/metaDMG/lib/python3.9/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   t  }|| t | }zb||W | sl|  tt j || W d    S 1 sb0    Y  S 1 st0    Y  nF| s|  tt j || W d    n1 s0    Y  0 d S N)	r   r	   Z	set_debugensure_futurerun_until_completedonecancelr   ZCancelledError)mainr   r   taskr   r   r   run   s$    


(   z_patch_asyncio.<locals>.run   c                 S   s    t  }|d u rt   }|S r   )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tasksZ_PyTaskTaskZ_CTaskZfuturesZ	_PyFutureFutureZ_CFuture_current_tasksZ	all_tasksr   r   r	   r   r   )r   r   r   r   r   r      s$    




r   c                  C   s   dd } t  }| |j_dS )z1Patch the policy to always return a patched loop.c                 S   s.   | j jd u r&|  }t| | | | j jS r   )_local_loopZnew_event_loopr
   Zset_event_loop)selfr   r   r   r   r	   @   s
    
z%_patch_policy.<locals>.get_event_loopN)r   r   	__class__r	   )r	   policyr   r   r   r   =   s    r   c                    s   fdd}fdd} fdd}t dd t d	d
 dd }t| drTdS t| tjsptdt|  | j}||_||_	||_
||_||_|  rdnd|_tjdkot|tj|_tjdk r|j|_tjdkrtjjntjj d|_dS )z Patch loop to make it reentrant.c              	      sl   | J  | " |    | jrq&qW d    n1 s:0    Y  W d    n1 sX0    Y  d| _d S )NF)	_run_once	_stoppingr-   )manage_asyncgens
manage_runr   r   run_foreverN   s
    @z _patch_loop.<locals>.run_foreverc                    sz    | ^ t j|| d}||ur&d|_| s@|   | jr&q@q&| sPtd| W  d    S 1 sl0    Y  d S )Nr   Fz+Event loop stopped before Future completed.)r   r   Z_log_destroy_pendingr   r0   r1   RuntimeErrorresult)r-   futuref)r4   r   r   r   V   s    
z'_patch_loop.<locals>.run_until_completec           	   
      s  | j }| j}|r$|d jr$t| q|s.| jr2dn$|rTtt|d j|   ddnd}| j	
|}| | |  | j }|r|d j|k rt|}|| q|tt|D ]Z}|s q
| }|js | d}z|  W |dur| | < q|dur| | < 0 qd}dS )zu
        Simplified re-implementation of asyncio's _run_once that
        runs handles as they become ready.
        r   iQ N)Z_readyZ
_scheduledZ
_cancelledr   r1   minmaxZ_whentime	_selectorselectZ_process_eventsZ_clock_resolutionappendrangelenpopleftpopZ_run)	r-   readyZ	scheduledtimeoutZ
event_listZend_timehandle_Z	curr_task)
curr_tasksr   r   r0   d   s@    




z_patch_loop.<locals>._run_oncec              	   s   s6  |    | j}t }zt | _t|  |  jd7  _| jrV| j	du rV| 
| j dV  W || _t| |  jd8  _| jr| jdkr| j	dur| j	j}| j	  |dur| j| d| _	nn|| _t| |  jd8  _| jr0| jdkr0| j	dur0| j	j}| j	  |dur*| j| d| _	0 dS )zSet up the loop for running.   Nr   )Z_check_closedZ
_thread_idr   r   	threading	get_identZ_set_running_loop_num_runs_pending_is_proactorloopZ_self_reading_futureZ	call_soonZ_loop_self_readingZ_ovr   Z	_proactorZ_unregister)r-   Zold_thread_idZold_running_loopovr   r   r   r4      sF    








z_patch_loop.<locals>.manage_runc              	   s   s   t tdsd S t }zP| | j | jd ur@tj| j| jd d V  W | d | jd urtj|  n | d | jd urtj|  0 d S )Nget_asyncgen_hooks)	firstiter	finalizerF)	r$   r%   rO   _set_coroutine_origin_tracking_debugZ
_asyncgensset_asyncgen_hooksZ_asyncgen_firstiter_hookZ_asyncgen_finalizer_hook)r-   Zold_agen_hooksr   r   r   r3      s"    





z%_patch_loop.<locals>.manage_asyncgensc                 S   s   dS )z2Do not throw exception if loop is already running.Nr   r2   r   r   r   _check_running   s    z#_patch_loop.<locals>._check_runningr   NzCan't patch loop of type %srI   r   ntr!   T)r   r$   
isinstancer   ZBaseEventLoop
ValueErrortyper.   r5   r   r0   rU   Z_check_runnungZ
is_runningrL   osname
issubclassZProactorEventLooprM   r%   r&   Z_set_coroutine_wrapperrR   r'   r*   r(   r   )r   r5   r   r0   rU   clsr   )rH   r3   r4   r   r
   K   s8    )




r
   c                  C   s@   dt jv r<ddlm}  tj| _tj| jv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.concurrentZ
concurrentr   r)   ZFUTURES)Ztcr   r   r   r      s
    
r   )N)__doc__r   Zasyncio.eventsr   rZ   r%   rJ   
contextlibr   r   heapqr   r   r   r   r
   r   r   r   r   r   <module>   s   

' 