B
    ind/Z                 @   sp  d dl Z d dlm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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 )%    N)Sequence)shlex)SplitResult	parse_qsl	urlencodeurlsplit)run_in_threadpool)Scopec               @   s   e Zd ZU eed< eed< dS )AddresshostportN)__name__
__module____qualname__str__annotations__int r   r   </tmp/pip-unpacked-wheel-_bom8ime/starlette/datastructures.pyr
   
   s   
r
   _KeyType_CovariantValueTypeT)	covariantc               @   s  e Zd Zd.eeje ejddddZe	e
dddZe	edd	d
Ze	edddZe	edddZe	edddZe	edddZe	ejdef dddZe	ejdef dddZe	ejdef dddZe	eje dddZe	edddZejd dddZejd dd d!Zejd dd"d#Zejeeje f d d$d%d&Zejed'd(d)Zedd*d+Zedd,d-Z dS )/URL N)urlscope
componentsreturnc             K   sL  |d k	r|rt d|r"t d|dd}|dd }|dd|d  }|d	d
}d }x(|d D ]\}	}
|	dkrh|
d}P qhW |d k	r| d| | }n\|d kr|}nN|\}}ddddd| }||kr| d| | }n| d| d| | }|rB|d|  7 }n*|rB|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	root_pathr   pathquery_string    headerss   hostzlatin-1z://P   i  )r   httpswswss:?z)Cannot set both "url" and "**components".)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   c             C   s   t | dst| j| _| jS )N_components)hasattrr   r1   r7   )r2   r   r   r   r   ?   s    
zURL.componentsc             C   s   | j jS )N)r   r   )r2   r   r   r   r   E   s    z
URL.schemec             C   s   | j jS )N)r   netloc)r2   r   r   r   r9   I   s    z
URL.netlocc             C   s   | j jS )N)r   r"   )r2   r   r   r   r"   M   s    zURL.pathc             C   s   | j jS )N)r   query)r2   r   r   r   r:   Q   s    z	URL.queryc             C   s   | j jS )N)r   fragment)r2   r   r   r   r;   U   s    zURL.fragmentc             C   s   | j jS )N)r   username)r2   r   r   r   r<   Y   s    zURL.usernamec             C   s   | j jS )N)r   password)r2   r   r   r   r=   ]   s    zURL.passwordc             C   s   | j jS )N)r   hostname)r2   r   r   r   r>   a   s    zURL.hostnamec             C   s   | j jS )N)r   r   )r2   r   r   r   r   e   s    zURL.portc             C   s
   | j dkS )N)r'   r)   )r   )r2   r   r   r   	is_securei   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=   r>   r   @]r*      r   r9   )popr   r<   r=   r9   
rpartitionrsplitr   _replace	__class__r0   )
r2   r@   r>   r   r<   r=   r9   _Zuserpassr   r   r   r   r/   m   s0    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   ).0r3   r4   r   r   r   
<dictcomp>   s    z,URL.include_query_params.<locals>.<dictcomp>)r:   )	MultiDictr   r:   updateitemsr   multi_itemsr/   )r2   r@   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   )r   )rL   r3   r4   r   r   r   
<listcomp>   s    z,URL.replace_query_params.<locals>.<listcomp>)r:   )r   rP   r/   )r2   r@   r:   r   r   r   replace_query_params   s    zURL.replace_query_params)keysr   c             C   sT   t |tr|g}tt| jdd}x|D ]}||d  q(W t| }| j|dS )NT)rK   )r:   )	
isinstancer   rN   r   r:   rE   r   rQ   r/   )r2   rV   rR   r3   r:   r   r   r   remove_query_params   s    

