U
    Rh>W                     @  sv  d dl mZ d dlZd dlmZ d dlmZmZmZmZ d dl	m
Z
 d dlmZ G dd dejZed	Zejd
ddZG dd dZG dd deZG dd dZG dd deje ZG dd dejeef ZG dd deejejf ZG dd deeef ZG dd dZG dd deeejeef f ZG dd  d ejeef Z G d!d" d"e Z!G d#d$ d$Z"dS )%    )annotationsN)shlex)SplitResult	parse_qsl	urlencodeurlsplit)run_in_threadpool)Scopec                   @  s   e Zd ZU ded< ded< dS )AddressstrhostintportN)__name__
__module____qualname____annotations__ r   r   >./venv/lib/python3.8/site-packages/starlette/datastructures.pyr
      s   
r
   _KeyType_CovariantValueTypeT)Z	covariantc                   @  sT  e Zd Zd7ddddddd	Zed
dddZeddddZeddddZeddddZeddddZ	eddddZ
eddddZeddddZeddddZeddd d!Zed"dd#d$Zdd d%d&d'Zdd d%d(d)Zdd d%d*d+Zd,d d-d.d/Zdd"d0d1d2Zddd3d4Zddd5d6ZdS )8URL Nr   zScope | None
typing.AnyNone)urlscope
componentsreturnc                 K  s>  |d k	r
|rt d|r"t d|dd}|dd }|d }|dd}d }|d	 D ]\}	}
|	d
krZ|
d} qzqZ|d k	r| d| | }n\|d kr|}nN|\}}ddddd| }||kr| d| | }n| d| d| | }|r4|d|  7 }n*|r4|rt dtdjf |j }|| _d S )Nz"Cannot set both "url" and "scope".z+Cannot set both "scope" and "**components".schemehttpserverpathquery_string    headerss   hostlatin-1z://P   i  )r    httpswswss:?z)Cannot set both "url" and "**components".r   )AssertionErrorgetdecoder   replacer   geturl_url)selfr   r   r   r   r!   r"   r#   Zhost_headerkeyvaluer   r   Zdefault_portr   r   r   __init__   s6    

zURL.__init__r   r   c                 C  s   t | dst| j| _| jS )N_components)hasattrr   r2   r8   r3   r   r   r   r   @   s    
zURL.componentsc                 C  s   | j jS N)r   r   r:   r   r   r   r   F   s    z
URL.schemec                 C  s   | j jS r;   )r   netlocr:   r   r   r   r<   J   s    z
URL.netlocc                 C  s   | j jS r;   )r   r"   r:   r   r   r   r"   N   s    zURL.pathc                 C  s   | j jS r;   )r   queryr:   r   r   r   r=   R   s    z	URL.queryc                 C  s   | j jS r;   )r   fragmentr:   r   r   r   r>   V   s    zURL.fragmentz
None | strc                 C  s   | j jS r;   )r   usernamer:   r   r   r   r?   Z   s    zURL.usernamec                 C  s   | j jS r;   )r   passwordr:   r   r   r   r@   ^   s    zURL.passwordc                 C  s   | j jS r;   )r   hostnamer:   r   r   r   rA   b   s    zURL.hostname
int | Nonec                 C  s   | j jS r;   )r   r   r:   r   r   r   r   f   s    zURL.portboolc                 C  s
   | j dkS )N)r(   r*   )r   r:   r   r   r   	is_securej   s    zURL.is_secure)kwargsr   c           
      K  s   d|ks d|ks d|ks d|kr| dd }| d| j}| d| j}| d| j}|d kr| j}|d\}}}|d dkr|dd	d
 }|}|d k	r|d| 7 }|d k	r|}|d k	r|d| 7 }| d| }||d< | jjf |}	| 	|	
 S )Nr?   r@   rA   r   @]r+      r   r<   )popr   r?   r@   r<   
