o
    .jY                     @  s  d dl mZ d dlZd dlmZ d dlmZ d dlm	Z	m
Z
 d dlmZ d dlmZ ejr;d dlmZ G d	d
 d
eZg dZedZedZedZejdejeef ejejeef  d
f ZG dd de	Zeddd*ddZd+ddZG dd dej eef ej!eef Z"G d d! d!ej#ejeef  Z$G d"d dej!eef Z%ejd#ej&d$Z'ed%Z(G d&d' d'ej)e' Z*G d(d) d)ej+e'e(f Z,dS ),    )annotationsN)OrderedDict)Mapping)Enumauto)	lru_cache)RLock)Protocolc                   @  s    e Zd Zd
ddZdddZd	S )HasGettableStringKeysreturntyping.Iterator[str]c                 C     d S N selfr   r   P/home/thesage/.local/lib/python3.10/site-packages/urllib3_future/_collections.pykeys       zHasGettableStringKeys.keyskeystrc                 C  r   r   r   r   r   r   r   r   __getitem__   r   z!HasGettableStringKeys.__getitem__Nr   r   r   r   r   r   )__name__
__module____qualname__r   r   r   r   r   r   r
      s    
r
   )RecentlyUsedContainerHTTPHeaderDictGroupedDict_KT_VT_DTr   c                   @  s   e Zd Ze ZdS )	_SentinelN)r   r   r   r   
not_passedr   r   r   r   r$   +   s    
r$   @   )maxsizestringr   r   c                 C     |   S )zjReasoning: We are often calling lower on repetitive identical header key. This was unnecessary exhausting!)lower)r(   r   r   r   _lower_wrapper/   s   r+   	potentialobjectValidHTTPHeaderSource | Nonec                 C  s|   t | tr| S t | tjrttjttf | S t | tjr,ttjtjttf  | S t| dr<t| dr<td| S d S )Nr   r   r
   )	
isinstancer   typingr   castr   IterableTuplehasattr)r,   r   r   r   %ensure_can_construct_http_header_dict5   s   
r5   c                      s   e Zd ZU dZded< ded< ded< ded	< 	
	d%d& fddZd'ddZd(ddZd)ddZd*ddZ	d+ddZ
d,d d!Zd-d#d$Z  ZS ).r   a^  
    Provides a thread-safe dict-like container which maintains up to
    ``maxsize`` keys while throwing away the least-recently-used keys beyond
    ``maxsize``. Caution: RecentlyUsedContainer is deprecated and scheduled for
    removal in a next major of urllib3.future. It has been replaced by a more
    suitable implementation in ``urllib3.util.traffic_police``.

    :param maxsize:
        Maximum number of recent elements to retain.

    :param dispose_func:
        Every time an item is evicted from the container,
        ``dispose_func(value)`` is called.  Callback which will get called
    ztyping.OrderedDict[_KT, _VT]
_containerint_maxsize#typing.Callable[[_VT], None] | Nonedispose_funcr   lock
   Nr'   r   Nonec                   s*   t    || _|| _t | _t | _d S r   )super__init__r8   r:   r   r6   r   r;   )r   r'   r:   	__class__r   r   r?   ^   s
   
zRecentlyUsedContainer.__init__r   r!   r"   c                 C  sD   | j  | j|}|| j|< |W  d    S 1 sw   Y  d S r   )r;   r6   pop)r   r   itemr   r   r   r   i   s
   
$z!RecentlyUsedContainer.__getitem__valuec              	   C  s   d }| j 5 z|| j|f}|| j|< W n ty2   || j|< t| j| jkr0| jjdd}Y nw W d    n1 s=w   Y  |d urT| jrV|\}}| | d S d S d S )NF)last)r;   r6   rB   KeyErrorlenr8   popitemr:   )r   r   rD   evicted_item_evicted_valuer   r   r   __setitem__p   s"   
z!RecentlyUsedContainer.__setitem__c                 C  sJ   | j  | j|}W d    n1 sw   Y  | jr#| | d S d S r   )r;   r6   rB   r:   )r   r   rD   r   r   r   __delitem__   s   z!RecentlyUsedContainer.__delitem__c                 C  s4   | j  t| jW  d    S 1 sw   Y  d S r   )r;   rG   r6   r   r   r   r   __len__   s   $zRecentlyUsedContainer.__len__typing.NoReturnc                 C  s   t d)Nz7Iteration over this class is unlikely to be threadsafe.)NotImplementedErrorr   r   r   r   __iter__   s   zRecentlyUsedContainer.__iter__c                 C  s`   | j  t| j }| j  W d    n1 sw   Y  | jr,|D ]	}| | q$d S d S r   )r;   listr6   valuesclearr:   )r   rS   rD   r   r   r   rT      s   zRecentlyUsedContainer.clearset[_KT]c                 C  s8   | j  t| j W  d    S 1 sw   Y  d S r   )r;   setr6   r   r   r   r   r   r      s   $zRecentlyUsedContainer.keys)r<   N)r'   r7   r:   r9   r   r=   )r   r!   r   r"   )r   r!   rD   r"   r   r=   )r   r!   r   r=   r   r7   )r   rO   r   r=   )r   rU   )r   r   r   __doc____annotations__r?   r   rL   rM   rN   rQ   rT   r   __classcell__r   r   r@   r   r   I   s    
 