zURL.remove_query_params)otherr   c             C   s   t | t |kS )N)r   )r2   rY   r   r   r   __eq__   s    z
URL.__eq__c             C   s   | j S )N)r1   )r2   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=   r/   rI   r   repr)r2   r   r   r   r   __repr__   s    zURL.__repr__)r   N)!r   r   r   r   typingOptionalr	   Anyr6   propertyr   r   r   r9   r"   r:   r;   Unionr<   r=   r>   r   r   boolr?   r/   rS   rU   r   rX   rZ   r[   r_   r   r   r   r   r      sD    #!	r   c               @   sV   e Zd ZdZdeeed dddZdeeeddddZejee	f e	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"   protocolr   r   c             C   s   |dkst t| |S )N)r   	websocketr   )r,   r   __new__)clsr"   rg   r   r   r   r   ri      s    zURLPath.__new__Nc             C   s   || _ || _d S )N)rg   r   )r2   r"   rg   r   r   r   r   r6      s    zURLPath.__init__)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   rh   /)r   r9   r"   )
rW   r   r   rg   r?   r   r   r9   r"   rstrip)r2   rk   r   r9   r"   r   r   r   make_absolute_url   s    
zURLPath.make_absolute_url)r   r   )r   r   )r   r   r   __doc__r   ri   r6   r`   rd   r   rn   r   r   r   r   rf      s   rf   c               @   sH   e Zd ZdZedddZedddZeddd	Ze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.
    )r4   c             C   s
   || _ d S )N)_value)r2   r4   r   r   r   r6      s    zSecret.__init__)r   c             C   s   | j j}| dS )Nz('**********'))rI   r   )r2   
class_namer   r   r   r_      s    zSecret.__repr__c             C   s   | j S )N)rq   )r2   r   r   r   r[      s    zSecret.__str__c             C   s
   t | jS )N)re   rq   )r2   r   r   r   __bool__   s    zSecret.__bool__N)
r   r   r   ro   r   r6   r_   r[   re   rs   r   r   r   r   rp      s
   rp   c               @   s   e Zd Zejeeje f dddZedddZ	ejee
f ejddd	Zeje dd
dZedddZedddZdS )CommaSeparatedStrings)r4   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)rL   itemr   r   r   rT      s    z2CommaSeparatedStrings.__init__.<locals>.<listcomp>)rW   r   r   
whitespacewhitespace_split_itemslist)r2   r4   splitterr   r   r   r6      s    
zCommaSeparatedStrings.__init__)r   c             C   s
   t | jS )N)lenr{   )r2   r   r   r   __len__   s    zCommaSeparatedStrings.__len__)indexr   c             C   s
   | j | S )N)r{   )r2   r   r   r   r   __getitem__   s    z!CommaSeparatedStrings.__getitem__c             C   s
   t | jS )N)iterr{   )r2   r   r   r   __iter__   s    zCommaSeparatedStrings.__iter__c             C   s&   | j j}dd | D }| d|dS )Nc             S   s   g | ]}|qS r   r   )rL   rx   r   r   r   rT      s    z2CommaSeparatedStrings.__repr__.<locals>.<listcomp>r\   r]   )rI   r   )r2   rr   rP   r   r   r   r_      s    zCommaSeparatedStrings.__repr__c             C   s   d dd | D S )Nz, c             s   s   | ]}t |V  qd S )N)r^   )rL   rx   r   r   r   	<genexpr>   s    z0CommaSeparatedStrings.__str__.<locals>.<genexpr>)join)r2   r   r   r   r[      s    zCommaSeparatedStrings.__str__N)r   r   r   r`   rd   r   r   r6   r   r   slicerb   r   Iteratorr   r_   r[   r   r   r   r   rt      s   	rt   c               @   s4  e Zd ZU ejeef ed< ejdej	eef ej
ejeef  f ejddddZejeje ddd	Zeje d
ddZeje d
ddZejeef d
ddZejejeef  d
ddZeedddZejedddZeje d
ddZed
ddZejedddZed
ddZ dS ) ImmutableMultiDict_dictz1ImmutableMultiDict[_KeyType, _CovariantValueType]N)argsr@   r   c             O   s   t |dk std|r |d ng }|r@t| t|  }|sJg }nt|drvttttf |}t	| }nVt|drttj
ttf |}t	| }n(ttjtjtjtjf  |}t	|}dd |D | _|| _d S )N   zToo many arguments.r   rQ   rP   c             S   s   i | ]\}}||qS r   r   )rL   kvr   r   r   rM   #  s    z/ImmutableMultiDict.__init__.<locals>.<dictcomp>)r~   r,   r   rQ   r8   r`   castr   r   r|   MappingrP   ListTuplerb   r   _list)r2   r   r@   r4   r{   r   r   r   r6     s&    	