rpartitionrsplitr   _replace	__class__r1   )
r3   rE   rA   r   r?   r@   r<   _Zuserpassr   r   r   r   r0   n   s*     zURL.replacec                 K  sB   t t| jdd}|dd | D  t| }| j|dS )NTZkeep_blank_valuesc                 S  s   i | ]\}}t |t |qS r   r   .0r4   r5   r   r   r   
<dictcomp>   s      z,URL.include_query_params.<locals>.<dictcomp>r=   )	MultiDictr   r=   updateitemsr   multi_itemsr0   )r3   rE   paramsr=   r   r   r   include_query_params   s    zURL.include_query_paramsc                 K  s"   t dd | D }| j|dS )Nc                 S  s    g | ]\}}t |t |fqS r   rQ   rR   r   r   r   
<listcomp>   s     z,URL.replace_query_params.<locals>.<listcomp>rU   )r   rX   r0   )r3   rE   r=   r   r   r   replace_query_params   s    zURL.replace_query_paramsstr | typing.Sequence[str])keysr   c                 C  sP   t |tr|g}tt| jdd}|D ]}||d  q&t| }| j|dS )NTrP   rU   )	
isinstancer   rV   r   r=   rJ   r   rY   r0   )r3   r_   rZ   r4   r=   r   r   r   remove_query_params   s    
zURL.remove_query_paramsotherr   c                 C  s   t | t |kS r;   rQ   r3   rc   r   r   r   __eq__   s    z
URL.__eq__c                 C  s   | j S r;   )r2   r:   r   r   r   __str__   s    zURL.__str__c                 C  s6   t | }| jrt | jdd}| jj dt| dS )Nz********)r@   ())r   r@   r0   rN   r   repr)r3   r   r   r   r   __repr__   s    zURL.__repr__)r   N)r   r   r   r6   propertyr   r   r<   r"   r=   r>   r?   r@   rA   r   rD   r0   r[   r]   ra   re   rf   rj   r   r   r   r   r      s@     (	r   c                   @  sL   e Zd ZdZddddd dddZdddddddd	Zd
ddddZdS )URLPathz
    A URL path string that may also hold an associated protocol and/or host.
    Used by the routing to return `url_path_for` matches.
    r   r   )r"   protocolr   r   c                 C  s   |dkst t| |S )N)r    	websocketr   )r-   r   __new__)clsr"   rm   r   r   r   r   ro      s    zURLPath.__new__r   c                 C  s   || _ || _d S r;   )rm   r   )r3   r"   rm   r   r   r   r   r6      s    zURLPath.__init__z	str | URLr   )base_urlr   c                 C  sp   t |trt|}| jr<ddddddd| j |j }n|j}| jpL|j}|j	dt|  }t|||dS )	Nr(   r    )TFr*   r)   )r    rn   /)r   r<   r"   )
