U
    }Wod<                     @  s4  d dl mZ d dlZd dlmZ d dlmZmZ d dlm	Z	 ej
r^d dlmZ G dd deZd	d
g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dd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 dS )    )annotationsN)OrderedDict)Enumauto)RLock)Protocolc                   @  s*   e Zd ZddddZdddddZd	S )
HasGettableStringKeystyping.Iterator[str]returnc                 C  s   d S N selfr   r   8/tmp/pip-unpacked-wheel-pkxu86yo/urllib3/_collections.pykeys   s    zHasGettableStringKeys.keysstrkeyr   c                 C  s   d S r   r   r   r   r   r   r   __getitem__   s    z!HasGettableStringKeys.__getitem__N)__name__
__module____qualname__r   r   r   r   r   r   r      s   r   RecentlyUsedContainerHTTPHeaderDict_KT_VT_DTc                   @  s   e Zd Ze ZdS )	_SentinelN)r   r   r   r   
not_passedr   r   r   r   r   '   s   r   objectValidHTTPHeaderSource | None)	potentialr   c                 C  s   t | tr| S t | tjr0ttjttf | S t | tjrXttjtjttf  | S t| drxt| drxtd| S d S d S )Nr   r   r   )	
isinstancer   typingMappingcastr   IterableTuplehasattr)r#   r   r   r   %ensure_can_construct_http_header_dict+   s    
r+   c                      s   e Zd ZU dZded< ded< ded< ded	< d%dd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Z	ddddZ
ddd d!Zd"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``.

    :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_maxsizez#typing.Callable[[_VT], None] | Nonedispose_funcr   lock
   NNone)maxsizer/   r   c                   s*   t    || _|| _t | _t | _d S r   )super__init__r.   r/   r   r,   r   r0   )r   r3   r/   	__class__r   r   r5   R   s
    
zRecentlyUsedContainer.__init__r   r   r   c              
   C  s8   | j ( | j|}|| j|< |W  5 Q R  S Q R X d S r   )r0   r,   pop)r   r   itemr   r   r   r   ]   s    
z!RecentlyUsedContainer.__getitem__)r   valuer   c              	   C  s   d }| j b z|| j|f}|| j|< W n< tk
rf   || j|< t| j| jkrb| jjdd}Y nX W 5 Q R X |d k	r| jr|\}}| | d S )NF)last)r0   r,   r8   KeyErrorlenr.   popitemr/   )r   r   r:   Zevicted_item_evicted_valuer   r   r   __setitem__d   s    
z!RecentlyUsedContainer.__setitem__c              	   C  s2   | j  | j|}W 5 Q R X | jr.| | d S r   )r0   r,   r8   r/   )r   r   r:   r   r   r   __delitem__}   s    z!RecentlyUsedContainer.__delitem__r
   c              
   C  s(   | j  t| jW  5 Q R  S Q R X d S r   )r0   r=   r,   r   r   r   r   __len__   s    zRecentlyUsedContainer.__len__ztyping.NoReturnc                 C  s   t dd S )Nz7Iteration over this class is unlikely to be threadsafe.)NotImplementedErrorr   r   r   r   __iter__   s    zRecentlyUsedContainer.__iter__c              	   C  sH   | j  t| j }| j  W 5 Q R X | jrD|D ]}| | q4d S r   )r0   listr,   valuesclearr/   )r   rG   r:   r   r   r   rH      s    zRecentlyUsedContainer.clearzset[_KT]c              
   C  s,   | j  t| j W  5 Q R  S Q R X d S r   )r0   setr,   r   r   r   r   r   r      s    zRecentlyUsedContainer.keys)r1   N)r   r   r   __doc____annotations__r5   r   rA   rB   rC   rE   rH   r   __classcell__r   r   r6   r   r   ?   s   
  
c                   @  sV   e Zd ZU dZ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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   _headersr2   )headersr   c                 C  s
   || _ d S r   )rN   )r   rO   r   r   r   r5      s    zHTTPHeaderDictItemView.__init__r-   r
   c                 C  s   t t| j S r   )r=   rF   rN   	iteritemsr   r   r   r   rC      s    zHTTPHeaderDictItemView.__len__ typing.Iterator[tuple[str, str]]c                 C  s
   | j  S r   )rN   rP   r   r   r   r   rE      s    zHTTPHeaderDictItemView.__iter__r!   bool)r9   r   c                 C  sD   t |tr@t|dkr@|\}}t |tr@t |tr@| j||S dS )N   F)r$   tupler=   r   rN   _has_value_for_header)r   r9   Z
passed_keyZ
passed_valr   r   r   __contains__   s
    z#HTTPHeaderDictItemView.__contains__N)	r   r   r   rJ   rK   r5   rC   rE   rV   r   r   r   r   rM      s   
rM   c                      s  e Zd ZU dZded< dKddd f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Z	dLdddd fddZ
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'd(Zd)d*dddd
d+d,d-Zd.dd
d/d0d1Zejdd2dd3d4Zejdd5d6dd7d4Zejfdd8d6dd9d4ZeZeZeZeZdd!d:d;Zd d
dd<d=Zd d!d>d?Zd@d!dAdBZd@d!dCdDZdEd!dFdGZ ddddHdIdJZ!  Z"S )Mr   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]]r,   Nr"   r   )rO   kwargsc                   sJ   t    i | _|d k	r8t|tr.| | n
| | |rF| | d S r   )r4   r5   r,   r$   r   
_copy_fromextend)r   rO   rW   r6   r   r   r5      s    


