o
    i1                     @   s  d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dl	Z	d dl
Z
d dlZd dl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mZmZ d dlZd dlmZ d dlmZmZ ddlmZmZmZ ddlm Z  dd	l!m"Z"m#Z#m$Z$m%Z% dd
l&m'Z'm(Z(m)Z) ddddddZ*dZ+dZ,dZ-dZ.ej/j0ej/j1ej/j2ej/j3ej/j4ej5fZ6e	7e8Z9G dd dZ:dd Z;dd Z<G dd dZ=dS )    N)get_annotations)Callable
ForwardRefOptional)evaluated_annotation)FunctionWithAioMethodWithAio   )$is_async_gen_function_follow_wrapped$is_coroutine_function_follow_wrappedwraps_by_interfaceCallback)UserCodeException suppress_synchronicity_tb_framesunwrap_coro_exceptionwrap_coro_exception)DEFAULT_CLASS_PREFIXDEFAULT_FUNCTION_PREFIXES	Interface__iter__	__enter____exit____next__close)	__aiter__
__aenter__	__aexit__	__anext__aclose)__provides____del___future_sync_target_interface_sync_synchronizerc                   @   s    e Zd ZdZdd Zdd ZdS )classpropertyzBRead-only class property recognized by Synchronizer's wrap method.c                 C   s
   || _ d S Nfget)selfr(    r*   N/home/ubuntu/.local/lib/python3.10/site-packages/synchronicity/synchronizer.py__init__F      
zclassproperty.__init__c                 C   s
   |  |S r&   r'   )r)   objownerr*   r*   r+   __get__I   r-   zclassproperty.__get__N)__name__
__module____qualname____doc__r,   r0   r*   r*   r*   r+   r%   C   s    r%   c                 C   s~   t | tr| j} t | tr zt| |d} W n
 ty   Y dS w t| dr=| jtv r,dS t	| ddD ]
}t
||r< dS q2dS )N)declaration_moduleF
__origin__T__args__r*   )
isinstancer   __forward_arg__strr   	Exceptionhasattrr6   ASYNC_GENERIC_ORIGINSgetattr_type_requires_aio_usage)
annotationr5   ar*   r*   r+   r?   M   s    




r?   c                 C   s@   t | st| r
dS t| }| D ]}t|| jr dS qdS )NTF)r   r
   r   valuesr?   r2   )funcannosannor*   r*   r+   should_have_aio_interfaceb   s   rF   c                   @   s&  e Zd ZdZ			dadeeejgdf  fddZg dZ	d	d
 Z
dd Zdd Zdd Zdd Zejdejd dejfddZejdedejejdf fddZdbdejejdf fddZdd Zdd Zdd Zdd  Zd!d" Zd#d$ Zd%d& Zd'd( Zdcd)d*Zd+d, Z d-d. Z!d/d0 Z"d1d2 Z#d3d4 Z$d5d6 Z%d7d8 Z&ddd9d:Z'					ded;d<Z(		dfd=d>Z)d?d@ Z*dAdB Z+dCdD Z,dEdF Z-dGdH Z.dcdIdJZ/			dgdKdLZ0dMdN Z1dOdP Z2dQdR Z3dSdT Z4dUdV Z5dWdX Z6dhdYee7 dZee7 fd[d\Z8dhdYee7 dZee7 fd]d^Z9d_d` Z:dS )iSynchronizerzHHelps you offer a blocking (synchronous) interface to asynchronous code.FTNblocking_in_async_callbackc                 C   s   d| _ || _|| _|| _d | _t | _d | _d | _	d | _
d | _d | _d| _dt|  | _dt|  | _dt|  | _dt|  | _dt|  | _tj| _| | j t| j d S )Ng?g      $@z_sync_wrapped_%dz_sync_original_%dz_sync_nonwrap_%dz_sync_input_translation_%dz_sync_output_translation_%d)_future_poll_interval_multiwrap_warning_async_leakage_warning_blocking_in_async_callback_loop	threadingLock_loop_creation_lock_thread_thread_exception_thread_traceback
_owner_pid	_stopping#_asyncgen_finalizer_timeout_secondsid_wrapped_attr_original_attr_nowrap_attr_input_translation_attr_output_translation_attr
contextlib_AsyncGeneratorContextManager_ctx_mgr_clscreate_blockingatexitregister_close_loop)r)   multiwrap_warningasync_leakage_warningrH   r*   r*   r+   r,   r   s(   
zSynchronizer.__init__)rJ   rK   rL   c                    s   t  fdd jD S )Nc                    s   g | ]	}|t  |fqS r*   )r>   ).0attrr)   r*   r+   
<listcomp>   s    z-Synchronizer.__getstate__.<locals>.<listcomp>)dict_PICKLE_ATTRSrh   r*   rh   r+   __getstate__   s   zSynchronizer.__getstate__c                 C   s    | j D ]
}t| |||  qd S r&   )rk   setattr)r)   drg   r*   r*   r+   __setstate__   s   
zSynchronizer.__setstate__c                    s   j ? jrj rjW  d    S t   fdd}t _tj|dd}|	   
  |_jW  d    S 1 sEw   Y  d S )Nc               
      s    fdd} z!z
