o
    iB8                     @   s  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aG dd dZ	d"ddd	d
edefddZejdk rHdd Znejdk rRdd Zndd Zejdk rcddddZndddddZdddef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)heappopTc                   @   s   e Zd ZdZdS )_NestAsyncio2zInternal class of `nest_asyncio2`.

    Mainly for holding the original properties to support unapply() and nest_asyncio2.run().
    N)__name__
__module____qualname____doc__ r
   r
   Q/home/app/Keep/.python/lib/python3.10/site-packages/polars/_utils/nest_asyncio.pyr   1   s    r   F)run_close_looperror_on_mispatchedr   r   c                C   s<   t |d t  t  | pt } | durt|  t|M adS )ax  Patch asyncio to make its event loop reentrant.

    - `run_close_loop`: Close the event loop created by `asyncio.run()`, if any.
      See README for details.
    - `error_on_mispatched`:
      - `False` (default): Warn if asyncio is already patched by `nest_asyncio` on Python 3.12+.
      - `True`: Raise `RuntimeError` if asyncio is already patched by `nest_asyncio`.
    r   N)_patch_asyncio_patch_policy_patch_tornado_get_event_loop_patch_loop_run_close_loop)loopr   r   r
   r
   r   apply:   s   

r         r   c                   C   s   t  S N)asyncioget_event_loopr
   r
   r
   r   r   T   s   r   r      r   c                  C   s$   t  } | d u rt  }|jj} | S r   )events_get_running_loopget_event_loop_policy_local_loop)r   policyr
   r
   r   r   X   s
   c                   C   s    zt  W S  ty   Y d S w r   )r   r   RuntimeErrorr
   r
   r
   r   r   b   s
   
)debugc                C   s   t  }|| t | }z)||W | s7|  tt j || W d    S 1 s1w   Y  S S | sZ|  tt j || W d    w 1 sUw   Y  w r   )	r   r   	set_debugensure_futurerun_until_completedonecancelr   CancelledError)mainr&   r   taskr
   r
   r   runl   s   



r/   )r&   loop_factoryc                C   sv  d}d }zt  }W n8 tyB   ts*t }|d u r)|d u r!t j}| }t | n|d u r;t  }t }t | n| }d}Y nw t| || t j	| |d}z6|
|W | s{|  tt j |
| W d    n1 svw   Y  |rt | |r|  S S | s|  tt j |
| W d    n1 sw   Y  |rt | |r|  w w )NFTr   )r   get_running_loopr%   r   r   new_event_loopset_event_loopr   r'   r(   r)   r*   r+   r   r,   close)r-   r&   r0   r3   r4   r   r.   r
   r
   r   r/   y   s\   	






r   c                 C   s   ddd}t tdr%t tds#| rtdtjdkr#dd	l}|d
 d	S tjdkrItjdk rItjj t_	 tj_
tj_	tjj t_ tj_tj_tjdk r[tjj	jtj_tjj	jt_tjdkrntjdk rn| t_ t_t_tt_dt_t t_d	S )z:Patch asyncio module to use pure Python tasks and futures.r   c                 S   s    t  }|d u rt   }|S r   )r   r    r!   r   )
stacklevelr   r
   r
   r   r      s   z'_patch_asyncio.<locals>._get_event_loop_nest_patched_nest_asyncio2z*asyncio is already patched by nest_asyncior   r   NzUasyncio is already patched by nest_asyncio. You may encounter bugs related to asyncio)r      r   r   r      r   )r   	   r   T)r   )hasattrr   r%   sysversion_infowarningswarntasks_PyTaskTask_CTaskfutures	_PyFutureFuture_CFuture_current_tasks	all_tasksr   r   r   r/   r7   r   r8   )r   r   r@   r
   r
   r   r      s0   




r   c                  C   s>   t jdkrdS dd } t jdk rt }nt }| |j_dS )z1Patch the policy to always return a patched loop.r   Nc                 S   s.   | j jd u r|  }t| | | | j jS r   )r"   r#   r3   r   r4   )selfr   r
   r
   r   r      s
   
