a
    ñ»jª  ã                   @  s    d dl mZ d dlmZmZmZmZ d dlmZm	Z	m
Z
 g d¢ZG dd„ deƒZG dd„ deeef ƒZG d	d
„ d
e	ƒZe
eeeef eeeef  ef ZdS )é    )Úannotations)ÚIterableÚIteratorÚMappingÚMutableMapping)ÚAnyÚProtocolÚUnion)ÚHeadersÚHeadersLikeÚMultipleValuesErrorc                      s&   e Zd ZdZddœ‡ fdd„Z‡  ZS )r   zP
    Exception raised when :class:`Headers` has multiple values for a key.

    Ústr©Úreturnc                   s&   t | jƒdkrt| jd ƒS tƒ  ¡ S ©Né   r   )ÚlenÚargsÚreprÚsuperÚ__str__©Úself©Ú	__class__© ú?E:\soccer\ml_env\Lib\site-packages\websockets/datastructures.pyr      s    zMultipleValuesError.__str__)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Ú__classcell__r   r   r   r   r      s   r   c                      s  e Zd ZdZddgZd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	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#„Zdddœd$d%„Zd&dd'œd(d)„Zdd
œd*d+„Zddddœ‡ fd,d-„Zdd.dœd/d0„Zd1d
œd2d3„Z‡  ZS )4r
   aÈ  
    Efficient data structure for manipulating HTTP headers.

    A :class:`list` of ``(name, values)`` is inefficient for lookups.

    A :class:`dict` doesn't suffice because header names are case-insensitive
    and multiple occurrences of headers with the same name are possible.

    :class:`Headers` stores HTTP headers in a hybrid data structure to provide
    efficient insertions and lookups while preserving the original data.

    In order to account for multiple values with minimal hassle,
    :class:`Headers` follows this logic:

    - When getting a header with ``headers[name]``:
        - if there's no value, :exc:`KeyError` is raised;
        - if there's exactly one value, it's returned;
        - if there's more than one value, :exc:`MultipleValuesError` is raised.

    - When setting a header with ``headers[name] = value``, the value is
      appended to the list of values for that header.

    - When deleting a header with ``del headers[name]``, all values for that
      header are removed (this is slow).

    Other methods for manipulating headers are consistent with this logic.

    As long as no header occurs multiple times, :class:`Headers` behaves like
    :class:`dict`, except keys are lower-cased to provide case-insensitivity.

    Two methods support manipulating multiple values explicitly:

    - :meth:`get_all` returns a list of all values for a header;
    - :meth:`raw_items` returns an iterator of ``(name, values)`` pairs.

    Ú_dictÚ_listr   r   ÚNone)r   Úkwargsr   c                 O  s    i | _ g | _| j|i |¤Ž d S ©N)r"   r#   Úupdate©r   r   r%   r   r   r   Ú__init__D   s    zHeaders.__init__r   c                 C  s   d  dd„ | jD ƒ¡d S )NÚ c                 s  s"   | ]\}}|› d |› d�V  qdS )z: ú
Nr   )Ú.0ÚkeyÚvaluer   r   r   Ú	<genexpr>J   ó    z"Headers.__str__.<locals>.<genexpr>r+   )Újoinr#   r   r   r   r   r   I   s    zHeaders.__str__c                 C  s   | j j› d| j›d�S )Nú(ú))r   r   r#   r   r   r   r   Ú__repr__L   s    zHeaders.__repr__c                 C  s$   |   ¡ }| j ¡ |_| j ¡ |_|S r&   )r   r"   Úcopyr#   )r   r5   r   r   r   r5   O   s    zHeaders.copyÚbytesc                 C  s   t | ƒ ¡ S r&   )r   Úencoder   r   r   r   Ú	serializeU   s    zHeaders.serializeÚobjectÚbool©r-   r   c                 C  s   t |tƒo| ¡ | jv S r&   )Ú
isinstancer   Úlowerr"   ©r   r-   r   r   r   Ú__contains__[   s    zHeaders.__contains__zIterator[str]c                 C  s
   t | jƒS r&   )Úiterr"   r   r   r   r   Ú__iter__^   s    zHeaders.__iter__Úintc                 C  s
   t | jƒS r&   )r   r"   r   r   r   r   Ú__len__a   s    zHeaders.__len__c                 C  s.   | j | ¡  }t|ƒdkr"|d S t|ƒ‚d S r   )r"   r=   r   r   ©r   r-   r.   r   r   r   Ú__getitem__f   s    zHeaders.__getitem__)r-   r.   r   c                 C  s,   | j  | ¡ g ¡ |¡ | j ||f¡ d S r&   )r"   Ú
setdefaultr=   Úappendr#   rD   r   r   r   Ú__setitem__m   s    zHeaders.__setitem__c                   s.   |  ¡ ‰ | j ˆ ¡ ‡ fdd„| jD ƒ| _d S )Nc                   s$   g | ]\}}|  ¡ ˆ kr||f‘qS r   )r=   )r,   ÚkÚv©Ú	key_lowerr   r   Ú
<listcomp>u   r0   z'Headers.__delitem__.<locals>.<listcomp>)r=   r"   Ú__delitem__r#   r>   r   rK   r   rN   q   s    zHeaders.__delitem__r   )Úotherr   c                 C  s   t |tƒstS | j|jkS r&   )r<   r
   ÚNotImplementedr"   )r   rO   r   r   r   Ú__eq__w   s    
zHeaders.__eq__c                 C  s   i | _ g | _dS )z&
        Remove all headers.

        N)r"   r#   r   r   r   r   Úclear|   s    zHeaders.clearc                   s(   t dd„ |D ƒƒ}tƒ j|i |¤Ž dS )zT
        Update from a :class:`Headers` instance and/or keyword arguments.

        c                 s  s$   | ]}t |tƒr| ¡ n|V  qd S r&   )r<   r
   Ú	raw_items)r,   Úargr   r   r   r/   ‰   s   z!Headers.update.<locals>.<genexpr>N)Útupler   r'   r(   r   r   r   r'   „   s    ÿzHeaders.updatez	list[str]c                 C  s   | j  | ¡ g ¡S )z|
        Return the (possibly empty) list of all values for a header.

        Args:
            key: Header name.

        )r"   Úgetr=   r>   r   r   r   Úget_all�   s    zHeaders.get_allzIterator[tuple[str, str]]c                 C  s
   t | jƒS )zO
        Return an iterator of all values as ``(name, value)`` pairs.

        )r@   r#   r   r   r   r   rS   š   s    zHeaders.raw_items)r   r   r   r    Ú	__slots__r)   r   r4   r5   r8   r?   rA   rC   rE   rH   rN   rQ   rR   r'   rW   rS   r!   r   r   r   r   r
      s$   %
r
   c                   @  s.   e Zd ZdZddœdd„Zdddœdd	„Zd
S )ÚSupportsKeysAndGetItemz_
    Dict-like types with ``keys() -> str`` and ``__getitem__(key: str) -> str`` methods.

    zIterable[str]r   c                 C  s   d S r&   r   r   r   r   r   Úkeys©   r0   zSupportsKeysAndGetItem.keysr   r;   c                 C  s   d S r&   r   r>   r   r   r   rE   «   r0   z"SupportsKeysAndGetItem.__getitem__N)r   r   r   r    rZ   rE   r   r   r   r   rY   £   s   rY   N)Ú
__future__r   Úcollections.abcr   r   r   r   Útypingr   r   r	   Ú__all__ÚLookupErrorr   r   r
   rY   rU   r   r   r   r   r   Ú<module>   s    	
ýÿ