U
    x^ &                     @   s   d Z ddlm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	 e	
eZd
d ZG dd deZG dd deZG dd deZdd Zdd ZG dd de	eeZG dd deZG dd deZdS )a  Base implementation classes.

The public-facing ``Events`` serves as the base class for an event interface;
its public attributes represent different kinds of events.   These attributes
are mirrored onto a ``_Dispatch`` class, which serves as a container for
collections of listener functions.   These collections are represented both
at the class level of a particular ``_Dispatch`` class as well as within
instances of ``_Dispatch``.

    )absolute_importN   )_ClsLevelDispatch)_EmptyListener)_JoinedListener   )utilc                 C   s   |  d o| dkS )N_dispatch)
startswith)name r   =/tmp/pip-install-dq5v43_d/SQLAlchemy/sqlalchemy/event/base.py_is_event_name   s    r   c                   @   s   e Zd ZdZdd ZdS )_UnpickleDispatchzSerializable callable that re-generates an instance of
    :class:`_Dispatch` given a particular :class:`.Events` subclass.

    c                 C   s8   |j D ]$}d|jkr|jd j|  S qtdd S )Nr
   z*No class with a 'dispatch' member present.)__mro____dict__r
   
_for_classAttributeError)self_instance_clsclsr   r   r   __call__)   s    


z_UnpickleDispatch.__call__N)__name__
__module____qualname____doc__r   r   r   r   r   r   #   s   r   c                   @   sx   e Zd ZdZdZe ZdddZdd Z	e
dd	 Ze
d
d Zdd Zdd Zdd Zdd ZdddZdd ZdS )	_Dispatcha;  Mirror the event listening definitions of an Events class with
    listener collections.

    Classes which define a "dispatch" member will return a
    non-instantiated :class:`._Dispatch` subclass when the member
    is accessed at the class level.  When the "dispatch" member is
    accessed at the instance level of its owner, an instance
    of the :class:`._Dispatch` class is returned.

    A :class:`._Dispatch` class is generated for each :class:`.Events`
    class defined, by the :func:`._create_dispatcher_class` function.
    The original :class:`.Events` classes remain untouched.
    This decouples the construction of :class:`.Events` subclasses from
    the implementation used by the event internals, and allows
    inspecting tools like Sphinx to work in an unsurprising
    way against the public API.

    )_parentr   r   _empty_listenersNc                    sb   || _  | _ rXz| j  | _W q^ tk
rT    fdd|jD  | _| j < Y q^X ni | _d S )Nc                    s   i | ]}|j t| qS r   )r   r   ).0lsinstance_clsr   r   
<dictcomp>W   s    z&_Dispatch.__init__.<locals>.<dictcomp>)r   r   _empty_listener_regr   KeyError_event_descriptors)r   parentr#   r   r"   r   __init__M   s    


z_Dispatch.__init__c                 C   sB   z| j | }W n tk
r*   t|Y nX t| |j| |S d S N)r   r&   r   setattrr   )r   r   r!   r   r   r   __getattr__^   s    z_Dispatch.__getattr__c                 c   s   | j D ]}t| |V  qd S r*   )_event_namesgetattr)r   kr   r   r   r'   i   s    
z_Dispatch._event_descriptorsc                 C   s   | j jS r*   )_events_listenr   r   r   r   r1   p   s    z_Dispatch._listenc                 C   s   |  | |S r*   )	__class__)r   r#   r   r   r   r   t   s    z_Dispatch._for_classc                 C   s   |j }| |S r*   )r3   r   )r   instancer#   r   r   r   _for_instancew   s    z_Dispatch._for_instancec                 C   s<   d| j jkr0td| j j tfd| ji}|| j _| | |S )zCreate a 'join' of this :class:`._Dispatch` and another.

        This new dispatcher will dispatch events to both
        :class:`._Dispatch` objects.

        _joined_dispatch_clszJoined%s	__slots__)r3   r   typer   _JoinedDispatcherr-   r6   )r   otherr   r   r   r   _join{   s    
z_Dispatch._joinc                 C   s   t  | jffS r*   )r   r   r2   r   r   r   
__reduce__   s    z_Dispatch.__reduce__Tc                 C   s8   |j D ],}t|trqt| |j| j||d qdS )zMPopulate from the listeners in another :class:`_Dispatch`
            object.)only_propagateN)r'   
isinstancer   r.   r   
for_modify_update)r   r:   r=   r!   r   r   r   r@      s    

 z_Dispatch._updatec                 C   s   | j D ]}||   qd S r*   )r'   r?   clear)r   r!   r   r   r   _clear   s    
z_Dispatch._clear)N)T)r   r   r   r   r7   weakrefWeakKeyDictionaryr%   r)   r,   propertyr'   r1   r   r5   r;   r<   r@   rB   r   r   r   r   r   3   s   




