U
    [hN                     @  sT  U d Z ddlmZ ddlZddlZddl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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  ej!shesd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( nHd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d#ed$Z+ed%ed$Z,ed&ed$Z-ed'd(d)Z.e/ Z0d*e1d+< e/dgZ2d*e1d,< d-d-d-d.d/d0Z3d1d2d3d4d5Z4e# Z5d6e1d7< G d8d9 d9e&e,e-f Z6ed:ed$Z7ed;ed$Z8G d<d= d=ee+ Z9G d>d? d?e9e+ Z:G d@dA dAe%e9e+ Z;dwdBdCZ<e=Z>e<Z?G dDdE dEee+ Z@G dFdG dGe$ZAG dHdI dIee,e-f ZBG dJdK dKee,e-f ZCeDZEe=ZFe'ZGG dLdM dMee+ ZHdNd-dOdPdQZIdxdNdRd-dSdTdUZJdVdWdXdYdZd[ZKd\d] ZLdNd^d_d`daZMdydbdcdNdbdddedfZNdgdhd_didjZOG dkdl dlejPe,e-f ZQG dmdn dne e. ZRG dodp dpe ZSG dqdr dree+ ZTG dsdt dteTe+ ZUdudv ZVdS )zzCollection 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)Zbound_KT_VT_T_coT)Z	covariantzFrozenSet[Any]	EMPTY_SETNONE_SET	List[Any])abreturnc                 C  sj   t | |}g }t| t| }}|D ].}||krL|| || }} q$|| q(|| qfq$|S )af  merge 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intersectioniterdiscardappendextend)r)   r*   Zoverlapresultcurrentotherelement r6   B./venv/lib/python3.8/site-packages/sqlalchemy/util/_collections.pymerge_lists_w_orderingL   s    #


r8   zMapping[_KT, _VT]zimmutabledict[_KT, _VT])dr+   c                 C  s"   | st S t| tr| S t| S d S N)
EMPTY_DICT
isinstancer   r9   r6   r6   r7   coerce_to_immutabledict   s
    
r>   zimmutabledict[Any, Any]r;   c                   @  s\   e Zd ZdZdddddZddd	d
ZddddZddddddZddddZdS )
FacadeDictz*A dictionary that is not publicly mutable.r   zFacadeDict[Any, Any])argsr+   c                 G  s   t | }|S r:   )r   __new__)clsr@   newr6   r6   r7   rA      s    
zFacadeDict.__new__r   r+   c                 C  s   t dd S )Nz\an immutabledict shouldn't need to be copied.  use dict(d) if you need a mutable dictionary.)NotImplementedErrorselfr6   r6   r7   copy   s    zFacadeDict.copyc                 C  s   t t| ffS r:   )r?   dictrF   r6   r6   r7   
__reduce__   s    zFacadeDict.__reduce__r#   r$   Nonekeyvaluer+   c                 C  s   t | || dS )z,insert an item into the dictionary directly.N)rI   __setitem__rG   rM   rN   r6   r6   r7   _insert_item   s    zFacadeDict._insert_itemstrc                 C  s   dt |  S )NzFacadeDict(%s))rI   __repr__rF   r6   r6   r7   rS      s    zFacadeDict.__repr__N)	__name__
__module____qualname____doc__rA   rH   rJ   rQ   rS   r6   r6   r6   r7   r?      s   r?   _DT_Fc                      s  e Zd ZU dZdZded< ddddZdd	d
dZdd	ddZdd	 fddZ	d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ddd"d#Zd$d	d%d&Zd$dd'd(d)Zdddd*d+Zdd,dd-d.Zd/d	d0d1Zddd2d3d4Zedd5dd6d7Zedd8d8d9d:d7ZdKdd<d=d9d>d7Zdd	d?d@ZdAd	dBdCZdDd	dEdFZdd,ddGdHZdd	dIdJZ  ZS )L
Propertiesz8Provide a __getattr__/__setattr__ interface over a dict._datazDict[str, _T]r\   )datac                 C  s   t | d| d S Nr\   object__setattr__)rG   r]   r6   r6   r7   __init__   s    zProperties.__init__intrD   c                 C  s
   t | jS r:   lenr\   rF   r6   r6   r7   __len__   s    zProperties.__len__Iterator[_T]c                 C  s   t t| j S r:   )r.   listr\   valuesrF   r6   r6   r7   __iter__   s    zProperties.__iter__z	List[str]c                   s   t t dd | j D  S )Nc                 S  s   g | ]}t |qS r6   )rR   .0kr6   r6   r7   
