a
    <+bk                     @   sV  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 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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/ ddl0m1Z1 ddl2m3Z3 ddl4m5Z5 ddl6m7Z7 ddl8m9Z9 ddl:m;Z;m<Z< ddl=m>Z>m?Z?m@Z@ ddlAmBZB eCeZDeDEdddddddd d! eCeZFeFEd"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d/ eDEe eFEe eDEe@ eFEe? d0ZGG d1d" d"eee1ZHeHjIZJd2d3 ZKeLd4krReK  dS )5z%An Application for launching a kernel    N)partial)TextIOWrapperFileIO)StreamHandler)ioloop)	ZMQStream)BaseIPythonApplication
base_flagsbase_aliasescatch_config_error)
ProfileDir)InteractiveShellAppshell_flagsshell_aliases)	AnyInstanceDictUnicodeIntegerBoolDottedObjectNameTypedefault)import_item)filefindjupyter_runtime_dir)write_connection_file)ConnectionFileMixin   )IOPubThread)ControlThread)	Heartbeat)IPythonKernel)ParentPollerUnixParentPollerWindows)Sessionsession_flagssession_aliases)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-stderrr7   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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 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Z+e(dddj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Z0e1e2e3j45dp\dddjddZ6e1e2e3j45dpdddjddZ7d d! Z8d"d# Z9d$d% Z:d&d' Z;d(d) Z<d*d+ Z=d,d- Z>d.d/ Z?d0d1 Z@d2d3 ZAd4d5 ZBd6d7 ZCd8d9 ZDd:d; ZEd<d= ZFd>d? ZGd@dA ZHdBdC ZIdDdE ZJdFdG ZKdHdI ZLdJdK ZMdLdM ZNdNdO ZOdPdQ ZPeQdW fdSdT	ZRdUdV ZS  ZTS )Xr2   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)Z
allow_noneZinstall)z0ipykernel.kernelspec.InstallIPythonKernelSpecAppzInstall the IPython kernelconnection_dirc                 C   s   t  S Nr   self r@   2lib/python3.9/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 r=   )ospathbasenameconnection_filejoinr<   r>   r@   r@   rA   abs_connection_file   s    zIPKernelApp.abs_connection_fileFr4   )r;   r6   zSet main event loop.z(Only send stdout/stderr to output streamzipykernel.iostream.OutStreamz*The importstring for the OutStream factoryz$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 r=   )
excepthooksysr>   r@   r@   rA   init_crash_handler   s    zIPKernelApp.init_crash_handlerc                 C   s   t j|||tjd d S )Nfile)	tracebackprint_exceptionrJ   
__stderr__)r?   etypeevaluetbr@   r@   rA   rI      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 )NZwin32r   )rJ   platform	interruptparent_handler%   pollerr$   r>   r@   r@   rA   init_poller   s
    
zIPKernelApp.init_pollerc                 C   s   d| j | jf }| j dkrD|dkr.||}q|d| j|f  nf| j dkr|dkrd}d| j|f }tj|r|d }d| j|f }qhnd| j|f }|d|  |S )	Nz%s://%sZtcpr   ztcp://%s:%iZipcr   z%s-%izipc://%s)r1   r*   Zbind_to_random_portZbindrC   rD   exists)r?   sportZifacerD   r@   r@   rA   _try_bind_socket   s    

