U
    d:                     @  s  U 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 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 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 eeZde d< ddddd Z!G d!d" d"Z"G d#d$ d$ee Z#G d%d& d&e#e Z$d'd(d)d*d+Z%G d,d- d-ee Z&G d.d/ d/e&e Z'G d0d1 d1e#e Z(G d2d3 d3ee Z)G d4d5 d5e)e Z*dS )6a  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``.

    )annotationsN)Any)cast)Dict)Generic)Iterator)List)MutableMapping)Optional)overload)Tuple)Type)Union   )_ClsLevelDispatch)_EmptyListener)_InstanceLevelDispatch)_JoinedListener)_ET)	_EventKey   )util)Literalz8MutableMapping[str, List[Type[_HasEventsDispatch[Any]]]]_registrarsstrboolnamereturnc                 C  s   |  d r| dkp|  dS )N_dispatchZ	_sa_event)
startswith)r    r"   9/tmp/pip-unpacked-wheel-wbr0uges/sqlalchemy/event/base.py_is_event_name1   s    r$   c                   @  s    e Zd ZdZdddddZdS )_UnpickleDispatchzSerializable callable that re-generates an instance of
    :class:`_Dispatch` given a particular :class:`.Events` subclass.

    	Type[_ET]_Dispatch[_ET])_instance_clsr   c                 C  s>   |j D ]*}d|jkrtd|jd j|  S qtdd S )Nr    r'   z*No class with a 'dispatch' member present.)__mro____dict__r   r    
_for_classAttributeError)selfr(   clsr"   r"   r#   __call__A   s    

 

z_UnpickleDispatch.__call__N)__name__
__module____qualname____doc__r/   r"   r"   r"   r#   r%   ;   s   r%   c                   @  sL   e Zd ZU dZded< dddddZd	d
dddZeddddZdS )_DispatchCommonr"   Optional[Type[_ET]]r(   _DispatchCommon[_ET]_JoinedDispatcher[_ET]otherr   c                 C  s
   t  d S NNotImplementedError)r-   r9   r"   r"   r#   _joinP   s    z_DispatchCommon._joinr   _InstanceLevelDispatch[_ET]r   c                 C  s
   t  d S r:   r;   r-   r   r"   r"   r#   __getattr__S   s    z_DispatchCommon.__getattr__Type[_HasEventsDispatch[_ET]]r   c                 C  s
   t  d S r:   r;   r-   r"   r"   r#   _eventsV   s    z_DispatchCommon._eventsN)	r0   r1   r2   	__slots____annotations__r=   r@   propertyrD   r"   r"   r"   r#   r4   K   s   
r4   c                   @  s   e Zd ZU dZdZded< e Zded< ded< d	ed
< ded< ded< ded< d<dddddZ	dddddZ
eddddZdd d!d"d#d$Zd%d&d'd(d)Zd*d&d+d,d-Zd.d/d0d1d2Zd3dd4d5Zd=d&dd!d7d8d9Zd!dd:d;ZdS )>	_DispatchaM  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 :meth:`._HasEventsDispatch._create_dispatcher_class`
    method.  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_listenersr   Z_active_historyz9MutableMapping[Type[_ET], Dict[str, _EmptyListener[_ET]]]_empty_listener_regzDict[str, _EmptyListener[_ET]]rJ   z	List[str]_event_namesr5   r(   zType[_JoinedDispatcher[_ET]]_joined_dispatch_clsrA   rD   NzOptional[_Dispatch[_ET]])parentinstance_clsc                   sn   || _  | _ rd|d k	stz| j  | _W qj tk
r`    fdd|jD  | _| j < Y qjX ni | _d S )Nc                   s   i | ]}|j t| qS r"   )r   r   ).0lsrO   r"   r#   
<dictcomp>   s    z&_Dispatch.__init__.<locals>.<dictcomp>)rI   r(   AssertionErrorrK   rJ   KeyError_event_descriptors)r-   rN   rO   r"   rR   r#   __init__   s    


z_Dispatch.__init__r   r>   r   c                 C  sB   z| j | }W n tk
r*   t|Y nX t| |j| |S d S r:   )rJ   rU   r,   setattrr   )r-   r   rQ   r"   r"   r#   r@      s    z_Dispatch.__getattr__z Iterator[_ClsLevelDispatch[_ET]]rB   c                 c  s   | j D ]}t| |V  qd S r:   )rL   getattr)r-   kr"   r"   r#   rV      s    
z_Dispatch._event_descriptors_EventKey[_ET]r   None	event_keykwr   c                 K  s   | j j|f|S r:   )rD   _listenr-   r^   r_   r"   r"   r#   r`      s    z_Dispatch._listenr&   r'   )rO   r   c                 C  s   |  | |S r:   )	__class__)r-   rO   r"   r"   r#   r+      s    z_Dispatch._for_classr   )instancer   c                 C  s   |j }| |S r:   )rb   r+   )r-   rc   rO   r"   r"   r#   _for_instance   s    z_Dispatch._for_instancer6   r7   r8   c                 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.

        rM   zJoined%srE   )rb   r*   typer0   _JoinedDispatcherrL   rM   )r-   r9   r.   r"   r"   r#   r=      s    