t |   W W d S  ty( } z
|_t _|d }~ww  tyC } zdt|vr8|W Y d }~d S d }~ww )Nc                      s2   t  _t  _   j I d H  d S r&   )asyncioget_running_looprM   EventrU   setwaitr*   is_readyr)   r*   r+   
loop_inner   s
   

zBSynchronizer._start_loop.<locals>.thread_inner.<locals>.loop_innerz/can't create new thread at interpreter shutdown)	rp   runBaseExceptionrR   	traceback
format_excrS   RuntimeErrorr:   )rw   	exc_innerexcru   r*   r+   thread_inner   s    
z.Synchronizer._start_loop.<locals>.thread_innerT)targetdaemon)rP   rM   
is_runningrN   rr   osgetpidrT   Threadstartrt   rQ   )r)   r   threadr*   ru   r+   _start_loop   s   
$zSynchronizer._start_loopc                 C   sN   t | dd d ur%| j s| j| jj | j  d | _d | _d | _d S d S )NrQ   )	r>   rM   	is_closedcall_soon_threadsaferU   rs   rQ   joinrT   rh   r*   r*   r+   rc      s   


zSynchronizer._close_loopc                 C   s   |    d S r&   )rc   rh   r*   r*   r+   r!      s   zSynchronizer.__del__r   returnc                 C      d S r&   r*   r)   r   r*   r*   r+   	_get_loop      zSynchronizer._get_loopc                 C   r   r&   r*   r   r*   r*   r+   r      r   c                 C   sl   | j r(| j  s(| jt kr"tdt| j d| j	  t
dd | _ d | _| jd u r3|r3|  S | jS )Nz.Synchronizer thread unexpectedly died.
Cause: z
Traceback:z%Synchronizer thread unexpectedly died)rQ   is_aliverT   r   r   loggererrortyperR   rS   r|   rM   r   r   r*   r*   r+   r      s   c                 C   s    zt  W S  ty   Y d S w r&   )rp   rq   r|   rh   r*   r*   r+   _get_running_loop   s
   
zSynchronizer._get_running_loopc                 C   s6   |   }|d u r
dS t | jkrdS |  }||kS NF)r   rN   current_threadrQ   r   )r)   loopcurrent_loopr*   r*   r+   _is_inside_loop   s   zSynchronizer._is_inside_loopc                    s   | j s S  fdd}| S )zCheck if a coroutine returns another coroutine (or an async generator) and warn.

        The reason this is important to catch is that otherwise even synchronized code might end up
        "leaking" async code into the caller.
        c                     sL    I d H } t | rtd|  d | S t | r$td|  d | S )Nz8Potential async leakage: coroutine returned a coroutine .z?Potential async leakage: Coroutine returned an async generator )inspectiscoroutinewarningswarn
isasyncgen)valuecoror*   r+   coro_wrapped  s   


