B
    í\4  ã               @   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ZddlZejj	Z
ddlm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mZmZ er dndZG d	d
„ d
eƒZe dej¡Z dd„ Z!dZ"dd„ Z#dd„ Z$G dd„ de%ƒZ&G dd„ deƒZ'dd„ Z(dd„ Z)d dd„Z*e'j*j e*_ d!dd„Z+e'j+j e+_ dS )"zTools for managing kernel specsé    N)ÚPY3)Ú	HasTraitsÚListÚUnicodeÚDictÚSetÚBoolÚTypeÚCaselessStrEnum)ÚLoggingConfigurable)Újupyter_data_dirÚjupyter_pathÚSYSTEM_JUPYTER_PATHZpython3Zpython2c               @   s\   e Zd Zeƒ Zeƒ Zeƒ Zeƒ Z	eƒ Z
eddgddZeƒ Zedd„ ƒZdd„ Zdd	„ Zd
S )Ú
KernelSpecÚmessageÚsignal)Zdefault_valuec          	   C   sB   t |dƒ}tj|ddd}t |¡}W dQ R X | f d|i|—ŽS )z|Create a KernelSpec object by reading kernel.json

        Pass the path to the *directory* containing kernel.json.
        zkernel.jsonÚrzutf-8)ÚencodingNÚresource_dir)ÚpjoinÚioÚopenÚjsonÚload)Úclsr   Zkernel_fileÚfZkernel_dict© r   ú8lib/python3.7/site-packages/jupyter_client/kernelspec.pyÚfrom_resource_dir'   s    
zKernelSpec.from_resource_dirc             C   s$   t | j| j| j| j| j| jd}|S )N)ÚargvÚenvÚdisplay_nameÚlanguageÚinterrupt_modeÚmetadata)Údictr   r    r!   r"   r#   r$   )ÚselfÚdr   r   r   Úto_dict2   s    
zKernelSpec.to_dictc             C   s   t  |  ¡ ¡S )zOSerialise this kernelspec to a JSON object.

        Returns a string.
        )r   Údumpsr(   )r&   r   r   r   Úto_json=   s    zKernelSpec.to_jsonN)Ú__name__Ú
__module__Ú__qualname__r   r   r   r!   r"   r   r    r   r
   r#   r$   Úclassmethodr   r(   r*   r   r   r   r   r      s   r   z^[a-z0-9._\-]+$c             C   s
   t  | ¡S )z"Check that a kernel name is valid.)Ú_kernel_name_patÚmatch)Únamer   r   r   Ú_is_valid_kernel_nameG   s    r2   zuKernel names can only contain ASCII letters and numbers and these separators: - . _ (hyphen, period, and underscore).c             C   s   t j | ¡ot j t| dƒ¡S )zIs ``path`` a kernel directory?zkernel.json)ÚosÚpathÚisdirÚisfiler   )r4   r   r   r   Ú_is_kernel_dirQ   s    r7   c             C   sv   | dkst j | ¡si S i }xTt  | ¡D ]F}t| |ƒ}t|ƒs@q(| ¡ }t|ƒsftj	dt
|f dd |||< q(W |S )z…Return a mapping of kernel names to resource directories from dir.

    If dir is None or does not exist, returns an empty dict.
    Nz*Invalid kernelspec directory name (%s): %sé   )Ú
stacklevel)r3   r4   r5   Úlistdirr   r7   Úlowerr2   ÚwarningsÚwarnÚ_kernel_name_description)ÚdirÚkernelsr   r4   Úkeyr   r   r   Ú_list_kernels_inV   s    
rB   c               @   s   e Zd Zdd„ Zdd„ ZdS )ÚNoSuchKernelc             C   s
   || _ d S )N)r1   )r&   r1   r   r   r   Ú__init__l   s    zNoSuchKernel.__init__c             C   s   d  | j¡S )NzNo such kernel named {})Úformatr1   )r&   r   r   r   Ú__str__o   s    zNoSuchKernel.__str__N)r+   r,   r-   rD   rF   r   r   r   r   rC   k   s   rC   c               @   s°   e Zd ZeedddZeddddZeƒ Z	dd„ Z