r   c                   @  sB   e Zd ZU dZded< dddZdd
dZdddZdddZdS )HTTPHeaderDictItemViewa  
    HTTPHeaderDict is unusual for a Mapping[str, str] in that it has two modes of
    address.

    If we directly try to get an item with a particular name, we will get a string
    back that is the concatenated version of all the values:

    >>> d['X-Header-Name']
    'Value1, Value2, Value3'

    However, if we iterate over an HTTPHeaderDict's items, we will optionally combine
    these values based on whether combine=True was called when building up the dictionary

    >>> d = HTTPHeaderDict({"A": "1", "B": "foo"})
    >>> d.add("A", "2", combine=True)
    >>> d.add("B", "bar")
    >>> list(d.items())
    [
        ('A', '1, 2'),
        ('B', 'foo'),
        ('B', 'bar'),
    ]

    This class conforms to the interface required by the MutableMapping ABC while
    also giving us the nonstandard iteration behavior we want; items with duplicate
    keys, ordered by time of first insertion.
    r   _headersheadersr   r=   c                 C  
   || _ d S r   )r]   )r   r^   r   r   r   r?         
zHTTPHeaderDictItemView.__init__r7   c                 C  s   t t| j S r   )rG   rR   r]   	iteritemsr   r   r   r   rN      s   zHTTPHeaderDictItemView.__len__ typing.Iterator[tuple[str, str]]c                 C  s
   | j  S r   )r]   ra   r   r   r   r   rQ      r`   zHTTPHeaderDictItemView.__iter__rC   r-   boolc                 C  sD   t |tr t|dkr |\}}t |tr t |tr | j||S dS )N   F)r/   tuplerG   r   r]   _has_value_for_header)r   rC   
passed_key
passed_valr   r   r   __contains__   s
   z#HTTPHeaderDictItemView.__contains__N)r^   r   r   r=   rW   r   rb   )rC   r-   r   rc   )	r   r   r   rY   rZ   r?   rN   rQ   ri   r   r   r   r   r\      s   
 


r\   c                      s8  e Zd ZU dZded< dMdN fd	d
ZdOddZdPddZdQddZdRddZ	dSdT fddZ
dUddZdUd d!ZdVd#d$ZdWd&d'ZdQd(d)Zd*d+dXd-d.ZdYd1d2ZejdZd4d5Zejd[d8d5Zejfd\d:d5ZeZeZeZeZd]d;d<Zd^d=d>Zd_d?d@Zd`dBdCZd`dDdEZdadGdHZ dbdKdLZ!  Z"S )cr   ap  
    :param headers:
        An iterable of field-value pairs. Must not contain multiple field names
        when compared case-insensitively.

    :param kwargs:
        Additional field-value pairs to pass in to ``dict.update``.

    A ``dict`` like container for storing HTTP Headers.

    Field names are stored and compared case-insensitively in compliance with
    RFC 7230. Iteration provides the first case-sensitive key seen for each
    case-insensitive pair.

    Using ``__setitem__`` syntax overwrites fields that compare equal
    case-insensitively in order to maintain ``dict``'s api. For fields that
    compare equal, instead create a new ``HTTPHeaderDict`` and use ``.add``
    in a loop.

    If multiple fields that are equal case-insensitively are passed to the
    constructor or ``.update``, the behavior is undefined and some will be
    lost.

    >>> headers = HTTPHeaderDict()
    >>> headers.add('Set-Cookie', 'foo=bar')
    >>> headers.add('set-cookie', 'baz=quxx')
    >>> headers['content-length'] = '7'
    >>> headers['SET-cookie']
    'foo=bar, baz=quxx'
    >>> headers['Content-Length']
    '7'
    z%typing.MutableMapping[str, list[str]]r6   Nr^   r.   kwargsr   c                   sN   t    i | _|d urt|tr| | n| | |r%| | d S d S r   )r>   r?   r6   r/   r   
_copy_fromextend)r   r^   rk   r@   r   r   r?      s   


zHTTPHeaderDict.__init__r   valr   r=   c                 C  s   ||g| j t|< d S r   r6   r+   r   r   rn   r   r   r   rL     s   zHTTPHeaderDict.__setitem__c                 C  s4   t |tr
|d}| jt| }d|dd  S )Nlatin-1,    )r/   bytesdecoder6   r+   joinrp   r   r   r   r     s   

zHTTPHeaderDict.__getitem__c                 C  s$   t |tr
|d}| jt|= d S )Nrq   )r/   rt   ru   r6   r+   r   r   r   r   rM     s   

zHTTPHeaderDict.__delitem__r-   rc   c                 C  s0   t |tr
|d}t |trt|| jv S dS )Nrq   F)r/   rt   ru   r   r+   r6   r   r   r   r   ri     s
   


zHTTPHeaderDict.__contains__ defaultc                   s   t  ||S r   )r>   
setdefaultr   r   rx   r@   r   r   ry     s   zHTTPHeaderDict.setdefaultotherc                 C  sD   t |}|d u r
dS t| |}dd |  D dd | D kS )NFc                 S  s   i | ]	\}}t ||qS r   )r+   ).0kvr   r   r   
<dictcomp>'  s    z)HTTPHeaderDict.__eq__.<locals>.<dictcomp>)r5   type
itermerged)r   r{   maybe_constructableother_as_http_header_dictr   r   r   __eq__   s   zHTTPHeaderDict.__eq__c                 C  s   |  | S r   )r   )r   r{   r   r   r   __ne__+  s   zHTTPHeaderDict.__ne__r7   c                 C  s
   t | jS r   )rG   r6   r   r   r   r   rN   .  r`   zHTTPHeaderDict.__len__r   c                 c  s     | j  D ]}|d V  qd S Nr   )r6   rS   )r   valsr   r   r   rQ   1  s   zHTTPHeaderDict.__iter__c                 C  s"   z| |= W d S  t y   Y d S w r   )rF   r   r   r   r   discard6  s
   zHTTPHeaderDict.discardF)combiner   c                C  sT   t |}||g}| j||}||ur(|r!|d d | |d< dS || dS dS )a  Adds a (name, value) pair, doesn't overwrite the value if it already
        exists.

        If this is called with combine=True, instead of adding a new header value
        as a distinct item during iteration, this will instead append the value to
        any existing header value with a comma. If no existing header value exists
        for the key, then the value will simply be added, ignoring the combine parameter.

        >>> headers = HTTPHeaderDict(foo='bar')
        >>> headers.add('Foo', 'baz')
        >>> headers['foo']
        'bar, baz'
        >>> list(headers.items())
        [('foo', 'bar'), ('foo', 'baz')]
        >>> headers.add('foo', 'quz', combine=True)
        >>> list(headers.items())
        [('foo', 'bar, baz, quz')]
        rr   N)r+   r6   ry   append)r   r   rn   r   	key_lowernew_valsr   r   r   r   add<  s   zHTTPHeaderDict.addargsValidHTTPHeaderSourcec                 O  s
  t |dkrtdt | dt |dkr|d nd}t|tr1| D ]