r`   r   r   rm   rD   r   r   r<   r"   rstrip)r3   rq   r   r<   r"   r   r   r   make_absolute_url   s    
zURLPath.make_absolute_urlN)r   r   )r   r   )r   r   r   __doc__ro   r6   rt   r   r   r   r   rl      s   rl   c                   @  sH   e Zd ZdZddddZddddZddd	d
ZddddZdS )Secretz
    Holds a string value that should not be revealed in tracebacks etc.
    You should cast the value to `str` at the point it is required.
    r   r5   c                 C  s
   || _ d S r;   _valuer3   r5   r   r   r   r6      s    zSecret.__init__r7   c                 C  s   | j j}| dS )Nz('**********')rN   r   )r3   
class_namer   r   r   rj      s    zSecret.__repr__c                 C  s   | j S r;   rx   r:   r   r   r   rf      s    zSecret.__str__rC   c                 C  s
   t | jS r;   )rC   ry   r:   r   r   r   __bool__   s    zSecret.__bool__N)r   r   r   ru   r6   rj   rf   r}   r   r   r   r   rv      s
   rv   c                   @  sb   e Z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ZdS )CommaSeparatedStringsr^   rw   c                 C  sB   t |tr4t|dd}d|_d|_dd |D | _n
t|| _d S )NT)posix,c                 S  s   g | ]}|  qS r   )striprS   itemr   r   r   r\      s     z2CommaSeparatedStrings.__init__.<locals>.<listcomp>)r`   r   r   Z
whitespaceZwhitespace_split_itemslist)r3   r5   Zsplitterr   r   r   r6      s    
zCommaSeparatedStrings.__init__r   r7   c                 C  s
   t | jS r;   )lenr   r:   r   r   r   __len__   s    zCommaSeparatedStrings.__len__zint | slicer   )indexr   c                 C  s
   | j | S r;   )r   )r3   r   r   r   r   __getitem__   s    z!CommaSeparatedStrings.__getitem__ztyping.Iterator[str]c                 C  s
   t | jS r;   )iterr   r:   r   r   r   __iter__   s    zCommaSeparatedStrings.__iter__r   c                 C  s&   | j j}dd | D }| d|dS )Nc                 S  s   g | ]}|qS r   r   r   r   r   r   r\      s     z2CommaSeparatedStrings.__repr__.<locals>.<listcomp>rg   rh   r{   r3   r|   rX   r   r   r   rj      s    zCommaSeparatedStrings.__repr__c                 C  s   d dd | D S )N, c                 s  s   | ]}t |V  qd S r;   )ri   r   r   r   r   	<genexpr>   s     z0CommaSeparatedStrings.__str__.<locals>.<genexpr>)joinr:   r   r   r   rf      s    zCommaSeparatedStrings.__str__N)	r   r   r   r6   r   r   r   rj   rf   r   r   r   r   r~      s   	r~   c                   @  s   e Zd ZU ded< dd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Z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&Zddd'd(d)Zd*dd+d,Zd-S ).ImmutableMultiDictz#dict[_KeyType, _CovariantValueType]_dictzImmutableMultiDict[_KeyType, _CovariantValueType] | typing.Mapping[_KeyType, _CovariantValueType] | typing.Iterable[tuple[_KeyType, _CovariantValueType]]r   r   argsrE   r   c                 O  s   t |dk std|r |d ng }|r@t| t|  }|sJg }nnt|drvttttf |}t	| }nBt|drttj
ttf |}t	| }ntd|}t	|}dd |D | _|| _d S )	N   Too many arguments.r   rY   rX   z#list[tuple[typing.Any, typing.Any]]c                 S  s   i | ]\}}||qS r   r   rS   kvr   r   r   rT     s      z/ImmutableMultiDict.__init__.<locals>.<dictcomp>)r   r-   r   rY   r9   typingcastr   r   r   MappingrX   r   _list)r3   r   rE   r5   r   r   r   r   r6      s     

