o
     dp                     @   s  d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZd dl	m
Z
 d dlmZ d dlmZmZ d dlZd dlZ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mZ d dlmZ ejd	krpd d
lm Z  nd d
l!m Z  ej"g ej#ej$j% f Z&ej"eegej'd f Z(ej"ege(f Z)ej"eeegej'd f Z*ej+e,ej-e,ej.e, f f Z/dej-e)e*f de0fddZ1G dd dZ2G dd de Z3G dd de4Z5G dd dZ6G dd dej7Z8G dd dej9Z:dS )    N)Future)GeneratorType)unquoteurljoin)StapledObjectStream)is_async_callable)ASGIAppMessageReceiveScopeSend)WebSocketDisconnect)      )	TypedDictappreturnc                 C   s   t | r
t| dS t| S )N	__await__)inspectisclasshasattrr   r    r   ?/usr/local/lib/python3.10/dist-packages/starlette/testclient.py	_is_asgi3(   s   

r   c                   @   s<   e Zd ZdZdeddfddZdeded	eddfd
dZ	dS )
_WrapASGI2z7
    Provide an ASGI3 interface onto an ASGI2 app.
    r   r   Nc                 C   
   || _ d S Nr   )selfr   r   r   r   __init__3      
z_WrapASGI2.__init__scopereceivesendc                    s    |  |}|||I d H  d S r   r   )r   r!   r"   r#   instancer   r   r   __call__6   s   
z_WrapASGI2.__call__)
__name__
__module____qualname____doc__ASGI2Appr   r   r
   r   r%   r   r   r   r   r   .   s    r   c                   @   s*   e Zd ZU eed< ejeejf ed< dS )_AsyncBackendbackendbackend_optionsN)r&   r'   r(   str__annotations__typingDictAnyr   r   r   r   r+   ;   s   
 r+   c                   @   s   e Zd ZdddZdS )_UpgradesessionWebSocketTestSessionr   Nc                 C   r   r   )r4   )r   r4   r   r   r   r   A   r    z_Upgrade.__init__)r4   r5   r   N)r&   r'   r(   r   r   r   r   r   r3   @   s    r3   c                   @   s$  e Zd ZdedededdfddZd-dd	Zd
ej	ddfddZ
d.ddZdefddZdeddfddZdeddfddZdeddfddZdeddfddZdeddfddZd/dej	deddfdd Zd0d"eddfd#d$Zdefd%d&Zdefd'd(Zdefd)d*Zd/dedej	fd+d,ZdS )1r5   r   r!   portal_factoryr   Nc                 C   s6   || _ || _d | _|| _t | _t | _d | _d S r   )	r   r!   accepted_subprotocolr6   queueQueue_receive_queue_send_queueextra_headers)r   r   r!   r6   r   r   r   r   F   s   


zWebSocketTestSession.__init__c                 C   s   t  | _| j|  | _z| j| j}| ddi | 	 }| 
| W n ty4   | j   w |dd | _|dd | _| S )Ntypezwebsocket.connectsubprotocolheaders)
contextlib	ExitStack
exit_stackenter_contextr6   portalstart_task_soon_runr#   r"   _raise_on_close	Exceptionclosegetr7   r<   )r   _messager   r   r   	__enter__T   s   

zWebSocketTestSession.__enter__argsc                 G   sZ   z|  d W | j   n| j   w | j s+| j }t|tr$|| j rd S d S )N  )rI   rB   r;   emptyrJ   
isinstanceBaseException)r   rN   rL   r   r   r   __exit__d   s   


zWebSocketTestSession.__exit__c              
      sV   | j }| j}| j}z| |||I dH  W dS  ty* } z| j|  d}~ww )zE
        The sub-thread in which the websocket session runs.
        N)r!   _asgi_receive
_asgi_sendr   rR   r;   put)r   r!   r"   r#   excr   r   r   rF   n   s   zWebSocketTestSession._runc                    s0   | j  rtdI d H  | j  s| j  S )Nr   )r:   rP   anyiosleeprJ   r   r   r   r   rT   {   s
   


z"WebSocketTestSession._asgi_receiverL   c                    s   | j | d S r   )r;   rV   r   rL   r   r   r   rU      s   zWebSocketTestSession._asgi_sendc                 C   s*   |d dkrt |dd|ddd S )Nr=   zwebsocket.closecoderO   reason )r   rJ   r[   r   r   r   rG      s
   z$WebSocketTestSession._raise_on_closec                 C   s   | j | d S r   )r:   rV   r[   r   r   r   r#      s   zWebSocketTestSession.senddatac                 C      |  d|d d S )Nwebsocket.receiver=   textr#   r   r_   r   r   r   	send_text      zWebSocketTestSession.send_textc                 C   r`   )Nra   r=   bytesrd   re   r   r   r   
send_bytes   rg   zWebSocketTestSession.send_bytesrc   modec                 C   sL   |dv sJ t |}|dkr| d|d d S | d|dd d S )Nrc   binaryrc   ra   rb   utf-8rh   )jsondumpsr#   encode)r   r_   rk   rc   r   r   r   	send_json   s
   