zImmutableMultiDict.__init__)r3   r   c                s    fdd| j D S )Nc                s   g | ]\}}| kr|qS r   r   )rL   item_key
item_value)r3   r   r   rT   '  s    z.ImmutableMultiDict.getlist.<locals>.<listcomp>)r   )r2   r3   r   )r3   r   getlist&  s    zImmutableMultiDict.getlist)r   c             C   s
   | j  S )N)r   rV   )r2   r   r   r   rV   )  s    zImmutableMultiDict.keysc             C   s
   | j  S )N)r   values)r2   r   r   r   r   ,  s    zImmutableMultiDict.valuesc             C   s
   | j  S )N)r   rP   )r2   r   r   r   rP   /  s    zImmutableMultiDict.itemsc             C   s
   t | jS )N)r|   r   )r2   r   r   r   rQ   2  s    zImmutableMultiDict.multi_itemsc             C   s
   | j | S )N)r   )r2   r3   r   r   r   r   5  s    zImmutableMultiDict.__getitem__c             C   s
   || j kS )N)r   )r2   r3   r   r   r   __contains__8  s    zImmutableMultiDict.__contains__c             C   s   t |  S )N)r   rV   )r2   r   r   r   r   ;  s    zImmutableMultiDict.__iter__c             C   s
   t | jS )N)r~   r   )r2   r   r   r   r   >  s    zImmutableMultiDict.__len__)rY   r   c             C   s$   t || jsdS t| jt|jkS )NF)rW   rI   sortedr   )r2   rY   r   r   r   rZ   A  s    zImmutableMultiDict.__eq__c             C   s    | j j}|  }| d|dS )Nr\   r]   )rI   r   rQ   )r2   rr   rP   r   r   r   r_   F  s    zImmutableMultiDict.__repr__)!r   r   r   r`   Dictr   r   r   rd   r   Iterabler   rb   r6   r   r   KeysViewrV   
ValuesViewr   	ItemsViewrP   rQ   r   re   r   r   r   r   r   rZ   r   r_   r   r   r   r   r      s$   
r   c               @   s   e Zd ZejejddddZejddddZdejejejdd	d
ZejdddZ	ejej
dddZddddZdejejejdddZejej
ddddZejejddddZejd ejej
ejejejf  f ejddddZdS )rN   N)r3   r4   r   c             C   s   |  ||g d S )N)setlist)r2   r3   r4   r   r   r   __setitem__M  s    zMultiDict.__setitem__)r3   r   c                s"    fdd| j D | _ | j = d S )Nc                s    g | ]\}}| kr||fqS r   r   )rL   r   r   )r3   r   r   rT   Q  s    z)MultiDict.__delitem__.<locals>.<listcomp>)r   r   )r2   r3   r   )r3   r   __delitem__P  s    zMultiDict.__delitem__)r3   defaultr   c                s$    fdd| j D | _ | j |S )Nc                s    g | ]\}}| kr||fqS r   r   )rL   r   r   )r3   r   r   rT   U  s    z!MultiDict.pop.<locals>.<listcomp>)r   r   rE   )r2   r3   r   r   )r3   r   rE   T  s    zMultiDict.pop)r   c                s,   | j  \ } fdd| jD | _ |fS )Nc                s    g | ]\}}| kr||fqS r   r   )rL   r   r   )r3   r   r   rT   Z  s    z%MultiDict.popitem.<locals>.<listcomp>)r   popitemr   )r2   r4   r   )r3   r   r   X  s    zMultiDict.popitemc                s"    fdd| j D }|   |S )Nc                s   g | ]\}}| kr|qS r   r   )rL   r   r   )r3   r   r   rT   ^  s    z%MultiDict.poplist.<locals>.<listcomp>)r   rE   )r2   r3   r   r   )r3   r   poplist]  s    
zMultiDict.poplistc             C   s   | j   | j  d S )N)r   clearr   )r2   r   r   r   r   b  s    
zMultiDict.clearc             C   s*   || kr"|| j |< | j||f | | S )N)r   r   append)r2   r3   r   r   r   r   
setdefaultf  s    
zMultiDict.setdefault)r3   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   )rL   r   r   )r3   r   r   rT   q  s    z%MultiDict.setlist.<locals>.<listcomp>c                s   g | ]} |fqS r   r   )rL   r4   )r3   r   r   rT   r  s    rB   )rE   r   r   )r2   r3   r   existing_itemsr   )r3   r   r   m  s
    zMultiDict.setlistc             C   s   | j ||f || j|< d S )N)r   r   r   )r2   r3   r4   r   r   r   r   u  s    zMultiDict.append)r   r@   r   c                s<   t ||  fdd| jD }|   | _| j  d S )Nc                s$   g | ]\}}|   kr||fqS r   )rV   )rL   r   r   )r4   r   r   rT     s    z$MultiDict.update.<locals>.<listcomp>)rN   r   rQ   r   rO   )r2   r   r@   r   r   )r4   r   rO   y  s    	
zMultiDict.update)N)N)r   r   r   r`   rb   r   r   rE   r   r   r   r   r   r   r   r   rd   r   rO   r   r   r   r   rN   L  s   rN   c                   sn   e Zd ZdZejdejejejej	ej	f  e
ef ej	dd fddZe
ddd	Ze
dd
dZ  ZS )QueryParamsz!
    An immutable multidict.
    r   N)r   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   zToo many arguments.r   T)rK   zlatin-1c             S   s    g | ]\}}t |t |fqS r   )r   )rL   r   r   r   r   r   rT     s    z(QueryParams.__init__.<locals>.<listcomp>c             S   s   i | ]\}}t |t |qS r   )r   )rL   r   r   r   r   r   rM     s    z(QueryParams.__init__.<locals>.<dictcomp>)r~   r,   rW   r   superr6   r   bytesr.   r   r   rP   )r2   r   r@   r4   )rI   r   r   r6     s    

