U
    luf&                     @   s   d Z ddlZddlmZmZmZ ddlmZmZm	Z	m
Z
mZ ddlmZmZmZ ddlmZ G dd	 d	eeeZG d
d deeedZdS )zKernel Provisioner Classes    N)ABCABCMetaabstractmethod)AnyDictListOptionalUnion)InstanceLoggingConfigurableUnicode   )KernelConnectionInfoc                   @   s   e Zd ZdS )KernelProvisionerMetaN)__name__
__module____qualname__ r   r   P/tmp/pip-unpacked-wheel-naub1w99/jupyter_client/provisioning/provisioner_base.pyr      s   r   c                   @   s  e Zd ZU dZedddZeed< edddZ	e
eef ed< i Zeed< eeed	d
dZeee d	ddZeee d	ddZeeddddZed7eddddZed8eddddZeee eedddZed9eddddZd:eddddZeeeef d d!d"Zedd d#d$Zeeef d	d%d&Z edd'd(d)Z!d;e"e"d+d,d-Z#d<e"e"d+d/d0Z$eeef dd1d2d3Z%eeef eeef d4d5d6Z&dS )=KernelProvisionerBasea  
    Abstract base class defining methods for KernelProvisioner classes.

    A majority of methods are abstract (requiring implementations via a subclass) while
    some are optional and others provide implementations common to all instances.
    Subclasses should be aware of which methods require a call to the superclass.

    Many of these methods model those of :class:`subprocess.Popen` for parity with
    previous versions where the kernel process was managed directly.
    z$jupyter_client.kernelspec.KernelSpecT)
allow_nonekernel_specN	kernel_idconnection_info)returnc                 C   s   dS )z
        Returns true if this provisioner is currently managing a process.

        This property is asserted to be True immediately following a call to
        the provisioner's :meth:`launch_kernel` method.
        Nr   selfr   r   r   has_process$   s    	z!KernelProvisionerBase.has_processc                    s   dS )z
        Checks if kernel process is still running.

        If running, None is returned, otherwise the process's integer-valued exit code is returned.
        This method is called from :meth:`KernelManager.is_alive`.
        Nr   r   r   r   r   poll/   s    zKernelProvisionerBase.pollc                    s   dS )z
        Waits for kernel process to terminate.

        This method is called from `KernelManager.finish_shutdown()` and
        `KernelManager.kill_kernel()` when terminating a kernel gracefully or
        immediately, respectively.
        Nr   r   r   r   r   wait9   s    	zKernelProvisionerBase.wait)signumr   c                    s   dS )z
        Sends signal identified by signum to the kernel process.

        This method is called from `KernelManager.signal_kernel()` to send the
        kernel process a signal.
        Nr   )r   r    r   r   r   send_signalD   s    z!KernelProvisionerBase.send_signalF)restartr   c                    s   dS )aL  
        Kill the kernel process.

        This is typically accomplished via a SIGKILL signal, which cannot be caught.
        This method is called from `KernelManager.kill_kernel()` when terminating
        a kernel immediately.

        restart is True if this operation will precede a subsequent launch_kernel request.
        Nr   r   r"   r   r   r   killN   s    zKernelProvisionerBase.killc                    s   dS )a  
        Terminates the kernel process.

        This is typically accomplished via a SIGTERM signal, which can be caught, allowing
        the kernel provisioner to perform possible cleanup of resources.  This method is
        called indirectly from `KernelManager.finish_shutdown()` during a kernel's
        graceful termination.

        restart is True if this operation precedes a start launch_kernel request.
        Nr   r#   r   r   r   	terminate[   s    zKernelProvisionerBase.terminate)cmdkwargsr   c                    s   dS )z
        Launch the kernel process and return its connection information.

        This method is called from `KernelManager.launch_kernel()` during the
        kernel manager's start kernel sequence.
        Nr   )r   r&   r'   r   r   r   launch_kerneli   s    z#KernelProvisionerBase.launch_kernelc                    s   dS )a"  
        Cleanup any resources allocated on behalf of the kernel provisioner.

        This method is called from `KernelManager.cleanup_resources()` as part of
        its shutdown kernel sequence.

        restart is True if this operation precedes a start launch_kernel request.
        Nr   r#   r   r   r   cleanups   s    
zKernelProvisionerBase.cleanupc                    s   dS )a  
        Allows the provisioner to determine if the kernel's shutdown has been requested.

        This method is called from `KernelManager.request_shutdown()` as part of
        its shutdown sequence.

        This method is optional and is primarily used in scenarios where the provisioner
        may need to perform other operations in preparation for a kernel's shutdown.
        Nr   r#   r   r   r   shutdown_requested   s    