zWebSocketTestSession.send_jsonrO   r\   c                 C   r`   )Nzwebsocket.disconnect)r=   r\   rd   )r   r\   r   r   r   rI      rg   zWebSocketTestSession.closec                 C   s   | j  }t|tr||S r   )r;   rJ   rQ   rR   r[   r   r   r   r"      s   

zWebSocketTestSession.receivec                 C      |   }| | |d S )Nrc   r"   rG   r[   r   r   r   receive_text      
z!WebSocketTestSession.receive_textc                 C   rs   )Nri   rt   r[   r   r   r   receive_bytes   rv   z"WebSocketTestSession.receive_bytesc                 C   sH   |dv sJ |   }| | |dkr|d }n|d d}t|S )Nrl   rc   ri   rn   )r"   rG   decodero   loads)r   rk   rL   rc   r   r   r   receive_json   s   


z!WebSocketTestSession.receive_json)r   r5   r   N)rc   )rO   )r&   r'   r(   ASGI3Appr   _PortalFactoryTyper   rM   r0   r2   rS   rF   r	   rT   rU   rG   r#   r.   rf   ri   rj   rr   intrI   r"   ru   rw   rz   r   r   r   r   r5   E   s2    



r5   c                   @   sF   e Zd Z		ddededededdf
d	d
Zdej	dej
fddZdS )_TestClientTransportTr^   r   r6   raise_server_exceptions	root_pathr   Nc                 C   s   || _ || _|| _|| _d S r   )r   r   r   r6   )r   r   r6   r   r   r   r   r   r      s   
z_TestClientTransport.__init__requestc                    s  j j}j jjdd}j j}j j}j jjdd}ddddd| }d|v r6|dd\}}	t|	}
n|}|}
dj	v rBg }n|
|krNd	|
 fg}nd	| d|
 
 fg}|d
d j	 D 7 }|dv rj	dd }|d u rxg }n
dd |dD }dt||| j||
 |ddg||
g|d
}t| j|| j}t|ddjt||| j||
 |ddg||
gdi id}dddt id d  dtffdd}dtdd f fdd}z&|  }|tj|| j||| W d    n	1 sw   Y  W n ty' } z| jr|W Y d }~nd }~ww | jr4s3J d ns?d!g t d"td  d< tjd$i d#i}d ura|_  |_!|S )%Nascii)encodingP   i  )httpwshttpswss:   hosts   hostc                 S   s$   g | ]\}}|   | fqS r   )lowerrq   .0keyvaluer   r   r   
<listcomp>   s    z7_TestClientTransport.handle_request.<locals>.<listcomp>>   r   r   sec-websocket-protocolc                 S   s   g | ]}|  qS r   )strip)r   r   r   r   r   r      s    ,	websocket
testclientiP  )
r=   pathraw_pathr   schemequery_stringr?   clientserversubprotocolsr   z1.1http.response.debug)r=   http_versionmethodr   r   r   r   r   r?   r   r   
extensionsFstreamr   c                     s   r  s I d H  ddiS   } t| tr!| d}n5| d u r(d}n.t| trTz| d }t|tr=|d}d|ddW S  tyS   dddd Y S w | }dd|dS )	Nr=   zhttp.disconnectrn       zhttp.requestT)r=   body	more_body)r=   r   )	is_setwaitreadrQ   r.   rq   r   r#   StopIteration)r   
body_byteschunk)r   request_completeresponse_completer   r   r"     s.   





z4_TestClientTransport.handle_request.<locals>.receiverL   c                    s   | d dkr$rJ d| d d< dd |  dg D d< d	d S | d d
kras0J d r8J d|  dd}|  dd}jdkrPd | |s_d d   d S d S | d dkru| d d | d d  d S d S )Nr=   zhttp.response.startz1Received multiple "http.response.start" messages.statusstatus_codec                 S   s    g | ]\}}|  |  fqS r   )rx   r   r   r   r   r   4  s    zE_TestClientTransport.handle_request.<locals>.send.<locals>.<listcomp>r?   Tzhttp.response.bodyz<Received "http.response.body" without "http.response.start".z7Received "http.response.body" after response completed.r   r   r   FHEADr   r   r   infotemplatecontext)rJ   r   r   writeseekset)rL   r   r   )r   
raw_kwargsr   r   response_startedr   r   r   r#   ,  s@   


z1_TestClientTransport.handle_request.<locals>.sendz(TestClient did not receive any response.i  )r   r?   r   r   r   )"urlr   netlocrx   r   r   querysplitr~   r?   rq   itemsrJ   r   r   r5   r   r6   r3   r   ioBytesIOr	   callrX   EventrR   r   httpx
ByteStreamr   Responser   r   )r   r   r   r   r   r   r   default_portr   port_stringportr?   r>   r   r!   r4   r"   r#   rD   rW   responser   )r   r   r   r   r   r   r   r   handle_request   s   

 

z#_TestClientTransport.handle_request)Tr^   )r&   r'   r(   r|   r}   boolr.   r   r   Requestr   r   r   r   r   r   r      s    
r   c                        s  e Zd ZU dZded< dZejej	j
 ed< 								dFd
edededededejejeejf  dejjdejeef ddf fddZejdejej	j
ddf fddZdeje deje dejeejjf fddZdddddddejjddejjdddedejjdejejj deje d ejejj  d!ejd"ejejj! dejejj" dejejj d#ejejj#ejjf deje deje d$ejejj$ejjf d%ejejeejf  dej%f fd&d'Z&dddejjddejjdd(dejjd"ejejj! dejejj" dejejj d#ejejj#ejjf deje deje d$ejejj$ejjf d%ejejeejf  dej%f fd)d*Z'dddejjddejjdd(dejjd"ejejj! dejejj" dejejj d#ejejj#ejjf deje deje d$ejejj$ejjf d%ejejeejf  dej%f fd+d,Z(dddejjddejjdd(dejjd"ejejj! dejejj" dejejj d#ejejj#ejjf deje deje d$ejejj$ejjf d%ejejeejf  dej%f fd-d.Z)dddddddejjddejjdddejjdejejj deje d ejejj  d!ejd"ejejj! dejejj" dejejj d#ejejj#ejjf deje deje d$ejejj$ejjf d%ejejeejf  dej%f fd/d0Z*dddddddejjddejjdddejjdejejj deje d ejejj  d!ejd"ejejj! dejejj" dejejj d#ejejj#ejjf deje deje d$ejejj$ejjf d%ejejeejf  dej%f fd1d2Z+dddddddejjddejjdddejjdejejj deje d ejejj  d!ejd"ejejj! dejejj" dejejj d#ejejj#ejjf deje deje d$ejejj$ejjf d%ejejeejf  dej%f fd3d4Z,dddejjddejjdd(dejjd"ejejj! dejejj" dejejj d#ejejj#ejjf deje deje d$ejejj$ejjf d%ejejeejf  dej%f fd5d6Z-	dGded7ej.e d8ejdejf fd9d:Z/dHd;d<Z0d=ejddfd>d?Z1dId@dAZ2dIdBdCZ3dIdDdEZ4  Z5S )J
TestClientFzFuture[None]taskNrD   http://testserverTr^   asyncior   base_urlr   r   r,   r-   cookiesr?   r   c	                    s   t ||pi d| _t|rtt|}|}	n
tt|}t|}	|	| _t	| j| j
||d}
|d u r3i }|dd t j| j|||
d|d d S )N)r,   r-   )r6   r   r   z
user-agentr   T)r   r   r?   	transportfollow_redirectsr   )r+   async_backendr   r0   castr|   r*   r   r   r   _portal_factory
setdefaultsuperr   )r   r   r   r   r   r,   r-   r   r?   asgi_appr   	__class__r   r   r   j  s4   
zTestClient.__init__c                 c   sX    | j d ur| j V  d S tjjdi | j}|V  W d    d S 1 s%w   Y  d S )Nr   )rD   rX   from_threadstart_blocking_portalr   )r   rD   r   r   r   r     s   

"zTestClient._portal_factoryr   allow_redirectsc                 C   sP   t jj}|d urd}t|t |}|d ur|}|S |d ur&|d ur&td|S )NzMThe `allow_redirects` argument is deprecated. Use `follow_redirects` instead.z9Cannot use both `allow_redirects` and `follow_redirects`.)r   _clientUSE_CLIENT_DEFAULTwarningswarnDeprecationWarningRuntimeError)r   r   r   redirectrL   r   r   r   _choose_redirect_arg  s   zTestClient._choose_redirect_arg)contentr_   filesro   paramsr?   r   authr   r   timeoutr   r   r   r   r_   r   ro   r   r   r   r   c                   s>   | j |}| ||}t j|||||||||	|
|||dS N)r   r_   r   ro   r   r?   r   r   r   r   r   )r   joinr   r   r   )r   r   r   r   r_   r   ro   r   r?   r   r   r   r   r   r   r   r   r   r   r     s"   zTestClient.request)r   r?   r   r   r   r   r   r   c             
      (   |  ||}
t j||||||
||	dS N)r   r?   r   r   r   r   r   )r   r   rJ   r   r   r   r?   r   r   r   r   r   r   r   r   r   r   rJ        zTestClient.getc             
      r   r   )r   r   optionsr   r   r   r   r     r   zTestClient.optionsc             
      r   r   )r   r   headr   r   r   r   r     r   zTestClient.headc                   0   |  |
|}t j|||||||||	|||dS r   )r   r   postr   r   r   r_   r   ro   r   r?   r   r   r   r   r   r   r   r   r   r   r   1     zTestClient.postc                   r   r   )r   r   rV   r   r   r   r   rV   V  r   zTestClient.putc                   r   r   )r   r   patchr   r   r   r   r   {  r   zTestClient.patchc             
      r   r   )r   r   deleter   r   r   r   r     r   zTestClient.deleter   kwargsc              
      s   t d|}|di }|dd |dd |dd |d ur*|d	d
| ||d< zt jd|fi | W td tyT } z
|j}W Y d }~|S d }~ww )Nzws://testserverr?   
connectionupgradezsec-websocket-keyztestserver==zsec-websocket-version13r   z, GETzExpected WebSocket upgrade)	r   rJ   r   r   r   r   r3   r4   r   )r   r   r   r   r?   rW   r4   r   r   r   websocket_connect  s    
zTestClient.websocket_connectc                    s   t  R}|tjjdi j _ |jdfdd}t	t
tj _t	t
tj _ j_ j |jd fdd}| _W d    S 1 sYw   Y  S )Nr   c                      s
   d  _ d S r   )rD   r   rZ   r   r   reset_portal  s   
z*TestClient.__enter__.<locals>.reset_portalc                      s     j d S r   )r   wait_shutdownr   rD   r   r   r   r    s   z+TestClient.__enter__.<locals>.wait_shutdownr   r{   )r@   rA   rC   rX   r   r   r   rD   callbackr   create_memory_object_streammathinfstream_sendstream_receiverE   lifespanr   r   wait_startuppop_allrB   )r   stackr  r  r   r  r   rM     s*   




zTestClient.__enter__rN   c                 G   s   | j   d S r   )rB   rI   )r   rN   r   r   r   rS     s   zTestClient.__exit__c              	      sT   ddi}z|  || jj| jjI d H  W | jd I d H  d S | jd I d H  w )Nr=   r
  )r   r	  r"   r  r#   )r   r!   r   r   r   r
    s
   *zTestClient.lifespanc                    sh    j ddiI d H  dtjf fdd}| I d H }|d dv s$J |d dkr2| I d H  d S d S )Nr=   zlifespan.startupr   c                     (    j  I d H } | d u r j  | S r   r  r"   r   resultrL   rZ   r   r   r"     
   
z(TestClient.wait_startup.<locals>.receive)zlifespan.startup.completelifespan.startup.failedr  )r	  r#   r0   r2   r   r"   rL   r   rZ   r   r    s   zTestClient.wait_startupc              	      s   dt jf fdd} j4 I d H <  jddiI d H  | I d H }|d dv s,J |d dkrC| I d H  W d   I d H  d S W d   I d H  d S 1 I d H sTw   Y  d S )Nr   c                     r  r   r  r  rZ   r   r   r"     r  z)TestClient.wait_shutdown.<locals>.receiver=   zlifespan.shutdown)zlifespan.shutdown.completelifespan.shutdown.failedr  )r0   r2   r  r	  r#   r  r   rZ   r   r    s   .zTestClient.wait_shutdown)r   Tr^   r   NNNr   )r   r   r{   )6r&   r'   r(   __test__r/   rD   r0   OptionalrX   abcBlockingPortalr   r.   r   r1   r2   r   r   CookieTypesr   r@   contextmanager	Generatorr   UnionUseClientDefaultr   r   _typesURLTypesRequestContent_RequestDataRequestFilesQueryParamTypesHeaderTypes	AuthTypesTimeoutTypesr   r   rJ   r   r   r   rV   r   r   Sequencer   rM   rS   r
  r  r  __classcell__r   r   r   r   r   e  s  
 	
' 	
	
,
!
!
!	
)	
)	
)



r   );r@   r   r   ro   r  r8   sysr0   r   concurrent.futuresr   typesr   urllib.parser   r   rX   anyio.from_threadr   anyio.streams.stapledr   starlette._utilsr   starlette.typesr   r	   r
   r   r   starlette.websocketsr   version_infor   typing_extensionsCallableContextManagerr  r  r}   	AwaitableASGIInstancer*   r|   Mappingr.   r  Iterabler"  r   r   r   r+   rH   r3   r5   BaseTransportr   Clientr   r   r   r   r   <module>   sJ    
s .