\}}| || q%nCt|tjrG| D ]
\}}| || q;n-t|tj	r[|D ]
\}}| || qOnt
|drtt
|drt| D ]
}| |||  qi| D ]
\}}| || qxdS )	zGeneric import function for any type of header-like object.
        Adapted version of MutableMapping.update in order to insert items
        with self.add instead of self.__setitem__
        rs   z/extend() takes at most 1 positional arguments (z given)r   r   r   r   N)rG   	TypeErrorr/   r   ra   r   r0   r   itemsr2   r4   r   )r   r   rk   r{   r   rn   rD   r   r   r   rm   [  s.   
zHTTPHeaderDict.extend	list[str]c                 C  r   r   r   r   r   r   r   getlist{     zHTTPHeaderDict.getlistr#   list[str] | _DTc                 C  r   r   r   rz   r   r   r   r   ~  r   _Sentinel | _DTc                 C  s\   t |tr
|d}z	| jt| }W n ty'   |tju r#g  Y S | Y S w |dd S )zmReturns a list of all the values for the named field. Returns an
        empty list if the key doesn't exist.rq   rs   N)r/   rt   ru   r6   r+   rF   r$   r%   )r   r   rx   r   r   r   r   r     s   


	c                 C  s   t | j dt|   dS )N())r   r   dictr   r   r   r   r   __repr__  s   zHTTPHeaderDict.__repr__c                 C  s,   |D ]}| |}|g|| jt|< qd S r   )r   r6   r+   )r   r{   r   rn   r   r   r   rl     s   
zHTTPHeaderDict._copy_fromc                 C  s   t |  }||  |S r   )r   rl   )r   cloner   r   r   copy  s   

