U
    eX                     @  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   </tmp/pip-unpacked-wheel-2mv5qoba/starlette/datastructures.pyr
      s   
r
   _KeyType_CovariantValueTypeT)	covariantc                   @  sT  e Zd Zd8d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/d0Zdd"d1d2d3Zddd4d5Zddd6d7ZdS )9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   default_portr   r   r   __init__   s6    

zURL.__init__r   r   c                 C  s   t | dst| j| _| jS )N_components)hasattrr   r3   r:   r4   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   rA   Z   s    zURL.usernamec                 C  s   | j jS r=   )r   passwordr<   r   r   r   rB   ^   s    zURL.passwordc                 C  s   | j jS r=   )r   hostnamer<   r   r   r   rC   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 )NrA   rB   rC   r   @]r,      r   r>   )popr   rA   rB   r>   
rpartitionrsplitr   _replace	__class__r2   )
r4   rG   rC   r   rA   rB   r>   _Zuserpassr   r   r   r   r1   n   s8    zURL.replacec                 K  sB   t t| jdd}|dd | D  t| }| j|dS )NTkeep_blank_valuesc                 S  s   i | ]\}}t |t |qS r   r   .0r5   r6   r   r   r   
<dictcomp>   s      z,URL.include_query_params.<locals>.<dictcomp>r?   )	MultiDictr   r?   updateitemsr   multi_itemsr1   )r4   rG   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   rT   rU   r   r   r   
<listcomp>   s     z,URL.replace_query_params.<locals>.<listcomp>rX   )r   r[   r1   )r4   rG   r?   r   r   r   replace_query_params   s    zURL.replace_query_paramsstr | typing.Sequence[str]z'URL')keysr   c                 C  sP   t |tr|g}tt| jdd}|D ]}||d  q&t| }| j|dS )NTrR   rX   )	
isinstancer   rY   r   r?   rL   r   r\   r1   )r4   rb   r]   r5   r?   r   r   r   remove_query_params   s    
zURL.remove_query_paramsotherr   c                 C  s   t | t |kS r=   rT   r4   rf   r   r   r   __eq__   s    z
URL.__eq__c                 C  s   | j S r=   )r3   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********)rB   ())r   rB   r1   rP   r   repr)r4   r   r   r   r   __repr__   s    zURL.__repr__)r   N)r   r   r   r8   propertyr   r    r>   r#   r?   r@   rA   rB   rC   r   rF   r1   r^   r`   rd   rh   ri   rm   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   z	'URLPath')r#   protocolr   r   c                 C  s   |dkst t| |S )N)r!   	websocketr   )r.   r   __new__)clsr#   rp   r   r   r   r   rr      s    zURLPath.__new__r   c                 C  s   || _ || _d S r=   )rp   r   )r4   r#   rp   r   r   r   r   r8      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!   rq   /)r    r>   r#   )
rc   r   r   rp   rF   r    r   r>   r#   rstrip)r4   rt   r    r>   r#   r   r   r   make_absolute_url   s    
zURLPath.make_absolute_urlN)r   r   )r   r   )r   r   r   __doc__rr   r8   rw   r   r   r   r   ro      s   ro   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   r6   c                 C  s
   || _ d S r=   _valuer4   r6   r   r   r   r8      s    zSecret.__init__r9   c                 C  s   | j j}| dS )Nz('**********')rP   r   )r4   
class_namer   r   r   rm      s    zSecret.__repr__c                 C  s   | j S r=   r{   r<   r   r   r   ri      s    zSecret.__str__rE   c                 C  s
   t | jS r=   )rE   r|   r<   r   r   r   __bool__   s    zSecret.__bool__N)r   r   r   rx   r8   rm   ri   r   r   r   r   r   ry      s
   ry   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 )CommaSeparatedStringsra   rz   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rV   itemr   r   r   r_      s     z2CommaSeparatedStrings.__init__.<locals>.<listcomp>)rc   r   r   
