o
    _cj                     @  s   d dl mZ d dlZd dlmZmZmZmZmZm	Z	m
Z
mZmZ ejdd dkr0d dlmZ ne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 )    )annotationsN)	AnyDictIterableIteratorListMappingMutableMappingTupleUnion   )      )Protocol)HeadersHeadersLikeMultipleValuesErrorc                      s"   e Zd ZdZd fddZ  ZS )r   zT
    Exception raised when :class:`Headers` has more than one value for a key.

    returnstrc                   s&   t | jdkrt| jd S t  S N   r   )lenargsreprsuper__str__self	__class__ D/usr/local/lib/python3.10/dist-packages/websockets/datastructures.pyr       s   
zMultipleValuesError.__str__r   r   )__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d5d
dZd6ddZd6ddZd7ddZd8ddZ	d9ddZ
d:ddZd;ddZd<d d!Zd=d#d$Zd>d%d&Zd?d)d*Zd@d+d,Zd5 fd-d.ZdAd0d1ZdBd3d4Z  ZS )Cr   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   kwargsr   r   Nonec                 O  s    i | _ g | _| j|i | d S N)r(   r)   updater   r   r*   r    r    r!   __init__P   s   zHeaders.__init__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>V   s   " z"Headers.__str__.<locals>.<genexpr>r1   )joinr)   r   r    r    r!   r   U   s   zHeaders.__str__c                 C  s   | j j d| jdS )N())r   r#   r)   r   r    r    r!   __repr__X   s   zHeaders.__repr__c                 C  s$   |   }| j |_| j |_|S r,   )r   r(   copyr)   )r   r:   r    r    r!   r:   [   s   zHeaders.copybytesc                 C  s   t |  S r,   )r   encoder   r    r    r!   	serializea   s   zHeaders.serializer3   objectboolc                 C  s   t |to| | jv S r,   )
isinstancer   lowerr(   r   r3   r    r    r!   __contains__g   s   zHeaders.__contains__Iterator[str]c                 C  
   t | jS r,   )iterr(   r   r    r    r!   __iter__j      
zHeaders.__iter__intc                 C  rE   r,   )r   r(   r   r    r    r!   __len__m   rH   zHeaders.__len__c                 C  s*   | j |  }t|dkr|d S t|r   )r(   rA   r   r   r   r3   r4   r    r    r!   __getitem__r   s   zHeaders.__getitem__r4   c                 C  s,   | j | g | | j||f d S r,   )r(   
setdefaultrA   appendr)   rK   r    r    r!   __setitem__y   s   zHeaders.__setitem__c                   s.   |   | j   fdd| jD | _d S )Nc                   s$   g | ]\}}|   kr||fqS r    )rA   )r2   kv	key_lowerr    r!   
<listcomp>   s   $ z'Headers.__delitem__.<locals>.<listcomp>)rA   r(   __delitem__r)   rB   r    rR   r!   rU   }   s   zHeaders.__delitem__otherr   c                 C  s   t |tstS | j|jkS r,   )r@   r   NotImplementedr(   )r   rV   r    r    r!   __eq__   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)r2   argr    r    r!   r5      s    
z!Headers.update.<locals>.<genexpr>N)tupler   r-   r.   r   r    r!   r-      s   zHeaders.update	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(   getrA   rB   r    r    r!   get_all   s   zHeaders.get_allIterator[Tuple[str, str]]c                 C  rE   )zO
        Return an iterator of all values as ``(name, value)`` pairs.

        )rF   r)   r   r    r    r!   rZ      s   
zHeaders.raw_items)r   r   r*   r   r   r+   r"   )r   r   )r   r;   )r3   r>   r   r?   )r   rD   )r   rI   r3   r   r   r   )r3   r   r4   r   r   r+   )r3   r   r   r+   )rV   r   r   r?   )r   r+   )r3   r   r   r]   )r   r`   )r#   r$   r%   r&   	__slots__r/   r   r9   r:   r=   rC   rG   rJ   rL   rO   rU   rX   rY   r-   r_   rZ   r'   r    r    r   r!   r   '   s&    %














r   c                   @  s$   e Zd ZdZdddZddd	Zd
S )SupportsKeysAndGetItemz_
    Dict-like types with ``keys() -> str`` and ``__getitem__(key: str) -> str`` methods.

    r   Iterable[str]c                 C     d S r,   r    r   r    r    r!   keys      zSupportsKeysAndGetItem.keysr3   r   c                 C  re   r,   r    rB   r    r    r!   rL      rg   z"SupportsKeysAndGetItem.__getitem__N)r   rd   ra   )r#   r$   r%   r&   rf   rL   r    r    r    r!   rc      s    
rc   )
__future__r   systypingr   r   r   r   r   r   r	   r
   r   version_infor   r>   __all__LookupErrorr   r   r   rc   r   r    r    r    r!   <module>   s&    , 	
