U kfnN@sHUdZddlmZddlZddlZddlZddlZddlmZddlmZddlm Z ddlm Z ddlm Z dd lm Z dd lm Z dd lmZdd lmZdd lmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlZddlmZddlmZddlmZddlm Z ej!shesddl"m#Z#ddl"m$Z$ddl"m%Z%dd l"m&Z&dd!l"m'Z'dd"l"m(Z(nHddl)m%Z%dd l)m&Z&ddl)m#Z#ddl*m$Z$dd!l*m'Z'dd"l*m(Z(ed#ed$Z+ed%ed$Z,ed&ed$Z-ed'd(d)Z.e/Z0d*e1d+<e/dgZ2d*e1d,<d-d-d-d.d/d0Z3d1d2d3d4d5Z4e#Z5d6e1d7<Gd8d9d9e&e,e-fZ6ed:ed$Z7ed;ed$Z8Gdd?d?e9e+Z:Gd@dAdAe%e9e+Z;dtdBdCZe>> 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)r+r,Zoverlapresultcurrentotherelementr8L/opt/hc_python/lib64/python3.8/site-packages/sqlalchemy/util/_collections.pymerge_lists_w_orderingLs#    r:zMapping[_KT, _VT]zimmutabledict[_KT, _VT])dr-cCs"|stSt|tr|St|SdSN) EMPTY_DICT isinstancerr;r8r8r9coerce_to_immutabledicts  r@zimmutabledict[Any, Any]r=c@s\eZdZdZdddddZddd d Zddd d Zd dddddZddddZdS) FacadeDictz*A dictionary that is not publicly mutable.rzFacadeDict[Any, Any])argsr-cGst|}|Sr<)r__new__)clsrBnewr8r8r9rCs zFacadeDict.__new__rr-cCs tddS)Nz\an immutabledict shouldn't need to be copied. use dict(d) if you need a mutable dictionary.)NotImplementedErrorselfr8r8r9copyszFacadeDict.copycCstt|ffSr<)rAdictrHr8r8r9 __reduce__szFacadeDict.__reduce__r$r%Nonekeyvaluer-cCst|||dS)z,insert an item into the dictionary directly.N)rK __setitem__rIrOrPr8r8r9 _insert_itemszFacadeDict._insert_itemstrcCsdt|S)NzFacadeDict(%s))rK__repr__rHr8r8r9rUszFacadeDict.__repr__N) __name__ __module__ __qualname____doc__rCrJrLrSrUr8r8r8r9rAs rA_DT_FcseZdZUdZdZded<ddddZdd d d Zd d d dZdd fdd Z dddddZ ddddddZ dddddZ dddd d!Z ddddd"d#Zd$d d%d&Zd$dd'd(d)Zdddd*d+Zdd,dd-d.Zd/d d0d1Zddd2d3d4Zedd5dd6d7Zedd8d8d9d:d7ZdKddd7Zdd d?d@ZdAd dBdCZdDd dEdFZdd,ddGdHZdd dIdJZZS)L Propertiesz8Provide a __getattr__/__setattr__ interface over a dict._dataz Dict[str, _T]r^)datacCst|d|dSNr^object __setattr__)rIr_r8r8r9__init__szProperties.__init__intrFcCs t|jSr<lenr^rHr8r8r9__len__szProperties.__len__ Iterator[_T]cCstt|jSr<)r0listr^valuesrHr8r8r9__iter__szProperties.__iter__z List[str]csttdd|jDS)NcSsg|] }t|qSr8)rT.0kr8r8r9 sz&Properties.__dir__..)dirsuperr^keysrH __class__r8r9__dir__szProperties.__dir__zProperties[_F]zList[Union[_T, _F]])r6r-cCst|t|Sr<)rj)rIr6r8r8r9__add__szProperties.__add__rTr"rM)rOobjr-cCs||j|<dSr<r]rIrOrxr8r8r9rQszProperties.__setitem__rOr-cCs |j|Sr<r]rIrOr8r8r9 __getitem__szProperties.__getitem__cCs |j|=dSr<r]r{r8r8r9 __delitem__szProperties.__delitem__cCs||j|<dSr<r]ryr8r8r9rcszProperties.__setattr__zDict[str, Any]cCs d|jiSr`r]rHr8r8r9 __getstate__szProperties.__getstate__)stater-cCst|d|ddSr`ra)rIrr8r8r9 __setstate__szProperties.__setstate__cCs.z |j|WStk r(t|YnXdSr<)r^KeyErrorAttributeErrorr{r8r8r9 __getattr__s zProperties.__getattr__boolcCs ||jkSr<r]r{r8r8r9 __contains__szProperties.__contains__zReadOnlyProperties[_T]cCs t|jS)z8Return an immutable proxy for this :class:`.Properties`.)ReadOnlyPropertiesr^rHr8r8r9 as_readonlyszProperties.as_readonly)rPr-cCs|j|dSr<)r^update)rIrPr8r8r9rszProperties.updatez Optional[_T]cCsdSr<r8r{r8r8r9getszProperties.getzUnion[_DT, _T]rOdefaultr-cCsdSr<r8rIrOrr8r8r9rsNzOptional[Union[_DT, _T]]zOptional[Union[_T, _DT]]cCs||kr||S|SdSr<r8rr8r8r9rscCs t|jSr<)rjr^rHr8r8r9rsszProperties.keysList[_T]cCst|jSr<)rjr^rkrHr8r8r9rkszProperties.valueszList[Tuple[str, _T]]cCst|jSr<)rjr^itemsrHr8r8r9rszProperties.itemscCs ||jkSr<r]r{r8r8r9has_keyszProperties.has_keycCs|jdSr<)r^clearrHr8r8r9rszProperties.clear)N)rVrWrXrY __slots____annotations__rdrhrlrvrwrQr|r}rcr~rrrrrrrrsrkrrr __classcell__r8r8rtr9r\s: r\c@seZdZdZdZddZdS)OrderedPropertieszUProvide a __getattr__/__setattr__ interface with an OrderedDict as backing store.r8cCst|tdSr<)r\rd OrderedDictrHr8r8r9rd szOrderedProperties.__init__N)rVrWrXrYrrdr8r8r8r9rsrc@seZdZdZdZdS)rzDProvide immutable dict/object attribute to an underlying dictionary.r8N)rVrWrXrYrr8r8r8r9rsrcs0fddt|dD}|dS)zSort an OrderedDict in-place.csg|]}||fqSr8r8rmr?r8r9rpsz,_ordered_dictionary_sort..)rON)sortedrr)r;rOrr8r?r9_ordered_dictionary_sortsrc@s<eZdZdddddZddZdd Zd d Zd d ZdS) WeakSequencer8z Sequence[_T])_WeakSequence__elementscs0t|fdd|_fdd|D|_dS)NcSs|}|dk r|j|dSr<)_storageremove)itemselfrefrIr8r8r9_remove&sz&WeakSequence.__init__.._removecsg|]}t|qSr8)weakrefref)rnr7rr8r9rp,sz)WeakSequence.__init__..)rrrr)rIrr8rr9rd#s  zWeakSequence.__init__cCs|jt||jdSr<)rr2rrr)rIrr8r8r9r20szWeakSequence.appendcCs t|jSr<)rgrrHr8r8r9rh3szWeakSequence.__len__cCsdddd|jDDS)Ncss|]}|dk r|VqdSr<r8)rnrxr8r8r9 7sz(WeakSequence.__iter__..css|] }|VqdSr<r8)rnrr8r8r9r8s)rrHr8r8r9rl6szWeakSequence.__iter__cCs:z|j|}Wn tk r.td|YnX|SdS)NzIndex %s out of range)rr IndexError)rIindexrxr8r8r9r|;s zWeakSequence.__getitem__N)r8)rVrWrXrdr2rhrlr|r8r8r8r9r"s  rc@seZdZdddddZdS)OrderedIdentitySetNzOptional[Iterable[Any]])iterablecCs.t|t|_|r*|D]}||qdSr<)rrdrZ_membersadd)rIror8r8r9rdEs  zOrderedIdentitySet.__init__)N)rVrWrXrdr8r8r8r9rDsrc@s.eZdZdZddddZddddd Zd S) PopulateDictzA dict which populates missing values via a creation function. Note the creation function takes a key, unlike collections.defaultdict. zCallable[[_KT], _VT]creatorcCs ||_dSr<r)rIrr8r8r9rdUszPopulateDict.__init__rrzcCs||||<}|Sr<rrIrOvalr8r8r9 __missing__XszPopulateDict.__missing__NrVrWrXrYrdrr8r8r8r9rMsrc@s.eZdZdZddddZddddd Zd S) WeakPopulateDictzaLike PopulateDict, but assumes a self + a method and does not create a reference cycle. ztypes.MethodType)creator_methodcCs|j|_|j}t||_dSr<)__func__r__self__rrweakself)rIrrr8r8r9rdcszWeakPopulateDict.__init__rrzcCs|||||<}|Sr<)rrrr8r8r9rhszWeakPopulateDict.__missing__Nrr8r8r8r9r]src@s^eZdZUdZdZded<ded<ded<ddd d d d ZdddddZddddZd S)UniqueAppenderzAppends items to a collection ensuring uniqueness. Additional appends() of the same object are ignored. Membership is determined by identity (``is a``) not equality (``==``). )r__data_appender_uniquez&Union[Iterable[_T], Set[_T], List[_T]]r_zCallable[[_T], None]rzDict[int, Literal[True]]rNz Optional[str])r_viacCsT||_i|_|rt|||_n2t|dr8td|j|_nt|drPtd|j|_dS)Nr2rrzSet[_T])r_rgetattrrhasattrrr2r)rIr_rr8r8r9rds  zUniqueAppender.__init__r"rM)rr-cCs*t|}||jkr&||d|j|<dS)NT)idrr)rIrZid_r8r8r9r2s  zUniqueAppender.appendrirFcCs t|jSr<)r0r_rHr8r8r9rlszUniqueAppender.__iter__)N) rVrWrXrYrrrdr2rlr8r8r8r9rvs rr)argr-cCs6t|dkr(t|dtjr(t|dStd|SdS)Nrrr*)rgr>types GeneratorTyperjr)rr8r8r9coerce_generator_args rzOptional[List[Any]])xrr-cCs4|dkr |St|s|gSt|tr(|St|SdSr<)rr>rj)rrr8r8r9to_lists rzContainer[Any]z Iterable[Any]r)set_rr-cstfdd|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. c3s|]}|jr|kVqdSr<)__hash__)rnirr8r9rsz#has_intersection..)any)rrr8rr9has_intersectionsrcCs,|dkrtSt|ts$tt|S|SdSr<)r.r>rrr8r8r9to_sets   rzSet[Any])rr-cCs,|dkrtSt|ts$tt|S|SdSr<) column_setr>rrr8r8r9 to_column_sets   rcKs&|}|r|||jf||S)z5Copy the given dict and update with the given values.)rJr)r;_newkwr8r8r9 update_copys   rz Iterable[_T]riccs8|D].}t|ts,t|dr,t|EdHq|VqdS)zGiven an iterator of which further sub-elements may also be iterators, flatten the sub-elements into a single iterator. rlN)r>rTrflatten_iterator)relemr8r8r9rsrc@seZdZUdZdZded<ded<ded<d3ddd d ddZddZedddddZ eddddddZ d4ddddddZ dddddZ dd d!d"Z dd d#d$Z d%d d&d'Z ddd(d)d*d+Zdd(d,d-d.Zedd d/d0Zd(d d1d2Zd S)5LRUCachezDictionary 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_alertr^_counter_mutexrerfloatrz.Optional[Callable[[LRUCache[_KT, _VT]], None]]rd?Nz$Optional[Callable[(Ellipsis, None)]])rrrcCs,||_||_||_d|_t|_i|_dS)Nr)rrrr threadingLockrr^)rIrrrr8r8r9rds  zLRUCache.__init__cCs|jd7_|jS)Nr)rrHr8r8r9 _inc_counterszLRUCache._inc_counterr$z Optional[_VT]rzcCsdSr<r8r{r8r8r9rsz LRUCache.getzUnion[_VT, _T]rcCsdSr<r8rr8r8r9r szOptional[Union[_VT, _T]]cCs4|j|}|dk r,||dd<|dS|SdSNrr)r^rr)rIrOrrr8r8r9rs  r%cCs"|j|}||dd<|dSr)r^r)rIrOrr8r8r9r|s zLRUCache.__getitem__z Iterator[_KT]rFcCs t|jSr<)r0r^rHr8r8r9rlszLRUCache.__iter__cCs t|jSr<rfrHr8r8r9rh szLRUCache.__len__zValuesView[_VT]cCstdd|jDS)NcSsi|]\}}||dqS)rr8)rnrorr8r8r9 $sz#LRUCache.values..)typingrr^rrHr8r8r9rk#szLRUCache.valuesrMrNcCs"|||gf|j|<|dSr<)rr^ _manage_sizerRr8r8r9rQ&szLRUCache.__setitem__) _LRUCache__vr-cCs |j|=dSr<r])rIrr8r8r9r}*szLRUCache.__delitem__cCs|j|j|jSr<)rrrHr8r8r9size_threshold-szLRUCache.size_thresholdc Cs|jdsdSzt|j}t||j|j|jkr|rHd}||t|j t ddd}||jdD].}z|j |d=Wqpt k rYqpYqpXqpqW5|jXdS)NFrT)rOreverser)racquirereleaserrrgrrrr^rkoperator itemgetterr)rIrZ by_counterrr8r8r9r1s&   zLRUCache._manage_size)rrN)N)rVrWrXrYrrrdrrrr|rlrhrkrQr}propertyrrr8r8r8r9rs2     rc@seZdZddddZdS)_CreateFuncTyper&rFcCsdSr<r8rHr8r8r9__call__Jz_CreateFuncType.__call__NrVrWrXrr8r8r8r9rIsrc@seZdZddddZdS)_ScopeFuncTyperrFcCsdSr<r8rHr8r8r9rNrz_ScopeFuncType.__call__Nrr8r8r8r9rMsrc@sxeZdZUdZdZded<ded<ded<d d d d d ZddddZddddZdddddZ ddddZ dS)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]rrrrrCallable[[], _T]zCallable[[], Any])rrcCs||_||_i|_dS)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). Nr)rIrrr8r8r9rdfs zScopedRegistry.__init__r"rFcCs@|}z |j|WStk r:|j||YSXdSr<)rrr setdefaultrr{r8r8r9rws  zScopedRegistry.__call__rcCs||jkS)z9Return True if an object is present in the current scope.)rrrHr8r8r9has~szScopedRegistry.hasrMrxr-cCs||j|<dS)z$Set the value for the current scope.N)rrrIrxr8r8r9r.szScopedRegistry.setcCs*z|j|=Wntk r$YnXdS)z Clear the current scope, if any.N)rrrrHr8r8r9rszScopedRegistry.clearN) rVrWrXrYrrrdrrr.rr8r8r8r9rQs rc@sXeZdZdZddddZdddd Zd dd d Zdd dddZd dddZdS)ThreadLocalRegistryz\A :class:`.ScopedRegistry` that uses a ``threading.local()`` variable for storage. r)rcCs||_t|_dSr<)rrlocalr)rIrr8r8r9rdszThreadLocalRegistry.__init__r"rFcCs8z |jjWStk r2|}|j_|YSXdSr<)rrPrr)rIrr8r8r9rs  zThreadLocalRegistry.__call__rcCs t|jdS)NrP)rrrHr8r8r9rszThreadLocalRegistry.hasrMrcCs ||j_dSr<)rrPrr8r8r9r.szThreadLocalRegistry.setcCs$z |j`Wntk rYnXdSr<)rrPrrHr8r8r9rs zThreadLocalRegistry.clearN) rVrWrXrYrdrrr.rr8r8r8r9rs rcCs0d}|D]"}||kr|d7}|dkrdSqdS)zrGiven a sequence and search object, return True if there's more than one, False if zero or one of them. rrTFr8)sequencetargetcrr8r8r9 has_dupess r)N)N)N)WrY __future__rrrrrrrrrrrr r r r r rrrrrrrrrrZ_has_cyrrrr TYPE_CHECKINGZ_py_collectionsrrrrr r!Z$sqlalchemy.cyextension.immutabledictZ"sqlalchemy.cyextension.collectionsr"r$r%r& frozensetr(rr)r:r@r=rArZr[r\rrrrKrZsort_dictionaryrrrrr.rZ column_dictZordered_column_setrrrrrrrrMutableMappingrrrrrrr8r8r8r9 s                                        8   W  " %     i@