
    Ne;J                     f   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Zddlm	Z	 ddlm
Z
 ddlmZ ddlmZ ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ  G d de      Zdej>                  dej>                  fdZ  G d de      Z! G d de!      Z"y)z%A kernel manager for multiple kernels    N)Any)Bool)default)Dict)DottedObjectName)Instance)observe)Unicode)LoggingConfigurable)import_item   )KernelSpecManager)NATIVE_KERNEL_NAME)KernelManager)ensure_async)run_syncc                       e Zd Zy)DuplicateKernelErrorN)__name__
__module____qualname__     C/usr/lib/python3/dist-packages/jupyter_client/multikernelmanager.pyr   r      s    r   r   freturnc                      dt         j                  dt        dt         j                  dt         j                  dt         j                  t         j                  t         j
                  f   f
 fd}|S )zDdecorator for proxying MKM.method(kernel_id) to individual KMs by IDself	kernel_idargskwargsr   c                     | j                  |      }t        |j                        } ||i |} | |g|i | |S N)
get_kernelgetattrr   )r   r   r    r!   kmmethodrr   s          r   wrappedzkernel_method.<locals>.wrapped$   sM     __Y'QZZ(D#F# 	
$	+D+F+r   )tr   strUnionCallable	Awaitable)r   r)   s   ` r   kernel_methodr/   !   sY    ee #,-EE=>UU	
Q[[(	) Nr   c            
       d    e Zd ZdZ eed      j                  d      Z ee	d      Z
 edd      j                  d      Z ed	      d
        Z ed      Z ed      d        Zdej(                  fdZ edd      j                  d      Z ed      Z ed      Z e       Zed        Z ed      dej>                  fd       Z  ed      Z! e       Z" fdZ#dejH                  e%   fdZ&de'fdZ(de%de)fdZ*dejV                  e%   dej                  dejX                  e-e%e%f   fdZ.de%de-d ej^                  dd!fd"Z0de%d ej^                  dd!fd#Z1d$ Z2	 dCdejV                  e%   dej                  de%fd%Z3 e4e3      Z5	 	 dDde%d&ejV                  e)   d'ejV                  e)   dd!fd(Z6 e4e6      Z7e8dEde%d'ejV                  e)   dd!fd)       Z9e8	 	 dFde%d*ejV                  e:   d+ejV                  e:   dd!fd,       Z;e8dEde%d'e)dd!fd-       Z<de%de-fd.Z=dEd&e)dd!fd/Z> e4e>      Z?de%dd!fd0Z@e8de%d1e'dd!fd2       ZAdEde%d&e)dd!fd3ZB e4eB      ZCe8de%de)fd4       ZDde%dd!fd5ZEde%de-fd6ZFe8	 dGde%d7ej(                  d8e%dd!fd9       ZGe8	 dGde%d7ej(                  d8e%dd!fd:       ZHe8de%dej4                  e%ej                  f   fd;       ZIe8dCde%d<ejV                  eJ   deKj                  fd=       ZLe8dCde%d<ejV                  eJ   deKj                  fd>       ZMe8dCde%d<ejV                  eJ   deKj                  fd?       ZNe8dCde%d<ejV                  eJ   deKj                  fd@       ZOe8dCde%d<ejV                  eJ   deKj                  fdA       ZPdej                  de%fdBZQ xZRS )HMultiKernelManagerz&A class for managing multiple kernels.z'The name of the default kernel to starthelpTconfig)
allow_nonez)jupyter_client.ioloop.IOLoopKernelManagerzThe kernel manager class.  This is configurable to allow
        subclassing of the KernelManager for customized behavior.
        kernel_manager_classc                 .    | j                         | _        y r#   )_create_kernel_manager_factorykernel_manager_factory)r   changes     r   _kernel_manager_class_changedz0MultiKernelManager._kernel_manager_class_changedE   s    &*&I&I&K#r   z)this is kernel_manager_class after importr:   c                 "    | j                         S r#   )r9   r   s    r   _kernel_manager_factory_defaultz2MultiKernelManager._kernel_manager_factory_defaultK   s    2244r   r   c                      t         j                        dt        j                  dt        j                  dt        f fd}|S )Nr    r!   r   c                      j                   rGj                  j                  rj                         _        |j	                  dj                          | i |}|S )Ncontext)shared_contextrB   closed_context_default
setdefault)r    r!   r&   kernel_manager_ctorr   s      r   create_kernel_managerzPMultiKernelManager._create_kernel_manager_factory.<locals>.create_kernel_managerR   sQ    ""<<&&#'#8#8#:DL!!)T\\:$d5f5BIr   )r   r7   r*   r   r   )r   rH   rG   s   ` @r   r9   z1MultiKernelManager._create_kernel_manager_factoryO   s>    )$*C*CD	 	!%% 	M 	 %$r   z4Share a single zmq.Context to talk to all my kernelszzmq.ContextFc                     | j                   S )z#A shim for backwards compatibility.)_pending_kernelsr>   s    r   _starting_kernelsz$MultiKernelManager._starting_kernelsh   s     $$$r   rB   c                 8    d| _         t        j                         S )NT)_created_contextzmqContextr>   s    r   rE   z#MultiKernelManager._context_defaultm   s     ${{}r    c                 (   | j                   rd| j                  rX| j                  j                  sB| j                  r| j                  j	                  d|        | j                  j                          	 t        |   } |        y# t        $ r Y yw xY w)z:Handle garbage collection.  Destroy context if applicable.zDestroying zmq context for %sN)	rM   rB   rD   logdebugdestroysuper__del__AttributeError)r   	super_del	__class__s     r   rV   zMultiKernelManager.__del__v   sq      T\\$,,:M:Mxx>ELL  "	I K  		s   3
B 	BBc                 H    t        | j                  j                               S )z6Return a list of the kernel ids of the active kernels.)list_kernelskeysr>   s    r   list_kernel_idsz"MultiKernelManager.list_kernel_ids   s     DMM&&())r   c                 4    t        | j                               S )z%Return the number of running kernels.)lenr^   r>   s    r   __len__zMultiKernelManager.__len__   s    4'')**r   r   c                     || j                   v S r#   )r\   r   r   s     r   __contains__zMultiKernelManager.__contains__   s    DMM))r   kernel_namer!   c                 b   |j                  d | j                  di |      }|| v rt        d|z        || j                  }i }| j                  r| j                  |d<    | j
                  dt        j                  j                  | j                  d|z        | | j                  |d|}|||fS )Nr   zKernel already exists: %skernel_spec_managerzkernel-%s.json)connection_fileparentrR   re   r   )popnew_kernel_idr   default_kernel_namerg   r:   ospathjoinconnection_dirrR   )r   re   r!   r   constructor_kwargsr&   s         r   pre_start_kernelz#MultiKernelManager.pre_start_kernel   s     JJ{,>D,>,>,H,HI	&'BY'NOO22K  ##8<8P8P45(T(( 