z(KernelProvisionerBase.shutdown_requested)r'   r   c                    s8   | dtj }|| | | | ||d< |S )a(  
        Perform any steps in preparation for kernel process launch.

        This includes applying additional substitutions to the kernel launch command
        and environment. It also includes preparation of launch parameters.

        NOTE: Subclass implementations are advised to call this method as it applies
        environment variable substitutions from the local environment and calls the
        provisioner's :meth:`_finalize_env()` method to allow each provisioner the
        ability to cleanup the environment variables that will be used by the kernel.

        This method is called from `KernelManager.pre_start_kernel()` as part of its
        start kernel sequence.

        Returns the (potentially updated) keyword arguments that are passed to
        :meth:`launch_kernel()`.
        env)poposenvironcopyupdate/_KernelProvisionerBase__apply_env_substitutions_finalize_env)r   r'   r+   r   r   r   
pre_launch   s
    
z KernelProvisionerBase.pre_launchc                    s   dS )z
        Perform any steps following the kernel process launch.

        This method is called from `KernelManager.post_start_kernel()` as part of its
        start kernel sequence.
        Nr   )r   r'   r   r   r   post_launch   s    z!KernelProvisionerBase.post_launchc                    s   i }| j |d< | j|d< |S )a  
        Captures the base information necessary for persistence relative to this instance.

        This enables applications that subclass `KernelManager` to persist a kernel provisioner's
        relevant information to accomplish functionality like disaster recovery or high availability
        by calling this method via the kernel manager's `provisioner` attribute.

        NOTE: The superclass method must always be called first to ensure proper serialization.
        r   r   r   r   r   provisioner_infor   r   r   get_provisioner_info   s    


z*KernelProvisionerBase.get_provisioner_info)r7   r   c                    s   |d | _ |d | _dS )a  
        Loads the base information necessary for persistence relative to this instance.

        The inverse of `get_provisioner_info()`, this enables applications that subclass
        `KernelManager` to re-establish communication with a provisioner that is managing
        a (presumably) remote kernel from an entirely different process that the original
        provisioner.

        NOTE: The superclass method must always be called first to ensure proper deserialization.
        r   r   Nr5   r6   r   r   r   load_provisioner_info   s    
z+KernelProvisionerBase.load_provisioner_info      @)recommendedr   c                 C   s   |S )aE  
        Returns the time allowed for a complete shutdown. This may vary by provisioner.

        This method is called from `KernelManager.finish_shutdown()` during the graceful
        phase of its kernel shutdown sequence.

        The recommended value will typically be what is configured in the kernel manager.
        r   r   r;   r   r   r   get_shutdown_wait_time   s    	z,KernelProvisionerBase.get_shutdown_wait_time      $@c                 C   s   |S )z
        Returns the expected upper bound for a kernel (re-)start to complete.
        This may vary by provisioner.

        The recommended value will typically be what is configured in the kernel restarter.
        r   r<   r   r   r   get_stable_start_time   s    z+KernelProvisionerBase.get_stable_start_time)r+   r   c                 C   s*   | j jr&| j j dr&|dd dS )z
        Ensures env is appropriate prior to launch.

        This method is called from `KernelProvisionerBase.pre_launch()` during the kernel's
        start sequence.

        NOTE: Subclasses should be sure to call super()._finalize_env(env)
        pythonZPYTHONEXECUTABLEN)r   languagelower
startswithr,   )r   r+   r   r   r   r2      s    	z#KernelProvisionerBase._finalize_env)substitution_valuesr   c                 C   sL   i }| j rHddlm} | j j}| D ] \}}|||||i q&|S )aq  
        Walks entries in the kernelspec's env stanza and applies substitutions from current env.

        This method is called from `KernelProvisionerBase.pre_launch()` during the kernel's
        start sequence.

        Returns the substituted list of env entries.

        NOTE: This method is private and is not intended to be overridden by provisioners.
        r   )Template)r   stringrE   r+   itemsr0   safe_substitute)r   rD   Zsubstituted_envrE   Ztemplated_envkvr   r   r   Z__apply_env_substitutions   s    z/KernelProvisionerBase.__apply_env_substitutions)F)F)F)F)r:   )r>   )'r   r   r   __doc__r
   r   r   __annotations__r   r   r	   strr   r   propertyr   boolr   r   intr   r   r!   r$   r%   r   r(   r)   r*   r   r3   r4   r8   r9   floatr=   r?   r2   r1   r   r   r   r   r      s<   
		
				r   )	metaclass)rK   r-   abcr   r   r   typingr   r   r   r   r	   Ztraitlets.configr
   r   r   connectr   typer   r   r   r   r   r   <module>   s   
  