
    ` Ie+                         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rddlZd Zdd	Z G d
 de      Z G d de      Zy)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                     t        j                          } | j                  t         j                  t         j                  d       | j	                  t               df       | j                         d   }| j                          |S )z&Find a free port on the local machine.s           r      )socket
setsockopt
SOL_SOCKET	SO_LINGERbindr   getsocknameclose)sockports     C/usr/lib/python3/dist-packages/spyder_kernels/comms/frontendcomm.pyget_free_portr      s]    ==?DOOF%%v'7'7CIIy{Aa DJJLK    c                     t               j                  j                  j                         st	        d      t               j                  j                  | 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   kernelfrontend_commis_openr   frontend_call)r   r   s     r   frontend_requestr    )   sS     =--557?@@=-- .  r   c                        e Zd ZdZ fdZd fd	Z fdZd Zd Zd Z		 	 d fd	Z
dd	Zdd
Zd Z fdZd Zd Zd Z fdZ fdZ xZS )FrontendCommz(Mixin to implement the spyder_shell_api.c                 &    t         t                   | _         j                  j                  j                   j                   j                         d  _         j                  d j                         t        j                          _         j                  j                  rht        j                           _         j"                  j%                  t        j&                         _        d j(                  _        t-                _         j                  j                  j/                   j(                   j                         _        t1        t        d      rd j(                  _        t        j4                          _        t        j8                   j:                         _         j<                  j?                          t@        sB j                  j                  jB                   fd}| j                  j                  _!        y y y )N_send_comm_configi  ROUTER_HANDOVERr   )targetc                  4    j                                    y)zClose comm_socket_thread.N)close_thread)parent_closeselfs   r   r   z$FrontendComm.__init__.<locals>.closeb   s    %%' Nr   )"superr"   __init__r   comm_managerregister_target
_comm_name
_comm_open	comm_portregister_call_handlerr$   	threadingRLock	comm_lockparentzmqContextcontextr   ROUTERcomm_socketlingerr   _bind_sockethasattrrouter_handoverEventcomm_thread_closeThreadpoll_threadcomm_socket_threadstartr	   r   )r*   r   r   r)   	__class__s   `  @r   r,   zFrontendComm.__init__;   s|   lD*,   00OOT__	. ""#6#'#9#9	; #* ;;;;=DL#||223::>D&*D#*_DN![[//<<  $..2DNs-. 45  0%.__%6D"&/&6&6d>N>N&OD###))+ #{{1177#
 ,1""( + r   c                 n    | j                   5  t        t        |   |      cddd       S # 1 sw Y   yxY w)z)Close the comm and notify the other side.N)r5   r+   r"   r   )r*   comm_idrF   s     r   r   zFrontendComm.closei   s.    ^^ 	<t27;	< 	< 	<   +4c                 n    | j                   5  t        t        |   |i |cddd       S # 1 sw Y   yxY w)z*Publish custom messages to the other side.N)r5   r+   r"   _send_message)r*   argskwargsrF   s      r   rK   zFrontendComm._send_messagen   s7    ^^ 	Lt:DKFK	L 	L 	LrI   c                     | j                   j                          | j                  j                          | j                  j                          | j                  j                          y)Close comm.N)rA   setr;   r   r9   termrD   joinr*   s    r   r(   zFrontendComm.close_threads   sH    ""$ $$&r   c                     t         s"t        j                         j                          | j                  j                         s,| j                          | j                  j                         s+yy)z"Receive messages from comm socket.N)r	   r   IOLoop
initializerA   is_setpoll_onerS   s    r   rC   zFrontendComm.poll_threadz   sF    MMO&&(((//1MMO ((//1r   c                    d}| j                   j                  r| j                   j                  d   }	 | j                   j                  j                  | j                  d      \  }}|d   d   }|dk(  r,| j                  j                          | j                  |       y| j                   j                  j                  |d      }	 || j                   j                  j                  d	|       	 t         j"                  j%                          t         j&                  j%                          |r |j%                  t
        j(                         yyt*        rj ||||       	 t         j"                  j%                          t         j&                  j%                          |r |j%                  t
        j(                         yyddl}t/        |d
d      r+|j1                  |      r|j3                   ||||             n
 ||||       t         j"                  j%                          t         j&                  j%                          |r |j%                  t
        j(                         yy# t
        j                  j                  $ r Y yt        $ r* | j                   j                  j                  dd       Y yw xY w# t        $ r* | j                   j                  j                  dd       Y w xY w# t         j"                  j%                          t         j&                  j%                          |r |j%                  t
        j(                         w w xY 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   shell_streamssessionrecvr;   r7   errorContextTerminated	ExceptionlogwarningrA   rP   _comm_closeshell_handlersgetsysstdoutflushstderrPOLLOUTr	   asynciogetattriscoroutinefunctionr^   )r*   
out_streamidentmsgr\   handlerro   s          r   rX   zFrontendComm.poll_one   s   
;;$$ 2215J	,,11$2B2BAFJE3 x=,))""&&(S!++,,004@	.''(BHM* JJJJ  - / 
E3/$ JJJJ  - ' .//8GJs;< 
E3/
 JJJJ  - Q yy** 	 	KKOO##$6#F	>  	@KKOO!!/$ " @	@ JJJJ  - sI   3I# (J7 J7 >AJ7 #J4/J43J470K*'K- )K**K- -A Mc                 2    t         t        |   ||||      S )zGet a handler for remote calls.)r   rH   callbackr   )r+   r"   remote_call)r*   rH   r   rw   r   rF   s        r   rx   zFrontendComm.remote_call   s*     \44	 5  	r   c                      |       ryt        j                          } |       sk|t        j                          ||z   kD  ryt        j                         | j                  u r| j	                          nt        j
                  d        |       sky)z6Wait until condition is met. Returns False if timeout.TFg{Gz?)timer3   current_threadrD   rX   sleep)r*   	conditionr   t_starts       r   
wait_untilzFrontendComm.wait_until   so    ;))++"tyy{Ww5F'F'')T-D-DD 

4  + r   c                       fd} j                  |      s1|r j                  ||d       yt        dj                  |            y)z-Wait until the frontend replies to a request.c                        j                   v S )zThe reply is there!)_reply_inbox)call_idr*   s   r   reply_receivedz0FrontendComm._wait_reply.<locals>.reply_received   s    d////r   FNz%Timeout while waiting for '{}' reply.)r   _wait_replyr   format)r*   r   	call_namer   retryr   s   ``    r   r   zFrontendComm._wait_reply   sS    	0 ~.  )WeD7>>   	 /r   c                     |j                   | _        | j                  |       | j                  |d   d   d          | j	                          y)z%
        A new comm is open!
        contentdatapickle_protocolN)rH   calling_comm_id_register_comm_set_pickle_protocolr$   )r*   commrt   s      r   r0   zFrontendComm._comm_open   sG      $||D!!!#i."89J"KL r   c                 H    | j                   |d<   t        t        |   |      S )zA message is about to be sentr1   )r1   r+   r"   on_outgoing_call)r*   	call_dictrF   s     r   r   zFrontendComm.on_outgoing_call   s#    !%	+\49)DDr   c                     | j                         j                  | j                         | j                         j                  t        j
                         y)z%Send the comm config to the frontend.N)rx   _set_comm_portr1   r   pickleHIGHEST_PROTOCOLrS   s    r   r$   zFrontendComm._send_comm_config   s:    ))$..9//0G0GHr   c                 6    |d   d   }| j                  |       y)rO   r   rH   N)r   )r*   rt   rH   s      r   rg   zFrontendComm._comm_close   s    i.+ 	