GGLL)<)<>NQZ>Z[#	

 !
 ;	))r   r&   kernel_awaitableNc                    K   	 | d {    || j                   |<   | j                  j                  |d        y 7 0# t        $ r%}| j                  j                  |       Y d }~y d }~ww xY wwr#   )r\   rJ   rj   	ExceptionrR   	exception)r   r   r&   rs   es        r   _add_kernel_when_readyz)MultiKernelManager._add_kernel_when_ready   sc     	""""')DMM)$!!%%i6 #  	"HHq!!	"s7   A-< :/< A-< 	A*A% A-%A**A-c                    K   	 | d {    | j                  |       | j                  j                  |d        y 7 2# t        $ r%}| j                  j                  |       Y d }~y d }~ww xY wwr#   )remove_kernelrJ   rj   ru   rR   rv   )r   r   rs   rw   s       r   _remove_kernel_when_readyz,MultiKernelManager._remove_kernel_when_ready   sc     	""""y)!!%%i6 #  	"HHq!!	"s7   A/> <1> A/> 	A,A'"A/'A,,A/c                     t        | dd      S )zReturns a boolean; a clearer method for determining if
        this multikernelmanager is using pending kernels or not
        use_pending_kernelsF)r%   r>   s    r   _using_pending_kernelsz)MultiKernelManager._using_pending_kernels   s     t2E::r   c                 D  K   | j                  ||      \  }}}t        |t              s?| j                  j	                  dj                  | j                  j                               ||d<   t         |j                  di |      }t        j                  | j                  |||            }|| j                  |<   | j                         r|| j                  |<   |S | d{    |j                   j#                         r|j                   j#                         |S 7 :w)zStart a new kernel.

        The caller can pick a kernel_id by passing one in as a keyword arg,
        otherwise one will be generated using new_kernel_id().

        The kernel ID for the newly started kernel is returned.
        zHKernel manager class ({km_class}) is not an instance of 'KernelManager'!)km_classr   Nr   )rr   
