U
    
"gO,                     @   s   d dl mZ zd dlmZmZ W n$ ek
rD   d dlmZmZ Y nX zd dlmZ W n" ek
rx   G dd dZY nX d dlm	Z	 ddl
mZ d d	lmZmZmZ d
dgZe ZG dd
 d
eZG dd deZdS )    )absolute_import)MappingMutableMapping)RLockc                   @   s   e Zd Zdd Zdd ZdS )r   c                 C   s   d S N selfr   r   6/usr/lib/python3/dist-packages/urllib3/_collections.py	__enter__   s    zRLock.__enter__c                 C   s   d S r   r   )r	   exc_type	exc_value	tracebackr   r   r
   __exit__   s    zRLock.__exit__N)__name__
__module____qualname__r   r   r   r   r   r
   r      s   r   )OrderedDict   )InvalidHeader)iterkeys
itervaluesPY3RecentlyUsedContainerHTTPHeaderDictc                   @   sV   e Zd ZdZeZdddZdd Zdd	 Zd
d Z	dd Z
dd Zdd Zdd Zd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
    
   Nc                 C   s"   || _ || _|  | _t | _d S r   )_maxsizedispose_funcContainerCls
_containerr   lock)r	   maxsizer   r   r   r
   __init__.   s    
zRecentlyUsedContainer.__init__c              
   C   s8   | j ( | j|}|| j|< |W  5 Q R  S Q R X d S r   )r    r   pop)r	   keyitemr   r   r
   __getitem__5   s    
z!RecentlyUsedContainer.__getitem__c              	   C   sl   t }| j@ | j|t }|| j|< t| j| jkrF| jjdd\}}W 5 Q R X | jrh|t k	rh| | d S )NF)Zlast)_Nullr    r   getlenr   popitemr   )r	   r$   valueZevicted_valueZ_keyr   r   r
   __setitem__<   s    
z!RecentlyUsedContainer.__setitem__c              	   C   s2   | j  | j|}W 5 Q R X | jr.| | d S r   )r    r   r#   r   )r	   r$   r+   r   r   r
   __delitem__K   s    z!RecentlyUsedContainer.__delitem__c              
   C   s(   | j  t| jW  5 Q R  S Q R X d S r   )r    r)   r   r   r   r   r
   __len__R   s    zRecentlyUsedContainer.__len__c                 C   s   t dd S )Nz7Iteration over this class is unlikely to be threadsafe.)NotImplementedErrorr   r   r   r
   __iter__V   s    zRecentlyUsedContainer.__iter__c              	   C   sH   | j  tt| j}| j  W 5 Q R X | jrD|D ]}| | q4d S r   )r    listr   r   clearr   )r	   valuesr+   r   r   r
   r2   [   s    zRecentlyUsedContainer.clearc              
   C   s,   | j  tt| jW  5 Q R  S Q R X d S r   )r    r1   r   r   r   r   r   r
   keyse   s    zRecentlyUsedContainer.keys)r   N)r   r   r   __doc__r   r   r"   r&   r,   r-   r.   r0   r2   r4   r   r   r   r
   r      s   

c                       s   e Zd ZdZd/ fdd	Zdd Zdd Zd	d
 Zdd Zdd Z	dd Z
esZejZejZe Zdd Zdd ZefddZdd Zdd Zdd ZefddZdd  ZeZeZeZeZd!d" Zd#d$ Zd%d& Zd'd( Z d)d* Z!d+d, Z"e#d-d. Z$  Z%S )0r   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'
    Nc                    sP   t t|   t | _|d k	r>t|tr4| | n
| | |rL| | d S r   )superr   r"   r   r   
isinstance
_copy_fromextend)r	   headerskwargs	__class__r   r
   r"      s    

zHTTPHeaderDict.__init__c                 C   s    ||g| j | < | j |  S r   r   lowerr	   r$   valr   r   r
   r,      s    zHTTPHeaderDict.__setitem__c                 C   s    | j |  }d|dd  S )N, r   r   r?   joinr@   r   r   r
   r&      s    zHTTPHeaderDict.__getitem__c                 C   s   | j | = d S r   r>   r	   r$   r   r   r
   r-      s    zHTTPHeaderDict.__delitem__c                 C   s   |  | jkS r   )r?   r   rE   r   r   r
   __contains__   s    zHTTPHeaderDict.__contains__c                 C   s^   t |tst|dsdS t |t| s2t| |}tdd |  D tdd | D kS )Nr4   Fc                 s   s   | ]\}}|  |fV  qd S r   )r?   ).0kvr   r   r
   	<genexpr>   s     z(HTTPHeaderDict.__eq__.<locals>.<genexpr>)r7   r   hasattrtypedict
