
Ã|j;*  ã               @   s  d  d l  m Z y d  d l m Z m Z Wn( e k
 rT d  d l m Z m Z Yn Xy d  d l m Z Wn% e k
 r� Gd d „  d ƒ Z Yn Xd  d l m	 Z	 d d l
 m Z d d	 l m Z d d
 l m Z m Z d d g Z e ƒ  Z Gd d „  d e ƒ Z Gd 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   ú7/tmp/pip-build-1hwfuv5s/urllib3/urllib3/_collections.pyÚ	__enter__   s    zRLock.__enter__c             C   s   d  S)Nr   )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)Úsix)ÚiterkeysÚ
itervaluesÚRecentlyUsedContainerÚHTTPHeaderDictc               @   s‚   e  Z d  Z d Z e Z d 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   s1   | |  _  | |  _ |  j ƒ  |  _ t ƒ  |  _ d  S)N)Ú_maxsizeÚdispose_funcÚContainerClsÚ
_containerr   Úlock)r   Úmaxsizer   r   r   r   Ú__init__/   s    		zRecentlyUsedContainer.__init__c          
   C   s8   |  j  �( |  j j | ƒ } | |  j | <| SWd  QRXd  S)N)r   r   Úpop)r   ÚkeyÚitemr   r   r   Ú__getitem__6   s    
z!RecentlyUsedContainer.__getitem__c          
   C   s’   t  } |  j �Z |  j j | t  ƒ } | |  j | <t |  j ƒ |  j k re |  j j d d ƒ \ } } Wd  QRX|  j rŽ | t  k	 rŽ |  j | ƒ d  S)NÚlastF)Ú_Nullr   r   ÚgetÚlenr   Úpopitemr   )r   r"   ÚvalueÚevicted_valueÚ_keyr   r   r   Ú__setitem__=   s    
"z!RecentlyUsedContainer.__setitem__c          	   C   s=   |  j  � |  j j | ƒ } Wd  QRX|  j r9 |  j | ƒ d  S)N)r   r   r!   r   )r   r"   r*   r   r   r   Ú__delitem__L   s    
	z!RecentlyUsedContainer.__delitem__c          	   C   s"   |  j  � t |  j ƒ SWd  QRXd  S)N)r   r(   r   )r   r   r   r   Ú__len__S   s    
zRecentlyUsedContainer.__len__c             C   s   t  d ƒ ‚ d  S)Nz7Iteration over this class is unlikely to be threadsafe.)ÚNotImplementedError)r   r   r   r   Ú__iter__W   s    zRecentlyUsedContainer.__iter__c          
   C   s^   |  j  �' t t |  j ƒ ƒ } |  j j ƒ  Wd  QRX|  j rZ x | D] } |  j | ƒ qC Wd  S)N)r   Úlistr   r   Úclearr   )r   Úvaluesr*   r   r   r   r3   \   s    
	zRecentlyUsedContainer.clearc          
   C   s(   |  j  � t t |  j ƒ ƒ SWd  QRXd  S)N)r   r2   r   r   )r   r   r   r   Úkeysf   s    