isinstancer   rR   warningformatr7   rY   r   start_kernelasynciocreate_taskrx   rJ   r~   r\   readyrv   )r   re   r!   r&   r   startertasks          r   _async_start_kernelz&MultiKernelManager._async_start_kernel   s     &*%:%:;%O"K"m,HHZaa!66@@ b 
 ({r889""4#>#>y"g#VW+/i(&&( (*DMM)$  JJxx!!#hh((** s   C!D #D$;D nowrestartc                   K   | j                   j                  d|z         || j                  v ra| j                  |   }	 | d{    | j                  |      }t	        j
                  t        j                  |j                         d{    | j                  |      }|j                  j                         s,|j                  j                         r| j                  |       yt        |j                  ||            }t        j                   | j#                  ||            }|| j                  |<   | j%                         s?| d{    |j                  j                         r|j                  j                         yy7 B7 # t        j                  $ r Y t        $ r | j                  |       Y yw xY w7 tw)a3  Shutdown a kernel by its kernel uuid.

        Parameters
        ==========
        kernel_id : uuid
            The id of the kernel to shutdown.
        now : bool
            Should the kernel be shutdown forcibly using a signal.
        restart : bool
            Will the kernel be restarted?
        Kernel shutdown: %sN)rR   inforJ   r$   r*   castr   Futurer   CancelledErrorru   rz   	cancelledrv   r   shutdown_kernelensure_futurer{   r~   )r   r   r   r   r   r&   stopperfuts           r   _async_shutdown_kernelz)MultiKernelManager._async_shutdown_kernel   su    " 	+i78---((3D

__Y/ffW^^RXX666 __Y'xx!!#(:(:(<y)r11#w?@##D$B$B9g$VW+.i(**,IIxx!!#hh((** $ -# 6))  ""9- sf   <GF FAF F	F B;GG :GF 	F F=G!F=:G<F==Gc                      y)z,Ask a kernel to shut down by its kernel uuidNr   r   r   r   s      r   request_shutdownz#MultiKernelManager.request_shutdown      r   waittimepollintervalc                 @    | j                   j                  d|z         y)zDWait for a kernel to finish shutting down, and kill it if it doesn'tr   NrR   r   )r   r   r   r   s       r   finish_shutdownz"MultiKernelManager.finish_shutdown  s     	+i78r   c                      y)zClean up a kernel's resourcesNr   r   s      r   cleanup_resourcesz$MultiKernelManager.cleanup_resources%  r   r   c                 :    | j                   j                  |d      S )zremove a kernel from our mapping.

        Mainly so that a kernel can be removed if it is already dead,
        without having to call shutdown_kernel.

        The kernel object is returned, or `None` if not found.
        N)r\   rj   rc   s     r   rz   z MultiKernelManager.remove_kernel)  s     }}  D11r   c           	      :  K   | j                         }|t        | j                        z  }t        | j                  j	                               }t        |      D cg c]  }t        | j                  ||              }}t        j                  |  d{    | j                         r|D ]  }	 |j                   d{     yyc c}w 7 77 # t        j                  $ r* | j                  |j                     j                          Y at        $ r Y kw xY ww)zShutdown all kernels.r   N)r^   r[   rJ   r\   valuessetr   r   r   gatherr~   r   r   r   cancelru   )r   r   kidskmskidfutsr&   s          r   _async_shutdown_allz&MultiKernelManager._async_shutdown_all3  s     ##%T**++4=='')*LOPTIVST11#31?@VVnnd###&&( ((NN ) W#
 #-- A))",,7>>@  s`   AD#C>DCD0C?C C