zQueryParams.__init__)r   c             C   s
   t | jS )N)r   r   )r2   r   r   r   r[     s    zQueryParams.__str__c             C   s    | j j}t| }| d|dS )Nr\   r]   )rI   r   r   )r2   rr   r#   r   r   r   r_     s    zQueryParams.__repr__)r   r   r   ro   r`   rd   r   r   r   rb   r   r   r6   r[   r_   __classcell__r   r   )rI   r   r     s   r   c               @   s   e Zd ZdZddddejeje eje dddddZ	e
eje dd	d
Ze
edddZeddddZdeedddZe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.Optional[Headers])filer   r   r%   r   c            C   s"   || _ || _|| _|pt | _d S )N)r   r   r   Headersr%   )r2   r   r   r   r%   r   r   r   r6     s    zUploadFile.__init__)r   c             C   s   | j dd S )Nzcontent-type)r%   r-   )r2   r   r   r   content_type  s    zUploadFile.content_typec             C   s   t | jdd}| S )N_rolledT)getattrr   )r2   Zrolled_to_diskr   r   r   
_in_memory  s    zUploadFile._in_memory)datar   c                sH   | j d k	r|  j t|7  _ | jr0| j| nt| jj|I d H  d S )N)r   r~   r   r   writer   )r2   r   r   r   r   r     s
    