7r   c                 B    | j                         j                  |       y)zK
        Send an async error back to the frontend to be displayed.
        N)rx   _async_error)r*   error_wrappers     r   r   zFrontendComm._async_error   s     	''6r   c                 F    fd}|_         t        t        |          y)z3
        Remove side effect ipykernel has.
        c                 B    j                   rj                  |        yy)zHandle a comm_msg messageN)_msg_callback)rt   r   s    r   
handle_msgz/FrontendComm._register_comm.<locals>.handle_msg  s    !!""3' "r   N)r   r+   r"   r   )r*   r   r   rF   s    ` r   r   zFrontendComm._register_comm   s     	( %lD06r   c                    | j                   5  t        j                  }t        j                  }|j                  }|j                  }t
        rt        j                         nt        j                         }t        |||      |_        t        |||      |_        	 t        t        | 3  |||      ||_        ||_        cddd       S # ||_        ||_        w xY w# 1 sw Y   yxY w)z/Call the callback function for the remote call.N)r5   rj   rk   rm   writer	   thread	get_identr3   WriteWrapperr+   r"   _remote_callback)
r*   r   	call_argscall_kwargscurrent_stdoutcurrent_stderrsaved_stdout_writesaved_stderr_write	thread_idrF   s
            r   r   zFrontendComm._remote_callback  s    ^^ 	: ZZN ZZN!/!5!5!/!5!5.1((*y7J7J7LI#/"Iy$:N #/"Iy$:N :\4Ay+7 (:$'9$	: 	: (:$'9$	: 	:s$   BCC.CCCC"N)NFNN)T)__name__
__module____qualname____doc__r,   r   rK   r(   rC   rX   rx   r   r   r0   r   r$   rg   r   r   r   __classcell__)rF   s   @r   r"   r"   8   sj    2,1\<
L
'2.h BF " !E
I
7	7: :r   r"   c                   "    e Zd ZdZd Zd Zd Zy)r   z*Wrapper to warn user when text is printed.c                 <    || _         || _        || _        d| _        y )NF)_write_name
_thread_id_warning_shown)r*   r   namer   s       r   r,   zWriteWrapper.__init__  s    
##r   c                 J    ddg}t        |D cg c]  }||v  c}      S c c}w )z7Determine if a message is benign in order to filter it.DeprecationWarningzIOStream.flush timed out)any)r*   messagebenign_messagesrt   s       r   is_benign_messagezWriteWrapper.is_benign_message%  s0    
 !&
 o>sC7N>??>s    c                    t         rt        j                         nt        j                         }| j                  |k7  r| j                  |      S | j                  |      sf| j                  sId| _        t        | j                        dk7  r*| j                  dt        | j                        z   dz          | j                  |      S y)zPrint warning once.Tz'show_mpl_backend_errors'z
Output from spyder call z:
N)
r	   r   r   r3   r   r   r   r   reprr   )r*   stringr   s      r   __call__zWriteWrapper.__call__1  s    *-F$$&93F3F3H	??i';;v&&%%f-&&&*# 

#'BBKK4tDJJ7GG%O ;;v&& .r   N)r   r   r   r   r,   r   r    r   r   r   r     s    4$
@'r   r   r   )r   r   r   rj   r3   rz   IPython.core.getipythonr   jupyter_client.localinterfacesr   tornador   r7   spyder_kernels.comms.commbaser   r   spyder_kernels.py3compatr   r	   r   r   r    r"   objectr   r   r   r   <module>r      sZ   
   
   / 4  
 = 6 a:8 a:H&'6 &'r   