r   c                   @   s   e Zd ZdZdd ZdS )
_EventMetazKIntercept new Event subclasses and create
    associated _Dispatch classes.c                 C   s   t | ||| t| |||S r*   )_create_dispatcher_classr8   r)   )r   	classnamebasesdict_r   r   r   r)      s    z_EventMeta.__init__N)r   r   r   r   r)   r   r   r   r   rF      s   rF   c                 C   s   t | dr| jj}nt}dd |D }td| |fd|i}||_| | |}|jD ](}t||t| ||  t	| 
|  qT|jD ]B}	t|	tr|	tk	r|	jjjD ] }
t||
j|
 |j
|
j qqt| ddrt| | j_dS )zRCreate a :class:`._Dispatch` class corresponding to an
    :class:`.Events` class.r
   c                 S   s   g | ]}t |r|qS r   )r   )r    r/   r   r   r   
<listcomp>   s      z,_create_dispatcher_class.<locals>.<listcomp>z
%sDispatchr7   _dispatch_targetN)hasattrr
   r3   r   r8   r-   _set_dispatchr+   r   _registrarsappend	__bases__
issubclassr0   r'   r   r.   
dispatcherrL   )r   rH   rI   rJ   Zdispatch_baseZevent_namesdispatch_clsZdispatch_instr/   Zsuper_r!   r   r   r   rG      s*    

  

rG   c                 C   s.   | j jD ] }t| |  t| st|= qd S r*   )r
   r-   rO   remove)r   r/   r   r   r   _remove_dispatcher   s    rV   c                   @   sN   e Zd ZdZedd Zedd ZedddZed	d
 Z	edd Z
dS )Eventsz>Define event listening functions for a particular target type.c                 C   s   |d | _ | |_| j S r*   )r
   r0   )r   rT   r   r   r   rN      s    
zEvents._set_dispatchc                    sX    fdd} fdd}t  drT|| jjsP|t| jjsP|trT|| jjrT S d S )Nc                     s   t  fdd| D S )Nc                 3   s   | ]}t  j|V  qd S r*   )r>   r
   )r    ttargetr   r   	<genexpr>   s     z;Events._accept_with.<locals>.dispatch_is.<locals>.<genexpr>)all)typesrY   r   r   dispatch_is   s    z(Events._accept_with.<locals>.dispatch_isc                    s   t  jj| S r*   )r>   r
   r(   )rX   rY   r   r   dispatch_parent_is   s    z/Events._accept_with.<locals>.dispatch_parent_isr
   )rM   r
   r3   r8   r9   )r   rZ   r^   r_   r   rY   r   _accept_with   s    


zEvents._accept_withFc                 C   s   |j |||d d S )N)	propagateinsertnamed)Zbase_listen)r   	event_keyra   rb   rc   r   r   r   r1      s    zEvents._listenc                 C   s   |   d S r*   )rU   )r   rd   r   r   r   _remove   s    zEvents._removec                 C   s   | j   d S r*   )r
   rB   )r   r   r   r   rB      s    zEvents._clearN)FFF)r   r   r   r   staticmethodrN   classmethodr`   r1   re   rB   r   r   r   r   rW      s   



rW   c                   @   s<   e Zd ZdZdZdd Zdd Zedd Zed	d
 Z	dS )r9   z5Represent a connection between two _Dispatch objects.localr(   r   c                 C   s   || _ || _| j j| _d S r*   rh   )r   ri   r(   r   r   r   r)     s    z_JoinedDispatcher.__init__c                 C   s.   t | j|}t| j|j|}t| |j| |S r*   )r.   ri   r   r(   r   r+   )r   r   r!   Zjlr   r   r   r,   
  s    z_JoinedDispatcher.__getattr__c                 C   s   | j jS r*   )r(   r1   r2   r   r   r   r1     s    z_JoinedDispatcher._listenc                 C   s   | j jS r*   )r(   r0   r2   r   r   r   r0     s    z_JoinedDispatcher._eventsN)
r   r   r   r   r7   r)   r,   rE   r1   r0   r   r   r   r   r9      s   
r9   c                   @   s    e Zd ZdZdd Zdd ZdS )rS   zDescriptor used by target classes to
    deliver the _Dispatch class at the class level
    and produce new _Dispatch instances for target
    instances.

    c                 C   s   |j | _ || _d S r*   )r
   events)r   rj   r   r   r   r)   #  s    zdispatcher.__init__c                 C   s(   |d kr| j S | j | |jd< }|S )Nr
   )r
   r5   r   )r   objr   Zdispr   r   r   __get__'  s    zdispatcher.__get__N)r   r   r   r   r)   rl   r   r   r   r   rS     s   rS   )r   
__future__r   rC   attrr   r   r    r   defaultdictlistrO   r   objectr   r   r8   rF   rG   rV   with_metaclassrW   r9   rS   r   r   r   r   <module>   s    

k	"0