U
    ҥcan                     @   sb  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ddlm	Z	 ddl
mZm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 ddlmZ dd	lmZmZmZ dd
lmZ ddlmZ ddl m!Z!m"Z"m#Z# ddl$m%Z% ddl&m'Z' ddl(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1 ddl2m3Z3 ddl4m5Z5 ddl6m7Z7 ddl8m9Z9 ddl:m;Z; ddl<m=Z= ddl>m?Z? ddl@mAZAmBZB ddlCmDZD eEeZFeFGddddddd d!d" eEeZHeHGd#d$d%iid&fd#d'd%iid(fd#d)d*iid+fd,d-d.iid/fd0 eFGe eHGe eFGe" eHGe# d1ZIG d2d# d#eeeZJeJjKZLd3d4 ZMeNd5kr^eM  dS )6z%An Application for launching a kernel    N)partial)FileIOTextIOWrapper)StreamHandler)Optional)BaseIPythonApplicationbase_aliases
base_flagscatch_config_error)
ProfileDir)InteractiveShellAppshell_aliasesshell_flags)write_connection_file)ConnectionFileMixin)Sessionsession_aliasessession_flagsjupyter_runtime_dir)ioloop)	AnyBoolDictDottedObjectNameInstanceIntegerTypeUnicodedefault)filefind)import_item)	ZMQStream   )ControlThread)	Heartbeat)IOPubThread)IPythonKernel)ParentPollerUnixParentPollerWindows)ZMQInteractiveShellzIPKernelApp.ipzIPKernelApp.hb_portzIPKernelApp.shell_portzIPKernelApp.iopub_portzIPKernelApp.stdin_portzIPKernelApp.control_portzIPKernelApp.connection_filezIPKernelApp.transport)iphbshelliopubstdincontrolf	transportIPKernelApp	no_stdoutT"redirect stdout to the null device	no_stderr"redirect stderr to the null devicepylabautoz^Pre-load matplotlib and numpy for interactive use with
        the default matplotlib backend.ZInteractiveShell	trio_loopFzEnable Trio as main event loop.)z	no-stdoutz	no-stderrr8   z	trio-loopa#  NOTE: When using the `ipython kernel` entry point, Ctrl-C will not work.

To exit, you will have to explicitly quit this process, by either sending
"quit" from a client, or using Ctrl-\ in UNIX-like environments.

To read more about this, see https://github.com/ipython/ipython/issues/2049

c                       s  e Zd ZU dZdZeeZeeZ	e
eeegZeddddjddZe Ze Zeedd	Ze Zeej ed
< e Ze Ze Ze Z e Z!e Z"e Z#e Z$e Z%ddiZ&e' Z(e)ddd Z*e+dd Z,e-dddjddZ.e-dddjddZ/e-dddjddZ0e-dddjddZ1e2ddddjddZ3e2dddjddZ4e-dddjddZ5e6e7e8j9:dprdd djddZ;e6e7e8j9:d!pdd"djddZ<d#d$ Z=d%d& Z>d'd( Z?d)d* Z@d+d, ZAd-d. ZBd/d0 ZCd1d2 ZDd3d4 ZEd5d6 ZFd7d8 ZGd9d: ZHd;d< ZId=d> ZJd?d@ ZKdAdB ZLdCdD ZMdEdF ZNdGdH ZOdIdJ ZPdKdL ZQdMdN ZRdOdP ZSdQdR ZTdSdT ZUeVdZ fdVdW	ZWdXdY ZX  ZYS )[r3   z The IPYKernel application class.zipython-kernelz ipykernel.ipkernel.IPythonKernelzipykernel.kernelbase.KernelzThe Kernel subclass to be used.

    This should allow easy re-use of the IPKernelApp entry point
    to configure and launch kernels other than IPython's own.
    )klasshelpT)Zconfig)