whitespacewhitespace_split_itemslist)r4   r6   Zsplitterr   r   r   r8      s    
zCommaSeparatedStrings.__init__r   r9   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   )r4   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>rj   rk   r~   r4   r   r[   r   r   r   rm      s    zCommaSeparatedStrings.__repr__c                 C  s   d dd | D S )N, c                 s  s   | ]}t |V  qd S r=   )rl   r   r   r   r   	<genexpr>   s     z0CommaSeparatedStrings.__str__.<locals>.<genexpr>)joinr<   r   r   r   ri      s    zCommaSeparatedStrings.__str__N)	r   r   r   r8   r   r   r   rm   ri   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*typing.Dict[_KeyType, _CovariantValueType]_dictzImmutableMultiDict[_KeyType, _CovariantValueType] | typing.Mapping[_KeyType, _CovariantValueType] | typing.Iterable[typing.Tuple[_KeyType, _CovariantValueType]]r   r   argsrG   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   r\   r[   z#list[tuple[typing.Any, typing.Any]]c                 S  s   i | ]\}}||qS r   r   rV   kvr   r   r   rW     s      z/ImmutableMultiDict.__init__.<locals>.<dictcomp>)r   r.   r   r\   r;   typingcastr   r   r   Mappingr[   r   _list)r4   r   rG   r6   r   r   r   r   r8      s,    



 
zImmutableMultiDict.__init__zlist[_CovariantValueType]r5   r   c                   s    fdd| j D S )Nc                   s   g | ]\}}| kr|qS r   r   rV   item_key
item_valuer5   r   r   r_   "  s      z.ImmutableMultiDict.getlist.<locals>.<listcomp>r   r4   r5   r   r   r   getlist!  s    zImmutableMultiDict.getlistztyping.KeysView[_KeyType]r9   c                 C  s
   | j  S r=   )r   rb   r<   r   r   r   rb   $  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   r[   r<   r   r   r   r[   *  s    zImmutableMultiDict.itemsz*list[tuple[_KeyType, _CovariantValueType]]c                 C  s
   t | jS r=   r   r   r<   r   r   r   r\   -  s    zImmutableMultiDict.multi_itemsr   r   c                 C  s
   | j | S r=   r   r   r   r   r   r   0  s    zImmutableMultiDict.__getitem__rE   c                 C  s
   || j kS r=   r   r   r   r   r   __contains__3  s    zImmutableMultiDict.__contains__ztyping.Iterator[_KeyType]c                 C  s   t |  S r=   r   rb   r<   r   r   r   r   6  s    zImmutableMultiDict.__iter__r   c                 C  s
   t | jS r=   )r   r   r<   r   r   r   r   9  s    zImmutableMultiDict.__len__re   c                 C  s$   t || jsdS t| jt|jkS NF)rc   rP   sortedr   rg   r   r   r   rh   <  s    zImmutableMultiDict.__eq__r   c                 C  s    | j j}|  }| d|dS Nrj   rk   )rP   r   r\   r   r   r   r   rm   A  s    zImmutableMultiDict.__repr__N)r   r   r   r   r8   r   rb   r   r[   r\   r   r   r   r   rh   rm   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 )#rY   r   r   r5   r6   r   c                 C  s   |  ||g d S r=   )setlistr4   r5   r6   r   r   r   __setitem__H  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_   L  s      z)MultiDict.__delitem__.<locals>.<listcomp>)r   r   r   r   r   r   __delitem__K  s    zMultiDict.__delitem__N)r5   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_   P  s      z!MultiDict.pop.<locals>.<listcomp>)r   r   rL   r4   r5   r   r   r   r   rL   O  s    zMultiDict.popztuple[typing.Any, typing.Any]r9   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_   U  s      z%MultiDict.popitem.<locals>.<listcomp>)r   popitemr   r}   r   r   r   r   S  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_   Y  s      z%MultiDict.poplist.<locals>.<listcomp>)r   rL   )r4   r5   r   r   r   r   poplistX  s    
zMultiDict.poplistc                 C  s   | j   | j  d S r=   )r   clearr   r<   r   r   r   r   ]  s    
zMultiDict.clearc                 C  s*   || kr"|| j |< | j||f | | S r=   )r   r   appendr   r   r   r   
setdefaulta  s    
zMultiDict.setdefault)r5   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_   l  s      z%MultiDict.setlist.<locals>.<listcomp>c                   s   g | ]} |fqS r   r   )rV   r6   r   r   r   r_   m  s     rI   )rL   r   r   )r4   r5   r   existing_itemsr   r   r   r   h  s
    zMultiDict.setlistc                 C  s   | j ||f || j|< d S r=   )r   r   r   r   r   r   r   r   p  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   )rb   r   rz   r   r   r_   |  s      z$MultiDict.update.<locals>.<listcomp>)rY   r   r\   r   rZ   )r4   r   rG   r   r   rz   r   rZ   t  s    
zMultiDict.update)N)N)r   r   r   r   r   rL   r   r   r   r   r   r   rZ   r   r   r   r   rY   G  s   rY   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   TrR   r'   c                 S  s    g | ]\}}t |t |fqS r   rT   r   r   r   r   r_     s     z(QueryParams.__init__.<locals>.<listcomp>c                 S  s   i | ]\}}t |t |qS r   rT   r   r   r   r   rW     s      z(QueryParams.__init__.<locals>.<dictcomp>)r   r.   rc   r   superr8   r   bytesr0   r   r   r[   )r4   r   rG   r6   rP   r   r   r8     s    	