zImmutableMultiDict.__init__zlist[_CovariantValueType]r4   r   c                   s    fdd| j D S )Nc                   s   g | ]\}}| kr|qS r   r   rS   item_key
item_valuer4   r   r   r\     s      z.ImmutableMultiDict.getlist.<locals>.<listcomp>r   r3   r4   r   r   r   getlist  s    zImmutableMultiDict.getlistztyping.KeysView[_KeyType]r7   c                 C  s
   | j  S r;   )r   r_   r:   r   r   r   r_     s    zImmutableMultiDict.keysz&typing.ValuesView[_CovariantValueType]c                 C  s
   | j  S r;   )r   valuesr:   r   r   r   r     s    zImmutableMultiDict.valuesz/typing.ItemsView[_KeyType, _CovariantValueType]c                 C  s
   | j  S r;   )r   rX   r:   r   r   r   rX      s    zImmutableMultiDict.itemsz*list[tuple[_KeyType, _CovariantValueType]]c                 C  s
   t | jS r;   r   r   r:   r   r   r   rY   #  s    zImmutableMultiDict.multi_itemsr   r   c                 C  s
   | j | S r;   r   r   r   r   r   r   &  s    zImmutableMultiDict.__getitem__rC   c                 C  s
   || j kS r;   r   r   r   r   r   __contains__)  s    zImmutableMultiDict.__contains__ztyping.Iterator[_KeyType]c                 C  s   t |  S r;   r   r_   r:   r   r   r   r   ,  s    zImmutableMultiDict.__iter__r   c                 C  s
   t | jS r;   )r   r   r:   r   r   r   r   /  s    zImmutableMultiDict.__len__rb   c                 C  s$   t || jsdS t| jt|jkS NF)r`   rN   sortedr   rd   r   r   r   re   2  s    zImmutableMultiDict.__eq__r   c                 C  s    | j j}|  }| d|dS Nrg   rh   )rN   r   rY   r   r   r   r   rj   7  s    zImmutableMultiDict.__repr__N)r   r   r   r   r6   r   r_   r   rX   rY   r   r   r   r   re   rj   r   r   r   r   r      s   
r   c                   @  s   e Zd ZddddddZdddddZd!dd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d
ddZ	ddddddZ
ddddddZdddddd Zd	S )#rV   r   r   r4   r5   r   c                 C  s   |  ||g d S r;   )setlistr3   r4   r5   r   r   r   __setitem__>  s    zMultiDict.__setitem__r   c                   s"    fdd| j D | _ | j = d S )Nc                   s    g | ]\}}| kr||fqS r   r   r   r   r   r   r\   B  s      z)MultiDict.__delitem__.<locals>.<listcomp>)r   r   r   r   r   r   __delitem__A  s    zMultiDict.__delitem__N)r4   defaultr   c                   s$    fdd| j D | _ | j |S )Nc                   s    g | ]\}}| kr||fqS r   r   r   r   r   r   r\   F  s      z!MultiDict.pop.<locals>.<listcomp>)r   r   rJ   r3   r4   r   r   r   r   rJ   E  s    zMultiDict.popztuple[typing.Any, typing.Any]r7   c                   s,   | j  \ } fdd| jD | _ |fS )Nc                   s    g | ]\}}| kr||fqS r   r   r   r   r   r   r\   K  s      z%MultiDict.popitem.<locals>.<listcomp>)r   popitemr   rz   r   r   r   r   I  s    zMultiDict.popitemzlist[typing.Any]c                   s"    fdd| j D }|   |S )Nc                   s   g | ]\}}| kr|qS r   r   r   r   r   r   r\   O  s      z%MultiDict.poplist.<locals>.<listcomp>)r   rJ   )r3   r4   r   r   r   r   poplistN  s    
zMultiDict.poplistc                 C  s   | j   | j  d S r;   )r   clearr   r:   r   r   r   r   S  s    
zMultiDict.clearc                 C  s*   || kr"|| j |< | j||f | | S r;   )r   r   appendr   r   r   r   
setdefaultW  s    
zMultiDict.setdefault)r4   r   r   c                   sP   |s|   d  n: fdd| jD }| fdd|D  | _|d | j < d S )Nc                   s    g | ]\}}| kr||fqS r   r   r   r   r   r   r\   b  s      z%MultiDict.setlist.<locals>.<listcomp>c                   s   g | ]} |fqS r   r   )rS   r5   r   r   r   r\   c  s     rG   )rJ   r   r   )r3   r4   r   existing_itemsr   r   r   r   ^  s
    zMultiDict.setlistc                 C  s   | j ||f || j|< d S r;   )r   r   r   r   r   r   r   r   f  s    zMultiDict.appendzXMultiDict | typing.Mapping[typing.Any, typing.Any] | list[tuple[typing.Any, typing.Any]]r   c                   s<   t ||  fdd| jD }|   | _| j  d S )Nc                   s$   g | ]\}}|   kr||fqS r   )r_   r   rw   r   r   r\   p  s      z$MultiDict.update.<locals>.<listcomp>)rV   r   rY   r   rW   )r3   r   rE   r   r   rw   r   rW   j  s    
zMultiDict.update)N)N)r   r   r   r   r   rJ   r   r   r   r   r   r   rW   r   r   r   r   rV   =  s   rV   c                      sF   e Zd ZdZdddd fddZdd	d
dZdd	ddZ  ZS )QueryParamsz!
    An immutable multidict.
    zImmutableMultiDict[typing.Any, typing.Any] | typing.Mapping[typing.Any, typing.Any] | list[tuple[typing.Any, typing.Any]] | str | bytesr   r   r   c                   s   t |dk std|r |d ng }t|trHt jt|ddf| n8t|trrt jt|dddf| nt j|| dd | j	D | _	d	d
 | j
 D | _
d S )Nr   r   r   TrP   r&   c                 S  s    g | ]\}}t |t |fqS r   rQ   r   r   r   r   r\     s     z(QueryParams.__init__.<locals>.<listcomp>c                 S  s   i | ]\}}t |t |qS r   rQ   r   r   r   r   rT     s      z(QueryParams.__init__.<locals>.<dictcomp>)r   r-   r`   r   superr6   r   bytesr/   r   r   rX   )r3   r   rE   r5   rN   r   r   r6   z  s    	

 zQueryParams.__init__r   r7   c                 C  s
   t | jS r;   )r   r   r:   r   r   r   rf     s    zQueryParams.__str__c                 C  s    | j j}t| }| d|dS r   )rN   r   r   )r3   r|   r#   r   r   r   rj     s    zQueryParams.__repr__)r   r   r   ru   r6   rf   rj   __classcell__r   r   r   r   r   u  s   r   c                   @  s   e Zd ZdZdddddddddd	d
