o
    ZhIX                     @  s  d Z ddlm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ZddlmZmZmZmZmZmZmZmZ ddlmZ ddlmZ d	d
lmZ d	dlmZm Z  d	dl!m"Z" d	dl#m$Z$m%Z%m&Z& G dd de'Z(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    )annotationsNwraps)Path)AnyBoolDictDottedObjectNameInstanceUnicodedefaultobserve)LoggingConfigurable)import_item   )KernelConnectionInfo)NATIVE_KERNEL_NAMEKernelSpecManager)KernelManager)ensure_asyncrun_syncutcnowc                   @  s   e Zd ZdS )DuplicateKernelErrorN)__name__
__module____qualname__ r   r   X/var/www/html/lang_env/lib/python3.10/site-packages/jupyter_client/multikernelmanager.pyr      s    r   f
t.Callablereturnc                   s   t  d fd	d
}|S )zDdecorator for proxying MKM.method(kernel_id) to individual KMs by IDselft.Any	kernel_idstrargskwargsr    t.Callable | t.Awaitablec                   s@   |  |}t| j}||i |} | |g|R i | |S N)
get_kernelgetattrr   )r!   r#   r%   r&   kmmethodrr   r   r   wrapped!   s
   
zkernel_method.<locals>.wrappedN)
r!   r"   r#   r$   r%   r"   r&   r"   r    r'   r   )r   r/   r   r.   r   kernel_method   s   r0   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	dddZeddZeddddZdddZedddjddZedZedZe ZedddZeddddZed Zed!ddZe Zd fd$d%Z d fd&d'Z!dd)d*Z"dd,d-Z#dd1d2Z$dd6d7Z%dd:d;Z&dd@dAZ'ddBdCZ(ddDdEZ)d!dFddGdHZ*e+e*Z,		dddLdMZ-e+e-Z.e/dddNdOZ0e/	!	PdddTdUZ1e/dddVdWZ2ddXdYZ3dddZd[Z4e+e4Z5dd\d]Z6e/dd_d`Z7dddadbZ8e+e8Z9e/ddcddZ:ddedfZ;ddgdhZ<e/	KdddkdlZ=e/	KdddmdnZ>e/ddpdqZ?e/	!dddudvZ@e/	!dddwdxZAe/	!dddydzZBe/	!ddd{d|ZCe/	!ddd}d~ZDdddZE  ZFS )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_classchanger"   r    Nonec                 C  s   |   | _d S r(   )_create_kernel_manager_factorykernel_manager_factory)r!   r8   r   r   r   _kernel_manager_class_changedC   s   z0MultiKernelManager._kernel_manager_class_changedz)this is kernel_manager_class after importr;   r   c                 C  s   |   S r(   )r:   r!   r   r   r   _kernel_manager_factory_defaultI   s   z2MultiKernelManager._kernel_manager_factory_defaultc                   s   t j d fdd}|S )	Nr%   r"   r&   r    r   c                    s8   j rjjr _|dj  | i |}|S )Ncontext)shared_contextr?   closed_context_default
setdefault)r%   r&   r+   Zkernel_manager_ctorr!   r   r   create_kernel_managerP   s   
zPMultiKernelManager._create_kernel_manager_factory.<locals>.create_kernel_manager)r%   r"   r&   r"   r    r   )r   r7   )r!   rE   r   rD   r   r:   M   s   
	z1MultiKernelManager._create_kernel_manager_factoryz4Share a single zmq.Context to talk to all my kernelszmq.ContextFdictc                 C  s   | j S )z#A shim for backwards compatibility.)_pending_kernelsr=   r   r   r   _starting_kernelsf   s   z$MultiKernelManager._starting_kernelsr?   c                 C  s   d| _ t S NT)_created_contextzmqContextr=   r   r   r   rB   k   s   z#MultiKernelManager._context_default Nr%   r&   c                   s   t  j|i | i | _d S r(   )super__init__kernel_id_to_connection_file)r!   r%   r&   	__class__r   r   rP   u   s   
zMultiKernelManager.__init__c                   s^   | j r| jr| jjs| jr| jd|  | j  zt j}W n
 ty)   Y dS w |  dS )z:Handle garbage collection.  Destroy context if applicable.zDestroying zmq context for %sN)	rK   r?   rA   logdebugdestroyrO   __del__AttributeError)r!   Z	super_delrR   r   r   rW   y   s   