zIPKernelApp._try_bind_socketc                 C   s   z
t j}W n ty    d }Y n0 |r*dnd}t|D ]d}z| ||W   S  tjy } z2|j t jkrv|j |krv ||d kr W Y d }~q6d }~0 0 q6d S )Nr   d   )errnoZWSAEADDRINUSEAttributeErrorranger\   zmqZZMQErrorZ
EADDRINUSE)r?   rZ   r[   Z
win_in_useZmax_attemptsZattemptZzer@   r@   rA   _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*   keyr1   
shell_port
stdin_porthb_port
iopub_portcontrol_portN)rH   logdebugr   r*   sessionrc   r1   rd   re   rf   rg   rh   r?   Zcfr@   r@   rA   r      s    z!IPKernelApp.write_connection_filec                 C   sB   | j }| jd| zt| W n ty4   Y n0 |   d S )NzCleaning up connection file: %s)rH   ri   rj   rC   removeOSErrorZcleanup_ipc_filesrl   r@   r@   rA   cleanup_connection_file   s    z#IPKernelApp.cleanup_connection_filec                 C   s   | j sdt  | _ zt| j d| jg| _ W nJ tyv   | jd| j  tjtj	
| jddd t| j Y d S 0 z|   W n0 ty   | jjd| j dd | d	 Y n0 d S )
Nzkernel-%s.json.zConnection file not found: %si  T)modeexist_okz"Failed to load connection file: %rexc_infor   )rF   rC   getpidr   r<   rn   ri   rj   makedirsrD   dirnamerH   atexitregisterro   Zload_connection_file	Exceptionerrorexitr>   r@   r@   rA   init_connection_file   s    z IPKernelApp.init_connection_filec                 C   s   | j dt  | jd u s$J 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 )NzStarting the kernel at pid: %iz$init_sockets cannot be called twice!  z shell ROUTER Channel on port: %iz stdin ROUTER Channel on port: %iROUTER_HANDOVERr   )ri   inforC   ru   contextra   Contextrx   ry   closesocketROUTERshell_socketlingerrb   rd   rj   stdin_socketre   hasattrrouter_handoverinit_control
init_iopubr?   r   r@   r@   rA   init_sockets  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 )Nr~   z"control ROUTER Channel on port: %ir   r   T)Zdaemon)r   ra   r   control_socketr   rb   rh   ri   rj   ZSTREAMdebugpy_socketZDEALERdebug_shell_socketr   Z
getsockoptZLAST_ENDPOINTZconnectr   r   r!   control_threadr   r@   r@   rA   r   ,  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 )Nr~   ziopub PUB Channel on port: %iT)pipe)r   ra   ZPUBiopub_socketr   rb   rg   ri   rj   configure_tornado_loggerr    iopub_threadstartZbackground_socketr   r@   r@   rA   r   B  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)ra   r   r"   r1   r*   rf   	heartbeatr[   ri   rj   r   )r?   Zhb_ctxr@   r@   rA   init_heartbeatM  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  | 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,   r/   r.   zClosing %s channelZ_socketNzTerminating zmq contextzTerminated zmq context)reset_iori   r   r   rj   r   Ztermr   stopr   r   Zis_aliverG   r   closedr   getattr)r?   Zchannelr   r@   r@   rA   r   W  s2    








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s| j	t
jk rtttjd |D ]}t|tjd q~t| 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 %srL   )r,   r-   r.   r+   r/   N)rC   rD   rE   rF   rw   r<   ri   r   rV   	log_levelloggingCRITICALprint_ctrl_c_messagerJ   
__stdout__dictrd   rg   re   rf   rh   _ports)r?   rE   taillinesliner@   r@   rA   log_connection_infov  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)
r3   r5   openrC   devnullrJ   stdoutr   stderrrP   )r?   Z	blackholer@   r@   rA   init_blackhole  s    zIPKernelApp.init_blackholec                 C   s(  | j rtt| j }tjdu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u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   strrJ   r   flushquietr   rP   capture_fd_outputr   rk   r   r   r   ri   handlers
isinstancer   streambufferfilenorj   r   r   r   displayhook_classr   displayhookpatch_io)r?   Zoutstream_factoryZe_stdoutZe_stderrhandlerZdisplayhook_factoryr@   r@   rA   init_io  sB    





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)rJ   r   r   rP   r   __displayhook__r   r>   r@   r@   rA   r     s    zIPKernelApp.reset_ioc                    sp   zddl }W n ty   Y nN0 |j tjdf fdd	}||_t|drl|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)rM   all_threadsr@   )rM   r   kwargs)faulthandler_enabler@   rA   enable  s    z$IPKernelApp.patch_io.<locals>.enablery   Fc                    s    | f|||d|S )N)rM   r   chainr@   )ZsignumrM   r   r   r   )faulthandler_registerr@   rA   ry     s
    
z&IPKernelApp.patch_io.<locals>.register)faulthandlerImportErrorr   rJ   rP   r   ry   )r?   r   r   ry   r@   )r   r   rA   r     s    
zIPKernelApp.patch_ioc                 C   s   t  t jt j d S r=   )signalSIGINTSIG_IGNr>   r@   r@   rA   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)parentrk   control_streamdebugpy_streamr   shell_streamr   r   r   r   ri   profile_diruser_nsc                 S   s   i | ]\}}|d  |qS )Z_portr@   ).0namer[   r@   r@   rA   
<dictcomp>   s   z+IPKernelApp.init_kernel.<locals>.<dictcomp>c                      s    j S r=   )Zexecution_countr@   kernelr@   rA   <lambda>      z)IPKernelApp.init_kernel.<locals>.<lambda>N)r   r   r   r   io_loopr   r   kernel_classinstancerk   r   r   r   r   ri   r   r   Zrecord_portsr   itemsr   r   Zget_execution_count)r?   r   r   r   Zkernel_factoryr@   r   rA   init_kernel  s.    