zUploadFile.writerB   )r   r   c                s&   | j r| j|S t| jj|I d H S )N)r   r   readr   )r2   r   r   r   r   r     s    zUploadFile.read)offsetr   c                s,   | j r| j| nt| jj|I d H  d S )N)r   r   seekr   )r2   r   r   r   r   r     s    zUploadFile.seekc                s(   | j r| j  nt| jjI d H  d S )N)r   r   closer   )r2   r   r   r   r     s    zUploadFile.close)rB   )r   r   r   ro   r`   BinaryIOra   r   r   r6   rc   r   re   r   r   r   r   r   r   r   r   r   r   r     s   	r   c            	       s|   e Zd ZdZejd ejeejeef f ej	ej
eejeef f  f ejeef dd fddZddddZ  ZS )	FormDatazN
    An immutable multidict, containing both file uploads and text input.
    N)r   r@   r   c                s   t  j|| d S )N)r   r6   )r2   r   r@   )rI   r   r   r6     s    	zFormData.__init__)r   c                s2   x,|   D ] \}}t|tr
| I d H  q
W d S )N)rQ   rW   r   r   )r2   r3   r4   r   r   r   r     s    
zFormData.close)r   r   r   ro   r`   rd   r   r   r   r   r   r6   r   r   r   r   )rI   r   r     s    r   c               @   sP  e Zd ZdZd"ejejeef  ejejej	e
e
f   ejejeejf  ddddZeejej	e
e
f  dddZeje dd	d
Zeje dddZejej	eef  dddZeeje dddZddddZeedddZejedddZejej dddZedddZejedddZedd d!ZdS )#r   z3
    An immutable, case-insensitive multidict.
    N)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 )zlatin-1)lowerencode)rL   r3   r4   r   r   r   rT     s   z$Headers.__init__.<locals>.<listcomp>z"Cannot set both "raw" and "scope".r%   )r   r,   rP   r|   )r2   r%   r   r   r   r   r   r6     s    zHeaders.__init__)r   c             C   s
   t | jS )N)r|   r   )r2   r   r   r   r     s    zHeaders.rawc             C   s   dd | j D S )Nc             S   s   g | ]\}}| d qS )zlatin-1)r.   )rL   r3   r4   r   r   r   rT     s    z Headers.keys.<locals>.<listcomp>)r   )r2   r   r   r   rV     s    zHeaders.keysc             C   s   dd | j D S )Nc             S   s   g | ]\}}| d qS )zlatin-1)r.   )rL   r3   r4   r   r   r   rT      s    z"Headers.values.<locals>.<listcomp>)r   )r2   r   r   r   r     s    zHeaders.valuesc             C   s   dd | j D S )Nc             S   s$   g | ]\}}| d | d fqS )zlatin-1)r.   )rL   r3   r4   r   r   r   rT   $  s   z!Headers.items.<locals>.<listcomp>)r   )r2   r   r   r   rP   "  s    zHeaders.items)r3   r   c                s"   |  d  fdd| jD S )Nzlatin-1c                s"   g | ]\}}| kr| d qS )zlatin-1)r.   )rL   r   r   )get_header_keyr   r   rT   +  s   z#Headers.getlist.<locals>.<listcomp>)r   r   r   )r2   r3   r   )r   r   r   (  s    
zHeaders.getlistMutableHeadersc             C   s   t | jd d  dS )N)r   )r   r   )r2   r   r   r   mutablecopy0  s    zHeaders.mutablecopyc             C   s@   |  d}x$| jD ]\}}||kr|dS qW t|d S )Nzlatin-1)r   r   r   r.   KeyError)r2   r3   r   
header_keyheader_valuer   r   r   r   3  s
    zHeaders.__getitem__c             C   s2   |  d}x| jD ]\}}||krdS qW dS )Nzlatin-1TF)r   r   r   )r2   r3   r   r   r   r   r   r   r   :  s
    zHeaders.__contains__c             C   s   t |  S )N)r   rV   )r2   r   r   r   r   A  s    zHeaders.__iter__c             C   s
   t | jS )N)r~   r   )r2   r   r   r   r   D  s    zHeaders.__len__)rY   r   c             C   s"   t |tsdS t| jt|jkS )NF)rW   r   r   r   )r2   rY   r   r   r   rZ   G  s    