<listcomp>   s     z&Properties.__dir__.<locals>.<listcomp>)dirsuperr\   keysrF   	__class__r6   r7   __dir__   s    zProperties.__dir__zProperties[_F]zList[Union[_T, _F]])r4   r+   c                 C  s   t | t | S r:   )rh   )rG   r4   r6   r6   r7   __add__   s    zProperties.__add__rR   r"   rK   )rM   objr+   c                 C  s   || j |< d S r:   r[   rG   rM   rv   r6   r6   r7   rO      s    zProperties.__setitem__rM   r+   c                 C  s
   | j | S r:   r[   rG   rM   r6   r6   r7   __getitem__   s    zProperties.__getitem__c                 C  s   | j |= d S r:   r[   ry   r6   r6   r7   __delitem__   s    zProperties.__delitem__c                 C  s   || j |< d S r:   r[   rw   r6   r6   r7   ra      s    zProperties.__setattr__zDict[str, Any]c                 C  s
   d| j iS r^   r[   rF   r6   r6   r7   __getstate__   s    zProperties.__getstate__)stater+   c                 C  s   t | d|d  d S r^   r_   )rG   r}   r6   r6   r7   __setstate__   s    zProperties.__setstate__c                 C  s.   z| j | W S  tk
r(   t|Y nX d S r:   )r\   KeyErrorAttributeErrorry   r6   r6   r7   __getattr__   s    zProperties.__getattr__boolc                 C  s
   || j kS r:   r[   ry   r6   r6   r7   __contains__   s    zProperties.__contains__zReadOnlyProperties[_T]c                 C  s
   t | jS )z8Return an immutable proxy for this :class:`.Properties`.)ReadOnlyPropertiesr\   rF   r6   r6   r7   as_readonly   s    zProperties.as_readonly)rN   r+   c                 C  s   | j | d S r:   )r\   update)rG   rN   r6   r6   r7   r      s    zProperties.updatezOptional[_T]c                 C  s   d S r:   r6   ry   r6   r6   r7   get   s    zProperties.getzUnion[_DT, _T]rM   defaultr+   c                 C  s   d S r:   r6   rG   rM   r   r6   r6   r7   r      s    NzOptional[Union[_DT, _T]]zOptional[Union[_T, _DT]]c                 C  s   || kr| | S |S d S r:   r6   r   r6   r6   r7   r      s    c                 C  s
   t | jS r:   )rh   r\   rF   r6   r6   r7   rq      s    zProperties.keysList[_T]c                 C  s   t | j S r:   )rh   r\   ri   rF   r6   r6   r7   ri      s    zProperties.valueszList[Tuple[str, _T]]c                 C  s   t | j S r:   )rh   r\   itemsrF   r6   r6   r7   r      s    zProperties.itemsc                 C  s
   || j kS r:   r[   ry   r6   r6   r7   has_key   s    zProperties.has_keyc                 C  s   | j   d S r:   )r\   clearrF   r6   r6   r7   r      s    zProperties.clear)N)rT   rU   rV   rW   	__slots____annotations__rb   rf   rj   rt   ru   rO   rz   r{   ra   r|   r~   r   r   r   r   r   r   rq   ri   r   r   r   __classcell__r6   r6   rr   r7   rZ      s:   
 rZ   c                   @  s   e Zd ZdZdZdd ZdS )OrderedPropertieszUProvide a __getattr__/__setattr__ interface with an OrderedDict
    as backing store.r6   c                 C  s   t | t  d S r:   )rZ   rb   OrderedDictrF   r6   r6   r7   rb   
  s    zOrderedProperties.__init__N)rT   rU   rV   rW   r   rb   r6   r6   r6   r7   r     s   r   c                   @  s   e Zd ZdZdZdS )r   zDProvide immutable dict/object attribute to an underlying dictionary.r6   N)rT   rU   rV   rW   r   r6   r6   r6   r7   r     s   r   c                   s0    fddt  |dD }    | dS )zSort an OrderedDict in-place.c                   s   g | ]}| | fqS r6   r6   rk   r=   r6   r7   rn     s     z,_ordered_dictionary_sort.<locals>.<listcomp>)rM   N)sortedr   r   )r9   rM   r   r6   r=   r7   _ordered_dictionary_sort  s    r   c                   @  s<   e Zd ZdddddZdd Zdd	 Zd
