L iNUdZddlmZddlZddlZddlZddlZddlmZddlmZddlm Z ddlm Z ddlm Z dd lm Z dd lm Z dd lmZdd lmZdd lmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlZddlmZddlmZddlmZddlm Z ejBses%ddl"m#Z#ddl"m$Z$ddl"m%Z%dd l"m&Z&dd!l"m'Z'dd"l"m(Z(n$ddl)m%Z%dd l)m&Z&ddl)m#Z#ddl*m$Z$dd!l*m'Z'dd"l*m(Z(ed#e$Z+ed%e$Z,ed&e$Z-ed'd()Z.e/Z0d*e1d+<e/dgZ2d*e1d,<dXd-Z3dYd.Z4e#Z5d/e1d0<Gd1d2e&e,e-fZ6ed3e$Z7ed4e$Z8Gd5d6e e+Z9Gd7d8e9e+Z:Gd9d:e%e9e+Z;dZd;Zed?e$ZAGd@dAe e,e-fZBGdBdCe e,e-fZCeDZEe=ZFe'ZGGdDdEe e+ZHd[dFZIdZd\dGZJd]dHZKdIZLd^dJZM dZ d_dKZNd`dLZOGdMdNeje,e-fZQGdOdPe e.ZRGdQdRe ZSGdSdTe e+ZTGdUdVeTe+ZUdWZVy)azCollection classes and helpers.) annotationsN)Any)Callable)cast) Container)Dict) FrozenSet)Generic)Iterable)Iterator)List)Mapping)NoReturn)Optional)overload)Sequence)Set)Tuple)TypeVar)Union) ValuesView)HAS_CYEXTENSION)is_non_string_iterable)Literal)Protocol) immutabledict) IdentitySet)ReadOnlyContainer)ImmutableDictBase) OrderedSet) unique_list_T)bound_KT_VT_T_coT) covariantzFrozenSet[Any] EMPTY_SETNONE_SETct|j|}g}t|t|}} |D].}||vr|j|||}}n'|j |0|j | |SH)afmerge two lists, maintaining ordering as much as possible. this is to reconcile vars(cls) with cls.__annotations__. Example:: >>> a = ["__tablename__", "id", "x", "created_at"] >>> b = ["id", "name", "data", "y", "created_at"] >>> merge_lists_w_ordering(a, b) ['__tablename__', 'id', 'name', 'data', 'y', 'x', 'created_at'] This is not necessarily the ordering that things had on the class, in this case the class is:: class User(Base): __tablename__ = "users" id: Mapped[int] = mapped_column(primary_key=True) name: Mapped[str] data: Mapped[Optional[str]] x = Column(Integer) y: Mapped[int] created_at: Mapped[datetime.datetime] = mapped_column() But things are *mostly* ordered. The algorithm could also be done by creating a partial ordering for all items in both lists and then using topological_sort(), but that is too much overhead. Background on how I came up with this is at: https://gist.github.com/zzzeek/89de958cf0803d148e74861bd682ebae )set intersectioniterdiscardappendextend)aboverlapresultcurrentotherelements b/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/sqlalchemy/util/_collections.pymerge_lists_w_orderingr:LsF!f!!!$G F!Wd1gUG  G'!(!(%w MM' "  MM%  M cL|stSt|tr|St|SN) EMPTY_DICT isinstancer)ds r9coerce_to_immutabledictrAs%  A} %Qr;zimmutabledict[Any, Any]r>c8eZdZdZddZd dZd dZd dZd dZy) FacadeDictz*A dictionary that is not publicly mutable.c0tj|}|Sr=)r __new__)clsargsnews r9rEzFacadeDict.__new__s'', r;ctd)Nz\an immutabledict shouldn't need to be copied. use dict(d) if you need a mutable dictionary.)NotImplementedErrorselfs r9copyzFacadeDict.copys! 0  r;c&tt|ffSr=)rCdictrKs r9 __reduce__zFacadeDict.__reduce__sDJ=((r;c2tj|||y)z,insert an item into the dictionary directly.N)rO __setitem__rLkeyvalues r9 _insert_itemzFacadeDict._insert_items sE*r;c2dtj|zS)NzFacadeDict(%s))rO__repr__rKs r9rXzFacadeDict.__repr__s$--"555r;N)rGrreturnzFacadeDict[Any, Any])rYrrYrrTr%rUr&rYNone)rYstr) __name__ __module__ __qualname____doc__rErMrPrVrXr;r9rCrCs4 )+6r;rC_DT_FceZdZUdZdZded<ddZddZddZdfd Z d d Z d!d Z d"d Z d#d Z d!d Zd$dZd%dZd"dZd&dZd'dZd(dZed)dZed*dZ d+ d,dZddZd-dZd.dZd&dZd/dZxZS)0 Propertiesz8Provide a __getattr__/__setattr__ interface over a dict._data Dict[str, _T]rhc2tj|d|yNrhobject __setattr__)rLdatas r9__init__zProperties.__init__s4$/r;c,t|jSr=lenrhrKs r9__len__zProperties.__len__4::r;cZtt|jjSr=)r.listrhvaluesrKs r9__iter__zProperties.__iter__sD**,-..r;ctt|jjDcgc] }t |c}zScc}wr=)dirsuperrhkeysr])rLk __class__s r9__dir__zProperties.__dir__s157|tzz/@A!s1vAAAAsAc0t|t|zSr=)rw)rLr7s r9__add__zProperties.__add__sDzDK''r;c"||j|<yr=rgrLrTobjs r9rRzProperties.__setitem__ 3r;c |j|Sr=rgrLrTs r9 __getitem__zProperties.__getitem__szz#r;c|j|=yr=rgrs r9 __delitem__zProperties.__delitem__ JJsOr;c"||j|<yr=rgrs r9rnzProperties.__setattr__rr;cd|jiSrkrgrKs r9 __getstate__zProperties.__getstate__s$$r;c8tj|d|dyrkrl)rLstates r9 __setstate__zProperties.__setstate__s4%.9r;cR |j|S#t$r t|wxYwr=)rhKeyErrorAttributeErrorrs r9 __getattr__zProperties.__getattr__s/ &::c? " & % % &s&c||jvSr=rgrs r9 __contains__zProperties.__contains__djj  r;c,t|jS)z8Return an immutable proxy for this :class:`.Properties`.)ReadOnlyPropertiesrhrKs r9 as_readonlyzProperties.as_readonlys"$**--r;c:|jj|yr=)rhupdate)rLrUs r9rzProperties.updates % r;cyr=rbrs r9getzProperties.gets-0r;cyr=rbrLrTdefaults r9rzProperties.getHKr;c||vr||S|Sr=rbrs r9rzProperties.gets $;9 Nr;c,t|jSr=)rwrhrKs r9r}zProperties.keysDJJr;cHt|jjSr=)rwrhrxrKs r9rxzProperties.valuessDJJ%%'((r;cHt|jjSr=)rwrhitemsrKs r9rzProperties.itemssDJJ$$&''r;c||jvSr=rgrs r9has_keyzProperties.has_keyrr;c8|jjyr=)rhclearrKs r9rzProperties.clears r;)rorirYintrY Iterator[_T])rYz List[str])r7zProperties[_F]rYzList[Union[_T, _F]])rTr]rr#rYr\)rTr]rYr#)rTr]rYr\)rYDict[str, Any])rrrYr\)rTr]rYbool)rYzReadOnlyProperties[_T])rUrirYr\)rTr]rYz Optional[_T])rTr]rUnion[_DT, _T]rYrr=)rTr]rzOptional[Union[_DT, _T]]rYzOptional[Union[_T, _DT]])rYList[_T])rYzList[Tuple[str, _T]]rYr\)r^r_r`ra __slots____annotations__rprtryrrrRrrrnrrrrrrrrr}rxrrr __classcell__)rs@r9rfrfsBI 0/B(%:& !. !00 KK=A!9 ! )(!r;rfceZdZdZdZdZy)OrderedPropertieszUProvide a __getattr__/__setattr__ interface with an OrderedDict as backing store.rbc@tj|tyr=)rfrp OrderedDictrKs r9rpzOrderedProperties.__init__ sD+-0r;N)r^r_r`rarrprbr;r9rrsI1r;rceZdZdZdZy)rzDProvide immutable dict/object attribute to an underlying dictionary.rbN)r^r_r`rarrbr;r9rrs NIr;rct||Dcgc] }|||f }}|j|j|ycc}w)zSort an OrderedDict in-place.)rTN)sortedrr)r@rTr~rs r9_ordered_dictionary_sortrs?!'qc 2 31a1Y 3E 3GGIHHUO 4sAc.eZdZdddZdZdZdZdZy) WeakSequencectj|fd}||_|Dcgc]}tj||c}|_ycc}w)NcN|}||jj|yyr=)_storageremove)itemselfrefrLs r9_removez&WeakSequence.__init__.._remove&s&9D $$T* r;)weakrefrefrr)rL_WeakSequence__elementsrr8s r9rpzWeakSequence.__init__#sE#*++d"3 +  9C .5GKK )   sA cv|jjtj||jyr=)rr0rrr)rLrs r9r0zWeakSequence.append0s# W[[t||<=r;c,t|jSr=)rsrrKs r9rtzWeakSequence.__len__3s4==!!r;c6dd|jDDS)Nc3&K|] }|| ywr=rb).0rs r9 z(WeakSequence.__iter__..7s sC sc3*K|] }| ywr=rb)rrs r9rz(WeakSequence.__iter__..8s;cCE;s)rrKs r9ryzWeakSequence.__iter__6s ;T]];  r;cf |j|}|S#t$rtd|zwxYw)NzIndex %s out of range)rr IndexError)rLindexrs r9rzWeakSequence.__getitem__;s@ --&C5L >4u<= = >s0N)rb)rz Sequence[_T])r^r_r`rpr0rtryrrbr;r9rr"s  >" r;rceZdZdddZy)OrderedIdentitySetNctj|t|_|r|D]}|j |yyr=)rrpr_membersadd)rLiterableos r9rpzOrderedIdentitySet.__init__Es;T"#      r;r=)rzOptional[Iterable[Any]])r^r_r`rprbr;r9rrDsr;rc eZdZdZddZddZy) PopulateDictzA dict which populates missing values via a creation function. Note the creation function takes a key, unlike collections.defaultdict. c||_yr=creator)rLrs r9rpzPopulateDict.__init__Us  r;c2|j|x||<}|Sr=rrLrTvals r9 __missing__zPopulateDict.__missing__Xs,,s++S C r;N)rzCallable[[_KT], _VT]rTrrYrr^r_r`rarprrbr;r9rrMsr;rc eZdZdZddZddZy)WeakPopulateDictzaLike PopulateDict, but assumes a self + a method and does not create a reference cycle. cr|j|_|j}tj||_yr=)__func__r__self__rrweakself)rLcreator_methodrs r9rpzWeakPopulateDict.__init__cs*%.. !** H- r;cP|j|j|x||<}|Sr=)rrrs r9rzWeakPopulateDict.__missing__hs&,,t}}<<S C r;N)rztypes.MethodTyperrrbr;r9rr]s . r;rcVeZdZUdZdZded<ded<ded< d dd Zdd Zdd Zy )UniqueAppenderzAppends items to a collection ensuring uniqueness. Additional appends() of the same object are ignored. Membership is determined by identity (``is a``) not equality (``==``). )ro_data_appender_unique&Union[Iterable[_T], Set[_T], List[_T]]rozCallable[[_T], None]rzDict[int, Literal[True]]rNc||_i|_|rt|||_yt |drt d|j |_yt |drt d|j|_yy)Nr0rrzSet[_T])rorgetattrrhasattrrr0r)rLrovias r9rpzUniqueAppender.__init__sg   ")$"4D  T8 $"&z4"8"?"?D  T5 !"&y$"7";";D "r;cxt|}||jvr!|j|d|j|<yy)NT)idrr)rLrid_s r9r0zUniqueAppender.appends8h dll "    % $DLL  #r;c,t|jSr=)r.rorKs r9ryzUniqueAppender.__iter__sDIIr;r=)rorrz Optional[str])rr#rYr\r) r^r_r`rarrrpr0ryrbr;r9rrvsF 4I 00(( %% " <4 < <% r;rct|dk(r+t|dtjrt |dSt d|S)Nrr List[Any])rsr?types GeneratorTyperwr)args r9coerce_generator_argrs; 3x1}CFE,?,?@CF|K%%r;c`||St|s|gSt|tr|St|Sr=)rr?rw)xrs r9to_listrs3y !! $s At Awr;c,tfd|DS)zreturn True if any items of set\_ are present in iterable. Goes through special effort to ensure __hash__ is not called on items in iterable that don't support it. c3@K|]}|js|vywr=)__hash__)riset_s r9rz#has_intersection..s9QajjqDy9s )any)r rs` r9has_intersectionrs 9(9 99r;cf| tSt|tstt|S|Sr=)r,r?rrs r9to_setrs+yu a 71:r;cf| tSt|tstt|S|Sr=) column_setr?rrs r9 to_column_setrs-y| a $'!*%%r;c p|j}|r|j||jdi||S)z5Copy the given dict and update with the given values.rb)rMr)r@_newkws r9 update_copyrs1 A   AHHNrN Hr;c#K|D]6}t|ts t|drt|Ed{3|8y7 w)zGiven an iterator of which further sub-elements may also be iterators, flatten the sub-elements into a single iterator. ryN)r?r]rflatten_iterator)relems r9rrs@ $$z)B'- - -J  -s0A? AceZdZUdZdZded<ded<ded< d dd Zd Zedd Z edd Z d ddZ ddZ ddZ ddZ d dZ d!dZd"dZed#dZd$dZy )%LRUCachezDictionary with 'squishy' removal of least recently used items. Note that either get() or [] should be used here, but generally its not safe to do an "in" check first as the dictionary can change subsequent to that call. )capacity threshold size_alertrh_counter_mutexrrfloatr z.Optional[Callable[[LRUCache[_KT, _VT]], None]]r!Nc|||_||_||_d|_t j |_i|_y)Nr)rr r!r" threadingLockr#rh)rLrr r!s r9rpzLRUCache.__init__s5 ! "$ nn& <> r;cD|xjdz c_|jSNr)r"rKs r9 _inc_counterzLRUCache._inc_counters  }}r;cyr=rbrs r9rz LRUCache.get s.1r;cyr=rbrs r9rz LRUCache.get rr;cv|jj|}||j|dd<|dS|SNrr)rhrr*)rLrTrrs r9rz LRUCache.gets@zz~~c"  **,DGAJ7NNr;cV|j|}|j|dd<|dSr.)rhr*)rLrTrs r9rzLRUCache.__getitem__s.zz#&&(Q Awr;c,t|jSr=)r.rhrKs r9ryzLRUCache.__iter__rr;c,t|jSr=rrrKs r9rtzLRUCache.__len__"rur;c tj|jjDcic] \}}||d c}}Scc}}wr))typingrrhr)rLr~r s r9rxzLRUCache.values%s:  djj6F6F6H!Ida!QqT'!IJJ!IsA cf|||jgf|j|<|jyr=)r*rh _manage_sizerSs r9rRzLRUCache.__setitem__(s.(9(9(;'<= 3 r;c|j|=yr=rg)rL _LRUCache__vs r9rzLRUCache.__delitem__,rr;cN|j|j|jzzSr=)rr rKs r9size_thresholdzLRUCache.size_threshold/s}}t}}t~~===r;c|jjdsy t|j}t ||j |j |j zzkDr|rd}|j|t|jjtjdd}||j dD]} |j|d=t ||j |j |j zzkDr|jjy#t$rYowxYw#|jjwxYw)NFr/T)rTreverser)r#acquirerr!rsrr rrhrxoperator itemgetterrrelease)rLr! by_counterrs r9r6zLRUCache._manage_size3s{{""5)  "doo.Jd)dmmdmmdnn.LLL!&JOOD)#JJ%%' ++A.  't}}7!D! JJtAw/!d)dmmdmmdnn.LLL KK   ! $! ! KK   !s0B'D5D&4D5& D2/D51D22D55E)dg?N)rrr r$r!zOptional[Callable[..., None]])rTr%rYz Optional[_VT])rTr%rUnion[_VT, _T]rYrCr=)rTr%rOptional[Union[_VT, _T]]rYrD)rTr%rYr&)rYz Iterator[_KT]r)rYzValuesView[_VT]r[)r8r%rYr\)rYr$r)r^r_r`rarrrpr*rrrryrtrxrRrpropertyr:r6rbr;r9rrsIM>>48 ? ? ?2 ?11 KK=A!9 !  K>>"r;rceZdZddZy)_CreateFuncTypecyr=rbrKs r9__call__z_CreateFuncType.__call__Lr;N)rYr'r^r_r`rIrbr;r9rGrGKs$r;rGceZdZddZy)_ScopeFuncTypecyr=rbrKs r9rIz_ScopeFuncType.__call__PrJr;NrZrKrbr;r9rMrMOs"r;rMcdeZdZUdZdZded<ded<ded< dd Zdd Zdd Zdd Z dd Z y)ScopedRegistryaA Registry that can store one or multiple instances of a single class on the basis of a "scope" function. The object implements ``__call__`` as the "getter", so by calling ``myregistry()`` the contained object is returned for the current scope. :param createfunc: a callable that returns a new object to be placed in the registry :param scopefunc: a callable that will return a key to store/retrieve an object.  createfunc scopefuncregistryz_CreateFuncType[_T]rRrMrSrrTc.||_||_i|_y)aVConstruct a new :class:`.ScopedRegistry`. :param createfunc: A creation function that will generate a new value for the current scope, if none is present. :param scopefunc: A function that returns a hashable token representing the current scope (such as, current thread identifier). NrQ)rLrRrSs r9rpzScopedRegistry.__init__hs%" r;c|j} |j|S#t$r-|jj||j cYSwxYwr=)rSrTr setdefaultrRrs r9rIzScopedRegistry.__call__ysRnn D==% % D==++C1BC C Ds!3AAc:|j|jvS)z9Return True if an object is present in the current scope.)rSrTrKs r9haszScopedRegistry.hass~~4==00r;c>||j|j<y)z$Set the value for the current scope.N)rTrSrLrs r9r,zScopedRegistry.sets+. dnn&'r;cZ |j|j=y#t$rYywxYw)z Clear the current scope, if any.N)rTrSrrKs r9rzScopedRegistry.clears,  dnn./   s  **N)rRCallable[[], _T]rSzCallable[[], Any]rYr#rYrrr#rYr\r) r^r_r`rarrrprIrYr,rrbr;r9rPrPSsI 6I##M*7H"D1 . r;rPc8eZdZdZddZd dZd dZd dZd dZy) ThreadLocalRegistryz\A :class:`.ScopedRegistry` that uses a ``threading.local()`` variable for storage. cD||_tj|_yr=)rRr&localrT)rLrRs r9rpzThreadLocalRegistry.__init__s$!) r;c |jjS#t$r&|jx}|j_|cYSwxYwr=)rTrUrrR)rLrs r9rIzThreadLocalRegistry.__call__sC ==&& & (,(9 9C$--%J s,AAc.t|jdS)NrU)rrTrKs r9rYzThreadLocalRegistry.hasst}}g..r;c&||j_yr=)rTrUr[s r9r,zThreadLocalRegistry.sets! r;c< |j`y#t$rYywxYwr=)rTrUrrKs r9rzThreadLocalRegistry.clears#  #   s  N)rRr]r^r_r`r) r^r_r`rarprIrYr,rrbr;r9rbrbs  */"r;rbc8d}|D]}||us|dz }|dkDsyy)zrGiven a sequence and search object, return True if there's more than one, False if zero or one of them. rrTFrb)sequencetargetcrs r9 has_dupesrms7 A 6> FA1u  r;)r2rr3rrYr)r@zMapping[_KT, _VT]rYzimmutabledict[_KT, _VT]r=)rrrYr)rrrzOptional[List[Any]]rYr)r zContainer[Any]rz Iterable[Any]rYr)rrrYzSet[Any])r@Dict[Any, Any]rzOptional[Dict[Any, Any]]rrrYrn)rz Iterable[_T]rYr)Wra __future__rr>r&rr4rrrrrr r r r r rrrrrrrrrrr_has_cyrrrr TYPE_CHECKING_py_collectionsrrrr r!r"$sqlalchemy.cyextension.immutabledict"sqlalchemy.cyextension.collectionsr#r%r&r' frozensetr)rr*r:rAr>rCrcrdrfrrrrOrsort_dictionaryrrrrr,r column_dictordered_column_setrrrrrrrrMutableMappingrrGrMrPrbrmrbr;r9rzs&" $* ?;GG9;NK  T e3 e34(%K >'$dV,.,5p '4o #56"38,60e3 TTTn1 21*JrN  *8B<D 4S>  tCH~ (  "WR["J&:9=    5  DG     f"v$$S#X.f"R%huo%#X#=WR[=@.,<r;