zMultiKernelManager.__del__	list[str]c           	   	   C  sZ  | j durt| j }| rdd | D }t| j }t| j }t| j D ]}||vrA||| }| j|= | j	|= q,|D ]a}|| j v rNqDz	t
| }W n	 ty`   Y qDw | jd| d|v rpd|v sqqD|  }|| j|< | j| | jdd}|| t |_d	|_d
|_||_|d |_|jd || j	|< qDt| j	 S )z6Return a list of the kernel ids of the active kernels.Nc                 S  s   g | ]}|  r|qS r   )is_file).0pr   r   r   
<listcomp>   s    z6MultiKernelManager.list_kernel_ids.<locals>.<listcomp>zLoading connection file %skernel_namekeyF)parentrT   Zowns_kernelidler   )external_connection_dirr   is_diriterdirlistrQ   keysvaluesindex_kernelsjsonloads	read_text	ExceptionrT   rU   new_kernel_idr;   Zload_connection_infor   Zlast_activityZexecution_stateconnectionsr#   r^   ready
set_result)	r!   rb   Zconnection_fileskvconnection_filer#   Zconnection_infor+   r   r   r   list_kernel_ids   sR   




z"MultiKernelManager.list_kernel_idsintc                 C  s   t |  S )z%Return the number of running kernels.)lenru   r=   r   r   r   __len__   s   zMultiKernelManager.__len__r#   r$   boolc                 C  s
   || j v S r(   )ri   r!   r#   r   r   r   __contains__   s   
zMultiKernelManager.__contains__r^   
str | Nonetuple[KernelManager, str, str]c                 C  s   | d| jdi |}|| v rtd| |d u r| j}i }| jr'| j|d< | jdtj| j	d| | | j
|d|}|||fS )Nr#   zKernel already exists: %skernel_spec_managerzkernel-%s.json)rt   r`   rT   r^   r   )poprn   r   default_kernel_namer~   r;   ospathjoinconnection_dirrT   )r!   r^   r&   r#   Zconstructor_kwargsr+   r   r   r   pre_start_kernel   s"   

z#MultiKernelManager.pre_start_kernelenvt.Dict[str, str]c                C  s"   || v r| j | j|d dS dS )z
        Allow to update the environment of the given kernel.

        Forward the update env request to the corresponding kernel.

        .. version-added: 8.5
        )r   N)ri   
update_env)r!   r#   r   r   r   r   r      s   zMultiKernelManager.update_envr+   r   kernel_awaitablet.Awaitablec              
     s^   z|I d H  || j |< | j|d  W d S  ty. } z| j| W Y d }~d S d }~ww r(   )ri   rH   r   rm   rT   	exception)r!   r#   r+   r   er   r   r   _add_kernel_when_ready      

z)MultiKernelManager._add_kernel_when_readyc              
     s^   z|I d H  |  | | j|d  W d S  ty. } z| j| W Y d }~d S d }~ww r(   )remove_kernelrH   r   rm   rT   r   )r!   r#   r   r   r   r   r   _remove_kernel_when_ready   r   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_kernels)r^   c                  s   |  ||\}}}t|ts| jdj| jjd ||d< t|j	di |}t
| |||}|| j|< |  rC|| j|< |S |I dH  |j rR|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#   Nr   )r   
isinstancer   rT   warningformatr7   rS   r   start_kernelasynciocreate_taskr   rH   r   ri   rp   r   )r!   r^   r&   r+   r#   Zstartertaskr   r   r   _async_start_kernel   s&   





z&MultiKernelManager._async_start_kernelnowbool | Nonerestartc                   s
  | j d| || jv rB| j| }z|I dH  | |}ttj|jI dH  W n tj	y3   Y n t
yA   | | Y dS w | |}|j sX|j rX| | dS t|||}t| ||}|| j|< |  s|I dH  |j r|j dS 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?
        Kernel shutdown: %sN)rT   inforH   r)   tcastr   Futurerp   CancelledErrorrm   r   	cancelledr   r   shutdown_kernelensure_futurer   r   )r!   r#   r   r   r   r+   Zstopperfutr   r   r   _async_shutdown_kernel!  s6   










z)MultiKernelManager._async_shutdown_kernelc                 C     dS )z,Ask a kernel to shut down by its kernel uuidNr   r!   r#   r   r   r   r   request_shutdownP      z#MultiKernelManager.request_shutdown皙?waittimefloat | Nonepollintervalc                 C  s   | j d| dS )zDWait for a kernel to finish shutting down, and kill it if it doesn'tr   NrT   r   )r!   r#   r   r   r   r   r   finish_shutdownT  s   z"MultiKernelManager.finish_shutdownc                 C  r   )zClean up a kernel's resourcesNr   r   r   r   r   cleanup_resources^  r   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)ri   r   rz   r   r   r   r   b  s   z MultiKernelManager.remove_kernelc              	     s     }|tj7 }tj } fddt|D }tj| I dH   rR|D ]&}z|j	I dH  W q- tj
yI   j|j   Y q- tyQ   Y q-w dS dS )zShutdown all kernels.c                   s   g | ]	}j | d qS )r   )r   )r[   kidr   r!   r   r   r]   q  s    z:MultiKernelManager._async_shutdown_all.<locals>.<listcomp>N)ru   re   rH   ri   rg   setr   gatherr   rp   r   r#   cancelrm   )r!   r   ZkidsZkmsZfutsr+   r   r   r   _async_shutdown_alll  s"   z&MultiKernelManager._async_shutdown_allc                 C  s:   |  |}|j sd}t|| }| 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)   rp   doneRuntimeErrorinterrupt_kernelrT   r   )r!   r#   kernelmsgoutr   r   r   r     s   

