B
    \                 @   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   sz   |sd S |j }| j } t| }t|  }xP|D ]H}t |}|| }t| }| |krb||  |ksjtn||| < |||< q*W d S )N)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   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}| j| j| j  }}}t|j|}|||}	| |	} t| jjj| j}
t	|
drt|

  |r| t| jj|| n| jjj| f|| d S )NonceFnamed_sa_warn)r   r%   r!   r   getattrdispatchZ_adjust_fn_specr/   Z_eventshasattrr3   r   Z	only_oncelistenZ_listen)r,   argskwr1   r2   r    r!   r"   dispatch_collectionZadjusted_fnZstub_functionr   r   r   r7      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remover/   )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	   )r,   r   r   r   contains   s    z_EventKey.containsFc             C   sL   | j | j }}t|j|}|r4||j| | n||j| | d S )N)r%   r!   r4   r5   Z
for_modifyinsertappend)r,   Z	propagater>   r2   Zretvalr    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   r?   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   rA   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   rA   r   r   r   prepend_to_list  s    
z_EventKey.prepend_to_list)N)FFFN)__name__
__module____qualname____doc__	__slots__r.   propertyr   r/   r0   r7   r<   r=   r@   r   rB   rC   rE   r   r   r   r   r      s   

r   )rI   Z
__future__r   collectionsr'   r    r   r   defaultdictdictr	   r   r   r   r   r   r   objectr   r   r   r   r   <module>   s   