zRecentlyUsedContainer.keys)r   r   r   Ú__doc__r   r   r    r$   r-   r.   r/   r1   r3   r5   r   r   r   r   r      s   
c                   sc  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 j rŠ e j Z e j Z e ƒ  Z d d „  Z d d „  Z e d d „ Z d d „  Z d d „  Z d d „  Z e 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$ ‡  S)-r   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                sn   t  t |  ƒ j ƒ  t ƒ  |  _ | d  k	 rW t | t ƒ rJ |  j | ƒ n |  j | ƒ | rj |  j | ƒ d  S)N)Ú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 ƒ  <|  j  | j ƒ  S)N)r   Úlower)r   r"   Úvalr   r   r   r-   ˜   s    zHTTPHeaderDict.__setitem__c             C   s*   |  j  | j ƒ  } d j | d d  … ƒ S)Nz, r   )r   r>   Újoin)r   r"   r?   r   r   r   r$   œ   s    zHTTPHeaderDict.__getitem__c             C   s   |  j  | j ƒ  =d  S)N)r   r>   )r   r"   r   r   r   r.       s    zHTTPHeaderDict.__delitem__c             C   s   | j  ƒ  |  j k S)N)r>   r   )r   r"   r   r   r   Ú__contains__£   s    zHTTPHeaderDict.__contains__c             C   s‡   t  | t ƒ r$ t | d ƒ r$ d St  | t |  ƒ ƒ sK t |  ƒ | ƒ } t d d „  |  j ƒ  Dƒ ƒ t d d „  | j ƒ  Dƒ ƒ k S)Nr5   Fc             s   s'   |  ] \ } } | j  ƒ  | f Vq d  S)N)r>   )Ú.0ÚkÚvr   r   r   ú	<genexpr>«   s    z(HTTPHeaderDict.__eq__.<locals>.<genexpr>c             s   s'   |  ] \ } } | j  ƒ  | f Vq d  S)N)r>   )rB   rC   rD   r   r   r   rE   ¬   s    )r8   r   ÚhasattrÚtypeÚdictÚ
itermerged)r   Úotherr   r   r   Ú__eq__¦   s     zHTTPHeaderDict.__eq__c             C   s   |  j  | ƒ S)N)rK   )r   rJ   r   r   r   Ú__ne__¯   s    zHTTPHeaderDict.__ne__c             C   s   t  |  j ƒ S)N)r(   r   )r   r   r   r   r/   ¸   s    zHTTPHeaderDict.__len__c             c   s'   x  |  j  j ƒ  D] } | d Vq Wd  S)Nr   )r   r4   )r   Úvalsr   r   r   r1   »   s    zHTTPHeaderDict.__iter__c             C   sH   y |  | } Wn( t  k
 r8 | |  j k r0 ‚  | SYn X|  | =| Sd S)z§D.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$   y |  | =Wn t  k
 r Yn Xd  S)N)rN   )r   r"   r   r   r   ÚdiscardÑ   s    zHTTPHeaderDict.discardc             C   sJ   | j  ƒ  } | | g } |  j j | | ƒ } | | k	 rF | j | ƒ d S)zâAdds 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"   r?   Ú	key_lowerÚnew_valsrM   r   r   r   Úadd×   s
    	zHTTPHeaderDict.addc             O   sZ  t  | ƒ d k r- t d j t  | ƒ ƒ ƒ ‚ t  | ƒ d k rI | d n f  } t | t ƒ rŽ xÈ | j ƒ  D] \ } } |  j | | ƒ qk Wn› t | t ƒ rÅ x‰ | D] } |  j | | | ƒ q¤ Wnd t | d ƒ rxR | j	 ƒ  D] } |  j | | | ƒ qá Wn' x$ | D] \ } } |  j | | ƒ q	Wx* | j
 ƒ  D] \ } } |  j | | ƒ q6Wd S)zÀGeneric 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   r5   N)r(   Ú	TypeErrorÚformatr8   r   Ú	iteritemsrV   r   rF   r5   Úitems)r   Úargsr<   rJ   r"   r?   r*   r   r   r   r:   ç   s$    "zHTTPHeaderDict.extendc             C   sU   y |  j  | j ƒ  } Wn) t k
 rB | |  j k r: g  S| SYn X| d d … Sd 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>   rN   rO   )r   r"   rP   rM   r   r   r   Úgetlist  s    	zHTTPHeaderDict.getlistc             C   s#   d t  |  ƒ j t |  j ƒ  ƒ f S)Nz%s(%s))rG   r   rH   rI   )r   r   r   r   Ú__repr__  s    zHTTPHeaderDict.__repr__c             C   sY   xR | D]J } | j  | ƒ } t | t ƒ r7 t | ƒ } | g | |  j | j ƒ  <q Wd  S)N)r\   r8   r2   r   r>   )r   rJ   r"   r?   r   r   r   r9     s
    zHTTPHeaderDict._copy_fromc             C   s    t  |  ƒ ƒ  } | j |  ƒ | S)N)rG   r9   )r   Úcloner   r   r   Úcopy"  s    zHTTPHeaderDict.copyc             c   sR   xK |  D]C } |  j  | j ƒ  } x' | d d … D] } | d | f Vq1 Wq Wd S)z8Iterate over all header lines, including duplicate ones.r   Nr   )r   r>   )r   r"   rM   r?   r   r   r   rY   '  s    zHTTPHeaderDict.iteritemsc             c   sJ   xC |  D]; } |  j  | j ƒ  } | d d j | d d … ƒ f Vq Wd S)z:Iterate over all headers, merging duplicate ones together.r   z, r   N)r   r>   r@   )r   r"   r?   r   r   r   rI   .  s    zHTTPHeaderDict.itermergedc             C   s   t  |  j ƒ  ƒ S)N)r2   rY   )r   r   r   r   rZ   4  s    zHTTPHeaderDict.itemsc             C   s´   d } g  } x› | j  D]� } | j | ƒ ru | sD t d | ƒ ‚ n1 | d \ } } | | d | j ƒ  f | d <q | j d d ƒ \ } } | j | | j ƒ  f ƒ q W|  | ƒ S)	z4Read headers from a Python 2 httplib message object.ú ú	z/Header continuation with no previous header: %sr   ú:)r`   ra   éÿÿÿÿrc   )r;   Ú
startswithr   ÚstripÚsplitrS   )ÚclsÚmessageZobs_fold_continued_leadersr;   Úliner"   r*   r   r   r   Úfrom_httplib7  s    zHTTPHeaderDict.from_httplib)%r   r   r   r6   r    r-   r$   r.   rA   rK   rL   r   ÚPY2r   r   r   ÚobjectrO   r/   r1   r!   rQ   rV   r:   r\   Ú
getheadersÚgetallmatchingheadersÚigetÚget_allr]   r9   r_   rY   rI   rZ   Úclassmethodrj   r   r   )r=   r   r   k   s<    					N)Ú
__future__r   Úcollections.abcr   r   ÚImportErrorÚcollectionsÚ	threadingr   r   Ú
exceptionsr   Úpackagesr   Zpackages.sixr   r   Ú__all__rl   r&   r   r   r   r   r   r   Ú<module>   s    	L