B
    2d;J                 @   s0  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 deZejejdddZ G dd deZ!G dd de!Z"dS )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               @   s   e Zd ZdS )DuplicateKernelErrorN)__name__
__module____qualname__ r   r   n/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/jupyter_client/multikernelmanager.pyr      s   r   )freturnc                s2   t jtt jt jt jt jt jf d fdd}|S )zDdecorator for proxying MKM.method(kernel_id) to individual KMs by ID)self	kernel_idargskwargsr   c                s6   |  |}t| j}|||} | |f|| |S )N)
get_kernelgetattrr   )r   r   r   r   kmmethodr)r   r   r   wrapped$   s
    

zkernel_method.<locals>.wrapped)tr   strUnionCallable	Awaitable)r   r#   r   )r   r   kernel_method!   s     r)   c                   s  e Zd ZdZeeddjddZee	ddZ
edddjddZed	d
d ZeddZeddd ZejdddZedddjddZedZedZe Zedd ZedejdddZ edZ!e Z" fddZ#ej$e% dddZ&e'dd d!Z(e%e)d"d#d$Z*ej+e% ejej,e-e%e%f d%d&d'Z.e%e-ej/d(d)d*d+Z0e%ej/d(d,d-d.Z1d/d0 Z2dhej+e% eje%d%d1d2Z3e4e3Z5die%ej+e) ej+e) d(d3d4d5Z6e4e6Z7e8dje%ej+e) d(d6d7d8Z9e8dke%ej+e: ej+e: d(d:d;d<Z;e8dle%e)d(d6d=d>Z<e%e-d"d?d@Z=dme)d(dAdBdCZ>e4e>Z?e%d(d"dDdEZ@e8e%e'd(dFdGdHZAdne%e)d(dIdJdKZBe4eBZCe8e%e)d"dLdMZDe%d(d"dNdOZEe%e-d"dPdQZFe8doe%eje%d(dSdTdUZGe8dpe%eje%d(dSdVdWZHe8e%eje%ejf d"dXdYZIe8dqe%ej+eJ eKjKdZd[d\ZLe8dre%ej+eJ eKjKdZd]d^ZMe8dse%ej+eJ eKjKdZd_d`ZNe8dte%ej+eJ eKjKdZdadbZOe8due%ej+eJ eKjKdZdcddZPeje%dedfdgZQ  ZRS )v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             C   s   |   | _d S )N)_create_kernel_manager_factorykernel_manager_factory)r   Zchanger   r   r   _kernel_manager_class_changedE   s    z0MultiKernelManager._kernel_manager_class_changedz)this is kernel_manager_class after importr0   c             C   s   |   S )N)r/   )r   r   r   r   _kernel_manager_factory_defaultK   s    z2MultiKernelManager._kernel_manager_factory_default)r   c                s*   t j tjtjtd fdd}|S )N)r   r   r   c                 s4   j r&jjr _|dj  | |}|S )Ncontext)shared_contextr3   closed_context_default
setdefault)r   r   r    )kernel_manager_ctorr   r   r   create_kernel_managerR   s    

zPMultiKernelManager._create_kernel_manager_factory.<locals>.create_kernel_manager)r   r.   r$   r   r   )r   r9   r   )r8   r   r   r/   O   s    
	z1MultiKernelManager._create_kernel_manager_factoryz4Share a single zmq.Context to talk to all my kernelszzmq.ContextFc             C   s   | j S )z#A shim for backwards compatibility.)_pending_kernels)r   r   r   r   _starting_kernelsh   s    z$MultiKernelManager._starting_kernelsr3   c             C   s   d| _ t S )NT)_created_contextzmqContext)r   r   r   r   r6   m   s    z#MultiKernelManager._context_default c                s^   | j r2| jr2| jjs2| jr(| jd|  | j  yt j}W n tk
rR   Y nX |  dS )z:Handle garbage collection.  Destroy context if applicable.zDestroying zmq context for %sN)	r<   r3   r5   logdebugdestroysuper__del__AttributeError)r   Z	super_del)	__class__r   r   rD   v   s    
zMultiKernelManager.__del__c             C   s   t | j S )z6Return a list of the kernel ids of the active kernels.)list_kernelskeys)r   r   r   r   list_kernel_ids   s    z"MultiKernelManager.list_kernel_idsc             C   s   t |  S )z%Return the number of running kernels.)lenrJ   )r   r   r   r   __len__   s    zMultiKernelManager.__len__)r   r   c             C   s
   || j kS )N)rH   )r   r   r   r   r   __contains__   s    zMultiKernelManager.__contains__)kernel_namer   r   c             C   s   | d| jf |}|| kr(td| |d kr6| j}i }| jrJ| j|d< | jf tj| j	d| | | j
