o
    Zh+                     @   s   d 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 ddlZddlmZmZ ddlmZmZ erBddlZdd	 Zdd
dZG dd deZG dd deZdS )z}
In addition to the remote_call mechanism implemented in CommBase:
 - Implements _wait_reply, so blocking calls can be made.
    N)get_ipython)	localhost)ioloop)CommBase	CommError)TimeoutErrorPY2c                  C   sB   t   } | t jt jd | t df |  d }|   |S )z&Find a free port on the local machine.s           r      )socket
setsockopt
SOL_SOCKET	SO_LINGERbindr   getsocknameclose)sockport r   X/var/www/html/lang_env/lib/python3.10/site-packages/spyder_kernels/comms/frontendcomm.pyget_free_port   s   r   c                 C   s*   t  jj stdt  jj| d|dS )zf
    Send a request to the frontend.

    If blocking is True, The return value will be returned.
    z%Can't make a request to a closed commF)blocking	broadcasttimeout)r   kernelZfrontend_commZis_openr   Zfrontend_call)r   r   r   r   r   frontend_request)   s   r   c                       s   e Zd ZdZ fddZd% fdd	Z fddZd	d
 Zdd Zdd Z			d& fdd	Z
d%ddZd'ddZdd Z fddZdd Zdd Zdd  Z fd!d"Z fd#d$Z  ZS )(FrontendCommz(Mixin to implement the spyder_shell_api.c                    s   t t  |_jjjj d _	dj
 t _jjrwt _jtj_dj_t _jjjj_ttdrPdj_t _tjjd_j  t syjjj!  fdd}|jj_!d S d S d S )N_send_comm_configi  ZROUTER_HANDOVERr	   )targetc                      s         dS )zClose comm_socket_thread.N)close_threadr   Zparent_closeselfr   r   r   b   s   
z$FrontendComm.__init__.<locals>.close)"superr   __init__r   Zcomm_managerZregister_targetZ
_comm_name
_comm_open	comm_portZregister_call_handlerr   	threadingRLock	comm_lockparentzmqContextcontextr
   ZROUTERcomm_socketZlingerr   Z_bind_sockethasattrZrouter_handoverEventcomm_thread_closeThreadpoll_threadcomm_socket_threadstartr   r   )r    r   r   	__class__r   r   r"   ;   s:   





zFrontendComm.__init__Nc                    s:   | j  tt| |W  d   S 1 sw   Y  dS )z)Close the comm and notify the other side.N)r'   r!   r   r   )r    comm_idr4   r   r   r   i   s   $zFrontendComm.closec                    s@   | j  tt| j|i |W  d   S 1 sw   Y  dS )z*Publish custom messages to the other side.N)r'   r!   r   _send_message)r    argskwargsr4   r   r   r7   n   s   $zFrontendComm._send_messagec                 C   s,   | j   | j  | j  | j  dS )Close comm.N)r/   setr,   r   r+   termr2   joinr    r   r   r   r   s   s   


zFrontendComm.close_threadc                 C   s4   t st   | j s|   | j rdS dS )z"Receive messages from comm socket.N)r   r   ZIOLoopZ
initializer/   is_setpoll_oner>   r   r   r   r1   z   s
   
zFrontendComm.poll_threadc              	   C   s  d}| j jr| j jd }z| j j| jd\}}W n tjjy%   Y dS  ty7   | j j	j
ddd Y dS w |d d }|dkrN| j  | | dS | j j|d}zze|du r|| j j	
d	| W W tj  tj  |rz|tj dS dS tr|||| W W tj  tj  |r|tj dS dS ddl}t|d
dr||r||||| n|||| W n ty   | j j	jddd Y nw W tj  tj  |r|tj dS dS tj  tj  |r|tj w w )z%Receive one message from comm socket.Nr   zInvalid Message:T)exc_infoheadermsg_typeshutdown_requestzUnknown message type: %rrunFzException in message handler:)r   Zshell_streamssessionrecvr,   r)   errorZContextTerminated	Exceptionlogwarningr/   r;   _comm_closeZshell_handlersgetsysstdoutflushstderrPOLLOUTr   asynciogetattriscoroutinefunctionrE   )r    Z
out_streamidentmsgrC   handlerrS   r   r   r   r@      sr   










