U
    dn*                     @  s  U d Z ddlm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	 ddlm
Z
 dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlZddlmZ ddlmZ ejrddlmZ ddlmZ edef Zeeeeef f Zeeeef ZedddZG dd dZ e
d Z!e"e#Z$de%d< e
def Z&e"e#Z'de%d< d d!d"d#d$Z(d%d&d'd(d)d*Z)d%d&d!d(d+d,Z*d&d&d-d!d.d/d0Z+d&d-d!d1d2d3Z,G d4d5 d5ee Z-dS )6aJ  Provides managed registration services on behalf of :func:`.listen`
arguments.

By "managed registration", we mean that event listening functions and
other objects can be added to various collections in such a way that their
membership in all those collections can be revoked at once, based on
an equivalent :class:`._EventKey`.

    )annotationsN)Any)Callable)cast)Deque)Dict)Generic)Iterable)Optional)Tuple)TypeVar)Union   )exc)util   )RefCollection)
dispatcher._ETEventTarget)boundc                   @  s   e Zd ZU dZdZded< dS )r   zrepresents an event target, that is, something we can listen on
    either with that target as a class or as an instance.

    Examples include:  Connection, Mapper, Table, Session,
    InstrumentedAttribute, Engine, Pool, Dialect.

     zdispatcher[Any]dispatchN)__name__
__module____qualname____doc__	__slots____annotations__r   r   r   =/tmp/pip-unpacked-wheel-wbr0uges/sqlalchemy/event/registry.pyr   2   s   
)zweakref.ref[RefCollection[Any]]weakref.ref[_ListenerFnType]z6Dict[_EventKeyTupleType, _RefCollectionToListenerType]_key_to_collectionr    z>Dict[weakref.ref[RefCollection[Any]], _ListenerToEventKeyType]_collection_to_keyzweakref.ref[Any]None)refreturnc                 C  s^   t r| t krd S td| } t | }| D ],}|tkr,t| }||  |s,t| q,d S )Nz'weakref.ref[RefCollection[EventTarget]])r"   r   popvaluesr!   )r$   listener_to_keykeydispatch_regr   r   r   _collection_gcedg   s    


r+   _EventKey[_ET]RefCollection[_ET]bool)	event_keyownerr%   c                 C  sH   | j }t| }|j}t| j}||kr,dS |||< t| }|||< dS )NFT)_keyr!   r$   weakref
_listen_fnr"   )r/   r0   r)   r*   	owner_ref
listen_refr(   r   r   r   _stored_in_collectionx   s    r6   c                 C  sT   | j }t| }t| j}|j}||d  |s6t|= |tkrPt| }|| d S N)r1   r!   r2   r$   r3   r&   r"   )r/   r0   r)   r*   r5   r4   r(   r   r   r   _removed_from_collection   s    r8   zIterable[_ListenerFnType])newowneroldownerelementsr%   c              	   C  s   |sd S |j }| j }t| }t| }|D ]}t |}z|| }	W n tk
rZ   Y q(Y nX zt|	 }
W n tk
r   Y q(Y nX ||
kr|
| |kstn||
|< |	||< q(d S r7   )r$   r"   r2   KeyErrorr!   AssertionError)r9   r:   r;   Zoldowner_refZnewowner_refZold_listener_to_keyZnew_listener_to_key	listen_fnr5   r)   r*   r   r   r   _stored_in_collection_multi   s(    


r?   )r0   r;   r%   c                 C  sT   |sd S | j }t| }|D ]4}t |}|| }t| }||d  |st|= qd S r7   )r$   r"   r2   r!   r&   )r0   r;   r4   r(   r>   r5   r)   r*   r   r   r   _clear   s    
r@   c                   @  s   e Zd ZU dZdZded< ded< ded< d	ed
< ded< ded< d7ddddddddZeddddZdddddZ	dddddZ
ddddd d!Zddd"d#Zd$dd%d&Zd8d$d$d$d(d$dd)d*d+Zeddd,d-Zd.d/d$d0d1d2Zd.d/dd0d3d4Zd.d/d$d0d5d6ZdS )9	_EventKeyz$Represent :func:`.listen` arguments.)target
identifierfnfn_keyfn_wrapdispatch_targetr   rB   strrC   _ListenerFnTyperD   _ListenerFnKeyTyperE   r   rG   zOptional[_ListenerFnType]_fn_wrapN)rB   rC   rD   rG   rK   c                 C  sP   || _ || _|| _t|tjr6t|jt|jf| _	n
t|| _	|| _
|| _d S r7   )rB   rC   rD   
isinstancetypes
MethodTypeid__func____self__rE   rF   rG   )selfrB   rC   rD   rG   rK   r   r   r   __init__   s    
z_EventKey.__init___EventKeyTupleType)r%   c                 C  s   t | j| j| jfS r7   )rO   rB   rC   rE   rR   r   r   r   r1      s    z_EventKey._keyr,   )rF   r%   c                 C  s,   || j kr| S t| j| j| j| j|dS d S N)rK   )r3   rA   rB   rC   rD   rG   )rR   rF   r   r   r   with_wrapper   s    
z_EventKey.with_wrapper)rG   r%   c                 C  s,   || j kr| S t| j| j| j|| jdS d S rV   )rG   rA   rB   rC   rD   rF   )rR   rG   r   r   r   with_dispatch_target  s    
z_EventKey.with_dispatch_targetr#   )argskwr%   c                 O  s   | dd}| dd}| dd}| j| j| j  }}}t|j|}	|	||}
| |
} t| jjj| j}t	|dr|
  |s|r| tj| j|dj|| n| jjj| f|| d S )NonceFZ_once_unless_exceptionnamed_sa_warn)retry_on_exception)r&   rG   rC   r3   getattrr   Z_adjust_fn_specrW   Z_eventshasattrr]   r   Z	only_oncelistenZ_listen)rR   rY   rZ   r[   Zonce_unless_exceptionr\   rB   rC   rD   dispatch_collectionZadjusted_fnZstub_functionr   r   r   ra     s6    

 
  z_EventKey.listenc                 C  st   | j }|tkr(td| j| j| jf t|}| D ]4\}}| }| }|d k	r:|d k	r:|	| 
