U a:@sdZddlmZddlmZddlZddlmZddlZddlm Z ddlm Z d d lm Z d d lm Z d d l m Z d d lmZGddde jZGdddeZGdddeZGdddeZGdddeZGdddeZGdddeZGdddeZdS)aAttribute implementation for _Dispatch classes. The various listener targets for a particular event class are represented as attributes, which refer to collections of listeners to be fired off. These collections can exist at the class level as well as at the instance level. An event is fired off using code like this:: some_object.dispatch.first_connect(arg1, arg2) Above, ``some_object.dispatch`` would be an instance of ``_Dispatch`` and ``first_connect`` is typically an instance of ``_ListenerCollection`` if event listeners are present, or ``_EmptyListener`` if none are present. The attribute mechanics here spend effort trying to ensure listener functions are available with a minimum of function call overhead, that unnecessary objects aren't created (i.e. many empty per-instance listener collections), as well as that everything is garbage collectable when owning references are lost. Other features such as "propagation" of listener functions across many ``_Dispatch`` instances, "joining" of multiple ``_Dispatch`` instances, as well as support for subclass propagation (e.g. events assigned to ``Pool`` vs. ``QueuePool``) are all implemented here. )absolute_import)with_statementN)chain)legacy)registry)exc)util) threading)AsyncAdaptedLockc@seZdZdZddZdS) RefCollection)refcCst|tjSN)weakrefrrZ_collection_gcedselfrVC:\Users\vtejo\AppData\Local\Temp\pip-unpacked-wheel-nyjtotrf\sqlalchemy\event\attr.py_memoized_attr_ref2sz RefCollection._memoized_attr_refN)__name__ __module__ __qualname__ __slots__rrrrrr /sr c@s4eZdZddZddZddZddZd d Zd S) _empty_collectioncCsdSrrrelementrrrappend7sz_empty_collection.appendcCsdSrr)rotherrrrextend:sz_empty_collection.extendcCsdSrrrrrrremove=sz_empty_collection.removecCstgSr)iterrrrr__iter__@sz_empty_collection.__iter__cCsdSrrrrrrclearCsz_empty_collection.clearN)rrrrrr r"r#rrrrr6s rc@sdeZdZdZdZddZddZddZd d Zd d Z d dZ ddZ ddZ ddZ ddZdS)_ClsLevelDispatchz2Class-level events on :class:`._Dispatch` classes.)clsnamename arg_nameshas_kwlegacy_signatures _clslevel __weakref__cCsv|j|_|j|_t|}|jdd|_t|j|_ t t t t |dgddd|_t||||_t|_dS)NrZ_legacy_signaturescSs|dS)Nrr)srrr]z,_ClsLevelDispatch.__init__..)key)rr&r%r Zinspect_getfullargspecargsr'boolvarkwr(listreversedsortedgetattrr)rZ_augment_fn_docs__doc__rWeakKeyDictionaryr*)rZparent_dispatch_clsfnargspecrrr__init__Ts   z_ClsLevelDispatch.__init__cCsN|r||}|jrJztj|dd}Wntk r:YnXt|||}|S)NT)Zno_self)_wrap_fn_for_kwr)r Zget_callable_argspec TypeErrorrZ_wrap_fn_for_legacy)rr9namedr:rrr_adjust_fn_speces z!_ClsLevelDispatch._adjust_fn_speccsfdd}|S)Ncs$ttj|}||f|Sr)dictzipr'update)r0kwZargdictr9rrrwrap_kwrs z2_ClsLevelDispatch._wrap_fn_for_kw..wrap_kwr)rr9rErrDrr<qsz!_ClsLevelDispatch._wrap_fn_for_kwcCs|j}t|tstdt|dds2td|t|D]H}||k r^||j kr^| |q<||j krr| ||j | |j qsz5_ClsLevelDispatch.update_subclass..)r*rO__mro__r)rrVrWrr\rrNs    z!_ClsLevelDispatch.update_subclasscCsB|j}t|D] }||jkr|j||jqt||dSr)rHr rMr*r rQr_removed_from_collection)rrTrVrWrrrr s  z_ClsLevelDispatch.removecCs8t}|jD]}|||qt||dS)zClear all class level listenersN)setr*valuesrBr#r_clear)rZto_clear dispatcherrrrr#s   z_ClsLevelDispatch.clearcCs|S)zReturn an event collection which can be modified. For _ClsLevelDispatch at the class level of a dispatcher, this returns self. rrobjrrr for_modifysz_ClsLevelDispatch.for_modifyN)rrrr7rr;r?r<rXrrOrNr r#rfrrrrr$Gs    r$c@seZdZdZddZdS)_InstanceLevelDispatchrcCs|j||Sr)parentr?rr9r>rrrr?sz&_InstanceLevelDispatch._adjust_fn_specN)rrrrr?rrrrrgsrgc@sreZdZdZeZdZdZddZddZ dd Z e Z Z Z ZZZd d Zd d ZddZddZeZdS)_EmptyListenerzServes as a proxy interface to the events served by a _ClsLevelDispatch, when there are no instance-level events present. Is replaced by _ListenerCollection when instance-level events are added. r)rhparent_listenersr&cCs2||jkr||||_|j||_|j|_dSr)r*rNrhrkr&rrhZ target_clsrrrr;s    z_EmptyListener.__init__cCsHt|j|j}t||j|kr.t||j|ntt||jtsDt|S)zReturn an event collection which can be modified. For _EmptyListener at the instance level of a dispatcher, this generates a new _ListenerCollection, applies it to the instance, and returns it. ) _ListenerCollectionrhZ _instance_clsr6r&setattrrI_JoinedListenerrK)rreresultrrrrfs z_EmptyListener.for_modifycOs tddS)Nzneed to call for_modify()NotImplementedErrorrr0rCrrr _needs_modifysz_EmptyListener._needs_modifycOs|jD]}|||qdSzExecute this event.N)rkrr0rCr9rrr__call__s z_EmptyListener.__call__cCs t|jSr)lenrkrrrr__len__sz_EmptyListener.__len__cCs t|jSr)r!rkrrrrr"sz_EmptyListener.__iter__cCs t|jSr)r1rkrrrr__bool__sz_EmptyListener.__bool__N)rrrr7 frozensetrU listenersrr;rfrt exec_onceexec_once_unless_exceptionrXrr r#rwryr"rz __nonzero__rrrrrjs, rjc@sdeZdZdZddZddZddZdd Zd d Zd d Z ddZ ddZ ddZ ddZ e ZdS)_CompoundListener)_exec_once_mutex _exec_once_exec_w_sync_oncecCs t|_dSr)r rrrrr _set_asynciosz_CompoundListener._set_asynciocCstSr)r Lockrrrr_memoized_attr__exec_once_mutexsz1_CompoundListener._memoized_attr__exec_once_mutexc OsX|jH|jsJz*z|||d}Wnd}YnXW5|rB|sHd|_XW5QRXdS)NTF)rr)rretry_on_exceptionr0rC exceptionrrr_exec_once_impls  z!_CompoundListener._exec_once_implcOs|js|jd||dS)z]Execute this event, but only if it has not been executed already for this collection.FN)Frrrsrrrr}$sz_CompoundListener.exec_oncecOs|js|jd||dS)atExecute this event, but only if it has not been executed already for this collection, or was called by a previous exec_once_unless_exception call and raised an exception. If exec_once was already called, then this method will never run the callable regardless of whether it raised or not. .. versionadded:: 1.3.8 TN)Trrsrrrr~+s z,_CompoundListener.exec_once_unless_exceptionc OsL|js>|j*z|||WnYnXd|_W5QRXn |||dS)anExecute this event, and use a mutex if it has not been executed already for this collection, or was called by a previous _exec_w_sync_on_first_run call and raised an exception. If _exec_w_sync_on_first_run was already called and didn't raise an exception, then a mutex is not used. .. versionadded:: 1.4.11 TN)rrrsrrr_exec_w_sync_on_first_run:s z+_CompoundListener._exec_w_sync_on_first_runcOs0|jD]}|||q|jD]}|||qdSru)rkr|rvrrrrwQs   z_CompoundListener.__call__cCst|jt|jSr)rxrkr|rrrrryYsz_CompoundListener.__len__cCst|j|jSr)rrkr|rrrrr"\sz_CompoundListener.__iter__cCst|jp |jSr)r1r|rkrrrrrz_sz_CompoundListener.__bool__N)rrrrrrrr}r~rrwryr"rzrrrrrrs rc@sNeZdZdZdZddZddZddd Zd d Zd d Z ddZ ddZ dS)rmzInstance-level attributes on instances of :class:`._Dispatch`. Represents a collection of listeners. As of 0.7.9, _ListenerCollection is only first created via the _EmptyListener.for_modify() method. )rkrhr&r|rUr+cCsP||jkr||d|_d|_|j||_||_|j|_t|_ t |_ dSNF) r*rNrrrkrhr&rYrZr|r`rUrlrrrr;xs    z_ListenerCollection.__init__cCs|S)zReturn an event collection which can be modified. For _ListenerCollection at the instance level of a dispatcher, this returns self. rrdrrrrfsz_ListenerCollection.for_modifyTcs\j}t|j|jfdd|jD}|||j|}t||dS)zIPopulate from the listeners in another :class:`_Dispatch` object.cs&g|]}|krr|jkr|qSr)rU)r[lZexisting_listener_setonly_propagaterrrr]s  z/_ListenerCollection._update..N)r|r`rUrBrunionrZ_stored_in_collection_multi)rrrZexisting_listenersZother_listenersZ to_associaterrr_updates  z_ListenerCollection._updatecCs$|||jr |r |j|jdSr)Zprepend_to_listr|rUaddrQrrTrUrrrrXsz_ListenerCollection.insertcCs$|||jr |r |j|jdSr)Zappend_to_listr|rUrrQrrrrrsz_ListenerCollection.appendcCs,|j|j|j|jt||dSr)r|r rQrUdiscardrr_rrTrrrr sz_ListenerCollection.removecCs&t||j|j|jdSr)rrbr|rUr#rrrrr#s z_ListenerCollection.clearN)T) rrrr7rr;rfrrXrr r#rrrrrmes    rmc@sTeZdZdZddZeddZddZdd Zd d Z d d Z ddZ ddZ dS)ro)rhr&localrkcCs$d|_||_||_||_|j|_dSr)rrhr&rrk)rrhr&rrrrr;s z_JoinedListener.__init__cCst|j|jSr)r6rhr&rrrrr|sz_JoinedListener.listenerscCs|j||Sr)rr?rirrrr?sz_JoinedListener._adjust_fn_speccCs|j||_|_|Sr)rrfrkrdrrrrfsz_JoinedListener.for_modifycCs|j||dSr)rrXrrrrrXsz_JoinedListener.insertcCs|j||dSr)rrrrrrrsz_JoinedListener.appendcCs|j|dSr)rr rrrrr sz_JoinedListener.removecCs tdSrrqrrrrr#sz_JoinedListener.clearN) rrrrr;propertyr|r?rfrXrr r#rrrrros ro)r7 __future__rrrY itertoolsrrrrr r r Zutil.concurrencyr Z MemoizedSlotsr objectrr$rgrjrrmrorrrrs(         ?WP