U
    gC                     @  s@  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
rjd dlmZ 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)Protocol)Selfc                   @  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-f4zjg0cl/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)maxsizer0   r   c                   s*   t    || _|| _t | _t | _d S r   )super__init__r/   r0   r   r-   r   r1   )r   r4   r0   	__class__r   r   r6   T   s
    
zRecentlyUsedContainer.__init__r   r   r   c              
   C  s8   | j ( | j|}|| j|< |W  5 Q R  S Q R X d S r   )r1   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)r1   r-   r9   KeyErrorlenr/   popitemr0   )r   r   r;   Zevicted_item_evicted_valuer   r   r   __setitem__f   s    
z!RecentlyUsedContainer.__setitem__c              	   C  s2   | j  | j|}W 5 Q R X | jr.| | d S r   )r1   r-   r9   r0   )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   )r1   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   )r1   listr-   valuesclearr0   )r   rH   r;   r   r   r   rI      s    zRecentlyUsedContainer.clearzset[_KT]c              
   C  s,   | j  t| j W  5 Q R  S Q R X d S r   )r1   setr-   r   r   r   r   r   r      s    zRecentlyUsedContainer.keys)r2   N)r   r   r   __doc____annotations__r6   r   rB   rC   rD   rF   rI   r   __classcell__r   r   r7   r   r   A   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   _headersr3   )headersr   c                 C  s
   || _ d S r   )rO   )r   rP   r   r   r   r6      s    zHTTPHeaderDictItemView.__init__r.   r   c                 C  s   t t| j S r   )r>   rG   rO   	iteritemsr   r   r   r   rD      s    zHTTPHeaderDictItemView.__len__ typing.Iterator[tuple[str, str]]c                 C  s
   | j  S r   )rO   rQ   r   r   r   r   rF      s    zHTTPHeaderDictItemView.__iter__r"   bool)r:   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   rO   _has_value_for_header)r   r:   Z
passed_keyZ
passed_valr   r   r   __contains__   s
    z#HTTPHeaderDictItemView.__contains__N)	r   r   r   rK   rL   r6   rD   rF   rW   r   r   r   r   rN      s   
rN   c                      s  e Zd ZU dZded< dTd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	dUd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d:d!d;d<ZeZeZeZeZdd!d=d>Zd d
dd?d@Zd:d!dAdBZdCd!dDdEZdCd!dFdGZ dHd!dIdJZ!ddddKdLdMZ"dd ddNdOZ#dd:ddPdQZ$dd:ddRdSZ%  Z&S )Vr   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   )rP   kwargsc                   sJ   t    i | _|d k	r8t|tr.| | n
| | |rF| | d S r   )r5   r6   r-   r%   r   
_copy_fromextend)r   rP   rX   r7   r   r   r6      s    


zHTTPHeaderDict.__init__r3   )r   valr   c                 C  s*   t |tr|d}||g| j| < d S )Nlatin-1)r%   bytesdecoder-   lowerr   r   r[   r   r   r   rB      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   rC     s    zHTTPHeaderDict.__delitem__r"   rS   c                 C  s   t |tr| | jkS dS )NF)r%   r   r_   r-   r   r   r   r   rW   
  s    
zHTTPHeaderDict.__contains__ )r   defaultr   c                   s   t  ||S r   )r5   
setdefaultr   r   rg   r7   r   r   rh     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   rj   maybe_constructableZother_as_http_header_dictr   r   r   __eq__  s    zHTTPHeaderDict.__eq__c                 C  s   |  | S r   )rr   )r   rj   r   r   r   __ne__  s    zHTTPHeaderDict.__ne__r.   r   c                 C  s
   t | jS r   )r>   r-   r   r   r   r   rD      s    zHTTPHeaderDict.__len__r
   c                 c  s   | j  D ]}|d V  q
d S )Nr   )r-   rH   )r   valsr   r   r   rF   #  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   r[   rv   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\   rT   ra   N)	r%   r]   r^   r_   r-   rh   r>   AssertionErrorappend)r   r   r[   rv   	key_lowernew_valsrt   r   r   r   add.  s    

zHTTPHeaderDict.addValidHTTPHeaderSource)argsrX   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__
        rb   z/extend() takes at most 1 positional arguments (z given)r   r   r   r   N)r>   	TypeErrorr%   r   rQ   r|   r&   r'   itemsr)   r(   r*   r   r+   r   )r   r~   rX   rj   r   r[   r;   r   r   r   rZ   Q  s(    
zHTTPHeaderDict.extendz	list[str]c                 C  s   d S r   r   r   r   r   r   getlistr  s    zHTTPHeaderDict.getlistr   zlist[str] | _DTc                 C  s   d S r   r   ri   r   r   r   r   v  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.rb   N)r-   r_   r=   r    r!   )r   r   rg   rt   r   r   r   r   z  s    

r   c                 C  s*   dddddddg}|D ]}|  | q| S )z
        Remove content-specific header fields before changing the request
        method to GET or HEAD according to RFC 9110, Section 15.4.
        zContent-EncodingzContent-LanguagezContent-LocationzContent-TypezContent-LengthDigestzLast-Modified)ru   )r   content_specific_headersheaderr   r   r   _prepare_for_method_change  s    	z)HTTPHeaderDict._prepare_for_method_changec                 C  s   t | j dt|   dS )N())ro   r   dictrp   r   r   r   r   __repr__  s    zHTTPHeaderDict.__repr__c                 C  s,   |D ]"}| |}|f|| j| < qd S r   )r   r-   r_   )r   rj   r   r[   r   r   r   rY     s    
zHTTPHeaderDict._copy_fromc                 C  s   t |  }||  |S r   )ro   rY   )r   cloner   r   r   copy  s    

zHTTPHeaderDict.copyrR   c                 c  s<   | D ]2}| j |  }|dd D ]}|d |fV  q"qdS )z8Iterate over all header lines, including duplicate ones.rb   Nr   re   )r   r   rt   r[   r   r   r   rQ     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   ra   rb   Nrc   r`   r   r   r   rp     s    zHTTPHeaderDict.itermergedrN   c                 C  s   t | S r   )rN   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 )Nrb   Fre   )r   r   r   r   r   r   rV     s    z$HTTPHeaderDict._has_value_for_headerc                 C  s"   t |}|d krtS | | | S r   )r,   NotImplementedrZ   )r   rj   rq   r   r   r   __ior__  s
    
zHTTPHeaderDict.__ior__c                 C  s*   t |}|d krtS |  }|| |S r   )r,   r   r   rZ   r   rj   rq   resultr   r   r   __or__  s    
zHTTPHeaderDict.__or__c                 C  s.   t |}|d krtS t| |}||  |S r   )r,   r   ro   rZ   r   r   r   r   __ror__  s    
zHTTPHeaderDict.__ror__)N)rf   )'r   r   r   rK   rL   r6   rB   r   rC   rW   rh   rr   rs   rD   rF   ru   r|   rZ   r&   overloadr   r    r!   r   
getheadersgetallmatchingheadersigetget_allr   rY   r   rQ   rp   r   rV   r   r   r   rM   r   r   r7   r   r      sH   
!#!	
)"
__future__r   r&   collectionsr   enumr   r   	threadingr   TYPE_CHECKINGr   Ztyping_extensionsr   r	   __all__TypeVarr   r   r   Unionr'   r   r)   r*   r}   r    r,   GenericMutableMappingr   SetrN   r   r   r   r   r   <module>   s0   


&] 0