U
    x^3                      @   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   sT   t r| t krd S t | }| D ],}|tkr"t| }||  |s"t| q"d S N)_collection_to_keypopvalues_key_to_collection)reflistener_to_keykeydispatch_reg r   A/tmp/pip-install-dq5v43_d/SQLAlchemy/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 r   )r   r
   r   r   r   r   r   )r   r   r   r   r   r   r   r   r   r   _removed_from_collectionV   s    r   c           	      C   sv   |sd S |j }| j } t| }t|  }|D ]H}t |}|| }t| }| |kr`||  |kshtn||| < |||< q(d S r   )r   r   r   r
   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   sT   |sd S | j } t|  }|D ]4}t |}|| }t| }|| d  |st|= qd S r   )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 r   )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 r   )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 r1   )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)retry_on_exception)r   r&   r"   r   getattrdispatchZ_adjust_fn_specr2   Z_eventshasattrr6   r   Z	only_oncelistenZ_listen)r-   argskwr4   Zonce_unless_exceptionr5   r!   r"   r#   dispatch_collectionZadjusted_fnZstub_functionr   r   r   r;      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 )r   r
   r   ZInvalidRequestErrorr!   r"   r#   r   itemsremover2   )r-   r   r   Zcollection_refZlistener_refZ
collectionZlistener_fnr   r   r   r@      s    
z_EventKey.removec                 C   s
   | j tkS )z?Return True if this event key is registered to listen.
        )r   r
   r0   r   r   r   contains   s    z_EventKey.containsFc                 C   sL   | j | j }}t|j|}|r4||j| | n||j| | d S r   )r&   r"   r8   r9   Z
for_modifyinsertappend)r-   	propagaterB   r5   retvalr!   r"   r>   r   r   r   base_listen   s      z_EventKey.base_listenc                 C   s   | j p
| jS r   )r%   r#   r0   r   r   r   r     s    z_EventKey._listen_fnc                 C   s"   t | |r|| j dS dS d S NTF)r   rC   r   r-   r   list_r   r   r   append_to_list  s    
z_EventKey.append_to_listc                 C   s   t | | || j d S r   )r   r@   r   rH   r   r   r   remove_from_list  s    
z_EventKey.remove_from_listc                 C   s"   t | |r|| j dS dS d S rG   )r   
appendleftr   rH   r   r   r   prepend_to_list  s    
z_EventKey.prepend_to_list)N)FFFN)__name__
__module____qualname____doc__	__slots__r/   propertyr   r2   r3   r;   r@   rA   rF   r   rJ   rK   rM   r   r   r   r   r       s(   	

        

r    )rQ   
__future__r   collectionsr(   r    r   r   defaultdictdictr
   r   r   r   r   r   r   objectr    r   r   r   r   <module>   s   