zQueryParams.__init__r   r9   c                 C  s
   t | jS r=   )r   r   r<   r   r   r   ri     s    zQueryParams.__str__c                 C  s    | j j}t| }| d|dS r   )rP   r   r   )r4   r   r$   r   r   r   rm     s    zQueryParams.__repr__)r   r   r   rx   r8   ri   rm   __classcell__r   r   r   r   r     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.BinaryIOrD   z
str | NonezHeaders | Noner   )filer   r   r&   r   c                C  s"   || _ || _|| _|pt | _d S r=   )r   r   r   Headersr&   )r4   r   r   r   r&   r   r   r   r8     s    zUploadFile.__init__r9   c                 C  s   | j dd S )Nzcontent-type)r&   r/   r<   r   r   r   content_type  s    zUploadFile.content_typerE   c                 C  s   t | jdd}| S )N_rolledT)getattrr   )r4   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   )r4   r   r   r   r   r     s
    
zUploadFile.writerI   r   )r   r   c                   s&   | j r| j|S t| jj|I d H S r=   )r   r   readr   )r4   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   )r4   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=rk   )rP   r   r   r   r&   r<   r   r   r   rm     s    $zUploadFile.__repr__)rI   )r   r   r   rx   r8   rn   r   r   r   r   r   r   rm   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   r8   )r4   r   rG   r   r   r   r8     s    zFormData.__init__r9   c                   s.   |   D ] \}}t|tr| I d H  qd S r=   )r\   rc   r   r   r   r   r   r   r     s    
zFormData.close)r   r   r   rx   r8   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encoderU   r   r   r   r_   	  s   z$Headers.__init__.<locals>.<listcomp>z"Cannot set both "raw" and "scope".r&   )r   r.   r[   r   )r4   r&   r   r   r   r   r   r8     s    
zHeaders.__init__list[tuple[bytes, bytes]]r9   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   r0   rU   r   r   r   r_     s     z Headers.keys.<locals>.<listcomp>r   r<   r   r   r   rb     s    zHeaders.keysc                 C  s   dd | j D S )Nc                 S  s   g | ]\}}| d qS r   r   rU   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   rU   r   r   r   r_      s   z!Headers.items.<locals>.<listcomp>r   r<   r   r   r   r[     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   r0   KeyErrorr4   r5   r   Z
header_keyheader_valuer   r   r   r   0  s
    zHeaders.__getitem__r   rE   c                 C  s0   |  d}| jD ]\}}||kr dS qdS )Nr'   TFr   r   r   r   r   r   7  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   A  s    zHeaders.__len__re   c                 C  s"   t |tsdS t| jt|jkS r   )rc   r   r   r   rg   r   r   r   rh   D  s    
zHeaders.__eq__c                 C  sF   | j j}t|  }t|t| kr4| d|dS | d| jdS )Nrj   rk   z(raw=)rP   r   dictr[   r   r   )r4   r   Zas_dictr   r   r   rm   I  s
    zHeaders.__repr__)NNN)r   r   r   rx   r8   rn   r   rb   r   r[   r   r   r   r   r   r   rh   rm   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'   rK   Nr   r   r   	enumerater   r   reversed)	r4   r5   r6   set_key	set_valueZfound_indexesidxr   r   r   r   r   r   R  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   )r4   r5   Zdel_keyZpop_indexesr   r   r   r   r   r   r   h  s    zMutableHeaders.__delitem__ztyping.Mapping[str, str]re   c                 C  s,   t |tjstd|jj | | | S NzExpected a mapping but got )rc   r   r   	TypeErrorrP   r   rZ   rg   r   r   r   __ior__v  s    
zMutableHeaders.__ior__c                 C  s4   t |tjstd|jj |  }|| |S r   )rc   r   r   r   rP   r   r   rZ   )r4   rf   newr   r   r   __or__|  s
    
zMutableHeaders.__or__r   r9   c                 C  s   | j S r=   r   r<   r   r   r   r     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   r0   r   )r4   r5   r6   r   r   r   r   r   r   r   r   r     s    
zMutableHeaders.setdefaultc                 C  s   |  D ]\}}|| |< qd S r=   )r[   )r4   rf   r5   valr   r   r   rZ     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   )r4   r5   r6   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   )r4   r   existingr   r   r   add_vary_header  s    
zMutableHeaders.add_vary_headerN)r   r   r   r   r   r   r   rn   r   r   rZ   r   r   r   r   r   r   r   Q  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__)r4   r   r   r   r   r8     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formatrP   r   )r4   r5   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   rx   r   r8   r   r   r   r   r   r   r   r   r     s   
r   )#
__future__r   r   r   urllib.parser   r   r   r   Zstarlette.concurrencyr   Zstarlette.typesr	   
NamedTupler
   TypeVarr   r   r   r   ro   ry   Sequencer   r   r   AnyrY   r   r   Unionr   r   r   r   r   r   r   r   <module>   s*   
 J:&?"WW