zHTTPHeaderDict.copyrb   c                 c  s>    | D ]}| j t| }|dd D ]	}|d |fV  qqdS )z8Iterate over all header lines, including duplicate ones.rs   Nr   ro   )r   r   r   rn   r   r   r   ra     s   zHTTPHeaderDict.iteritemsc                 c  s:    | D ]}| j t| }|d d|dd fV  qdS )z:Iterate over all headers, merging duplicate ones together.r   rr   rs   N)r6   r+   rv   rp   r   r   r   r     s
   zHTTPHeaderDict.itermergedr\   c                 C  s   t | S r   )r\   r   r   r   r   r        zHTTPHeaderDict.itemsheader_namepotential_valuec                 C  s&   || v r|| j t| dd  v S dS )Nrs   Fro   )r   r   r   r   r   r   rf     s   z$HTTPHeaderDict._has_value_for_headerr   )r^   r.   rk   r   )r   r   rn   r   r   r=   r   )r   r   r   r=   r   r-   r   rc   )rw   )r   r   rx   r   r   r   )r{   r-   r   rc   rW   r   )r   r   rn   r   r   rc   r   r=   )r   r   rk   r   r   r=   )r   r   r   r   )r   r   rx   r#   r   r   )r   r   rx   r   r   r   r   r   )r{   r   r   r=   )r   r   rj   )r   r\   )r   r   r   r   r   rc   )#r   r   r   rY   rZ   r?   rL   r   rM   ri   ry   r   r   rN   rQ   r   r   rm   r0   overloadr   r$   r%   
getheadersgetallmatchingheadersigetget_allr   rl   r   ra   r   r   rf   r[   r   r   r@   r   r      sB   
 !









 





_GK)bound_GVc                   @  sF   e Zd ZdZdZdddZdd
dZdddZdddZdddZ	dS )ReverseKeysViewaN  A read-only ``KeysView`` over the keys mapped to a single value.

    Returned by :meth:`GroupedDict.keys_for`. Backed by reference to an
    internal bucket so the view is live (mirrors ``dict.keys()`` semantics):
    subsequent mutations of the parent :class:`GroupedDict` are reflected on
    next iteration / membership test.
    _bucketbucket typing.Optional[typing.Set[_GK]]r   r=   c                 C  r_   r   r   )r   r   r   r   r   r?     s   
zReverseKeysView.__init__typing.Iterator[_GK]c                 C  s   | j d u r	tdS t| j S )Nr   )r   iterr   r   r   r   rQ     s   

zReverseKeysView.__iter__r7   c                 C  s   | j d u rdS t| j S r   )r   rG   r   r   r   r   rN        

zReverseKeysView.__len__r   r-   rc   c                 C  s   | j d u rdS || j v S )NFr   r   r   r   r   ri     r   zReverseKeysView.__contains__r   c                 C  s"   d| j rt| dS t dS )NzReverseKeysView(r   )r   rV   r   r   r   r   r     s   "zReverseKeysView.__repr__N)r   r   r   r=   )r   r   rW   r   r   )
r   r   r   rY   	__slots__r?   rQ   rN   ri   r   r   r   r   r   r     s    



r   c                      s   e Zd ZdZdZddd/ fddZd0 fddZd1 fddZd2 fddZd3 fddZ	d4 fddZ
d5d6 fddZd7d d!Zd8d#d$Zd9d&d'Zd9d(d)Ze	d5d:d-d.Z  ZS );r    uu  A ``dict`` subclass that maintains a reverse "value to keys" index.

    Optimized for the case where many keys share a small number of distinct
    values. Reverse lookups via :meth:`keys_for` are O(1) average time and
    return a live :class:`ReverseKeysView`.

    A ``key_fn`` may be supplied to control how values are hashed for the
    reverse index. By default, the value itself is used (identity over
    equality). Pass ``key_fn=id`` to index by object identity instead — this
    is the right choice when values may override ``__eq__`` / ``__hash__``
    in ways you don't want to collapse buckets on, or when values are not
    hashable themselves.

    All standard ``dict`` mutation entry points are overridden to keep the
    reverse index coherent. Empty buckets are pruned eagerly so that
    long-lived instances do not accumulate stale entries on value churn.
    )_index_key_fnNkey_fnr   