| q:d S )Nz*No listeners found for event %s / %r / %s )r1   r!   r   ZInvalidRequestErrorrB   rC   rD   r&   itemsremoverW   )rR   r)   r*   Zcollection_refZlistener_refZ
collectionZlistener_fnr   r   r   rd   8  s    
z_EventKey.remover.   c                 C  s
   | j tkS )z6Return True if this event key is registered to listen.)r1   r!   rU   r   r   r   containsI  s    z_EventKey.containsFzOptional[bool])	propagateinsertr\   retvalasyncior%   c           
      C  sT   | j | j }}t|j|}||j}	|r2|	  |rD|	| | n|	| | d S r7   )rG   rC   r_   r   
for_modifyZ_set_asynciorg   append)
rR   rf   rg   r\   rh   ri   rB   rC   rb   rj   r   r   r   base_listenM  s    	z_EventKey.base_listenc                 C  s   | j p
| jS r7   )rF   rD   rU   r   r   r   r3   c  s    z_EventKey._listen_fnr-   zDeque[_ListenerFnType])r0   list_r%   c                 C  s"   t | |r|| j dS dS d S NTF)r6   rk   r3   rR   r0   rm   r   r   r   append_to_listg  s    
z_EventKey.append_to_listc                 C  s   t | | || j d S r7   )r8   rd   r3   ro   r   r   r   remove_from_listr  s    
z_EventKey.remove_from_listc                 C  s"   t | |r|| j dS dS d S rn   )r6   
appendleftr3   ro   r   r   r   prepend_to_listz  s    
z_EventKey.prepend_to_list)N)FFFNF)r   r   r   r   r   r   rS   propertyr1   rW   rX   ra   rd   re   rl   r3   rp   rq   rs   r   r   r   r   rA      s8   
	       rA   ).r   
__future__r   collectionsrM   typingr   r   r   r   r   r   r	   r
   r   r   r   r2    r   r   TYPE_CHECKINGattrr   baser   rI   intrJ   rH   rT   r   r   Z_RefCollectionToListenerTypedefaultdictdictr!   r   Z_ListenerToEventKeyTyper"   r+   r6   r8   r?   r@   rA   r   r   r   r   <module>   sX   	

$