a
   œ±o0<30ã                   @   sÔ   d dl mZ zd dlmZmZ W n" eyB   d dlmZmZ Y n0 zd dlmZ W n  eyt   G dd„ dƒZY n0 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   ú8/usr/lib/python3.9/site-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   sD   | j * | j |¡}|| j|< |W  d   ƒ S 1 s60    Y  d S r   )r    r   Úpop)r	   ÚkeyÚitemr   r   r
   Ú__getitem__5   s    
z!RecentlyUsedContainer.__getitem__c                 C   s€   t }| jJ | j |t ¡}|| j|< t| jƒ| jkrF| jjdd\}}W d   ƒ n1 sZ0    Y  | jr||t ur||  |¡ d S )NF)Zlast)Ú_Nullr    r   ÚgetÚlenr   Úpopitemr   )r	   r$   ÚvalueZevicted_valueZ_keyr   r   r
   Ú__setitem__<   s    
0z!RecentlyUsedContainer.__setitem__c                 C   sF   | j  | j |¡}W d   ƒ n1 s(0    Y  | jrB|  |¡ d S r   )r    r   r#   r   )r	   r$   r+   r   r   r
   Ú__delitem__K   s    *z!RecentlyUsedContainer.__delitem__c                 C   s4   | j  t| jƒW  d   ƒ S 1 s&0    Y  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   s\   | j ( tt| jƒƒ}| j ¡  W d   ƒ n1 s40    Y  | jrX|D ]}|  |¡ qHd S r   )r    Úlistr   r   Úclearr   )r	   Úvaluesr+   r   r   r
   r2   [   s    (zRecentlyUsedContainer.clearc                 C   s8   | j  tt| jƒƒW  d   ƒ S 1 s*0    Y  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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 ).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                    sP   t t| ƒ ¡  tƒ | _|d u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v 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>ª   ó    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   )rR   rP   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 y.   || ju r&‚ | Y S 0 | |= |S d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"   z
| |= W n t y   Y n0 d S r   )rU   rE   r   r   r
   ÚdiscardÐ   s    
zHTTPHeaderDict.discardc                 C   s4   |  ¡ }||g}| j ||¡}||ur0| |¡ 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$   rA   Z	key_lowerZnew_valsrT   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 ]}|  ||| ¡ q˜n|D ]\}}|  ||¡ q´| 
¡ D ]\}}|  ||¡ qÒd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   r   r4   N)r)   Ú	TypeErrorÚformatr7   r   Ú	iteritemsr[   r   rL   r4   Úitems)r	   Úargsr;   rQ   r$   rA   r+   r   r   r
   r9   æ   s(    ÿÿ


zHTTPHeaderDict.extendc                 C   sL   z| j | ¡  }W n( ty:   || ju r2g  Y S | Y S 0 |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?   rU   rV   )r	   r$   rW   rT   r   r   r
   Úgetlist  s    

zHTTPHeaderDict.getlistc                 C   s   dt | ƒjt|  ¡ ƒf S )Nz%s(%s))rM   r   rN   rO   r   r   r   r
   Ú__repr__  s    zHTTPHeaderDict.__repr__c                 C   s>   |D ]4}|  |¡}t|tƒr$t|ƒ}|g| | j| ¡ < qd S r   )ra   r7   r1   r   r?   )r	   rQ   r$   rA   r   r   r
   r8     s
    

zHTTPHeaderDict._copy_fromc                 C   s   t | ƒƒ }| | ¡ |S r   )rM   r8   )r	   Zcloner   r   r
   Úcopy!  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$   rT   rA   r   r   r
   r^   &  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
   rO   -  s    zHTTPHeaderDict.itermergedc                 C   s   t |  ¡ ƒS r   )r1   r^   r   r   r   r
   r_   3  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: %séÿÿÿÿrd   ú:r   )r:   Ú
startswithr   ÚstripÚsplitrZ   )ÚclsÚmessageZobs_fold_continued_leadersr:   Úliner$   r+   r   r   r
   Úfrom_httplib6  s    

ÿzHTTPHeaderDict.from_httplib)N)%r   r   r   r5   r"   r,   r&   r-   rF   rR   rS   r   r   r   r   ÚobjectrV   r.   r0   r#   rX   r[   r9   ra   Z
getheadersZgetallmatchingheadersZigetZget_allrb   r8   rc   r^   rO   r_   Úclassmethodrn   Ú__classcell__r   r   r<   r
   r   j   s>   !	N)Z
__future__r   Úcollections.abcr   r   ÚImportErrorÚcollectionsÚ	threadingr   r   Ú
exceptionsr   Zpackages.sixr   r   r   Ú__all__ro   r'   r   r   r   r   r   r
   Ú<module>   s   L