typing.Anyr   .typing.Callable[[_GV], typing.Hashable] | Nonerk   r   r=   c                  sb   t  j|i | |d ur|ndd | _i | _t   D ]\}}| j| |t | qd S )Nc                 S  s   | S r   r   )xr   r   r   <lambda>  r   z&GroupedDict.__init__.<locals>.<lambda>)r>   r?   r   r   r   ry   rV   r   )r   r   r   rk   r}   r~   r@   r   r   r?     s   zGroupedDict.__init__r   r   rD   r   c                   s   || v rJt  |}| |}| |}||kr!t  || d S | j|}|d ur6|| |s6| j|= t  || | j|t 	| d S t  || | j| |t 	| d S r   )
r>   r   r   rL   r   getr   ry   rV   r   )r   r   rD   oldold_hnew_hr   r@   r   r   rL   
  s"   


 zGroupedDict.__setitem__c                   sX   t  |}t  | | |}| j|}|d ur(|| |s*| j|= d S d S d S r   )r>   r   rM   r   r   r   r   )r   r   r   r   r   r@   r   r   rM     s   

zGroupedDict.__delitem__c                   s   t |dkrtddt |  || vr|r|d S t|t |}| |}| j|}|d ur?|| |s?| j|= |S )Nrs   z&pop expected at most 2 arguments, got r   )	rG   r   rF   r>   rB   r   r   r   r   )r   r   r   rD   hr   r@   r   r   rB   '  s   

zGroupedDict.poptuple[_GK, _GV]c                   sJ   t   \}}| |}| j|}|d ur!|| |s!| j|= ||fS r   )r>   rH   r   r   r   r   )r   r   rD   r   r   r@   r   r   rH   7  s   

zGroupedDict.popitemc                   s   t    | j  d S r   )r>   rT   r   r   r@   r   r   rT   A  s   
zGroupedDict.clearrx   c                   s    || v r
t  |S || |< |S r   )r>   r   rz   r@   r   r   ry   E  s   zGroupedDict.setdefaultc                 O  s   t |dkrtdt | |rD|d }t|tr&|D ]}|| | |< qnt|dr9| D ]}|| | |< q/n|D ]\}}|| |< q;| D ]\}}|| |< qHd S )Nrs   z3update expected at most 1 positional argument, got r   r   )rG   r   r/   _Mappingr4   r   r   )r   r   rk   r{   r}   r~   r   r   r   updateL  s&   



zGroupedDict.updateReverseKeysView[_GK]c                 C  s   | j | |}t|S )a?  Return a live read-only view over all keys mapped to ``value``.

        Lookup is O(1) average time. The returned :class:`ReverseKeysView`
        reflects the current bucket contents and updates as the parent
        :class:`GroupedDict` is mutated. Returns an empty view if no key
        maps to ``value``.
        )r   r   r   r   )r   rD   r   r   r   r   keys_for`  s   zGroupedDict.keys_forGroupedDict[_GK, _GV]c                 C  s   t | | jd}|S )Nr   )r    r   )r   newr   r   r   r   k  s   zGroupedDict.copyc                 C  r)   r   )r   r   r   r   r   __copy__p  r   zGroupedDict.__copy__iterabletyping.Iterable[_GK]GroupedDict[_GK, typing.Any]c                   s   |  fdd|D S )Nc                   s   i | ]}| qS r   r   )r|   r}   rD   r   r   r   y  s    z(GroupedDict.fromkeys.<locals>.<dictcomp>r   )clsr   rD   r   r   r   fromkeyss  s   zGroupedDict.fromkeys)r   r   r   r   rk   r   r   r=   )r   r   rD   r   r   r=   )r   r   r   r=   )r   r   r   r   r   r   )r   r   rX   r   )r   r   rx   r   r   r   )r   r   rk   r   r   r=   )rD   r   r   r   )r   r   )r   r   rD   r   r   r   )r   r   r   rY   r   r?   rL   rM   rB   rH   rT   ry   r   r   r   r   classmethodr   r[   r   r   r@   r   r      s$    





r    )r(   r   r   r   )r,   r-   r   r.   )-
__future__r   r0   collectionsr   collections.abcr   r   enumr   r   	functoolsr   	threadingr   TYPE_CHECKINGtyping_extensionsr	   r
   __all__TypeVarr!   r"   r#   Unionr   r2   r3   r   r$   r+   r5   GenericMutableMappingr   Setr\   r   Hashabler   r   KeysViewr   Dictr    r   r   r   r   <module>   sB    



& _0 i
#