d Zdd ZdS )WeakSequencer6   zSequence[_T])_WeakSequence__elementsc                   s0   t | fdd  | _ fdd|D | _d S )Nc                 S  s   | }|d k	r|j |  d S r:   )_storageremove)itemselfrefrG   r6   r6   r7   _remove&  s    z&WeakSequence.__init__.<locals>._removec                   s   g | ]}t | qS r6   )weakrefref)rl   r5   r   r6   r7   rn   ,  s    z)WeakSequence.__init__.<locals>.<listcomp>)r   r   r   r   )rG   r   r6   r   r7   rb   #  s
    
zWeakSequence.__init__c                 C  s   | j t|| j d S r:   )r   r0   r   r   r   )rG   r   r6   r6   r7   r0   0  s    zWeakSequence.appendc                 C  s
   t | jS r:   )re   r   rF   r6   r6   r7   rf   3  s    zWeakSequence.__len__c                 C  s   dd dd | j D D S )Nc                 s  s   | ]}|d k	r|V  qd S r:   r6   )rl   rv   r6   r6   r7   	<genexpr>7  s     z(WeakSequence.__iter__.<locals>.<genexpr>c                 s  s   | ]}| V  qd S r:   r6   )rl   r   r6   r6   r7   r   8  s     )r   rF   r6   r6   r7   rj   6  s    zWeakSequence.__iter__c                 C  s:   z| j | }W n  tk
r.   td| Y nX | S d S )NzIndex %s out of range)r   r   
IndexError)rG   indexrv   r6   r6   r7   rz   ;  s
    zWeakSequence.__getitem__N)r6   )rT   rU   rV   rb   r0   rf   rj   rz   r6   r6   r6   r7   r   "  s
   r   c                   @  s   e Zd ZdddddZdS )OrderedIdentitySetNzOptional[Iterable[Any]])iterablec                 C  s.   t |  t | _|r*|D ]}| | qd S r:   )r   rb   r   Z_membersadd)rG   r   or6   r6   r7   rb   E  s
    
zOrderedIdentitySet.__init__)N)rT   rU   rV   rb   r6   r6   r6   r7   r   D  s   r   c                   @  s.   e Zd ZdZddddZddddd	Zd
S )PopulateDictzA dict which populates missing values via a creation function.

    Note the creation function takes a key, unlike
    collections.defaultdict.

    zCallable[[_KT], _VT]creatorc                 C  s
   || _ d S r:   r   )rG   r   r6   r6   r7   rb   U  s    zPopulateDict.__init__r   rx   c                 C  s   |  | | |< }|S r:   r   rG   rM   valr6   r6   r7   __missing__X  s    zPopulateDict.__missing__NrT   rU   rV   rW   rb   r   r6   r6   r6   r7   r   M  s   r   c                   @  s.   e Zd ZdZddddZddddd	Zd
S )WeakPopulateDictzaLike PopulateDict, but assumes a self + a method and does not create
    a reference cycle.

    ztypes.MethodType)creator_methodc                 C  s   |j | _|j}t|| _d S r:   )__func__r   __self__r   r   weakself)rG   r   r   r6   r6   r7   rb   c  s    zWeakPopulateDict.__init__r   rx   c                 C  s   |  |  | | |< }|S r:   )r   r   r   r6   r6   r7   r   h  s    zWeakPopulateDict.__missing__Nr   r6   r6   r6   r7   r   ]  s   r   c                   @  s^   e Zd ZU dZdZded< ded< ded< ddd
dddZdddddZddddZd	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]   zCallable[[_T], None]r   zDict[int, Literal[True]]r   NzOptional[str])r]   viac                 C  sT   || _ i | _|rt||| _n2t|dr8td|j| _nt|drPtd|j| _d S )Nr0   r   r   zSet[_T])r]   r   getattrr   hasattrr   r0   r   )rG   r]   r   r6   r6   r7   rb     s    

zUniqueAppender.__init__r"   rK   )r   r+   c                 C  s*   t |}|| jkr&| | d| j|< d S )NT)idr   r   )rG   r   Zid_r6   r6   r7   r0     s    

zUniqueAppender.appendrg   rD   c                 C  s
   t | jS r:   )r.   r]   rF   r6   r6   r7   rj     s    zUniqueAppender.__iter__)N)	rT   rU   rV   rW   r   r   rb   r0   rj   r6   r6   r6   r7   r   v  s   
 r   r   )argr+   c                 C  s6   t | dkr(t| d tjr(t| d S td| S d S )Nr   r   r(   )re   r<   typesGeneratorTyperh   r   )r   r6   r6   r7   coerce_generator_arg  s    r   zOptional[List[Any]])xr   r+   c                 C  s4   | d kr|S t | s| gS t| tr(| S t| S d S r:   )r   r<   rh   )r   r   r6   r6   r7   to_list  s    