DC:DDDDDDc                     | j                  |      }|j                  j                         st        d      |j	                         }| j
                  j                  d|z         |S )zInterrupt (SIGINT) the kernel by its uuid.

        Parameters
        ==========
        kernel_id : uuid
            The id of the kernel to interrupt.
        z/Kernel is in a pending state. Cannot interrupt.zKernel interrupted: %s)r$   r   doneRuntimeErrorinterrupt_kernelrR   r   )r   r   kernelouts       r   r   z#MultiKernelManager.interrupt_kernelG  sW     +||  "PQQ%%'.:;
r   signumc                 F    | j                   j                  d|d|       y)aR  Sends a signal to the kernel by its uuid.

        Note that since only SIGTERM is supported on Windows, this function
        is only useful on Unix systems.

        Parameters
        ==========
        kernel_id : uuid
            The id of the kernel to signal.
        signum : int
            Signal number to send kernel.
        zSignaled Kernel z with Nr   )r   r   r   s      r   signal_kernelz MultiKernelManager.signal_kernelV  s     	iHIr   c                    K   | j                  |      }| j                         r%|j                  j                         st	        d      t        |j                  |             d{   }| j                  j                  d|z         |S 7 $w)aE  Restart a kernel by its uuid, keeping the same ports.

        Parameters
        ==========
        kernel_id : uuid
            The id of the kernel to interrupt.
        now : bool, optional
            If True, the kernel is forcefully restarted *immediately*, without
            having a chance to do any cleanup action.  Otherwise the kernel is
            given 1s to clean up before a forceful restart is issued.

            In all cases the kernel is restarted, the only difference is whether
            it is given a chance to perform a clean shutdown or not.
        z-Kernel is in a pending state. Cannot restart.r   NzKernel restarted: %s)	r$   r~   r   r   r   r   restart_kernelrR   r   )r   r   r   r   r   s        r   _async_restart_kernelz(MultiKernelManager._async_restart_kernelf  sz      +&&(<<$$&"#RSS !6!63!6!?@@,y89
 As   A%B'B(%Bc                      y)zIs the kernel alive.

        This calls KernelManager.is_alive() which calls Popen.poll on the
        actual kernel subprocess.

        Parameters
        ==========
        kernel_id : uuid
            The id of the kernel.
        Nr   rc   s     r   is_alivezMultiKernelManager.is_alive  r   r   c                 (    || vrt        d|z        y)zcheck that a kernel id is validzKernel with id not found: %sN)KeyErrorrc   s     r   _check_kernel_idz#MultiKernelManager._check_kernel_id  s     D 9IEFF !r   c                 B    | j                  |       | j                  |   S )zGet the single KernelManager object for a kernel by its uuid.

        Parameters
        ==========
        kernel_id : uuid
            The id of the kernel.
        )r   r\   rc   s     r   r$   zMultiKernelManager.get_kernel  s!     	i(}}Y''r   callbackeventc                      y)z&add a callback for the KernelRestarterNr   r   r   r   r   s       r   add_restart_callbackz'MultiKernelManager.add_restart_callback  r   r   c                      y)z)remove a callback for the KernelRestarterNr   r   s       r   remove_restart_callbackz*MultiKernelManager.remove_restart_callback  r   r   c                      y)a  Return a dictionary of connection data for a kernel.

        Parameters
        ==========
        kernel_id : uuid
            The id of the kernel.

        Returns
        =======
        connection_dict : dict
            A dict of the information needed to connect to a kernel.
            This includes the ip address and the integer port
            numbers of the different channels (stdin_port, iopub_port,
            shell_port, hb_port).
        Nr   rc   s     r   get_connection_infoz&MultiKernelManager.get_connection_info  r   r   identityc                      y)a6  Return a zmq Socket connected to the iopub channel.

        Parameters
        ==========
        kernel_id : uuid
            The id of the kernel
        identity : bytes (optional)
            The zmq identity of the socket

        Returns
        =======
        stream : zmq Socket or ZMQStream
        Nr   r   r   r   s      r   connect_iopubz MultiKernelManager.connect_iopub  r   r   c                      y)a6  Return a zmq Socket connected to the shell channel.

        Parameters
        ==========
        kernel_id : uuid
            The id of the kernel
        identity : bytes (optional)
            The zmq identity of the socket

        Returns
        =======
        stream : zmq Socket or ZMQStream
        Nr   r   s      r   connect_shellz MultiKernelManager.connect_shell  r   r   c                      y)a8  Return a zmq Socket connected to the control channel.

        Parameters
        ==========
        kernel_id : uuid
            The id of the kernel
        identity : bytes (optional)
            The zmq identity of the socket

        Returns
        =======
        stream : zmq Socket or ZMQStream
        Nr   r   s      r   connect_controlz"MultiKernelManager.connect_control  r   r   c                      y)a6  Return a zmq Socket connected to the stdin channel.

        Parameters
        ==========
        kernel_id : uuid
            The id of the kernel
        identity : bytes (optional)
            The zmq identity of the socket

        Returns
        =======
        stream : zmq Socket or ZMQStream
        Nr   r   s      r   connect_stdinz MultiKernelManager.connect_stdin  r   r   c                      y)a3  Return a zmq Socket connected to the hb channel.

        Parameters
        ==========
        kernel_id : uuid
            The id of the kernel
        identity : bytes (optional)
            The zmq identity of the socket

        Returns
        =======
        stream : zmq Socket or ZMQStream
        Nr   r   s      r   