allow_nonecontextinstall)z0ipykernel.kernelspec.InstallIPythonKernelSpecAppzInstall the IPython kernelconnection_dirc                 C   s   t  S Nr   self rD   2lib/python3.8/site-packages/ipykernel/kernelapp.py_default_connection_dir   s    z#IPKernelApp._default_connection_dirc                 C   s0   t j| j| jkr&t j| j| jS | jS d S rA   )ospathbasenameconnection_filejoinr@   rB   rD   rD   rE   abs_connection_file   s    zIPKernelApp.abs_connection_fileFr5   )r<   r7   zSet main event loop.z(Only send stdout/stderr to output streamzipykernel.iostream.OutStreamz*The importstring for the OutStream factory)r<   r=   z$ipykernel.displayhook.ZMQDisplayHookz,The importstring for the DisplayHook factoryz[Attempt to capture and forward low-level output, e.g. produced by Extension libraries.
    ZJPY_PARENT_PIDr   zkill this process if its parent dies.  On Windows, the argument
        specifies the HANDLE of the parent process, otherwise it is simply boolean.
        ZJPY_INTERRUPT_EVENTzYONLY USED ON WINDOWS
        Interrupt this process when the parent is signaled.
        c                 C   s   | j t_ dS )zInitialize the crash handler.N)
excepthooksysrB   rD   rD   rE   init_crash_handler   s    zIPKernelApp.init_crash_handlerc                 C   s   t j|||tjd dS )zHandle an exception.fileN)	tracebackprint_exceptionrN   
__stderr__)rC   etypeevaluetbrD   rD   rE   rM      s    zIPKernelApp.excepthookc                 C   sD   t jdkr(| js| jr@t| j| j| _n| jr@| jdkr@t | _dS )zInitialize the poller.win32r#   N)rN   platform	interruptparent_handler)   pollerr(   rB   rD   rD   rE   init_poller   s
    
zIPKernelApp.init_pollerc                 C   s   | j  d| j }| j dkrF|dkr0||}q|d| j|f  nf| j dkr|dkrd}d| j|f }tj|r|d }d| j|f }qjnd| j|f }|d|  |S )	Nz://Ztcpr   ztcp://%s:%iZipcr#   z%s-%izipc://%s)r2   r+   Zbind_to_random_portZbindrG   rH   exists)rC   sportZifacerH   rD   rD   rE   _try_bind_socket   s    

zIPKernelApp._try_bind_socketc                 C   s   z
t j}W n tk
r"   d }Y nX |r,dnd}t|D ]b}z| ||W   S  tjk
r } z*|j t jkrz|j |krz ||d kr W 5 d }~X Y q8X q8d S )Nr#   d   )errnoZWSAEADDRINUSEAttributeErrorrangera   zmqZZMQErrorZ
EADDRINUSE)rC   r_   r`   Z
win_in_useZmax_attemptsZattemptZzerD   rD   rE   _bind_socket   s    

zIPKernelApp._bind_socketc                 C   sD   | j }| jd| t|| j| jj| j| j| j	| j
| j| jd	 dS )z"write connection info to JSON filezWriting connection file: %s)r+   keyr2   
shell_port
stdin_porthb_port
iopub_portcontrol_portN)rL   logdebugr   r+   sessionrh   r2   ri   rj   rk   rl   rm   rC   ZcfrD   rD   rE   r     s    z!IPKernelApp.write_connection_filec                 C   sD   | j }| jd| zt| W n tk
r6   Y nX |   dS )zClean up our connection file.zCleaning up connection file: %sN)rL   rn   ro   rG   removeOSErrorZcleanup_ipc_filesrq   rD   rD   rE   cleanup_connection_file  s    z#IPKernelApp.cleanup_connection_filec                 C   s   | j sdt  | _ zt| j d| jg| _ W nL tk
rx   | jd| j  tjtj	
| jddd t| j Y dS X z|   W n2 tk
r   | jjd| j dd	 | d
 Y nX dS )zInitialize our connection file.zkernel-%s.json.zConnection file not found: %si  T)modeexist_okNz"Failed to load connection file: %rexc_infor#   )rJ   rG   getpidr    r@   rs   rn   ro   makedirsrH   dirnamerL   atexitregisterrt   Zload_connection_file	ExceptionerrorexitrB   rD   rD   rE   init_connection_file  s$      z IPKernelApp.init_connection_filec                 C   s   | j dt  | jdks$tdt  | _}t	| j
 |tj| _d| j_| | j| j| _| j d| j  |tj| _d| j_| | j| j| _| j d| j  ttdrd | j_| j_| | | | dS )	z4Create a context, a session, and the kernel sockets.zStarting the kernel at pid: %iNz$init_sockets cannot be called twice!  z shell ROUTER Channel on port: %iz stdin ROUTER Channel on port: %iROUTER_HANDOVERr#   )rn   inforG   rz   r>   AssertionErrorrf   Contextr}   r~   closesocketROUTERshell_socketlingerrg   ri   ro   stdin_socketrj   hasattrrouter_handoverinit_control
init_iopubrC   r>   rD   rD   rE   init_sockets4  s     

zIPKernelApp.init_socketsc                 C   s   | tj| _d| j_| | j| j| _| jd| j  | tj	| _
d| j
_| tj| _d| j_| jtjr| j| jtj ttdrd| j_tdd| _dS )zInitialize the control channel.r   z"control ROUTER Channel on port: %ir   r#   T)daemonN)r   rf   r   control_socketr   rg   rm   rn   ro   ZSTREAMdebugpy_socketZDEALERdebug_shell_socketr   Z
getsockoptZLAST_ENDPOINTZconnectr   r   r$   control_threadr   rD   rD   rE   r   N  s    
zIPKernelApp.init_controlc                 C   sj   | tj| _d| j_| | j| j| _| jd| j  | 	  t
| jdd| _| j  | jj| _dS )zInitialize the iopub channel.r   ziopub PUB Channel on port: %iT)pipeN)r   rf   ZPUBiopub_socketr   rg   rl   rn   ro   configure_tornado_loggerr&   iopub_threadstartZbackground_socketr   rD   rD   rE   r   e  s    
zIPKernelApp.init_iopubc                 C   sJ   t  }t|| j| j| jf| _| jj| _| j	d| j  | j
  dS )zstart the heart beatingz!Heartbeat REP Channel on port: %iN)rf   r   r%   r2   r+   rk   	heartbeatr`   rn   ro   r   )rC   Zhb_ctxrD   rD   rE   init_heartbeatq  s
    