dZeddddZe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Zd dd!d"ZdS )$
UploadFilez@
    An uploaded file included as part of the request data.
    N)sizefilenamer%   ztyping.BinaryIOrB   z
str | NonezHeaders | Noner   )filer   r   r%   r   c                C  s"   || _ || _|| _|pt | _d S r;   )r   r   r   Headersr%   )r3   r   r   r   r%   r   r   r   r6     s    zUploadFile.__init__r7   c                 C  s   | j dd S )Nzcontent-type)r%   r.   r:   r   r   r   content_type  s    zUploadFile.content_typerC   c                 C  s   t | jdd}| S )NZ_rolledT)getattrr   )r3   Zrolled_to_diskr   r   r   
_in_memory  s    zUploadFile._in_memoryr   )datar   c                   sH   | j d k	r|  j t|7  _ | jr0| j| nt| jj|I d H  d S r;   )r   r   r   r   writer   )r3   r   r   r   r   r     s
    
zUploadFile.writerG   r   )r   r   c                   s&   | j r| j|S t| jj|I d H S r;   )r   r   readr   )r3   r   r   r   r   r     s    zUploadFile.read)offsetr   c                   s,   | j r| j| nt| jj|I d H  d S r;   )r   r   seekr   )r3   r   r   r   r   r     s    zUploadFile.seekc                   s(   | j r| j  nt| jjI d H  d S r;   )r   r   closer   r:   r   r   r   r     s    zUploadFile.closer   c                 C  s&   | j j d| jd| jd| jdS )Nz
(filename=z, size=z
, headers=rh   )rN   r   r   r   r%   r:   r   r   r   rj     s    $zUploadFile.__repr__)rG   )r   r   r   ru   r6   rk   r   r   r   r   r   r   rj   r   r   r   r   r     s   	r   c                      s8   e Zd ZdZdddd fddZddd	d
Z  ZS )FormDatazN
    An immutable multidict, containing both file uploads and text input.
    zUFormData | typing.Mapping[str, str | UploadFile] | list[tuple[str, str | UploadFile]]zstr | UploadFiler   r   c                   s   t  j|| d S r;   )r   r6   )r3   r   rE   r   r   r   r6     s    zFormData.__init__r7   c                   s.   |   D ] \}}t|tr| I d H  qd S r;   )rY   r`   r   r   r   r   r   r   r     s    
zFormData.close)r   r   r   ru   r6   r   r   r   r   r   r   r     s   r   c                   @  s   e Zd ZdZd.ddddddd	Ze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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-ZdS )/r   z3
    An immutable, case-insensitive multidict.
    Nztyping.Mapping[str, str] | Nonez list[tuple[bytes, bytes]] | Nonez-typing.MutableMapping[str, typing.Any] | Noner   )r%   rawr   r   c                 C  s   g | _ |d k	rD|d kstd|d ks.tddd | D | _ n>|d k	rd|d ks\td|| _ n|d k	rt|d  | _ |d< d S )Nz$Cannot set both "headers" and "raw".z&Cannot set both "headers" and "scope".c                 S  s(   g | ] \}}|  d |d fqS r&   )lowerencoderR   r   r   r   r\     s     z$Headers.__init__.<locals>.<listcomp>z"Cannot set both "raw" and "scope".r%   )r   r-   rX   r   )r3   r%   r   r   r   r   r   r6     s    zHeaders.__init__list[tuple[bytes, bytes]]r7   c                 C  s
   t | jS r;   r   r:   r   r   r   r     s    zHeaders.rawz	list[str]c                 C  s   dd | j D S )Nc                 S  s   g | ]\}}| d qS r   r/   rR   r   r   r   r\     s     z Headers.keys.<locals>.<listcomp>r   r:   r   r   r   r_     s    zHeaders.keysc                 C  s   dd | j D S )Nc                 S  s   g | ]\}}| d qS r   r   rR   r   r   r   r\   
  s     z"Headers.values.<locals>.<listcomp>r   r:   r   r   r   r   	  s    zHeaders.valueszlist[tuple[str, str]]c                 C  s   dd | j D S )Nc                 S  s$   g | ]\}}| d | d fqS r   r   rR   r   r   r   r\     s     z!Headers.items.<locals>.<listcomp>r   r:   r   r   r   rX     s    zHeaders.itemsr   r   c                   s"   |  d  fdd| jD S )Nr&   c                   s"   g | ]\}}| kr| d qS r   r   r   get_header_keyr   r   r\     s      z#Headers.getlist.<locals>.<listcomp>r   r   r   r   r   r   r   r     s    zHeaders.getlistMutableHeadersc                 C  s   t | jd d  dS )N)r   )r   r   r:   r   r   r   mutablecopy  s    zHeaders.mutablecopyc                 C  s@   |  d}| jD ]\}}||kr|d  S qt|d S )Nr&   )r   r   r   r/   KeyErrorr3   r4   r   Z
header_keyZheader_valuer   r   r   r     s
    zHeaders.__getitem__r   rC   c                 C  s0   |  d}| jD ]\}}||kr dS qdS )Nr&   TFr   r   r   r   r   r     s
    zHeaders.__contains__ztyping.Iterator[typing.Any]c                 C  s   t |  S r;   r   r:   r   r   r   r   $  s    zHeaders.__iter__r   c                 C  s
   t | jS r;   )r   r   r:   r   r   r   r   '  s    zHeaders.__len__rb   c                 C  s"   t |tsdS t| jt|jkS r   )r`   r   r   r   rd   r   r   r   re   *  s    