z#MultiKernelManager.interrupt_kernelsignumc                 C  s   | j d|| 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 %sNr   )r!   r#   r   r   r   r   signal_kernel  s   z MultiKernelManager.signal_kernelc                   sR   |  |}|  r|j sd}t|t|j|dI dH  | jd| 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.r   NzKernel restarted: %s)	r)   r   rp   r   r   r   restart_kernelrT   r   )r!   r#   r   r   r   r   r   r   _async_restart_kernel  s   
z(MultiKernelManager._async_restart_kernelc                 C  r   )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   rz   r   r   r   is_alive  r   zMultiKernelManager.is_alivec                 C  s   || vr
t d| dS )zcheck that a kernel id is validzKernel with id not found: %sN)KeyErrorrz   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   ri   rz   r   r   r   r)     s   

zMultiKernelManager.get_kernelcallbackeventc                 C  r   )z&add a callback for the KernelRestarterNr   r!   r#   r   r   r   r   r   add_restart_callback  r   z'MultiKernelManager.add_restart_callbackc                 C  r   )z)remove a callback for the KernelRestarterNr   r   r   r   r   remove_restart_callback  r   z*MultiKernelManager.remove_restart_callbackdict[str, t.Any]c                 C  r   )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   rz   r   r   r   get_connection_info  r   z&MultiKernelManager.get_connection_infoidentitybytes | Nonesocket.socketc                 C  r   )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  r   z MultiKernelManager.connect_iopubc                 C  r   )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   connect_shell  r   z MultiKernelManager.connect_shellc                 C  r   )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   connect_control  r   z"MultiKernelManager.connect_controlc                 C  r   )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   connect_stdin)  r   z MultiKernelManager.connect_stdinc                 C  r   )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   
connect_hb;  r   zMultiKernelManager.connect_hbc                 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   rn   M  s   z MultiKernelManager.new_kernel_id)r8   r"   r    r9   )r    r   )r    rG   )r    rF   )r%   r"   r&   r"   r    r9   )r    r9   )r    rY   )r    rv   )r#   r$   r    ry   )r^   r|   r&   r"   r    r}   )r#   r$   r   r   r    r9   )r#   r$   r+   r   r   r   r    r9   )r#   r$   r   r   r    r9   )r    ry   )r^   r|   r&   r"   r    r$   )FF)r#   r$   r   r   r   r   r    r9   )F)r#   r$   r   r   r    r9   )Nr   )r#   r$   r   r   r   r   r    r9   )r#   r$   r   ry   r    r9   )r#   r$   r    r   )r   ry   r    r9   )r#   r$   r    r9   )r#   r$   r   rv   r    r9   )r#   r$   r   ry   r    r9   )r   )r#   r$   r   r   r   r$   r    r9   )r#   r$   r    r   r(   )r#   r$   r   r   r    r   )r&   r"   r    r$   )Gr   r   r   __doc__r   r   tagr   r
   r   r~   r	   r7   r   r<   r   r;   r   r>   r:   r   r@   r?   rK   r   rH   propertyrI   rB   r   rb   ri   rP   rW   ru   rx   r{   r   r   r   r   r   r   r   r   r   r   r0   r   r   r   r   r   shutdown_allr   r   r   r   r   r   r)   r   r   r   r   r   r   r   r   rn   __classcell__r   r   rR   r   r1   3   s    



3







!-	




r1   c                   @  s   e Zd ZU eddddZedddjddZed	Z	e
d
dddZejZded< ejZded< ejZded< ejZded< dS )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   zmq.asyncio.Contextr?   r    c                 C  s   d| _ tj S rJ   )rK   rL   r   rM   r=   r   r   r   rB   h  s   
z(AsyncMultiKernelManager._context_defaultzt.Callable[..., t.Awaitable]r   r   r   r   N)r    r   )r   r   r   r	   r7   r   r   r   r
   r?   r   rB   r1   r   r   __annotations__r   r   r   r   r   r   r   r   r   r   r   W  s&   
 r   )r   r   r    r   ),r   
__future__r   r   rj   r   sockettypingr   r   	functoolsr   pathlibr   rL   Z	traitletsr   r   r   r	   r
   r   r   r   Ztraitlets.config.configurabler   Ztraitlets.utils.importstringr   connectr   Z
kernelspecr   r   managerr   utilsr   r   r   rm   r   r0   r1   r   r   r   r   r   <module>   s4    (
    (