zIPKernelApp.init_heartbeatc                 C   s   |    | jd | jr2| jd | jj  | jrX| jd | j  | j	  | j
r| j
 r| jd | j
  | j
  | jr| jjs| j	  | jr| jjs| j	  dD ]4}| jd| t| |d d}|r|js|	  q| jd	 | jr| j  | jd
 dS )z'Close zmq sockets in an orderly fashionzCleaning up socketszClosing heartbeat channelzClosing iopub channelzClosing control thread)r-   r0   r/   zClosing %s channelZ_socketNzTerminating zmq contextzTerminated zmq context)reset_iorn   r   r   ro   r>   Ztermr   stopr   r   is_aliverK   r   closedr   getattr)rC   Zchannelr   rD   rD   rE   r   {  s4    








zIPKernelApp.closec                 C   s   t j| j}|| jks,t j| j| jkr2|}n| j}dd| g}|D ]}| j| qH| jst	| j
tjk rtttjd |D ]}t|tjd qt| j| j| j| j| jd| _dS )z(display connection info, and store portsz.To connect another client to this kernel, use:z    --existing %srP   )r-   r.   r/   r,   r0   N)rG   rH   rI   rJ   r|   r@   rn   r   r[   int	log_levelloggingCRITICALprint_ctrl_c_messagerN   
__stdout__dictri   rl   rj   rk   rm   _ports)rC   rI   taillineslinerD   rD   rE   log_connection_info  s.    zIPKernelApp.log_connection_infoc                 C   s@   | j s| jr<ttjd}| j r*| t_t_| jr<| t_t_	dS )z/redirects stdout/stderr to devnull if necessarywN)
r4   r6   openrG   devnullrN   stdoutr   stderrrT   )rC   Z	blackholerD   rD   rE   init_blackhole  s    zIPKernelApp.init_blackholec                 C   s(  | j rtt| j }tjdk	r(tj  | jr2dntj}| jrBdntj}| j	sZt
|dd}|| j| jd|dt_tjdk	rtj  || j| jd|dt_ttjdr| jjD ]>}t|tr|jj dkr| jd	 tttjjd
|_q| jrtt| j}|| j| j| _| jt_|   dS )z.Redirect input streams and set a display hook.NF)Zwatchfdr   )Zechor   _original_stdstream_copy   z9Seeing logger to stderr, rerouting to raw filedescriptor.r   )outstream_classr!   strrN   r   flushquietr   rT   capture_fd_outputr   rp   r   r   r   rn   Zhandlers
isinstancer   streambufferfilenoro   r   r   r   displayhook_classr   displayhookpatch_io)rC   Zoutstream_factoryZe_stdoutZe_stderrhandlerZdisplayhook_factoryrD   rD   rE   init_io  s6    