z_Dispatch._joinzUnion[str, Tuple[Any, ...]]c                 C  s   t  | jffS r:   )r%   r(   rC   r"   r"   r#   
__reduce__   s    z_Dispatch.__reduce__T)r9   only_propagater   c                 C  s8   |j D ],}t|trqt| |j| j||d qdS )zIPopulate from the listeners in another :class:`_Dispatch`
        object.)rh   N)rV   
isinstancer   rY   r   
for_modify_update)r-   r9   rh   rQ   r"   r"   r#   rk      s    

 z_Dispatch._updatec                 C  s   | j D ]}||   qd S r:   )rV   rj   clear)r-   rQ   r"   r"   r#   _clear   s    
z_Dispatch._clear)N)T)r0   r1   r2   r3   rE   rF   weakrefWeakKeyDictionaryrK   rW   r@   rG   rV   r`   r+   rd   r=   rg   rk   rm   r"   r"   r"   r#   rH   [   s.   


  rH   rA   r\   )r.   r   c                 C  s.   | j jD ] }t| |  t| st|= qd S r:   )r    rL   r   remove)r.   rZ   r"   r"   r#   _remove_dispatcher   s    rq   c                	   @  s   e Zd ZU ded< ded< ejr0ddddd	Zd
dddZeddddddZ	eddddddddddd
dddZ
eddddddZeddd d
d!d"d#Zd$S )%_HasEventsDispatchr5   _dispatch_targetr'   r    r   r>   r   c                 C  s   d S r:   r"   r?   r"   r"   r#   r@      s    z_HasEventsDispatch.__getattr__r\   rB   c                 C  s   |  | j| j| j dS )zOIntercept new Event subclasses and create associated _Dispatch
        classes.N)_create_dispatcher_classr0   	__bases__r*   r.   r"   r"   r#   __init_subclass__   s    z$_HasEventsDispatch.__init_subclass__Union[_ET, Type[_ET]]Optional[Union[_ET, Type[_ET]]]target
identifierr   c                 C  s
   t  d S r:   r;   )r.   r{   r|   r"   r"   r#   _accept_with   s    z_HasEventsDispatch._accept_withF	propagateinsertnamedasyncior[   r   r^   r   r   r   r   r   c                C  s
   t  d S r:   r;   r.   r^   r   r   r   r   r"   r"   r#   r`     s    
z_HasEventsDispatch._listenrA   Type[_Dispatch[_ET]])klassdispatch_clsr   c                 C  s   |d | _ | |_| j S r:   )r    rD   )r   r   r"   r"   r#   _set_dispatch  s    

z _HasEventsDispatch._set_dispatchzTuple[type, ...]zDict[str, Any])	classnamebasesdict_r   c                 C  s   t | dr| jj}nt}dd |D }tdtd| |fd|i}||_| | |}|jD ](}t||t	| ||  t
| |  qZ|jD ]B}	t|	tr|	tk	r|	jjjD ] }
t||
j|
 |j|
j qqt| ddr| j}|dk	stt |drd	|jkrt| |_n
t| |_dS )
zVCreate a :class:`._Dispatch` class corresponding to an
        :class:`.Events` class.r    c                 S  s   g | ]}t |r|qS r"   )r$   )rP   rZ   r"   r"   r#   
<listcomp>*  s      z?_HasEventsDispatch._create_dispatcher_class.<locals>.<listcomp>r   z
%sDispatchrE   rs   N_slots_dispatch)hasattrr    rb   rH   r   re   rL   r   rX   r   r   appendru   
issubclassrD   rV   r   rY   rs   rT   rE   slots_dispatcher
dispatcher)r.   r   r   r   Zdispatch_baseZevent_namesr   Zdispatch_instrZ   Zsuper_rQ   Zdispatch_target_clsr"   r"   r#   rt     s>    


	