|d|}|||fS )Nr   zKernel already exists: %skernel_spec_managerzkernel-%s.json)Zconnection_fileparentr@   rN   )popnew_kernel_idr   default_kernel_namerO   r0   ospathjoinconnection_dirr@   )r   rN   r   r   Zconstructor_kwargsr    r   r   r   pre_start_kernel   s    
z#MultiKernelManager.pre_start_kernelN)r   r    kernel_awaitabler   c          
      sZ   y&|I d H  || j |< | j|d  W n. tk
rT } z| j| W d d }~X Y nX d S )N)rH   r:   rQ   	Exceptionr@   	exception)r   r   r    rY   er   r   r   _add_kernel_when_ready   s    

z)MultiKernelManager._add_kernel_when_ready)r   rY   r   c          
      sZ   y&|I d H  |  | | j|d  W n. tk
rT } z| j| W d d }~X Y nX d S )N)remove_kernelr:   rQ   rZ   r@   r[   )r   r   rY   r\   r   r   r   _remove_kernel_when_ready   s    

z,MultiKernelManager._remove_kernel_when_readyc             C   s   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   r   r   r   _using_pending_kernels   s    z)MultiKernelManager._using_pending_kernelsc                s   |  ||\}}}t|ts4| jdj| jjd ||d< t|j	f |}t
| |||}|| j|< |  r~|| j|< n|I dH  |j r|j |S )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'!)Zkm_classr   N)rX   
isinstancer   r@   warningformatr.   rF   r   start_kernelasynciocreate_taskr]   r:   ra   rH   readyr[   )r   rN   r   r    r   Zstartertaskr   r   r   _async_start_kernel   s    





z&MultiKernelManager._async_start_kernel)r   nowrestartr   c                s  | j d|  || jkr| j| }y.|I dH  | |}ttj|jI dH  W n2 tj	k
rh   Y n t
k
r   | | dS X | |}|j s|j r| | dS t|||}t| ||}|| j|< |  s|I dH  |j r|j dS )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?
        zKernel shutdown: %sN)r@   infor:   r   r$   castrf   Futurerh   CancelledErrorrZ   r^   	cancelledr[   r   shutdown_kernelensure_futurer_   ra   )r   r   rk   rl   ri   r    Zstopperfutr   r   r   _async_shutdown_kernel   s.    









z)MultiKernelManager._async_shutdown_kernel)r   rl   r   c             C   s   dS )z,Ask a kernel to shut down by its kernel uuidNr   )r   r   rl   r   r   r   request_shutdown  s    z#MultiKernelManager.request_shutdown皙?)r   waittimepollintervalr   c             C   s   | j d|  dS )zDWait for a kernel to finish shutting down, and kill it if it doesn'tzKernel shutdown: %sN)r@   rm   )r   r   rx   ry   r   r   r   finish_shutdown  s    z"MultiKernelManager.finish_shutdownc             C   s   dS )zClean up a kernel's resourcesNr   )r   r   rl   r   r   r   cleanup_resources%  s    z$MultiKernelManager.cleanup_resourcesc             C   s   | 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)rH   rQ   )r   r   r   r   r   r^   )  s    z MultiKernelManager.remove_kernel)rk   r   c          	      s     }|tj7 }tj } fddt|D }tj| I dH   rxV|D ]N}y|j	I dH  W qZ tj
k
r   j|j   Y qZ tk
r   Y qZX qZW dS )zShutdown all kernels.c                s   g | ]}t j| d qS ))rk   )r   rr   ).0kid)rk   r   r   r   
<listcomp>8  s    z:MultiKernelManager._async_shutdown_all.<locals>.<listcomp>N)rJ   rG   r:   rH   valuessetrf   gatherra   rh   rp   r   cancelrZ   )r   rk   ZkidsZkmsZfutsr    r   )rk   r   r   _async_shutdown_all3  s    
z&MultiKernelManager._async_shutdown_allc             C   s8   |  |}|j std| }| jd|  |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   rh   doneRuntimeErrorinterrupt_kernelr@   rm   )r   r   kerneloutr   r   r   r   G  s    