zIPKernelApp.init_ioc                 C   s   t jt _t jt _t jt _dS )zBrestore original io

        restores state after init_io
        N)rN   r   r   rT   r   __displayhook__r   rB   rD   rD   rE   r     s    zIPKernelApp.reset_ioc                    sr   zddl }W n tk
r    Y nNX |j tjdf fdd	}||_t|drn|jtjddffdd		}||_dS )
zAPatch important libraries that can't handle sys.stdout forwardingr   NTc                    s    f | |d|S )N)rQ   all_threadsrD   )rQ   r   kwargs)faulthandler_enablerD   rE   enable  s    z$IPKernelApp.patch_io.<locals>.enabler~   Fc                    s    | f|||d|S )N)rQ   r   chainrD   )ZsignumrQ   r   r   r   )faulthandler_registerrD   rE   r~   
  s      z&IPKernelApp.patch_io.<locals>.register)faulthandlerImportErrorr   rN   rT   r   r~   )rC   r   r   r~   rD   )r   r   rE   r     s    
zIPKernelApp.patch_ioc                 C   s   t  t jt j dS )zInitialize the signal handler.N)signalSIGINTSIG_IGNrB   rD   rD   rE   init_signal  s    zIPKernelApp.init_signalc                    s   t | j}t | j| jj}t | j| jj}| j  | jj}|| | j	||| j
|| j| j| j| j| j| j| jd  dd | j D   | _ fdd| j_dS )zCreate the Kernel object itself)parentrp   control_streamdebugpy_streamr   shell_streamr   r   r   r   rn   profile_diruser_nsc                 S   s   i | ]\}}|d  |qS )Z_portrD   ).0namer`   rD   rD   rE   
<dictcomp>,  s      z+IPKernelApp.init_kernel.<locals>.<dictcomp>c                      s    j S rA   )Zexecution_countrD   kernelrD   rE   <lambda>0      z)IPKernelApp.init_kernel.<locals>.<lambda>N)r"   r   r   r   io_loopr   r   kernel_classinstancerp   r   r   r   r   rn   r   r   Zrecord_portsr   itemsr   r   Zget_execution_count)rC   r   r   r   Zkernel_factoryrD   r   rE   init_kernel  s.    

zIPKernelApp.init_kernelc                    s\   t jdsdt jd< | j  dk	s(t j}z  fdd}| _t|  W 5 | _X dS )z=Enable GUI event loop integration, taking pylab into account.Z
MPLBACKENDz)module://matplotlib_inline.backend_inlineNc                    s4   t dtjd  d k	stt  j|tjd d S )Nz-GUI event loop or pylab initialization failedrP   )r   rN   r   r   ZInteractiveTBZstb2text)rU   rV   Zstbr-   rD   rE   print_tbG  s    z,IPKernelApp.init_gui_pylab.<locals>.print_tb)rG   environgetr-   r   _showtracebackr   init_gui_pylab)rC   r   r   rD   r   rE   r   2  s    
zIPKernelApp.init_gui_pylabc                 C   s(   t | jdd| _| jr$| jj|  dS )zInitialize the shell channel.r-   N)r   r   r-   ZconfigurablesappendrB   rD   rD   rE   
init_shellQ  s    zIPKernelApp.init_shellc                 C   s6   t d}t  }t t j}|| || dS )a5  Configure the tornado logging.Logger.

        Must set up the tornado logger or else tornado will call
        basicConfig for the root logger which makes the root logger
        go to the real sys.stderr instead of the capture streams.
        This function mimics the setup of logging.basicConfig.
        tornadoN)r   Z	getLoggerr   Z	FormatterZBASIC_FORMATZsetFormatterZ
addHandler)rC   loggerr   	formatterrD   rD   rE   r   W  s
    

z$IPKernelApp.configure_tornado_loggerc                 C   sh   t jdrdt jdkrdddl}zddlm}m} W n tk
rF   Y nX t|	 |krd|
|  dS )a  set default asyncio policy to be compatible with tornado

        Tornado 6 (at least) is not compatible with the default
        asyncio implementation on Windows

        Pick the older SelectorEventLoopPolicy on Windows
        if the known-incompatible default policy is in use.

        Support for Proactor via a background thread is available in tornado 6.1,
        but it is still preferable to run the Selector in the main thread
        instead of the background.

        do this as early as possible to make it a low priority and overrideable

        ref: https://github.com/tornadoweb/tornado/issues/2608

        FIXME: if/when tornado supports the defaults in asyncio without threads,
               remove and bump tornado requirement for py38.
               Most likely, this will mean a new Python version
               where asyncio.ProactorEventLoop supports add_reader and friends.

        win)      r   N)WindowsProactorEventLoopPolicyWindowsSelectorEventLoopPolicy)rN   rY   
startswithversion_infoasyncior   r   r   typeZget_event_loop_policyZset_event_loop_policy)rC   r   r   r   rD   rD   rE   _init_asyncio_patche  s    zIPKernelApp._init_asyncio_patchc                 C   s:   ddl }ddlm} t|dr6|j|_|j|_|j|_dS )zReplace pdb with IPython's version that is interruptible.

        With the non-interruptible version, stopping pdb() locks up the kernel in a
        non-recoverable state.
        r   N)debuggerInterruptiblePdb)pdbZIPython.corer   r   r   ZPdbZ	set_trace)rC   r   r   rD   rD   rE   init_pdb  s    
zIPKernelApp.init_pdbNc                    s   |    t | | jdk	r"dS |   |   |   |   |   | 	  | 
  |   |   z|   W n4 tk
r   t| jtjk r| jjddd Y nX |   |   |   | jr|   |   |   tj  tj  dS )zInitialize the application.NzUnable to initialize signal:Trx   ) r   super
initializesubappr   r   r   r]   r   r   r   r   r   r   r   r   r   r   r   rn   r   r   Z	init_pathr   r-   r   Zinit_extensionsZ	init_coderN   r   r   r   )rC   argv	__class__rD   rE   r    s6    

zIPKernelApp.initializec                 C   s   | j dk	r| j  S | jdk	r(| j  | j  tj | _| jrddl	m
} | }|| j| j z|  W q tk
r   Y qX n$z| j  W n tk
r   Y nX dS )zStart the application.Nr   )
TrioRunner)r  r   r\   r   r   ZIOLoopcurrentr   r:   Zipykernel.trio_runnerr  r  runKeyboardInterrupt)rC   r  trrD   rD   rE   r     s$    




zIPKernelApp.start)N)Z__name__
__module____qualname____doc__r   r   kernel_aliasesaliaseskernel_flagsflagsr'   r*   r   r   classesr   tagr   r   r   r\   r   r%   r   r>   r   rf   r   __annotations__r   r   r   r   r   r   r   r   r   subcommandsr   r@   r   rF   propertyrL   r   r4   r6   r:   r   r   r   r   r   r   r   rG   r   r   r[   rZ   rO   rM   r]   ra   rg   r   rt   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r
   r  r   __classcell__rD   rD   r  rE   r3   r   s   
	 

 
 $	#	%'c                  C   s   t  } |   |   dS )z!Run an IPKernel as an applicationN)r3   r   r  r   )ZapprD   rD   rE   main  s    r  __main__)Or  r}   rc   r   rG   r   rN   rR   	functoolsr   ior   r   r   typingr   rf   ZIPython.core.applicationr   r   r	   r
   ZIPython.core.profiledirr   ZIPython.core.shellappr   r   r   Zjupyter_clientr   Zjupyter_client.connectr   Zjupyter_client.sessionr   r   r   Zjupyter_core.pathsr   r   r   Ztraitlets.traitletsr   r   r   r   r   r   r   r   r   Ztraitlets.utilsr    Ztraitlets.utils.importstringr!   Zzmq.eventloop.zmqstreamr"   r0   r$   r   r%   Ziostreamr&   Zipkernelr'   Zparentpollerr(   r)   Zzmqshellr*   r   r  updater  r   r3   Zlaunch_instanceZlaunch_new_instancer  r  rD   rD   rD   rE   <module>   s   ,





    l