z<Synchronizer._wrap_check_async_leakage.<locals>.coro_wrapped)rK   )r)   r   r   r*   r   r+   _wrap_check_async_leakage   s   	z&Synchronizer._wrap_check_async_leakagec                 C   s@   |j }|j}|| j tj }||}||j| j< | |jt< |S r&   )	__class____dict__rX   r   BLOCKING__new__rY   SYNCHRONIZER_ATTR)r)   r.   clscls_dctwrapper_clsnew_objr*   r*   r+   _wrap_instance  s   

zSynchronizer._wrap_instancec                 C   s8   t |drt|r|j| j|S |j| j|S |S )Nr   )r<   r   isclassr   getrY   r)   r.   r*   r*   r+   _translate_scalar_in  s
   

z!Synchronizer._translate_scalar_inc                 C   s   t |r|j}| j|v r|| j tj S |S t|tjt	j
fr1t|| jr/t|| jtj S |S |jj}| j|v rB| j|tjdS |S )N	interface)r   r   r   rX   r   r   r8   typingTypeVartyping_extensions	ParamSpecr<   r>   r   _wrap)r)   r.   r   r*   r*   r+   _translate_scalar_out'  s   


z"Synchronizer._translate_scalar_outc                    sx   t |tkrt fdd|D S t |tkr$t fdd|D S t |tkr8t fdd| D S  |S )Nc                 3       | ]	}  |V  qd S r&   _recurse_maprf   itemmapperr)   r*   r+   	<genexpr>>      z,Synchronizer._recurse_map.<locals>.<genexpr>c                 3   r   r&   r   r   r   r*   r+   r   @  r   c                 3   s$    | ]\}}|  |fV  qd S r&   r   )rf   keyr   r   r*   r+   r   B  s   " )r   listtuplerj   items)r)   r   r.   r*   r   r+   r   <  s   zSynchronizer._recurse_mapc                 C   s   |  | j|S r&   )r   r   r   r*   r*   r+   _translate_inF  s   zSynchronizer._translate_inc                    s      fdd|S )Nc                    s
     | S r&   )r   )scalarrh   r*   r+   <lambda>K     
 z-Synchronizer._translate_out.<locals>.<lambda>r   )r)   r.   r   r*   rh   r+   _translate_outI  s   zSynchronizer._translate_outc                    s    fdd}| S )Nc                     s(    I d H } t jdr| S | S NT)r>   r\   r   resr   original_funcr)   r*   r+   unwrap_coroN  s
   

z5Synchronizer._translate_coro_out.<locals>.unwrap_coror*   )r)   r   r   r   r*   r   r+   _translate_coro_outM  s   z Synchronizer._translate_coro_outc           
         sn  |   rtd| jd ur(zt }W n ty   d }Y nw |d ur(| | t  |   | jddt	j
  fdd}t| }z#tjdkri	 z	|j| jd}W n t	j
jyf   Y nw qRn| }W n: ty } z. r }|j z| }W n t	j
jy }	 zd|	_|d }	~	ww W Y d }~nd }~ww t|| jdr| |S |S )	NzEDeadlock detected: calling a sync function from the synchronizer loopTr   c                           } |  | I d H S r&   create_task
set_result
inner_taskr   inner_task_futr   r*   r+   wrapper_coron  s   


z5Synchronizer._run_function_sync.<locals>.wrapper_corowin32r	   timeout)r   r;   rL   rp   rq   r|   r   r   r   
concurrentfuturesFuturerun_coroutine_threadsafesysplatformresultrI   TimeoutErrorKeyboardInterruptdoner   cancelCancelledError__suppress_context__r>   r\   r   )
r)   r   r   foreign_loopr   futr   r~   r   expected_cancellationr*   r   r+   _run_function_syncV  s\   





