o
    iL                     @   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	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mZ dd	lmZ dd
lmZmZ G dd deZ dej!dej!f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)wraps)AnyBoolDictDottedObjectNameInstanceUnicodedefaultobserve)LoggingConfigurable)import_item   )NATIVE_KERNEL_NAMEKernelSpecManager)KernelManager)ensure_asyncrun_syncc                   @   s   e Zd ZdS )DuplicateKernelErrorN)__name__
__module____qualname__ r   r   \/var/www/edux/Edux_v2/venv/lib/python3.10/site-packages/jupyter_client/multikernelmanager.pyr      s    r   freturnc                    sB   t  dtjdtdtjdtjdtjtjtjf f
 fdd}|S )zDdecorator for proxying MKM.method(kernel_id) to individual KMs by IDself	kernel_idargskwargsr   c                    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>.wrapped)r   tr   strUnionCallable	Awaitable)r   r&   r   r%   r   kernel_method   s   r,   c                
       sB  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dejf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dejfddZ edZ!e Z" fddZ#dej$e% fddZ&de'fd d!Z(d"e%de)fd#d$Z*d%ej+e% d&ejdej,e-e%e%f fd'd(Z.d"e%d)e-d*ej/dd+fd,d-Z0d"e%d*ej/dd+fd.d/Z1d0d1 Z2d+d2d%ej+e% d&ejde%fd3d4Z3e4e3Z5		dhd"e%d5ej+e) d6ej+e) dd+fd7d8Z6e4e6Z7e8did"e%d6ej+e) dd+fd9d:Z9e8	+	;djd"e%d<ej+e: d=ej+e: dd+fd>d?Z;e8did"e%d6e)dd+fd@dAZ<d"e%de-fdBdCZ=did5e)dd+fdDdEZ>e4e>Z?d"e%dd+fdFdGZ@e8d"e%dHe'dd+fdIdJZAdid"e%d5e)dd+fdKdLZBe4eBZCe8d"e%de)fdMdNZDd"e%dd+fdOdPZEd"e%de-fdQdRZFe8	6dkd"e%dSejdTe%dd+fdUdVZGe8	6dkd"e%dSejdTe%dd+fdWdXZHe8d"e%deje%ejf fdYdZZIe8	+dld"e%d[ej+eJ deKjKfd\d]ZLe8	+dld"e%d[ej+eJ deKjKfd^d_ZMe8	+dld"e%d[ej+eJ deKjKfd`daZNe8	+dld"e%d[ej+eJ deKjKfdbdcZOe8	+dld"e%d[ej+eJ deKjKfdddeZPd&ejde%fdfdgZQ  ZRS )m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 r   )_create_kernel_manager_factorykernel_manager_factory)r   changer   r   r   _kernel_manager_class_changed>   s   z0MultiKernelManager._kernel_manager_class_changedz)this is kernel_manager_class after importr5   c                 C   s   |   S r   )r4   r   r   r   r   _kernel_manager_factory_defaultD   s   z2MultiKernelManager._kernel_manager_factory_defaultr   c                    s.   t j dtjdtjdtf fdd}|S )Nr   r   r   c                     s8   j rjjr _|dj  | i |}|S )Ncontext)shared_contextr:   closed_context_default
setdefault)r   r   r"   kernel_manager_ctorr   r   r   create_kernel_managerK   s   
zPMultiKernelManager._create_kernel_manager_factory.<locals>.create_kernel_manager)r   r3   r'   r   r   )r   rA   r   r?   r   r4   H   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_kernelsr8   r   r   r   _starting_kernelsa   s   z$MultiKernelManager._starting_kernelsr:   c                 C   s   d| _ t S NT)_created_contextzmqContextr8   r   r   r   r=   f   s   z#MultiKernelManager._context_default 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)	rE   r:   r<   logdebugdestroysuper__del__AttributeError)r   	super_del	__class__r   r   rM   o   s   

zMultiKernelManager.__del__c                 C   s   t | j S )z6Return a list of the kernel ids of the active kernels.)list_kernelskeysr8   r   r   r   list_kernel_ids|   s   z"MultiKernelManager.list_kernel_idsc                 C   s   t |  S )z%Return the number of running kernels.)lenrU   r8   r   r   r   __len__   s   zMultiKernelManager.__len__r   c                 C   s
   || j v S r   )rS   r   r   r   r   r   __contains__   s   