eƒ Zdd„ Zedd	dZed
dZdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd"dd„Zd#dd„Zd$d d!„ZdS )%ÚKernelSpecManagerTz„The kernel spec class.  This is configurable to allow
        subclassing of the KernelSpecManager for customized behavior.
        )ZconfigÚhelpz†If there is no Python kernelspec registered and the IPython
        kernel is available, ensure it is added to the spec list.
        c             C   s   t ƒ S )N)r   )r&   r   r   r   Ú_data_dir_default‚   s    z#KernelSpecManager._data_dir_defaultc             C   s   t | jdƒS )Nr@   )r   Údata_dir)r&   r   r   r   Ú_user_kernel_dir_default†   s    z*KernelSpecManager._user_kernel_dir_defaultzcWhitelist of allowed kernel names.

        By default, all installed kernels are allowed.
        zLList of kernel directories to search. Later ones take priority over earlier.)rH   c             C   sz   t dƒ}yddlm} W n> tk
rV   yddlm} W n tk
rP   d }Y nX Y nX |d k	rv| tj |ƒ d¡¡ |S )Nr@   r   )Úget_ipython_dir)	r   ZIPython.pathsrL   ÚImportErrorZIPython.utils.pathÚappendr3   r4   Újoin)r&   ÚdirsrL   r   r   r   Ú_kernel_dirs_default’   s    z&KernelSpecManager._kernel_dirs_defaultc                sÌ   i }xLˆ j D ]B}t|ƒ}x4| ¡ D ](\}}||kr"ˆ j d||¡ |||< q"W qW ˆ jr¬t|kr¬y(ddlm} ˆ j dt|¡ ||t< W n" t	k
rª   ˆ j 
dt¡ Y nX ˆ jrÈ‡ fdd„| ¡ D ƒ}|S )z<Returns a dict mapping kernel names to resource directories.zFound kernel %s in %sr   )Ú	RESOURCESz$Native kernel (%s) available from %sz#Native kernel (%s) is not availablec                s    i | ]\}}|ˆ j kr||“qS r   )Ú	whitelist)Ú.0r1   Úspec)r&   r   r   ú
<dictcomp>·   s    z7KernelSpecManager.find_kernel_specs.<locals>.<dictcomp>)Úkernel_dirsrB   ÚitemsÚlogÚdebugÚensure_native_kernelÚNATIVE_KERNEL_NAMEÚipykernel.kernelspecrR   rM   ÚwarningrS   )r&   r'   Ú
kernel_dirr@   ÚknamerU   rR   r   )r&   r   Úfind_kernel_specs¢   s$    z#KernelSpecManager.find_kernel_specsc             C   s\   |t krPyddlm}m} W n tk
r0   Y n X ||krP| jf d|i|ƒ —ŽS | j |¡S )zb Returns a :class:`KernelSpec` instance for a given kernel_name
        and resource_dir.
        r   )rR   Úget_kernel_dictr   )r\   r]   rR   rb   rM   Úkernel_spec_classr   )r&   Úkernel_namer   rR   rb   r   r   r   Ú_get_kernel_spec_by_name»   s    z*KernelSpecManager._get_kernel_spec_by_namec             C   s¾   x†| j D ]|}yt |¡}W n8 tk
rR } z|jtjtjfkr@w‚ W dd}~X Y nX x.|D ]&}t||ƒ}| ¡ |krZt	|ƒrZ|S qZW qW |t
krºyddlm} W n tk
r´   Y nX |S dS )z2Find the resource directory of a named kernel specNr   )rR   )rW   r3   r:   ÚOSErrorÚerrnoZENOTDIRZENOENTr   r;   r7   r\   r]   rR   rM   )r&   rd   r_   ÚfilesÚer   r4   rR   r   r   r   Ú_find_spec_directoryË   s"    

z&KernelSpecManager._find_spec_directoryc             C   sB   t |ƒs| j d|t¡ |  | ¡ ¡}|dkr6t|ƒ‚|  ||¡S )z•Returns a :class:`KernelSpec` instance for the given kernel_name.

        Raises :exc:`NoSuchKernel` if the given kernel name is not found.
        z!Kernelspec name %r is invalid: %sN)r2   rY   r^   r>   rj   r;   rC   re   )r&   rd   r   r   r   r   Úget_kernel_specá   s    
z!KernelSpecManager.get_kernel_specc          	   C   s†   |   ¡ }i }xt| ¡ D ]h\}}y8| jtkr8|  ||¡}n
|  |¡}|| ¡ dœ||< W q tk
r|   | jj	d|dd Y qX qW |S )a*  Returns a dict mapping kernel names to kernelspecs.

        Returns a dict of the form::

            {
              'kernel_name': {
                'resource_dir': '/path/to/kernel_name',
                'spec': {"the spec itself": ...}
              },
              ...
            }
        )r   rU   zError loading kernelspec %rT)Úexc_info)
ra   rX   Ú	__class__rG   re   rk   r(   Ú	ExceptionrY   r^   )r&   r'   Zresr`   r   rU   r   r   r   Úget_all_specsð   s    