r   zContainer[Any]zIterable[Any]r   )set_r   r+   c                   s   t  fdd|D S )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.

    c                 3  s   | ]}|j r| kV  qd S r:   )__hash__)rl   ir   r6   r7   r     s      z#has_intersection.<locals>.<genexpr>)any)r   r   r6   r   r7   has_intersection  s    r   c                 C  s,   | d krt  S t| t s$t t| S | S d S r:   )r,   r<   r   r   r6   r6   r7   to_set  s
    
r   zSet[Any])r   r+   c                 C  s,   | d krt  S t| t s$t t| S | S d S r:   )
column_setr<   r   r   r6   r6   r7   to_column_set  s
    
r   zDict[Any, Any]zOptional[Dict[Any, Any]])r9   _newkwr+   c                 K  s&   |   } |r| | | jf | | S )z5Copy the given dict and update with the given values.)rH   r   )r9   r   r   r6   r6   r7   update_copy  s
    
r   zIterable[_T]rg   c                 c  s8   | D ].}t |ts,t|dr,t|E dH  q|V  qdS )zGiven an iterator of which further sub-elements may also be
    iterators, flatten the sub-elements into a single iterator.

    rj   N)r<   rR   r   flatten_iterator)r   elemr6   r6   r7   r     s    r   c                   @  s  e Zd ZU dZdZded< ded< ded< d3ddddddZdd ZedddddZ	eddddddZ	d4ddddddZ	dddddZ
dd d!d"Zdd d#d$Zd%d d&d'Zddd(d)d*d+Zdd(d,d-d.Zedd d/d0Zd(d d1d2ZdS )5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_alertr\   _counter_mutexrc   r   floatr   z.Optional[Callable[[LRUCache[_KT, _VT]], None]]r   d         ?Nz$Optional[Callable[(Ellipsis, None)]])r   r   r   c                 C  s,   || _ || _|| _d| _t | _i | _d S )Nr   )r   r   r   r   	threadingLockr   r\   )rG   r   r   r   r6   r6   r7   rb     s    
zLRUCache.__init__c                 C  s   |  j d7  _ | j S )Nr   )r   rF   r6   r6   r7   _inc_counter  s    zLRUCache._inc_counterr#   zOptional[_VT]rx   c                 C  s   d S r:   r6   ry   r6   r6   r7   r   
  s    zLRUCache.getzUnion[_VT, _T]r   c                 C  s   d S r:   r6   r   r6   r6   r7   r     s    zOptional[Union[_VT, _T]]c                 C  s4   | j |}|d k	r,|  |d d< |d S |S d S N   r   r   )r\   r   r   )rG   rM   r   r   r6   r6   r7   r     s
    r$   c                 C  s"   | j | }|  |d d< |d S r   )r\   r   )rG   rM   r   r6   r6   r7   rz     s    
zLRUCache.__getitem__zIterator[_KT]rD   c                 C  s
   t | jS r:   )r.   r\   rF   r6   r6   r7   rj     s    zLRUCache.__iter__c                 C  s
   t | jS r:   rd   rF   r6   r6   r7   rf   "  s    zLRUCache.__len__zValuesView[_VT]c                 C  s   t dd | j D S )Nc                 S  s   i | ]\}}||d  qS )r   r6   )rl   rm   r   r6   r6   r7   
<dictcomp>&  s      z#LRUCache.values.<locals>.<dictcomp>)typingr   r\   r   rF   r6   r6   r7   ri   %  s    zLRUCache.valuesrK   rL   c                 C  s"   |||   gf| j|< |   d S r:   )r   r\   _manage_sizerP   r6   r6   r7   rO   (  s    zLRUCache.__setitem__)_LRUCache__vr+   c                 C  s   | j |= d S r:   r[   )rG   r   r6   r6   r7   r{   ,  s    zLRUCache.__delitem__c                 C  s   | j | j | j  S r:   )r   r   rF   r6   r6   r7   size_threshold/  s    zLRUCache.size_thresholdc              	   C  s   | j dsd S zt| j}t| | j| j| j  kr|rHd}| |  t| j	
 tddd}|| jd  D ].}z| j	|d = W qp tk