itermergedr	   otherr   r   r
   __eq__   s    zHTTPHeaderDict.__eq__c                 C   s   |  | S r   )rQ   rO   r   r   r
   __ne__   s    zHTTPHeaderDict.__ne__c                 C   s
   t | jS r   )r)   r   r   r   r   r
   r.      s    zHTTPHeaderDict.__len__c                 c   s   | j  D ]}|d V  q
d S )Nr   )r   r3   )r	   valsr   r   r
   r0      s    zHTTPHeaderDict.__iter__c                 C   s@   z| | }W n$ t k
r0   || jkr( | Y S X | |= |S dS )zD.pop(k[,d]) -> v, remove specified key and return the corresponding value.
          If key is not found, d is returned if given, otherwise KeyError is raised.
        N)KeyError_HTTPHeaderDict__marker)r	   r$   defaultr+   r   r   r
   r#      s    

zHTTPHeaderDict.popc                 C   s$   z
| |= W n t k
r   Y nX d S r   )rT   rE   r   r   r
   discard   s    
zHTTPHeaderDict.discardc                 C   s4   |  }||g}| j||}||k	r0|| dS )zAdds a (name, value) pair, doesn't overwrite the value if it already
        exists.

        >>> headers = HTTPHeaderDict(foo='bar')
        >>> headers.add('Foo', 'baz')
        >>> headers['foo']
        'bar, baz'
        N)r?   r   
setdefaultappend)r	   r$   rA   Z	key_lowerZnew_valsrS   r   r   r
   add   s
    	zHTTPHeaderDict.addc                 O   s   t |dkrtdt |t |dkr2|d nd}t|tr`| D ]\}}| || qHnjt|tr|D ]}| |||  qnnDt|dr|	 D ]}| |||  qn|D ]\}}| || q|
 D ]\}}| || qd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__
        r   z9extend() takes at most 1 positional arguments ({0} given)r   r   r4   N)r)   	TypeErrorformatr7   r   	iteritemsrZ   r   rK   r4   items)r	   argsr;   rP   r$   rA   r+   r   r   r
   r9      s(    


zHTTPHeaderDict.extendc                 C   sN   z| j |  }W n* tk
r<   || 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.r   N)r   r?   rT   rU   )r	   r$   rV   rS   r   r   r
   getlist  s    

zHTTPHeaderDict.getlistc                 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-LengthZDigestzLast-Modified)rW   )r	   Zcontent_specific_headersheaderr   r   r
   _prepare_for_method_change  s    	z)HTTPHeaderDict._prepare_for_method_changec                 C   s   dt | jt|  f S )Nz%s(%s))rL   r   rM   rN   r   r   r   r
   __repr__(  s    zHTTPHeaderDict.__repr__c                 C   s>   |D ]4}| |}t|tr$t|}|g| | j| < qd S r   )r`   r7   r1   r   r?   )r	   rP   r$   rA   r   r   r
   r8   +  s
    

zHTTPHeaderDict._copy_fromc                 C   s   t |  }||  |S r   )rL   r8   )r	   Zcloner   r   r
   copy3  s    

zHTTPHeaderDict.copyc                 c   s<   | D ]2}| j |  }|dd D ]}|d |fV  q"qdS )z8Iterate over all header lines, including duplicate ones.r   Nr   r>   )r	   r$   rS   rA   r   r   r
   r]   8  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   rB   r   NrC   r@   r   r   r
   rN   ?  s    zHTTPHeaderDict.itermergedc                 C   s   t |  S r   )r1   r]   r   r   r   r
   r^   E  s    zHTTPHeaderDict.itemsc                 C   s   d}g }|j D ]h}||rT|s.td| n&|d \}}||d |  f|d< q|dd\}}||| f q| |S )z4Read headers from a Python 2 httplib message object.) 	z/Header continuation with no previous header: %sre   :r   )r:   
startswithr   stripsplitrY   )clsmessageZobs_fold_continued_leadersr:   liner$   r+   r   r   r
   from_httplibH  s    

zHTTPHeaderDict.from_httplib)N)&r   r   r   r5   r"   r,   r&   r-   rF   rQ   rR   r   r   r   r   objectrU   r.   r0   r#   rW   rZ   r9   r`   rb   Z
getheadersZgetallmatchingheadersZigetZget_allrc   r8   rd   r]   rN   r^   classmethodro   __classcell__r   r   r<   r
   r   j   s@   !	N)Z
__future__r   Zcollections.abcr   r   ImportErrorcollectionsZ	threadingr   r   
exceptionsr   Zsixr   r   r   __all__rp   r'   r   r   r   r   r   r
   <module>   s   L