zHeaders.__eq__c             C   sF   | j j}t|  }t|t| kr4| d|dS | d| jdS )Nr\   r]   z(raw=)rI   r   dictrP   r~   r   )r2   rr   Zas_dictr   r   r   r_   L  s
    zHeaders.__repr__)NNN)r   r   r   ro   r`   ra   r   r   r   r   r   MutableMappingrb   r6   rc   r   rV   r   rP   r   r   r   re   r   r   r   r   r   rZ   r_   r   r   r   r   r     s$     @ r   c               @   s   e Zd ZeeddddZeddddZejeef d dd	d
Zejeef d dddZ	e
ejejeef  dddZeeedddZejeef ddddZeeddddZeddddZdS )r   N)r3   r4   r   c       	      C   s   |  d}|d}g }x,t| jD ]\}\}}||kr(|| q(W x t|dd D ]}| j|= q\W |r|d }||f| j|< n| j||f dS )zs
        Set the header `key` to `value`, removing any duplicate entries.
        Retains insertion order.
        zlatin-1rD   Nr   )r   r   	enumerater   r   reversed)	r2   r3   r4   set_key	set_valueZfound_indexesidxr   r   r   r   r   r   U  s    
zMutableHeaders.__setitem__)r3   r   c             C   s^   |  d}g }x,t| jD ]\}\}}||kr|| qW xt|D ]}| j|= qJW dS )z*
        Remove the header `key`.
        zlatin-1N)r   r   r   r   r   r   )r2   r3   Zdel_keyZpop_indexesr   r   r   r   r   r   r   k  s    zMutableHeaders.__delitem__)rY   r   c             C   s,   t |tjstd|jj | | | S )NzExpected a mapping but got )rW   r`   r   	TypeErrorrI   r   rO   )r2   rY   r   r   r   __ior__y  s    
zMutableHeaders.__ior__c             C   s4   t |tjstd|jj |  }|| |S )NzExpected a mapping but got )rW   r`   r   r   rI   r   r   rO   )r2   rY   newr   r   r   __or__  s
    
zMutableHeaders.__or__)r   c             C   s   | j S )N)r   )r2   r   r   r   r     s    zMutableHeaders.rawc             C   sZ   |  d}|d}x,t| jD ]\}\}}||kr$|dS q$W | j||f |S )zo
        If the header `key` does not exist, then set it to `value`.
        Returns the header value.
        zlatin-1)r   r   r   r   r.   r   )r2   r3   r4   r   r   r   r   r   r   r   r   r     s    
zMutableHeaders.setdefaultc             C   s"   x|  D ]\}}|| |< q
W d S )N)rP   )r2   rY   r3   valr   r   r   rO     s    zMutableHeaders.updatec             C   s,   |  d}|d}| j||f dS )zD
        Append a header, preserving any duplicate entries.
        zlatin-1N)r   r   r   r   )r2   r3   r4   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   z, )r-   r   )r2   r   existingr   r   r   add_vary_header  s    
zMutableHeaders.add_vary_header)r   r   r   r   r   r   r`   r   r   r   rc   r   r   r   r   r   rO   r   r   r   r   r   r   r   T  s    r   c                   s   e Zd ZU dZejeejf ed< dej	ejeejf  d fddZ
ejejdddd	Zejejd
ddZej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`.
    _stateN)statec                s   |d kri }t  d| d S )Nr   )r   __setattr__)r2   r   )rI   r   r   r6     s    zState.__init__)r3   r4   r   c             C   s   || j |< d S )N)r   )r2   r3   r4   r   r   r   r     s    zState.__setattr__)r3   r   c             C   s<   y
| j | S  tk
r6   d}t|| jj|Y nX d S )Nz!'{}' object has no attribute '{}')r   r   AttributeErrorformatrI   r   )r2   r3   messager   r   r   __getattr__  s
    
zState.__getattr__c             C   s   | j |= d S )N)r   )r2   r3   r   r   r   __delattr__  s    zState.__delattr__)N)r   r   r   ro   r`   r   r   rb   r   ra   r6   r   r   r   r   r   r   )rI   r   r     s   
&r   )"r`   collections.abcr   r   urllib.parser   r   r   r   Zstarlette.concurrencyr   Zstarlette.typesr	   
NamedTupler
   TypeVarr   r   r   r   rf   rp   rt   r   r   rb   rN   r   r   rd   r   r   r   r   r   r   r   r   <module>   s*   
 N<(7"WW