z%_patch_policy.<locals>.get_event_loop)r>   r?   r   r!   Z_get_event_loop_policy	__class__r   )r   r$   r
   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r*dS t| tjs8tdt|  | j}||_||_	||_
||_||_|  rPdnd|_tjdko]t|tj|_tjdk rh|j|_tjdkrqtjjntjj d|_t |_dS )z Patch loop to make it reentrant.c              	      sn   | &  |  	 |    | jrnqW d    n1 sw   Y  W d    n1 s-w   Y  d| _d S )NTF)	_run_once	_stoppingrL   )manage_asyncgens
manage_runr
   r   run_forever   s    
z _patch_loop.<locals>.run_foreverc                    s    | 2 t j|| d}||urd|_| s#|   | jrn| r| s+td| W  d    S 1 s9w   Y  d S )Nr1   Fz+Event loop stopped before Future completed.)r   r(   _log_destroy_pendingr*   rN   rO   r%   result)rL   futuref)rR   r
   r   r)      s   
$z'_patch_loop.<locals>.run_until_completec           	         s  | j }| j}|r|d jrt| |r|d js|s| jrdn|r0tt|d j|   ddnd}| j	
|}| | |  | j }|r_|d j|k r_t|}|| |r_|d j|k sMtt|D ]d}|sn d}dS | }|jstjdk r | d}nz	tj| d}W n ty   d}Y nw z|  W |durtjdk r| | < qetj| | qe|durtjdk r| | < w tj| | w w qed}dS )zu
        Simplified re-implementation of asyncio's _run_once that
        runs handles as they become ready.
        r   iQ Nr   )_ready
_scheduled
_cancelledr   rO   minmax_whentime	_selectorselect_process_events_clock_resolutionappendrangelenpopleftr>   r?   popr   rB   Z_swap_current_taskKeyError_run)	rL   readyZ	scheduledtimeout
event_listend_timehandle_Z	curr_task)
curr_tasksr
   r   rN   
  s^    







z_patch_loop.<locals>._run_oncec              	   s   s:   |    | j}t }z]t | _t|  |  jd7  _| jr,| j	du r,| 
| j dV  W || _t| |  jd8  _| jrd| jdkrf| j	durh| j	j}| j	  |dur_| j| d| _	dS dS dS dS || _t| |  jd8  _| jr| jdkr| j	dur| j	j}| j	  |dur| j| d| _	w )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)rL   Zold_thread_idZold_running_loopovr
   r
   r   rR   @  sJ   











z_patch_loop.<locals>.manage_runc              	   s   s    t tdsd S t }z+| | j | jd ur!tj| j| jd d V  W | d | jd ur6tj|  d S d S | d | jd urHtj|  w w )Nget_asyncgen_hooks)	firstiter	finalizerF)	r=   r>   r{   _set_coroutine_origin_tracking_debug
_asyncgensset_asyncgen_hooks_asyncgen_firstiter_hook_asyncgen_finalizer_hook)rL   old_agen_hooksr
   r
   r   rQ   ]  s(   





z%_patch_loop.<locals>.manage_asyncgensc                 S   s   dS )z2Do not throw exception if loop is already running.Nr
   rP   r
   r
   r   _check_runningp  s   z#_patch_loop.<locals>._check_runningr7   NzCan't patch loop of type %srq   r   ntr:   T)r   r=   
isinstancer   BaseEventLoop
ValueErrortyperM   rS   r)   rN   r   Z_check_runnung
is_runningrw   osname
issubclassZProactorEventLooprx   r>   r?   Z_set_coroutine_wrapperr~   rB   rJ   rD   r7   r   r8   )r   rS   r)   rN   r   clsr
   )rp   rQ   rR   r   r      s<   6




r   c                  C   sH   dt jv r ddlm}  tj| _tj| jvr"|  jtjf7  _dS dS 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   rH   ZFUTURES)Ztcr
   r
   r   r     s   
r   r   )r	   r   Zasyncio.eventsr   r   r>   rt   
contextlibr   r   heapqr   r   r   boolr   r?   r   r/   r   r   r   r   r
   r
   r
   r   <module>   s>   #







2- 