zSynchronizer._run_function_syncc                 C   s@   t |}| |}| jdd}t|}| j||d}t||S )NTr   )r   )r   r   r   r   r   rp   r   )r)   r   r   r   r*   r*   r+   _run_function_sync_future  s   
z&Synchronizer._run_function_sync_futurec           	         sD  t   |   | jdd|  r I d H }nztj  fdd}t| }t	|}d }z4t
jdkr`	 zttjt|| jd}t|I d H }W n
 tjy^   Y q;w nt|I d H }W n* tjy   z| rw  r }|j |I d H   |r|  w w w t|| jdr| |S |S )NTr   c                     r   r&   r   r   r   r*   r+   r     s   


z6Synchronizer._run_function_async.<locals>.wrapper_coror   r	   r   )r   r   r   r   r   r   r   rp   r   wrap_futurer   r   r   wait_forshieldrI   r   r   	cancelledr   r   r   r   r>   r\   r   )	r)   r   r   r   r   c_futa_futshielded_taskr   r*   r   r+   _run_function_async  sZ   






z Synchronizer._run_function_asyncc           	      c   s   d\}}zt   	 z|r| |||}n	| |||}W nF ty5 } zd|j_|jd }~w tyh   Y W d    W t	 sfz|
 }| ||}|j| jd W d S  tye   Y d S w d S w z|V }d}W n tyx     ty } z
|}d}W Y d }~nd }~ww q1 sw   Y  W t	 sz|
 }| ||}|j| jd W d S  ty   Y d S w d S t	 sz|
 }| ||}|j| jd W w  ty   Y w w w )Nr   Tr   F)r   r   athrowasendr   r~   r   StopAsyncIterationr   is_finalizingr   r   r   rV   r;   GeneratorExitry   )	r)   genr   r   is_excuc_excr   finalization_futr~   r*   r*   r+   _run_generator_sync  sp   z Synchronizer._run_generator_syncc                 C  s  d\}}zt  h 	 z|r| |||I d H }n| |||I d H }W n ty; } zd|j_|jd }~w tyC   Y n'w z|V }d}W n tyS     t	yh } z
|}d}W Y d }~nd }~ww qW d    n1 stw   Y  W t
 szt| | |}tjt|| jdI d H  W d S  ty   Y d S w d S t
 szt| | |}tjt|| jdI d H  W w  ty   Y w w w )Nr   TFr   )r   r   r   r   r   r~   r   r   r   ry   r   r   rp   r   r   r   r   rV   r;   )r)   r  r   r   r  r  r~   
close_taskr*   r*   r+   _run_generator_async
  s\   
" z!Synchronizer._run_generator_asyncc                 C   s
   t | |S r&   r   )r)   fr*   r*   r+   create_callback/  r-   zSynchronizer.create_callbackc                 C   sJ   t || |dur||_||_|dur||_t|t|  t|t| dS )z(Very similar to functools.update_wrapperN)	functoolsupdate_wrapperr1   r3   r2   rm   r   TARGET_INTERFACE_ATTR)r)   	f_wrappedr  namer   target_moduler*   r*   r+   _update_wrapper2  s   zSynchronizer._update_wrapperc                    s   t jrjrtd d S |d u r t j }n|}t fdd}	j|	||d t	|	j t
jkrqrqtrqjt
j| |d}
t|	|
}	j|	||d t	|	j |	S )Nz	Function . is already wrapped, but getting wrapped againc            	   
      s  | td}tjdr| } |}| i | t }t }|r@s0td|r8	 S |r>td S |rt
jkrW }tsUt|}|S t
jkrz W S  tyv } zt |jd }~w ty } zrt
jrsd|j_|j|d }~ww d S |rt
jkr S t
jkr S d S t st tjrt  fdd}|S tjdrՈ  S  S )NFTz'Can not return future for this functionz%Can not return futures for generatorsc                     s>    | }  |}| i |}t jdr|S |S r   )r   r>   r\   r   )argskwargsf_res)r  r   r)   r*   r+   r    s   


zASynchronizer._wrap_callable.<locals>.f_wrapped.<locals>.f_wrapped)!pop_RETURN_FUTURE_KWARGr>   r[   r   r   r   r   r;   r   r   _ASYNC_WITH_BLOCKING_TYPESr   r   r   r   r   r   StopIterationwith_traceback__traceback__r   r~   r   r  r  
isfunctionr8   r
  partialr   r\   r   )	r  r  return_futureis_coroutineis_asyncgenr   r~   r  r  allow_futuresr  include_aio_interfacer   r)   unwrap_user_excsr   r+   r  Q  s`   







	z.Synchronizer._wrap_callable.<locals>.f_wrappedr  )r   r  r!  r#  r  )r<   rY   rJ   r   r   r   r1   r   r  rm   r   r   rF   _wrap_callabler  r   )r)   r  r   r  r!  r#  r  r"  _namer  async_interfacer*   r   r+   r%  =  s0   