zHTTPHeaderDict.__init__r2   )r   valr   c                 C  s*   t |tr|d}||g| j| < d S )Nlatin-1)r$   bytesdecoder,   lowerr   r   rZ   r   r   r   rA      s    

zHTTPHeaderDict.__setitem__r   c                 C  s    | j |  }d|dd  S )N,    r,   r^   joinr_   r   r   r   r     s    zHTTPHeaderDict.__getitem__c                 C  s   | j | = d S r   r,   r^   r   r   r   r   rB     s    zHTTPHeaderDict.__delitem__r!   rR   c                 C  s   t |tr| | jkS dS )NF)r$   r   r^   r,   r   r   r   r   rV     s    
zHTTPHeaderDict.__contains__ )r   defaultr   c                   s   t  ||S r   )r4   
setdefaultr   r   rf   r6   r   r   rg     s    zHTTPHeaderDict.setdefault)otherr   c                 C  sD   t |}|d krdS t| |}dd |  D dd | D kS )NFc                 S  s   i | ]\}}|  |qS r   )r^   ).0kvr   r   r   
<dictcomp>  s      z)HTTPHeaderDict.__eq__.<locals>.<dictcomp>)r+   type
itermerged)r   ri   Zmaybe_constructableZother_as_http_header_dictr   r   r   __eq__  s    zHTTPHeaderDict.__eq__c                 C  s   |  | S r   )rp   )r   ri   r   r   r   __ne__  s    zHTTPHeaderDict.__ne__r-   r
   c                 C  s
   t | jS r   )r=   r,   r   r   r   r   rC     s    zHTTPHeaderDict.__len__r	   c                 c  s   | j  D ]}|d V  q
d S )Nr   )r,   rG   )r   valsr   r   r   rE   !  s    zHTTPHeaderDict.__iter__c                 C  s$   z
| |= W n t k
r   Y nX d S r   )r<   r   r   r   r   discard&  s    
zHTTPHeaderDict.discardF)combine)r   rZ   rt   r   c                C  sr   t |tr|d}| }||g}| j||}||k	rnt|dksJt|rd|d d | |d< n
|| 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')]
        r[   rS   r`   N)	r$   r\   r]   r^   r,   rg   r=   AssertionErrorappend)r   r   rZ   rt   	key_lowernew_valsrr   r   r   r   add,  s    

zHTTPHeaderDict.addValidHTTPHeaderSource)argsrW   r   c                 O  s,  t |dkr tdt | dt |dkr4|d nd}t|trb| D ]\}}| || qJnt|tjr| D ]\}}| || qvnzt|tj	rt
tj	tjttf  |}|D ]\}}| || qn6t|drt|dr| D ]}| |||  q| D ]\}}| || qd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__
        ra   z/extend() takes at most 1 positional arguments (z given)r   r   r   r   N)r=   	TypeErrorr$   r   rP   rz   r%   r&   itemsr(   r'   r)   r   r*   r   )r   r|   rW   ri   r   rZ   r:   r   r   r   rY   O  s(    
zHTTPHeaderDict.extendz	list[str]c                 C  s   d S r   r   r   r   r   r   getlistp  s    zHTTPHeaderDict.getlistr   zlist[str] | _DTc                 C  s   d S r   r   rh   r   r   r   r   t  s    z_Sentinel | _DTc                 C  sN   z| j |  }W n* tk
r<   |tjkr4g  Y S | Y S X |dd S dS )zmReturns a list of all the values for the named field. Returns an
        empty list if the key doesn't exist.ra   N)r,   r^   r<   r   r    )r   r   rf   rr   r   r   r   r   x  s    

c                 C  s   t | j dt|   dS )N())rn   r   dictro   r   r   r   r   __repr__  s    zHTTPHeaderDict.__repr__c                 C  s,   |D ]"}| |}|f|| j| < qd S r   )r   r,   r^   )r   ri   r   rZ   r   r   r   rX     s    
zHTTPHeaderDict._copy_fromc                 C  s   t |  }||  |S r   )rn   rX   )r   cloner   r   r   copy  s    

zHTTPHeaderDict.copyrQ   c                 c  s<   | D ]2}| j |  }|dd D ]}|d |fV  q"qdS )z8Iterate over all header lines, including duplicate ones.ra   Nr   rd   )r   r   rr   rZ   r   r   r   rP     s    zHTTPHeaderDict.iteritemsc                 c  s8   | D ].}| j |  }|d d|dd fV  qdS )z:Iterate over all headers, merging duplicate ones together.r   r`   ra   Nrb   r_   r   r   r   ro     s    zHTTPHeaderDict.itermergedrM   c                 C  s   t | S r   )rM   r   r   r   r   r~     s    zHTTPHeaderDict.items)header_namepotential_valuer   c                 C  s&   || kr"|| j |  dd  kS dS )Nra   Frd   )r   r   r   r   r   r   rU     s    z$HTTPHeaderDict._has_value_for_header)N)re   )#r   r   r   rJ   rK   r5   rA   r   rB   rV   rg   rp   rq   rC   rE   rs   rz   rY   r%   overloadr   r   r    
getheadersgetallmatchingheadersigetget_allr   rX   r   rP   ro   r~   rU   rL   r   r   r6   r   r      s@   
!#!)!
__future__r   r%   collectionsr   enumr   r   	threadingr   TYPE_CHECKINGZtyping_extensionsr   r   __all__TypeVarr   r   r   Unionr&   r   r(   r)   r{   r   r+   GenericMutableMappingr   SetrM   r   r   r   r   r   <module>   s.   


&] 0