z#MultiKernelManager.interrupt_kernel)r   signumr   c             C   s   | j d||f  dS )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 %s with %sN)r@   rm   )r   r   r   r   r   r   signal_kernelV  s    z MultiKernelManager.signal_kernel)r   rk   r   c                sN   |  |}|  r$|j s$tdt|j|dI dH }| jd|  |S )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.)rk   NzKernel restarted: %s)	r   ra   rh   r   r   r   restart_kernelr@   rm   )r   r   rk   r   r   r   r   r   _async_restart_kernelf  s    

z(MultiKernelManager._async_restart_kernelc             C   s   dS )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   )r   r   r   r   r   is_alive  s    zMultiKernelManager.is_alivec             C   s   || krt d| dS )zcheck that a kernel id is validzKernel with id not found: %sN)KeyError)r   r   r   r   r   _check_kernel_id  s    z#MultiKernelManager._check_kernel_idc             C   s   |  | | j| S )zGet the single KernelManager object for a kernel by its uuid.

        Parameters
        ==========
        kernel_id : uuid
            The id of the kernel.
        )r   rH   )r   r   r   r   r   r     s    
zMultiKernelManager.get_kernelrl   )r   callbackeventr   c             C   s   dS )z&add a callback for the KernelRestarterNr   )r   r   r   r   r   r   r   add_restart_callback  s    z'MultiKernelManager.add_restart_callbackc             C   s   dS )z)remove a callback for the KernelRestarterNr   )r   r   r   r   r   r   r   remove_restart_callback  s    z*MultiKernelManager.remove_restart_callbackc             C   s   dS )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   )r   r   r   r   r   get_connection_info  s    z&MultiKernelManager.get_connection_info)r   identityr   c             C   s   dS )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   r   r   r   connect_iopub  s    z MultiKernelManager.connect_iopubc             C   s   dS )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   r   r   r   r   r   connect_shell  s    z MultiKernelManager.connect_shellc             C   s   dS )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   r   r   r   r   r   connect_control  s    z"MultiKernelManager.connect_controlc             C   s   dS )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   r   r   r   r   r   connect_stdin  s    z MultiKernelManager.connect_stdinc             C   s   dS )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   r   r   r   r   r   
connect_hb  s    zMultiKernelManager.connect_hb)r   r   c             K   s   t t 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   r   r   r   rR   
  s    z MultiKernelManager.new_kernel_id)N)FF)F)Nrw   )F)F)F)rl   )rl   )N)N)N)N)N)Sr   r   r   __doc__r	   r   tagrS   r   r   rO   r   r.   r   r1   r   r0   r   r2   r$   r'   r/   r   r4   r3   r<   r   r:   propertyr;   r=   r>   r6   rW   rH   rD   Listr%   rJ   intrL   boolrM   OptionalTupler   rX   r(   r]   r_   ra   rj   r   re   ru   rr   r)   rv   floatrz   r{   r^   r   shutdown_allr   r   r   r   r   r   r   r   r   r   bytessocketr   r   r   r   r   rR   __classcell__r   r   )rF   r   r*   5   s   

	! ( 


r*   c               @   sF   e Zd ZeddddZedddjddZej	Z
ejZejZejZd	S )
AsyncMultiKernelManagerz.jupyter_client.ioloop.AsyncIOLoopKernelManagerTzThe kernel manager class.  This is configurable to allow
        subclassing of the AsyncKernelManager for customized behavior.
        )r,   r+   FzWhether to make kernels available before the process has started.  The
        kernel has a `.ready` future which can be awaited before connecting)r+   )r,   N)r   r   r   r   r.   r   r   r`   r*   rj   re   r   r   ru   rr   r   r   r   r   r   r   r     s   r   )#r   rf   rT   r   typingr$   r   r=   Z	traitletsr   r   r   r   r   r   r   r	   Ztraitlets.config.configurabler
   Ztraitlets.utils.importstringr   Z
kernelspecr   r   managerr   utilsr   r   rZ   r   r'   r)   r*   r   r   r   r   r   <module>   s8      b