NzSynchronizer._wrap_callablec                    sr   t | jd r	|S  j|||ddt| fdd}|tjkr7|r7t|r7 |tj|}t	|| S |S )NF)r!  r#  c                    sv   | j  j }t ( z|g|R i |W W  d    S  ty0 } zd|j_|jd }~ww 1 s4w   Y  d S r   )r   rY   r   r   r~   r   )r)   r  r  instancer  synchronizer_selfwrapped_methodr*   r+   proxy_method  s   z5Synchronizer._wrap_proxy_method.<locals>.proxy_method)
r>   rZ   r%  r   r   r   rF   _wrap_proxy_methodr  r   )r*  methodr   r!  r"  r,  async_proxy_methodr*   r)  r+   r-    s    	zSynchronizer._wrap_proxy_methodc                 C   s(   |j }| ||}t|tr|S t|S r&   )__func__r%  r8   r   staticmethod)r)   r.  r   orig_functionr*   r*   r+   _wrap_proxy_staticmethod  s
   
z%Synchronizer._wrap_proxy_staticmethodc                 C   sN   |j }| j||dd}|tjkr#t|r#| |tj}t||| ddS t|S )NF)r"  T)is_classmethod)r0  r%  r   r   rF   r  r   classmethod)r)   orig_classmethodr   	orig_funcr.  async_methodr*   r*   r+   _wrap_proxy_classmethod  s   z$Synchronizer._wrap_proxy_classmethodc                 C   sF   i }dD ]}t ||rt ||}| j||ddd||< qtdi |S )N)r(   fsetfdelFr!  r"  r*   )r>   r-  property)r)   propr   r  rg   rC   r*   r*   r+   _wrap_proxy_property  s   


z!Synchronizer._wrap_proxy_propertyc                 C   s   | j |j|ddd}t|dS )NFr<  r'   )r-  r(   r%   )r)   r>  r   wrapped_funcr*   r*   r+   _wrap_proxy_classproperty  s   
z&Synchronizer._wrap_proxy_classpropertyc                    s6    fdd}j | jd t|j j |S )z+Returns a custom __init__ for the subclass.c                    sF    |} |} |i |}| i}||jj< || jj< d S r&   )r   r   rX   rY   )r)   r  r  r(  interface_instancesr   r   r*  r*   r+   my_init  s   

z5Synchronizer._wrap_proxy_constructor.<locals>.my_initr   )r  r,   rm   rY   )r*  r   r   rD  r*   rC  r+   _wrap_proxy_constructor  s   z$Synchronizer._wrap_proxy_constructorc                    sH  g }|j d|jD ]=}t|d}|tu s|r#|jtjkr#|| q
|r:| j	|j||d ud}||
|j q
|| j	|||d ud q
t|}	| j|i |d ur]| || d< |j  D ]\}
}|
tv rt|
 }| j|tjddd |< | j|tjdd |
< qb|
dv rqb|
tv rqbt|tr| |tj |
< qbt|tr| |tj |
< qbt|tr| |tj |
< qbt|tr| |tj |
< qbt|tr| |
< qbt |r| |tj |
< qb|d u rt!|j" }t#j$||	 fd	d
d}|d u r|j%n||_%|j&|_&d|j v r|j'|_'d|j v r|j(|_(t)|t*|  |S )N__orig_bases__r6   )require_already_wrappedr,   Fr<  )r!  )r   r,   c                    s
   |   S r&   )update)nsnew_dictr*   r+   r   D  r   z*Synchronizer._wrap_class.<locals>.<lambda>)	exec_body__annotations____annotate_func__)+r   r   	__bases__r<   objectr6   r   Genericappendr   __class_getitem__r7   r   rY   rE  r   _BUILTIN_ASYNC_METHODSr-  r   r   r  IGNORED_ATTRIBUTESr8   r1  r3  r5  r9  r=  r?  r%   rA  r   callabler   r1   types	new_classr2   r4   rM  rN  rm   r   )r)   r   r   r  r  	new_basesbasebase_is_genericwrapped_genericbaseskvk_syncnew_clsr*   rJ  r+   _wrap_class  sn   