zFrontendComm.poll_oneFc                    s   t t| j||||dS )zGet a handler for remote calls.)r   r6   callbackr   )r!   r   remote_call)r    r6   r   rY   r   r4   r   r   rZ      s   
zFrontendComm.remote_callc                 C   s`   | rdS t   }| s.|durt   || krdS t | ju r&|   nt d | rdS )z6Wait until condition is met. Returns False if timeout.TNFg{Gz?)timer%   current_threadr2   r@   sleep)r    	conditionr   Zt_startr   r   r   
wait_until   s   

	zFrontendComm.wait_untilTc                    sB    fdd} |s|r ||d dS td|dS )z-Wait until the frontend replies to a request.c                      s
    j v S )zThe reply is there!)Z_reply_inboxr   call_idr    r   r   reply_received   s   
z0FrontendComm._wait_reply.<locals>.reply_receivedFNz%Timeout while waiting for '{}' reply.)r_   _wait_replyr   format)r    ra   	call_namer   retryrb   r   r`   r   rc      s   
zFrontendComm._wait_replyc                 C   s4   |j | _| | | |d d d  |   dS )z%
        A new comm is open!
        contentdataZpickle_protocolN)r6   Zcalling_comm_id_register_comm_set_pickle_protocolr   )r    commrW   r   r   r   r#      s   
zFrontendComm._comm_openc                    s   | j |d< tt| |S )zA message is about to be sentr$   )r$   r!   r   on_outgoing_call)r    Z	call_dictr4   r   r   rl      s   
zFrontendComm.on_outgoing_callc                 C   s$   |   | j |   tj dS )z%Send the comm config to the frontend.N)rZ   Z_set_comm_portr$   rj   pickleHIGHEST_PROTOCOLr>   r   r   r   r      s   zFrontendComm._send_comm_configc                 C   s   |d d }|  | dS )r:   rg   r6   N)r   )r    rW   r6   r   r   r   rL      s   zFrontendComm._comm_closec                 C   s   |   | dS )zK
        Send an async error back to the frontend to be displayed.
        N)rZ   _async_error)r    Zerror_wrapperr   r   r   ro      s   zFrontendComm._async_errorc                    s&    fdd}| _ tt|   dS )z3
        Remove side effect ipykernel has.
        c                    s    j r
  |  dS dS )zHandle a comm_msg messageN)_msg_callback)rW   rk   r   r   
handle_msg  s   z/FrontendComm._register_comm.<locals>.handle_msgN)rr   r!   r   ri   )r    rk   rr   r4   rq   r   ri      s   zFrontendComm._register_commc           	   	      s   | j E tj}tj}|j}|j}trt nt }t	||||_t	||||_zt
t| |||W ||_||_W  d   S ||_||_w 1 sKw   Y  dS )z/Call the callback function for the remote call.N)r'   rN   rO   rQ   writer   thread	get_identr%   WriteWrapperr!   r   _remote_callback)	r    re   Z	call_argsZcall_kwargsZcurrent_stdoutZcurrent_stderrZsaved_stdout_writeZsaved_stderr_write	thread_idr4   r   r   rw     s,   
zFrontendComm._remote_callbackN)NFNN)T)__name__
__module____qualname____doc__r"   r   r7   r   r1   r@   rZ   r_   rc   r#   rl   r   rL   ro   ri   rw   __classcell__r   r   r4   r   r   8   s(    .4
	
	r   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	rv   z*Wrapper to warn user when text is printed.c                 C   s   || _ || _|| _d| _d S )NF)_write_name
_thread_id_warning_shown)r    rs   namerx   r   r   r   r"     s   
zWriteWrapper.__init__c                    s   ddg}t  fdd|D S )z7Determine if a message is benign in order to filter it.DeprecationWarningzIOStream.flush timed outc                    s   g | ]}| v qS r   r   ).0rW   messager   r   
<listcomp>/  s    z2WriteWrapper.is_benign_message.<locals>.<listcomp>)any)r    r   Zbenign_messagesr   r   r   is_benign_message%  s   zWriteWrapper.is_benign_messagec                 C   sr   t rt nt }| j|kr| |S | |s7| js2d| _t| j	dkr2| dt| j	 d  | |S dS )zPrint warning once.Tz'show_mpl_backend_errors'z
Output from spyder call z:
N)
r   rt   ru   r%   r   r   r   r   reprr   )r    stringrx   r   r   r   __call__1  s   



zWriteWrapper.__call__N)rz   r{   r|   r}   r"   r   r   r   r   r   r   rv     s
    rv   ry   )r}   rm   r
   rN   r%   r[   ZIPython.core.getipythonr   Zjupyter_client.localinterfacesr   tornador   r)   Zspyder_kernels.comms.commbaser   r   Zspyder_kernels.py3compatr   r   rt   r   r   r   objectrv   r   r   r   r   <module>   s&   

 e