B
    KLc&!                 @   s   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 e	e
Ze	e
Zdd Zd	d
 Zdd Zdd Zdd ZG dd deZdS )aJ  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`.

    )absolute_importN   )exc)utilc             C   sX   t r| t krd S t | }x8| D ],}|tkr$t| }||  |s$t| q$W d S )N)_collection_to_keypopvalues_key_to_collection)reflistener_to_keykeydispatch_reg r   8lib/python3.7/site-packages/sqlalchemy/event/registry.py_collection_gced5   s    

r   c             C   sH   | j }t| }|j}t| j}||kr,dS |||< t| }|||< dS )NFT)_keyr	   r
   weakref
_listen_fnr   )	event_keyownerr   r   	owner_ref
listen_refr   r   r   r   _stored_in_collectionC   s    r   c             C   sT   | j }t| }t| j}|j}||d  |s6t|= |tkrPt| }|| d S )N)r   r	   r   r
   r   r   r   )r   r   r   r   r   r   r   r   r   r   _removed_from_collectionV   s    r   c       	   	   C   s   |sd S |j }| j } t| }t|  }x|D ]}t |}y|| }W n tk
rZ   w*Y nX yt| }W n tk
r~   w*Y nX | |kr||  |kstn||| < |||< q*W d S )N)r
   r   r   KeyErrorr	   AssertionError)	ZnewownerZoldownerelementsZold_listener_to_keyZnew_listener_to_key	listen_fnr   r   r   r   r   r   _stored_in_collection_multig   s(    

r   c             C   sX   |sd S | j } t|  }x<|D ]4}t |}|| }t| }|| d  |st|= qW d S )N)r
   r   r   r	   r   )r   r   r   r   r   r   r   r   r   r   _clear   s    

r   c               @   s   e Zd ZdZdZdddZedd Zdd	 Zd
d Z	dd Z
dd Zdd ZdddZedd Zdd Zdd Zdd ZdS )	_EventKeyz$Represent :func:`.listen` arguments.)target
identifierfnfn_keyfn_wrapdispatch_targetNc             C   sP   || _ || _|| _t|tjr6t|jt|jf| _	n
t|| _	|| _
|| _d S )N)r!   r"   r#   
isinstancetypes
MethodTypeid__func____self__r$   r%   r&   )selfr!   r"   r#   r&   _fn_wrapr   r   r   __init__   s    
z_EventKey.__init__c             C   s   t | j| j| jfS )N)r*   r!   r"   r$   )r-   r   r   r   r      s    z_EventKey._keyc             C   s,   || j kr| S t| j| j| j| j|dS d S )N)r.   )r   r    r!   r"   r#   r&   )r-   r%   r   r   r   with_wrapper   s    
z_EventKey.with_wrapperc             C   s,   || j kr| S t| j| j| j|| jdS d S )N)r.   )r&   r    r!   r"   r#   r%   )r-   r&   r   r   r   with_dispatch_target   s    
z_EventKey.with_dispatch_targetc             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)Zretry_on_exception)r   r&   r"   r   getattrdispatchZ_adjust_fn_specr0   Z_eventshasattrr4   r   Z	only_oncelistenZ_listen)r-   argskwr2   Zonce_unless_exceptionr3   r!   r"   r#   dispatch_collectionZadjusted_fnZstub_functionr   r   r   r8      s&    


z_EventKey.listenc             C   sx   | j }|tkr(td| j| j| jf t|}x@| D ]4\}}| }| }|d k	r<|d k	r<|	| 
| q<W d S )Nz*No listeners found for event %s / %r / %s )r   r	   r   ZInvalidRequestErrorr!   r"   r#   r   itemsremover0   )r-   r   r   Zcollection_refZlistener_refZ
collectionZlistener_fnr   r   r   r=      s    
z_EventKey.removec             C   s
   | j tkS )z6Return True if this event key is registered to listen.)r   r	   )r-   r   r   r   contains   s    z_EventKey.containsFc       
      C   sT   | j | j }}t|j|}||j}	|r2|	  |rD|	| | n|	| | d S )N)r&   r"   r5   r6   
for_modifyZ_set_asyncioinsertappend)
r-   Z	propagater@   r3   ZretvalZasyncior!   r"   r;   r?   r   r   r   base_listen   s    	z_EventKey.base_listenc             C   s   | j p
| jS )N)r%   r#   )r-   r   r   r   r     s    z_EventKey._listen_fnc             C   s"   t | |r|| j dS dS d S )NTF)r   rA   r   )r-   r   list_r   r   r   append_to_list  s    
z_EventKey.append_to_listc             C   s   t | | || j d S )N)r   r=   r   )r-   r   rC   r   r   r   remove_from_list   s    
z_EventKey.remove_from_listc             C   s"   t | |r|| j dS dS d S )NTF)r   
appendleftr   )r-   r   rC   r   r   r   prepend_to_list$  s    
z_EventKey.prepend_to_list)N)FFFNF)__name__
__module____qualname____doc__	__slots__r/   propertyr   r0   r1   r8   r=   r>   rB   r   rD   rE   rG   r   r   r   r   r       s$   
     
r    )rK   Z
__future__r   collectionsr(   r    r   r   defaultdictdictr	   r   r   r   r   r   r   objectr    r   r   r   r   <module>   s   

 