zMultiKernelManager.__contains__kernel_namer   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)connection_fileparentrI   rZ   r   )popnew_kernel_idr   default_kernel_namer[   r5   ospathjoinconnection_dirrI   )r   rZ   r   r   constructor_kwargsr"   r   r   r   pre_start_kernel   s"   

z#MultiKernelManager.pre_start_kernelr"   kernel_awaitableNc              
      s^   z|I d H  || j |< | j|d  W d S  ty. } z| j| W Y d }~d S d }~ww r   )rS   rB   r^   	ExceptionrI   	exception)r   r   r"   rg   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_kernelrB   r^   rh   rI   ri   )r   r   rg   rj   r   r   r   _remove_kernel_when_ready   rl   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!   r8   r   r   r   _using_pending_kernels   s   z)MultiKernelManager._using_pending_kernels)rZ   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'!)km_classr   Nr   )rf   
isinstancer   rI   warningformatr3   rQ   r   start_kernelasynciocreate_taskrk   rB   rp   rS   readyri   )r   rZ   r   r"   r   startertaskr   r   r   _async_start_kernel   s&   






z&MultiKernelManager._async_start_kernelnow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)rI   inforB   r    r'   castrv   Futurerx   CancelledErrorrh   rm   	cancelledri   r   shutdown_kernelensure_futurern   rp   )r   r   r|   r}   rz   r"   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_shutdown      z#MultiKernelManager.request_shutdown皙?waittimepollintervalc                 C   s   | j d| dS )zDWait for a kernel to finish shutting down, and kill it if it doesn'tr~   NrI   r   )r   r   r   r   r   r   r   finish_shutdown  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)rS   r^   rX   r   r   r   rm   "  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   ).0kidr|   r   r   r   
<listcomp>1  s    z:MultiKernelManager._async_shutdown_all.<locals>.<listcomp>N)rU   rR   rB   rS   valuessetrv   gatherrp   rx   r   r   cancelrh   )r   r|   kidskmsfutsr"   r   r   r   _async_shutdown_all,  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    rx   doneRuntimeErrorinterrupt_kernelrI   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_kernelP  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    rp   rx   r   r   r   restart_kernelrI   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   rX   r   r   r   is_alivex  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)KeyErrorrX   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   rS   rX   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_callbackc                 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   rX   r   r   r   get_connection_info  r   z&MultiKernelManager.get_connection_infoidentityc                 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   r_     s   z MultiKernelManager.new_kernel_id)FF)F)Nr   )r}   r   )Sr   r   r   __doc__r   r   tagr`   r   r   r[   r   r3   r
   r7   r   r5   r	   r9   r'   r*   r4   r   r;   r:   rE   r   rB   propertyrC   rF   rG   r=   rd   rS   rM   Listr(   rU   intrW   boolrY   OptionalTupler   rf   r+   rk   rn   rp   r{   r   ru   r   r   r,   r   floatr   r   rm   r   shutdown_allr   r   r   r   r   r   r    r   r   r   bytessocketr   r   r   r   r   r_   __classcell__r   r   rP   r   r-   .   sl   









#
- 	
 r-   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ejjfddZejZejdejf ed< ejZejdejf ed< ejZejdejf ed< ejZejdejf ed< dS )AsyncMultiKernelManagerz.jupyter_client.ioloop.AsyncIOLoopKernelManagerTzThe kernel manager class.  This is configurable to allow
        subclassing of the AsyncKernelManager for customized behavior.
        )r1   r/   FzWhether to make kernels available before the process has started.  The
        kernel has a `.ready` future which can be awaited before connectingr.   r0   zzmq.asyncio.Contextr:   r   c                 C   s   d| _ tj S rD   )rE   rF   rv   rG   r8   r   r   r   r=   (  s   
z(AsyncMultiKernelManager._context_default.ru   r   r   r   N)r   r   r   r   r3   r   r   ro   r   r:   r	   rF   rv   rG   r=   r-   r{   ru   r'   r*   r+   __annotations__r   r   r   r   r   r   r   r   r   r   r     s>   
 r   )%r   rv   ra   r   typingr'   r   	functoolsr   rF   	traitletsr   r   r   r   r   r   r	   r
   traitlets.config.configurabler   traitlets.utils.importstringr   
kernelspecr   r   managerr   utilsr   r   rh   r   r*   r,   r-   r   r   r   r   r   <module>   s*    (   l