zHeaders.__eq__c                 C  sF   | j j}t|  }t|t| kr4| d|dS | d| jdS )Nrg   rh   z(raw=)rN   r   dictrX   r   r   )r3   r|   Zas_dictr   r   r   rj   /  s
    zHeaders.__repr__)NNN)r   r   r   ru   r6   rk   r   r_   r   rX   r   r   r   r   r   r   re   rj   r   r   r   r   r     s$      r   c                   @  s   e Z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dZeddddZdd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S )r   r   r   r   c           	      C  s   |  d}|d}g }t| jD ]\}\}}||kr&|| q&t|dd D ]}| j|= qV|r|d }||f| j|< n| j||f dS )zs
        Set the header `key` to `value`, removing any duplicate entries.
        Retains insertion order.
        r&   rI   Nr   r   r   	enumerater   r   reversed)	r3   r4   r5   set_key	set_valueZfound_indexesidxr   r   r   r   r   r   8  s    

zMutableHeaders.__setitem__r   c                 C  sV   |  d}g }t| jD ]\}\}}||kr|| qt|D ]}| j|= qDdS )z*
        Remove the header `key`.
        r&   Nr   )r3   r4   Zdel_keyZpop_indexesr   r   r   r   r   r   r   N  s    zMutableHeaders.__delitem__ztyping.Mapping[str, str]rb   c                 C  s,   t |tjstd|jj | | | S NzExpected a mapping but got )r`   r   r   	TypeErrorrN   r   rW   rd   r   r   r   __ior__\  s    
zMutableHeaders.__ior__c                 C  s4   t |tjstd|jj |  }|| |S r   )r`   r   r   r   rN   r   r   rW   )r3   rc   newr   r   r   __or__b  s
    