zKernelSpecManager.get_all_specsc             C   s^   | j }zd| _ |  ¡ }W d|| _ X || }| j d|¡ tj |¡rPt |¡ n
t 	|¡ |S )z\Remove a kernel spec directory by name.

        Returns the path that was deleted.
        FNzRemoving %s)
r[   ra   rY   rZ   r3   r4   ÚislinkÚremoveÚshutilÚrmtree)r&   r1   Zsave_nativeZspecsZspec_dirr   r   r   Úremove_kernel_spec  s    
z$KernelSpecManager.remove_kernel_specFNc             C   sL   |rt j | j|¡S |r4t j t j |¡ddd|¡S t j td d|¡S d S )NZshareZjupyterr@   r   )r3   r4   rO   Úuser_kernel_dirÚabspathr   )r&   rd   ÚuserÚprefixr   r   r   Ú_get_destination_dir$  s
    z&KernelSpecManager._get_destination_dirc             C   sì   |  d¡}|stj |¡}| ¡ }t|ƒs:td|tf ƒ‚|rJ|rJtdƒ‚|dk	rbtj	dt
dd | j|||d}| j d	|¡ tj |¡}|| jkr¨| j d
|| j¡ tj |¡rÌ| j d|¡ t |¡ t ||¡ | j d||¡ |S )a#  Install a kernel spec by copying its directory.

        If ``kernel_name`` is not given, the basename of ``source_dir`` will
        be used.

        If ``user`` is False, it will attempt to install into the systemwide
        kernel registry. If the process does not have appropriate permissions,
        an :exc:`OSError` will be raised.

        If ``prefix`` is given, the kernelspec will be installed to
        PREFIX/share/jupyter/kernels/KERNEL_NAME. This can be sys.prefix
        for installation inside virtual or conda envs.
        z/\zInvalid kernel name %r.  %szCCan't specify both user and prefix. Please choose one or the other.NzTreplace is ignored. Installing a kernelspec always replaces an existing installationé   )r9   )rw   rx   zInstalling kernelspec in %szFInstalling to %s, which is not in %s. The kernelspec may not be found.z"Removing existing kernelspec in %szInstalled kernelspec %s in %s)Úrstripr3   r4   Úbasenamer;   r2   Ú
ValueErrorr>   r<   r=   ÚDeprecationWarningry   rY   rZ   ÚdirnamerW   r^   r5   Úinforr   rs   Zcopytree)r&   Ú
source_dirrd   rw   Úreplacerx   Zdestinationr_   r   r   r   Úinstall_kernel_spec-  s2    



z%KernelSpecManager.install_kernel_specc             C   s*   t jddd ddlm} || |d dS )z+DEPRECATED: Use ipykernel.kenelspec.installzRinstall_native_kernel_spec is deprecated. Use ipykernel.kernelspec import install.rz   )r9   r   )Úinstall)rw   N)r<   r=   r]   r„   )r&   rw   r„   r   r   r   Úinstall_native_kernel_spec^  s    z,KernelSpecManager.install_native_kernel_spec)FN)NFNN)F)r+   r,   r-   r	   r   rc   r   r[   r   rJ   rI   ru   rK   r   rS   r   rW   rQ   ra   re   rj   rk   ro   rt   ry   rƒ   r…   r   r   r   r   rG   s   s.   !
	 
0rG   c               C   s
   t ƒ  ¡ S )z<Returns a dict mapping kernel names to resource directories.)rG   ra   r   r   r   r   ra   f  s    ra   c             C   s   t ƒ  | ¡S )z‚Returns a :class:`KernelSpec` instance for the given kernel_name.

    Raises KeyError if the given kernel name is not found.
    )rG   rk   )rd   r   r   r   rk   j  s    rk   Fc             C   s   t ƒ  | ||||¡S )N)rG   rƒ   )r   rd   rw   r‚   rx   r   r   r   rƒ   q  s    
rƒ   c             C   s   t ƒ j| dS )N)rw   )rG   r…   )rw   r   r   r   r…   x  s    r…   )NFFN)F),Ú__doc__rg   r   r   r3   Úrerr   r<   r4   rO   r   Zipython_genutils.py3compatr   Z	traitletsr   r   r   r   r   r   r	   r
   Ztraitlets.configr   Zjupyter_core.pathsr   r   r   r\   r   ÚcompileÚ
IGNORECASEr/   r2   r>   r7   rB   ÚKeyErrorrC   rG   ra   rk   rƒ   r…   r   r   r   r   Ú<module>   s:   () t 