z+_HasEventsDispatch._create_dispatcher_classN)r0   r1   r2   rF   typingTYPE_CHECKINGr@   rw   classmethodr}   r`   staticmethodr   rt   r"   r"   r"   r#   rr      s"   
rr   c                	   @  st   e Zd ZdZeddddddZeddddd	d
ddddddddZed
ddddZeddddZdS )Eventsz>Define event listening functions for a particular target type.rx   r   ry   rz   c                   sh   ddd fdd}ddd fdd}t  d	rd|| jjs`|t| jjs`|trd|| jjrd S d S )
N	Type[Any]r   )typesr   c                    s   t  fdd| D S )Nc                 3  s   | ]}t  j|V  qd S r:   )ri   r    )rP   tr{   r"   r#   	<genexpr>T  s     z;Events._accept_with.<locals>.dispatch_is.<locals>.<genexpr>)all)r   r   r"   r#   dispatch_isS  s    z(Events._accept_with.<locals>.dispatch_is)r   r   c                   s   t td jj| S )Nr7   )ri   r   r    rN   )r   r   r"   r#   dispatch_parent_isV  s     z/Events._accept_with.<locals>.dispatch_parent_isr    )r   r    rb   re   rf   )r.   r{   r|   r   r   r"   r   r#   r}   O  s    


zEvents._accept_withFr~   r[   r   r\   r   c                C  s   |j ||||d d S )Nr~   )Zbase_listenr   r"   r"   r#   r`   k  s    
   zEvents._listen)r^   r   c                 C  s   |   d S r:   )rp   )r.   r^   r"   r"   r#   _removey  s    zEvents._removerB   c                 C  s   | j   d S r:   )r    rm   rv   r"   r"   r#   rm   }  s    zEvents._clearN)	r0   r1   r2   r3   r   r}   r`   r   rm   r"   r"   r"   r#   r   L  s   r   c                   @  sr   e Zd ZU dZdZded< ded< ded< dddd	d
ZdddddZddddddZe	ddddZ
dS )rf   z5Represent a connection between two _Dispatch objects.localrN   r(   r6   r   rN   r5   r(   )r   rN   c                 C  s   || _ || _| j j| _d S r:   r   )r-   r   rN   r"   r"   r#   rW     s    z_JoinedDispatcher.__init__r   z_JoinedListener[_ET]r   c                 C  s.   t | j|}t| j|j|}t| |j| |S r:   )rY   r   r   rN   r   rX   )r-   r   rQ   Zjlr"   r"   r#   r@     s    z_JoinedDispatcher.__getattr__r[   r   r\   r]   c                 K  s   | j j|f|S r:   )rN   r`   ra   r"   r"   r#   r`     s    z_JoinedDispatcher._listenrA   rB   c                 C  s   | j jS r:   )rN   rD   rC   r"   r"   r#   rD     s    z_JoinedDispatcher._eventsN)r0   r1   r2   r3   rE   rF   rW   r@   r`   rG   rD   r"   r"   r"   r#   rf     s   
rf   c                   @  s\   e Zd ZdZddddZedddd	d
dZedddd	ddZdddd	ddZdS )r   zDescriptor used by target classes to
    deliver the _Dispatch class at the class level
    and produce new _Dispatch instances for target
    instances.

    rA   )eventsc                 C  s   |j | _ || _d S r:   )r    r   )r-   r   r"   r"   r#   rW     s    zdispatcher.__init__zLiteral[None]r   r   objr.   r   c                 C  s   d S r:   r"   r-   r   r.   r"   r"   r#   __get__  s    zdispatcher.__get__r   r6   c                 C  s   d S r:   r"   r   r"   r"   r#   r     s    c              
   C  s`   |d kr| j S | j |}z||jd< W n2 tk
rZ } ztd|f |W 5 d }~X Y nX |S )Nr    zGtarget %r doesn't have __dict__, should it be defining _slots_dispatch?)r    rd   r*   r,   	TypeError)r-   r   r.   dispZaer"   r"   r#   r     s    N)r0   r1   r2   r3   rW   r   r   r"   r"   r"   r#   r     s   r   c                   @  s   e Zd ZddddddZdS )r   r   r   r   c                 C  s4   |d kr| j S t|dr|jS | j |}||_|S )Nr   )r    r   r   rd   )r-   r   r.   r   r"   r"   r#   r     s    
zslots_dispatcher.__get__N)r0   r1   r2   r   r"   r"   r"   r#   r     s   r   )+r3   
__future__r   r   r   r   r   r   r   r   r	   r
   r   r   r   r   rn   attrr   r   r   r   registryr   r    r   Zutil.typingr   defaultdictlistr   rF   r$   r%   r4   rH   rq   rr   r   rf   r   r   r"   r"   r"   r#   <module>   sH   


 g6 %