zSynchronizer._wrap_classc                 C   sZ  t |dr(| j|jvr!t|jtr|j| ji  nt|| ji  |j| j }nt || js5t|| ji  t|| j}||v rO| jrKt	
d| d || S |rXt| dt|rg| j||||d}n@t|rv| j||||d}n1t|tjr| ||||}n"t|tjr| ||||}n| j|jjv r| |}ntd| |||< |S )Nr   zObject r  z5 needs to be serialized explicitly with a custom namer$  z(Argument %s is not a class or a callable)r<   rX   r   r8   rj   
setdefaultrm   r>   rJ   r   r   r|   r   r   rb  r  r%  r   r   _wrap_param_specr   r   _wrap_type_varr   r   r;   )r)   r.   r   r  rG  r  
interfacesr   r*   r*   r+   r   O  sB   


zSynchronizer._wrapc                 C   sj   t j||jd}t|| j| t|t|  t|t| ||_t|| j	s+t|| j	i  |t
|| j	|< |S )N)bound)r   r   	__bound__rm   rY   r   r  r2   r<   rX   r>   r)   r.   r   r  r  r   r*   r*   r+   re    s   	zSynchronizer._wrap_type_varc                 C   sd   t |}t|| j| t|t|  t|t| ||_t|| js(t|| ji  |t	|| j|< |S r&   )
r   r   rm   rY   r   r  r2   r<   rX   r>   ri  r*   r*   r+   rd    s   
zSynchronizer._wrap_param_specc                 C      t || jd |S r   )rm   rZ   r   r*   r*   r+   nowrap     zSynchronizer.nowrapc                 C   rj  r   )rm   r[   r   r*   r*   r+   no_input_translation  rl  z!Synchronizer.no_input_translationc                 C   rj  r   )rm   r\   r   r*   r*   r+   no_output_translation  rl  z"Synchronizer.no_output_translationc                 C   s   |  | |S r&   )rm  rn  r   r*   r*   r+   no_io_translation  s   zSynchronizer.no_io_translationr  r  c                 C   s   |  |||S r&   )wrap)r)   r.   r  r  r*   r*   r+   r`     s   zSynchronizer.create_blockingc                 C   s   | j |tj||d}|S )Nr$  )r   r   r   )r)   r.   r  r  wrappedr*   r*   r+   rp    s   zSynchronizer.wrapc                 C   s.   t |s
t |rt|| jS t|j| jS r&   )r   r   r  r<   rY   r   r   r*   r*   r+   is_synchronized  s   zSynchronizer.is_synchronized)FTN)Fr&   )NNN)NTTNT)TT)NFN)NN);r1   r2   r3   r4   r   r   rW  FunctionTyper,   rk   rl   ro   r   rc   r!   r   overloadLiteralrp   AbstractEventLoopr   boolUnionr   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r	  r  r%  r-  r3  r9  r?  rA  rE  rb  r   re  rd  rk  rm  rn  ro  r:   r`   rp  rr  r*   r*   r*   r+   rG   o   s    
!% 



	>	G&%

{
$


H
<rG   )>rp   ra   collections.abccollectionsr   concurrent.futuresr]   r
  r   loggingr   r   rN   rz   rW  r   r   r   r   r   r   r   synchronicity.annotationsr   synchronicity.combined_typesr   r   
async_wrapr
   r   r   callbackr   
exceptionsr   r   r   r   r   r   r   r   rT  rU  r  r  r   abc	Awaitable	CoroutineAsyncIteratorAsyncIterableAsyncGeneratorAbstractAsyncContextManagerr=   	getLoggerr1   r   r%   r?   rF   rG   r*   r*   r*   r+   <module>   s^    



