o
    ïT·jí  ã                   @  s¾   d dl mZ d dlZd dlmZmZmZmZ d dlm	Z	m
Z
 g d¢ZG dd„ deƒZe d¡jZG d	d
„ d
eeef ƒZG dd„ de
ƒZeeeef B eeeef  B eB Z	 ddlmZ dS )é    )ÚannotationsN)ÚIterableÚIteratorÚMappingÚMutableMapping)ÚAnyÚProtocol)ÚHeadersÚHeadersLikeÚMultipleValuesErrorc                      s"   e Zd ZdZd‡ fdd„Z‡  ZS )r   zP
    Exception raised when :class:`Headers` has multiple values 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__© ú\/home/dinkstrade/pdmp-scanner/venv/lib/python3.10/site-packages/websockets/datastructures.pyr      s   
zMultipleValuesError.__str__©r   r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Ú__classcell__r   r   r   r   r      s    r   z[\x09\x20-\x7e\x80-\xff]*c                      sÊ   e Zd ZdZddgZd7d
d„Zd8d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dAd)d*„ZdBd+d,„Zd7‡ fd-d.„ZdCd0d1„ZdDd3d4„Zd?d5d6„Z‡  ZS )Er	   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__I   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>O   s   €" z"Headers.__str__.<locals>.<genexpr>r*   )Újoinr"   r   r   r   r   r   N   s   zHeaders.__str__c                 C  s   | j j› d| j›d�S )Nú(ú))r   r   r"   r   r   r   r   Ú__repr__Q   s   zHeaders.__repr__c                 C  s$   |   ¡ }| j ¡ |_| j ¡ |_|S r%   )r   r!   Úcopyr"   )r   r3   r   r   r   r3   T   s   zHeaders.copyÚbytesc                 C  s   t | ƒ ¡ S r%   )r   Úencoder   r   r   r   Ú	serializeZ   s   zHeaders.serializer,   ÚobjectÚboolc                 C  s   t |tƒo| ¡ | jv S r%   )Ú
isinstancer   Úlowerr!   ©r   r,   r   r   r   Ú__contains__`   s   zHeaders.__contains__úIterator[str]c                 C  ó
   t | jƒS r%   )Úiterr!   r   r   r   r   Ú__iter__c   ó   
zHeaders.__iter__Úintc                 C  r>   r%   )r   r!   r   r   r   r   Ú__len__f   rA   zHeaders.__len__c                 C  s*   | j | ¡  }t|ƒdkr|d S t|ƒ‚r   )r!   r:   r   r   ©r   r,   r-   r   r   r   Ú__getitem__k   s   zHeaders.__getitem__r-   c                 C  sB   t t|ƒƒst||ƒ‚| j | ¡ g ¡ |¡ | j ||f¡ d S r%   )Úis_valid_header_valuer   ÚInvalidHeaderValuer!   Ú
setdefaultr:   Úappendr"   rD   r   r   r   Ú__setitem__r   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>|   s   $ z'Headers.__delitem__.<locals>.<listcomp>)r:   r!   Ú__delitem__r"   r;   r   rM   r   rP   x   s   zHeaders.__delitem__Úotherr   c                 C  s   t |tƒstS | j|jkS r%   )r9   r	   ÚNotImplementedr!   )r   rQ   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%   )r9   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.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!   Úgetr:   r;   r   r   r   Úget_all—   s   zHeaders.get_allúIterator[tuple[str, str]]c                 C  r>   )zO
        Return an iterator of all values as ``(name, value)`` pairs.

        )r?   r"   r   r   r   r   rU   ¡   s   
zHeaders.raw_itemsc                 C  s,   | j  | ¡ g ¡ |¡ | j ||f¡ dS )z=
        Set a header without validating its value.

        N)r!   rH   r:   rI   r"   rD   r   r   r   Úset_insecureª   s   zHeaders.set_insecure)r   r
   r#   r   r   r$   r   )r   r	   )r   r4   )r,   r7   r   r8   )r   r=   )r   rB   ©r,   r   r   r   )r,   r   r-   r   r   r$   )r,   r   r   r$   )rQ   r   r   r8   )r   r$   )r,   r   r   rX   )r   r[   )r   r   r   r   Ú	__slots__r(   r   r2   r3   r6   r<   r@   rC   rE   rJ   rP   rS   rT   r&   rZ   rU   r\   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.keysr,   r   c                 C  ra   r%   r   r;   r   r   r   rE   ¼   rc   z"SupportsKeysAndGetItem.__getitem__N)r   r`   r]   )r   r   r   r   rb   rE   r   r   r   r   r_   ´   s    
r_   r   )rG   )Ú
__future__r   ÚreÚcollections.abcr   r   r   r   Útypingr   r   Ú__all__ÚLookupErrorr   ÚcompileÚ	fullmatchrF   r   r	   r_   rW   r
   Ú
exceptionsrG   r   r   r   r   Ú<module>   s     "ÿ