r   Y qpY qpX qpqW 5 | j   X d S )NFr   T)rM   reverser   )r   acquirereleaser   r   re   r   r   r   r\   ri   operator
itemgetterr   )rG   r   Z
by_counterr   r6   r6   r7   r   3  s&    

zLRUCache._manage_size)r   r   N)N)rT   rU   rV   rW   r   r   rb   r   r   r   rz   rj   rf   ri   rO   r{   propertyr   r   r6   r6   r6   r7   r     s2   
		    
r   c                   @  s   e Zd ZddddZdS )_CreateFuncTyper%   rD   c                 C  s   d S r:   r6   rF   r6   r6   r7   __call__L      z_CreateFuncType.__call__NrT   rU   rV   r   r6   r6   r6   r7   r   K  s   r   c                   @  s   e Zd ZddddZdS )_ScopeFuncTyper   rD   c                 C  s   d S r:   r6   rF   r6   r6   r7   r   P  r   z_ScopeFuncType.__call__Nr   r6   r6   r6   r7   r   O  s   r   c                   @  sx   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ZddddZdddddZ	ddddZ
dS )ScopedRegistrya  A 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	scopefuncregistryz_CreateFuncType[_T]r   r   r   r   r   Callable[[], _T]zCallable[[], Any])r   r   c                 C  s   || _ || _i | _dS )aV  Construct 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   )rG   r   r   r6   r6   r7   rb   h  s    zScopedRegistry.__init__r"   rD   c                 C  s@   |   }z| j| W S  tk
r:   | j||   Y S X d S r:   )r   r   r   
setdefaultr   ry   r6   r6   r7   r   y  s
    zScopedRegistry.__call__r   c                 C  s   |   | jkS )z9Return True if an object is present in the current scope.)r   r   rF   r6   r6   r7   has  s    zScopedRegistry.hasrK   rv   r+   c                 C  s   || j |  < dS )z$Set the value for the current scope.N)r   r   rG   rv   r6   r6   r7   r,     s    zScopedRegistry.setc                 C  s*   z| j |  = W n tk
r$   Y nX dS )z Clear the current scope, if any.N)r   r   r   rF   r6   r6   r7   r     s    zScopedRegistry.clearN)rT   rU   rV   rW   r   r   rb   r   r   r,   r   r6   r6   r6   r7   r   S  s   
r   c                   @  sX   e Zd ZdZddddZdddd	Zd
dddZdddddZddddZdS )ThreadLocalRegistryz\A :class:`.ScopedRegistry` that uses a ``threading.local()``
    variable for storage.

    r   )r   c                 C  s   || _ t | _d S r:   )r   r   localr   )rG   r   r6   r6   r7   rb     s    zThreadLocalRegistry.__init__r"   rD   c                 C  s8   z
| j jW S  tk
r2   |   }| j _| Y S X d S r:   )r   rN   r   r   )rG   r   r6   r6   r7   r     s
    
zThreadLocalRegistry.__call__r   c                 C  s   t | jdS )NrN   )r   r   rF   r6   r6   r7   r     s    zThreadLocalRegistry.hasrK   r   c                 C  s   || j _d S r:   )r   rN   r   r6   r6   r7   r,     s    zThreadLocalRegistry.setc                 C  s$   z
| j `W n tk
r   Y nX d S r:   )r   rN   r   rF   r6   r6   r7   r     s    
zThreadLocalRegistry.clearN)	rT   rU   rV   rW   rb   r   r   r,   r   r6   r6   r6   r7   r     s   r   c                 C  s0   d}| D ]"}||kr|d7 }|dkr dS qdS )zrGiven a sequence and search object, return True if there's more
    than one, False if zero or one of them.


    r   r   TFr6   )Zsequencetargetcr   r6   r6   r7   	has_dupes  s    
r   )N)N)N)WrW   Z
__future__r   r   r   r   r   r   r   r   r   r   r   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   Z_has_cyr   r   r   r   ZTYPE_CHECKINGZ_py_collectionsr   r   r   r   r    r!   Z$sqlalchemy.cyextension.immutabledictZ"sqlalchemy.cyextension.collectionsr"   r#   r$   r%   	frozensetr&   r   r'   r8   r>   r;   r?   rX   rY   rZ   r   r   r   rI   r   Zsort_dictionaryr   r   r   r   r,   r   Zcolumn_dictZordered_column_setr   r   r   r   r   r   r   r   MutableMappingr   r   r   r   r   r   r6   r6   r6   r7   <module>	   s   8	W


"	%
	
 i@