connect_hbzMultiKernelManager.connect_hb  r   r   c                 <    t        t        j                               S )z
        Returns the id to associate with the kernel for this request. Subclasses may override
        this method to substitute other sources of kernel ids.
        :param kwargs:
        :return: string-ized version 4 uuid
        )r+   uuiduuid4)r   r!   s     r   rk   z MultiKernelManager.new_kernel_id
  s     4::<  r   r#   )FF)F)Ng?)r   )Sr   r   r   __doc__r
   r   tagrl   r   r   rg   r   r7   r	   r<   r   r:   r   r?   r*   r-   r9   r   rC   rB   rM   r   rJ   propertyrK   rN   rO   rE   rp   r\   rV   Listr+   r^   intra   boolrd   OptionalTupler   rr   r.   rx   r{   r~   r   r   r   r   r   r/   r   floatr   r   rz   r   shutdown_allr   r   r   r   r   r   r$   r   r   r   bytessocketr   r   r   r   r   rk   __classcell__)rY   s   @r   r1   r1   5   s   0!!J	cc  ##4F+3
 
cc  #$L %L !&QR%&5 '5%

 % C 
cc 
 }%GE{v% % Y#++   R[NvH* *+ +*c *d **::c?*45EE*	
S(	)*2"""/"CD;;"	"""01"	"; .2!::c?!=>UU!	!F /0L
 !&$)	++++ ZZ++ D!	++
 
++Z 56O;# ;

48H ;UY ; ;  '+*-	99 **U#9 jj'	9
 
9 9 ,3 , ,$ , ,2s 2} 2T d $ /0L# $  Js JC JD J JS t PT . 34N
# 
$ 
 
G# G$ G
	(C 	(M 	( AJ55()

5;>5	5 5
 AJ88()

8;>8	8 8
 S QVVCJ5G  " s ajj6G SYS`S`   s ajj6G SYS`S`    

58I U[UbUb   s ajj6G SYS`S`   C 1::e3D PVP]P]  !aee ! !r   r1   c                       e Zd Z eddd      Z edd      j                  d      Zej                  Z
ej                  Zej                  Zej                  Zy	)
AsyncMultiKernelManagerz.jupyter_client.ioloop.AsyncIOLoopKernelManagerTzThe kernel manager class.  This is configurable to allow
        subclassing of the AsyncKernelManager for customized behavior.
        )r5   r3   FzWhether to make kernels available before the process has started.  The
        kernel has a `.ready` future which can be awaited before connectingr2   r4   N)r   r   r   r   r7   r   r   r}   r1   r   r   r   r   r   r   r   r   r   r   r   r   r     sl    +8 O 
cc	  &99L'==N(??O%99Lr   r   )#r   r   rm   r   typingr*   r   rN   	traitletsr   r   r   r   r   r   r	   r
   traitlets.config.configurabler   traitlets.utils.importstringr   
kernelspecr   r   managerr   utilsr   r   ru   r   r-   r/   r1   r   r   r   r   <module>r      s    +  	    
     &    = 4 ) * "  	9 	QZZ AJJ (\!, \!~:0 :r   