zMutableHeaders.__or__r   r7   c                 C  s   | j S r;   r   r:   r   r   r   r   i  s    zMutableHeaders.rawc                 C  sZ   |  d}|d}t| jD ]"\}\}}||kr"|d  S q"| j||f |S )zo
        If the header `key` does not exist, then set it to `value`.
        Returns the header value.
        r&   )r   r   r   r   r/   r   )r3   r4   r5   r   r   r   r   r   r   r   r   r   m  s    
zMutableHeaders.setdefaultc                 C  s   |  D ]\}}|| |< qd S r;   )rX   )r3   rc   r4   valr   r   r   rW   {  s    zMutableHeaders.updatec                 C  s,   |  d}|d}| j||f dS )zD
        Append a header, preserving any duplicate entries.
        r&   N)r   r   r   r   )r3   r4   r5   Z
append_keyZappend_valuer   r   r   r     s    
zMutableHeaders.append)varyr   c                 C  s,   |  d}|d k	r d||g}|| d< d S )Nr   r   )r.   r   )r3   r   existingr   r   r   add_vary_header  s    
zMutableHeaders.add_vary_headerN)r   r   r   r   r   r   r   rk   r   r   rW   r   r   r   r   r   r   r   7  s   r   c                      sd   e Zd ZU dZded< ddd fddZd	d	d
dddZd	d	dddZd	d
dddZ  Z	S )Statezm
    An object that can be used to store arbitrary state.

    Used for `request.state` and `app.state`.
    zdict[str, typing.Any]_stateNzdict[str, typing.Any] | None)statec                   s   |d kri }t  d| d S )Nr   )r   __setattr__)r3   r   r   r   r   r6     s    zState.__init__r   r   r   c                 C  s   || j |< d S r;   r   r   r   r   r   r     s    zState.__setattr__r   c                 C  s>   z| j | W S  tk
r8   d}t|| jj|Y nX d S )Nz!'{}' object has no attribute '{}')r   r   AttributeErrorformatrN   r   )r3   r4   messager   r   r   __getattr__  s
    zState.__getattr__c                 C  s   | j |= d S r;   r   r   r   r   r   __delattr__  s    zState.__delattr__)N)
r   r   r   ru   r   r6   r   r   r   r   r   r   r   r   r     s   
r   )#Z
__future__r   r   r   Zurllib.parser   r   r   r   Zstarlette.concurrencyr   Zstarlette.typesr	   Z
NamedTupler
   ZTypeVarr   r   r   r   rl   rv   Sequencer~   r   r   ZAnyrV   r   r   ZUnionr   r   r   r   r   r   r   r   <module>   s*   
 E8$?"MW