zIPKernelApp.init_kernelc                    sV   t jdsdt jd< | j  j}z& fdd}| _t|  W | _n| _0 dS )z=Enable GUI event loop integration, taking pylab into account.Z
MPLBACKENDz)module://matplotlib_inline.backend_inlinec                    s(   t dtjd t  j|tjd d S )Nz-GUI event loop or pylab initialization failedrL   )r   rJ   r   ZInteractiveTBZstb2text)rQ   rR   Zstbr,   r@   rA   print_tb  s    z,IPKernelApp.init_gui_pylab.<locals>.print_tbN)rC   environgetr,   _showtracebackr   init_gui_pylab)r?   r   r   r@   r   rA   r     s    
zIPKernelApp.init_gui_pylabc                 C   s(   t | jdd | _| jr$| jj|  d S )Nr,   )r   r   r,   Zconfigurablesappendr>   r@   r@   rA   
init_shell%  s    zIPKernelApp.init_shellc                 C   s6   t d}t  }t t j}|| || dS )a6   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)r?   Zloggerr   Z	formatterr@   r@   rA   r   *  s
    

z$IPKernelApp.configure_tornado_loggerc                 C   sf   t jdrbt jdkrbddl}zddlm}m} W n tyD   Y n0 t|	 |u rb|
|  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)rJ   rT   
startswithversion_infoasyncior   r   r   typeZget_event_loop_policyZset_event_loop_policy)r?   r   r   r   r@   r@   rA   _init_asyncio_patch8  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)r?   r   r   r@   r@   rA   init_pdb_  s    
zIPKernelApp.init_pdbNc                    s   |    t | | jd ur"d S |   |   |   |   |   | 	  | 
  |   |   z|   W n. ty   | jtjk r| jjddd Y n0 |   |   |   | jr|   |   |   tj  tj  d S )NzUnable to initialize signal:Trs   )r   super
initializesubappr   r   r}   rX   r   r   r   r   r   r   rz   r   r   r   ri   r{   r   Z	init_pathr   r,   r   Zinit_extensionsZ	init_coderJ   r   r   r   )r?   argv	__class__r@   rA   r   m  s6    

zIPKernelApp.initializec                 C   s   | j d ur| j  S | jd ur(| j  | j  tj | _| jrddl	m
} | }|| j| j z|  W q ty   Y q0 n"z| j  W n ty   Y n0 d S )Nr   )
TrioRunner)r   r   rW   r   r   ZIOLoopZcurrentr   r9   Zipykernel.trio_runnerr   r   runKeyboardInterrupt)r?   r   Ztrr@   r@   rA   r     s$    




zIPKernelApp.start)N)U__name__
__module____qualname__r   r   kernel_aliasesaliaseskernel_flagsflagsr#   r)   r   r&   classesr   tagr   r   r   rW   r   r"   r   r   r   r   r   r   r   r   r   r   r   Zsubcommandsr   r<   r   rB   propertyrH   r   r3   r5   r9   r   r   r   r   r   r   intrC   r   r   rV   rU   rK   rI   rX   r\   rb   r   ro   r}   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   __classcell__r@   r@   r   rA   r2   i   s   




	)	'&c                  C   s   t  } |   |   dS )z!Run an IPKernel as an applicationN)r2   r   r   r   )Zappr@   r@   rA   main  s    r  __main__)M__doc__rx   rC   rJ   r^   r   rN   r   	functoolsr   ior   r   r   r   r   ra   Zzmq.eventloop.zmqstreamr   ZIPython.core.applicationr   r	   r
   r   ZIPython.core.profiledirr   ZIPython.core.shellappr   r   r   Z	traitletsr   r   r   r   r   r   r   r   r   Ztraitlets.utils.importstringr   Ztraitlets.utilsr   Zjupyter_core.pathsr   Zjupyter_clientr   Zjupyter_client.connectr   Ziostreamr    r/   r!   r   r"   Zipkernelr#   Zparentpollerr$   r%   Zjupyter_client.sessionr&   r'   r(   Zzmqshellr)   r   r  updater  r   r2   Zlaunch_instanceZlaunch_new_instancer  r   r@   r@   r@   rA   <module>   s   ,







    E
